You can add new item to game in a few very simple steps:
Download stendhal-0.xx-src.tar.gz from the stendhal-website and unpack it. All items.xml files are located in the /data/conf/items/ directory. They are arranged according to class (see below) such as shields, swords, keys, food, etc. The file contains all the description of the items in game. Lets start with how to do weapons, for example in swords.xml:
<item name="dagger"> <type class="sword" subclass="dagger" tileid="-1"/> <description>You see a dagger, it is little more than decorative but you can jab pretty fast with it.</description> <implementation class-name="games.stendhal.server.entity.item.Item"/> <attributes> <atk value="8"/> <rate value="3"/> </attributes> <weight value="0.2"/> <value value="8533"/> <equipable> <slot name="bag"/> <slot name="lhand"/> <slot name="rhand"/> </equipable> </item>
It is important to understand how it works.
We must give a name to the item and it is done in the item tag. Then we specify the class and the subclass on the type tag. If you check the way sprites are structure at client you will realize that it is in a similar fashion to:
sprites/ items/ class/ subclass.png
This way we can reuse a single GFX for different items. For example: knife+1, old knife, elvish knife, ... We give the item a nice description (for when the player does Look) inside the description tag.
The implementation tag should be copied from above, unless the item is stackable, in which case use:
Inside the attributes tag you can specify the attributes the weapon has:
- ATK it is a value proportional to the damage the item can do.
- DEF it is a value proportional to how much damage the item can block.
- RATE is how fast you can hit with an offensive weapon.
- RATE 1 means you can hit every turn, RATE 10 means only once every 10 turns.
- RATE must be greater than 0 but has no upper limit. (In stendhal the slowest rate weapon we have is 15)
- Only offensive weapons have a rate.
- RANGE is an attribute of attack - from - a - distance weapons like bow and arrow, or projectiles like spears.
- The larger the range the further the weapon is effective from.
- QUANTITY is an attribute for stackable weapons like arrows and spears (set to 1)
- LIFESTEAL is a special attribute for offensive weapons.
- It must be a number between -1 and 1.
- Any attack damage caused by a lifesteal weapon is 'refunded' to the player as healing HP
- A weapon with lifesteal 0.2 returns 20% HP to player of the damage they cause their enemy.
- Negative lifesteal drains the HP of a player according to the damage they cause their enemy.
For foods, drinks, potions and poisons the attributes are:
- AMOUNT - the total HP which the item restores (negative for poisonous items)
- REGEN - how much you are healed at a time (for potions this should be equal to AMOUNT, for poisons should be negative)
- FREQUENCY - how fast you are healed (lower number means faster, choose 1 for potions)
- QUANTITY - should be used (set to 1) they are all stackable items.
Note that potions and poisons (and antidotes) go in the drinks class. Antidotes have:
- AMOUNT - how long they protect you from poison (e.g. antidote is 400, greater is 800)
- REGEN equal to 0
- FREQUENCY equal to 1
- QUANTITY equal to 1
For scrolls, most of which are teleport scrolls, follow the examples in scrolls.xml for what implementation to use. The attribute INFOSTRING for marked scrolls is the destination of the scroll, e.g.
<infostring value="0_nalwor_city 40 60"/>
For summon scrolls the INFOSTRING is the creature name, but the implementation
takes care of this, so you do not set it.
That should be all the special items dealt with. Many items (e.g. herb, key, wood, money) would have no attributes, or no attributes except quantity.
Finally you need to specify where the item can be equipped:
All items should be equippable in bag, unless you have a good reason that players shouldn't be allowed to carry them. All stackable items should be equippable in rhand and lhand in case the player wants to split stacks. And although in stendhal we have the drawing of where the shield and sword should go on the character window, we do allow players to equip shield, and weapon in either hand. Rings go on the finger, but also in keyring and and bag for ease of carrying.
Now place the 32x32 sprite in the folder data/sprites/items/<class>/<subclass>.png
If you want your item image animated (like money) simply make a 32N x 32 sprite. E.g. if it has 5 frames in the animation it will be a 160 x 32 sprite. It will automatically appear animated.
Register the class
So far we have defined what the item is like to the server. Registering the class tells the client what to do with it. (Is it stackable and should have numbers displayed, is it useable and should have a Use displayed?) Most classes are already registered and you may be able to ignore this section... read on to find out.
Items will default to behave as a non stackable, non useable Item to the client. This covers armor, weapons, most items that don't change. Stackable but non useable classes get registered by class i.e. money, missiles, herbs etc. And most Useable items like food, drink, are registered as a whole class. So if you are adding to any existing class you very likely can ignore all this following stuff. Just come back if something doesn't work... like you expected to be able to use your new item and can't. Or if you are adding a totally new class.
So, if you have a new class and you want it to be stackable or useable or is a totally new client side object, extending Item, then add your class with type (item), class and your chosen behaviour to the rest in src/games/stendhal/client/entity/factory/EntityMap.java, e.g.
// flower was a new class of stackables register("item", "flower", null, StackableItem.class); // drink was a new class of Useables register("item", "drink", null, UseableItem.class); // Box is a new client side object register("item", "box", null, Box.class);
What if your item is part of a class which has a mixture of stackable and non stackable or useable and non useable? Remember the default is non stackable and non useable. So then you need to register the special ones individually. This is done by type (item), class, as before, and also subclass (same as in the xml) to specify which exact item you meant.
// most tools don't have a Use but the sugar mill should. the subclass in xml is sugarmill register("item", "tool", "sugarmill", UseableItem.class);
Finally, go to src/games/stendhal/client/gui/j2d/entity/EntityViewFactory.java and configure item in the same way only if you needed to add to EntityMap above. The examples are
// flower was a new class of stackables register("item", "flower", null, StackableItem2DView.class); // drink was a new class of Useables register("item", "drink", null, UseableItem2DView.class); // Box is a new client side object register("item", "box", null, Box2DView.class); // most tools don't have a Use but the sugar mill should. the subclass in xml is sugarmill register("item", "tool", "sugarmill", UseableItem2DView.class);
Item names should be short and enough to identify the item, but in spoken and written English there may be some extra words associated with saying the item. For example, Carmen should offer to sell 100 bottles of potion not 100 potion. (Add npc text example here?)
|potion||bottle of potion|
|leather legs||pair of leather legs|
|wine||glass of wine|
|plate armor||suit of plate armor|
|meat||piece of meat|
To add such a grammatical prefix to NPC speech and speech recognition, edit src/games/stendhal/common/grammar/PrefixManager.java.
Add to game
Dropped by creature
Creatures can drop items, see HowToAddCreaturesStendhal.
Add to map or grower
You may wish to add items to a map (for player to pick up or harvest). You can either add to zone by creating a java file (good for one - off items like the poison and scroll of Haizen's table in his hut) or add using tiled which is more work initially but allows you to add to the objects layer in tiled again and again in future. (Good for iron ore to collect from the ground, herbs etc). This needs a whole tutorial on spawners (also knows as growers), please see HowToAddGrowers.
Sold by NPC
If the NPC is not already created, you can code a new NPC. Then you will need to add a seller behaviour to your NPC, which should be covered separately. Until that is done, look at Seller examples such as Margaret in Semos Tavern in your source code. The file is src/games/stendhal/server/maps/semos/tavern/BarMaidNPC.java. If you have any problems with the NPC understanding the item name, you might like to check How to test NPC Parser.
Produced by NPC
If the NPC is not already created, you can code a new NPC. You will need to add a Producer behaviour to your NPC, which should be covered separately. Until that is done, look at Producer examples such as Arlindo in Ados Bakery in your source code. The file is src/games/stendhal/server/maps/ados/bakery/BakerNPC.java. If you have any problems with the NPC understanding the item name, you might like to check How to test NPC Parser.
Item Quests and Quest Rewards
Perhaps you will want your NPC to equip the player with an item as part of a quest, see HowToCreateQuests. You can also add your items to either the Daily Item quest or the Weekly item quest, which are related to the appearance around the world (e.g. rare item?).