How to add new wood types to the Classic Distro.

Sometimes you need to share your knowledge. This is where you can do it. A place for POL and Script guides.
Post Reply
Yukiko
Distro Developer
Posts: 2728
Joined: Thu Feb 02, 2006 1:41 pm
Location: San Antonio, Texas
Contact:

How to add new wood types to the Classic Distro.

Post by Yukiko » Sun Dec 09, 2018 1:28 am

Recently I was asked, in Discordance, how to add different wood types to the Classic Distro. I told the individual it was something that required a tutorial because it is not a simple thing to do. I said as soon as I had the time I would write one. Well, here it is.

The first thing I did when I added custom wood types to my server, Hope Lives was to look-up the graphics for the different trees I wanted to yield the custom wood types. I will use the Oak tree in this tutorial.

The Oak tree has eight graphics if you also include the leaves. I was nice and did not restrict my players from only double-clicking on the tree trunks to chop the wood. However, for the sake of realism in this tutorial, we will only be concerned with the trunk graphics for Oak trees.

The Oak tree trunk graphics are 0x0CDA, 0x0CDD, 0x224C, and 0x224D.

The next thing you need to do is define an Oak log. You will need to find a range of unused ObjType numbers. If you have executed POL you will have a file in the POL root named objtypes.txt. Open the file and look for a range of unused ObjType numbers. I would suggest looking above 0x20000.

Let me digress a moment to explain a little about the organization of art tiles and custom items. Ultima Online® originally had art tiles defined in the range 0x0000 to 0x3FFF. This was the situation until the UO expansion High Seas where the art tile range was expanded to 0x7FFF. When Time of Legends was released the art tile range was further expanded to 0xFFFF. Custom items used numbers above the art tile’s highest number. In the early days, this was 0x4000 to 0xFFFF. As the art tile range expanded we were forced to move custom items to a higher and higher number range. You might be asking “What are custom items?” They are special items that you create that are not part of the standard art tiles, such as custom logs. These custom items need their own ObjType number so that POL can reference them in the world data files and in eScript programmes. Custom items need to have a graphic assigned to them from among the art tile graphics but they have a unique item number or ObjType number. If you create an item that is within the art tile range, currently 0x0000 to 0xFFFF POL uses the art tile number as the ObjType for that item but custom items need their own unique object type number. I am happy to inform you that, thanks to the POL developers, we have a huge range of ObjType numbers to choose from. There is a setting in pol.cfg, MaxObjtype, which can be set as high as 0x7FFFFFFF. That is 2,147,352,575 possible locations to choose from. I am accounting for the first 131,072 (0x0000 through 0x1FFFF) being reserved ObjType numbers just in case the powers that be at UO Central decide to expand the art tile range again. So you have a wide open area to assign custom ObjType numbers without being concerned with duplication. If you are using the POL Configurator to configure POL’s settings you will find this on the Server Settings page. The default setting is 0x7FFFFFFF because, why not? If your MaxObjtype setting is below 0x30000 then I suggest you increase it to at least 0x30000. But why not go for the maximum?

Now back to the tutorial.
Assuming you have objtypes.txt open, I suggest finding a contiguous range of numbers that are unused. This allows for the expansion of wood types later.
For this example I will assume that 0x20000 is an unused ObjType number. Open /pkg/items/logs/config/itemdesc.cfg in your editor and enter the following:

Code: Select all

Item 0x20000  <<<< Change this number to one unused by your server.
{
	Name			oaklog
	Desc				oak log%s
	Graphic			0x1bdd
	Color			0x0030
	CProp			MaterialName	soak
	VendorSellsFor	8
	VendorBuysFor	1
	Weight			1/3
}
Congratulations! You have just defined a custom log. We still have to tell the lumberjacking programme (script) how to create that log when an Oak tree is chopped and the carpentry programme how to transfer the name “Oak” and the colour of the log to the crafted item.

First, we have to be able to chop the logs.
Open /pkg/skills/lumberjacking/lumberjack.src in your editor. Look for the line

Code: Select all

var points := CInt((AP_GetSkill(me, LUMBERJACKING) * 2) + 10);
After that line insert the following:

Code: Select all

   var logtype := 0x1bdd;
    var treetype := FindTreeType(tree);
    case(treetype)
	1:              difficulty := 10;   logtype := 0x1bdd;
	2:              difficulty := 30;   logtype := 0x20000; // Remember to change this number to the ObjType number you assigned to Oak logs.
    endcase
Search for the line:

Code: Select all

if(!CreateItemInBackpack(me, 0x1bdd, wood_amount))
Change 0x1bdd to logtype

Now go to the end of the file and enter the following function:

Code: Select all

function FindTreeType(tree)

         if( (Hex(tree.objtype) == "0xCDA") || (Hex(tree.objtype) == "0xCDD") || (Hex(tree.objtype) == "0x224C") || (Hex(tree.objtype) == "0x224D") )
           return 2;            // Oak tree

         else
           return 1;            // Any other kind of tree (normal logs)
         endif
endfunction

You can now chop Oak logs from Oak trees.

The second thing we need to do is to add the ability to craft things from the Oak logs. Open /pkg/skills/carpentry/carpentry.src in your editor.

Search for these lines. There should be two of them.

Code: Select all

if((item1.objtype != 0x1bdd) && (item1.objtype != 0x1bd7))
Change them to:

Code: Select all

if((item1.objtype != 0x1bdd) && (item1.objtype != 0x20000) && (item1.objtype != 0x1bd7)) // Remember to change 0x20000 to the ObjType number you defined for Oak logs.
Look for this line:

Code: Select all

if(SkillCheck(who, CARPENTRY, skill, (skill * 2)))
Above that line insert:

Code: Select all

var MatName;
Look a few lines below the SkillCheck line until you see:

Code: Select all

theitem := CreateItemInContainer(cont, objtype, 1);
Below that line insert the following lines:

Code: Select all

MatName := GetObjProperty(item1, "MaterialName");
theitem.Set_Member("Name", MatName + " " + theitem.Name);
SetObjProperty(theitem, "MaterialName", MatName);
theitem.Color := item1.Color;
Look nine lines down until you see another CreateItemInContainer function call just like the one above and below it insert those same lines:

Look for this line:

Code: Select all

if(SkillCheck(who, CARPENTRY, CInt(skill), 0))
Above that line insert:

Code: Select all

var MatName;
We are almost done.
While you are at this place, look a few lines down until you see:

Code: Select all

theitem := CreateItemInContainer(cont, objtype, amt);
Just below that line insert the following lines:

Code: Select all

MatName := GetObjProperty(item1, "MaterialName");
theitem.Set_Member("Name", MatName + " " + theitem.Name);
SetObjProperty(theitem, "MaterialName", MatName);
theitem.Color := item1.Color;
You can now use the carpentry skill to craft items from Oak logs and the name of the item will have the prefix “oak” and the item will be coloured the same as oak logs.

I have given you enough information to add all the custom wood types you desire. And since I took the time to write this tutorial, I have an assignment for you. Using the Classic Distro add Walnut logs to the lumberjacking and carpentry programmes (scripts). I will give you a little help. Use UO Fiddler to look up the two graphics for the walnut tree trunks. If you do not want to try to find a colour for the logs then you can use 0x73C. We used that hue on Hope Lives. It can be hard sometimes picking a hue that looks good.

Let me mention that this system of adding custom wood types could be written better. I was asked how to add new wood types to the Classic Distro and so I chose to work within the confines of that system. As you may know, it is based on the 095 Distro and I did not want to rewrite the whole lumberjacking programme. This will work and I leave it up to others to rewrite and improve upon the system.

User avatar
Ciechu
New User
Posts: 29
Joined: Mon Oct 15, 2018 5:36 am
Location: Poland

Re: How to add new wood types to the Classic Distro.

Post by Ciechu » Mon Dec 10, 2018 12:18 pm

It is very nice to see that there are people who spend thier free time for others. I know that someone will use it. Try to add this to tutorials in docs.

Greetz, Ciechu

Yukiko
Distro Developer
Posts: 2728
Joined: Thu Feb 02, 2006 1:41 pm
Location: San Antonio, Texas
Contact:

Re: How to add new wood types to the Classic Distro.

Post by Yukiko » Mon Dec 10, 2018 9:37 pm

Thank you for your kind words Ciechu. Perhaps the developers can add tutorials from the forums to the documents.

The truth is I have wanted to write this type of tutorial for a long time.

When I started playing UO back in 2002 I played on a shard, Journey's End, and it had custom wood and ore types. When it shut down I started my own shard and it took me a while, and lots of questions on these very forums, to begin to learn how to add those very same things to my shard. I wish there had been something like this tutorial back in 2003 when I started delving into the "script mine".

I hope this helps someone to not only implement new wood types but learn a little more about writing eScript programmes.

I would like more people to contribute tutorials as well.

Post Reply