Modding:Tutorial/Custom Items
From DoomRL Wiki
In the following tutorial you will learn the basics of item objects. Unique to item objects is the object's type, which carries with it a number of different prototype keys, engine hooks, and propertes. We will learn about each item type and what can be done with them to fit your particular item needs. In some cases items will appear roughly indistinguishable from cells: the defining factor here is that they can both exist on the same tile, whereas two cells or two items cannot.
Contents |
Base Prototype
Although this was more-or-less explained in the Game Objects tutorial, we will further explore each key in the base prototype.
Items{ name = "an item", --required field id = "generic", --defaults to 'name' sprite = 0, --required field; always set to 0 for now overlay = 0, --defaults to 0 color = WHITE, --defaults to LIGHTGRAY level = 1, --required field weight = 1000, --required field flags = {}, --default depends on item type set = "", --defaults to "" firstmsg = "You got an item!", --defaults to "" color_id = "generic", --defaults to 'id' res_bullet = 0, --defaults to 0 res_melee = 0, --defaults to 0 res_shrapnel = 0, --defaults to 0 res_acid = 0, --defaults to 0 res_fire = 0, --defaults to 0 res_plasma = 0, --defaults to 0 type = ITEMTYPE_NONE --required field ascii = "?" --default depends on item type }
- name is what the item appears to be in-game (e.g. using the 'look' command).
- id is what the item identifier, to be used in lua whenever you want to call the item prototype.
- sprite is what will eventually be the graphical tile of the item.
- overlay, like sprite, is based on there being graphical tiles in DoomRL. You can ignore this key entirely for the time being.
- color is one of 16 (4-bit) colors that you can use to distinguish the item on the map. For items that can be picked up, this is also the color of the item's name in your inventory/equipment screens.
- level is the minimum level that the item can appear on, for random item generation purposes.
- weight this affects the frequency that the item will appear, for random item generation purposes. Both level and weight are only important on levels that randomly generate items using Level.flood_items().
- flags defines what item flags you give your item. It is recommended that you figure out your item's type before adding flags, as some are only important for certain types.
- set defines what item set the item is in. For instance, the gothic armor/boots and phaseshift armor/boots are part of item sets. Item sets themselves are separate objects that must be defined before any item objects that use them.
- firstmsg is what will appear in the message area the very first time any item from this object prototype is picked up.
- color_id sets the id of the item for color-binding purposes. DoomRL levers, for instance, are all set to the same color_id, so that they cannot be disguished by a clever player manipulating color.lua carefully.
- res_[damage_type] sets the resistance for a particular damage type onto the item. This is only important for weapons, armor, and boots, as the resistance can only help if the item is equipped.
- type is, quite possibly, the most important key for an item, as it sets the item's type, which then determines what additional keys are required/allowed, what engine hooks it can use, and what properties it has. Each type will be explained shortly.
- ascii is the character that is used for the item on the map. Although this isn't explicitly a part of the base prototype, it exists across all item types, the only difference being its default character (which will be included with each type in this tutorial).
Item types are always written as ITEMTYPE_[type], where [type] is the actual type of the item. A shorthand o this form (e.g., "_RANGED") will be used throughout the tutorial
Deadweight (_NONE)
Deadweight items have no additional prototype keys. In fact, they only have two properties:
- itype is the item type in property form. As _NONE, an item cannot be picked up or used.
- proto is the prototype of the instantiated item.
In addition, deadweight items can make use of the OnCreate() engine hook.
Items of this type are, quite literally, placeholders. They serve little purpose other than display or preventing another item from being dropped onto its tile. It is technically possible to change a deadweight item that exists on the map into a different type, at which point other properties could be applied to it and would act similarly to another item type: however, with the engine hooks supplied in those other item types, there is almost never a need to do this.
Teleporters (_TELE)
Teleporter items are almost identical to deadweight items, except that they are allowed the use of an extra engine hook: OnEnter(). In fact, OnEnter() must be defined in the teleporter item, since they are so pivotal in their function. Teleporters use '*' as its default ASCII character.
In the case of DoomRL, teleporter items are given an extra property using the OnCreate() hook that defines a particular coordinate on the map. This coordinate is then used during OnEnter() to teleport a being that enters the teleporter. Since we want the location to be different for every teleporter, this is why we don't have a "location" prototype key and, instead, have to alter its properties. A basic example is given below:
Items{ name = "teleporter", id = "port", sprite = 0, color = LIGHTBLUE, weight = 0, type = ITEMTYPE_TELE, function OnCreate(self) local location = coord.random(area.get(area.FULL)) self:add_property("exit_pt",location) end, function OnEnter(self,being) being.displace(exit_pt) end }
First, we use OnCreate to determine a random location. This is done by using coord.random(), which returns a random coordinate between the two given coordinates. area.get() returns the upper-left and bottom-right coordinates of a given area: by selecting area.FULL (which is a pre-defined area that covers the entire map), we return the boundary coordinates of the map, which are then called into coord.random() to give us a random coordinate anywhere on the map.
After we grab this location, we use thing:add_property() which takes in the key of the property to be added and the value it should be given. For our cases, we make a key called "exit_pt" (exit point) and set its value to the random coordinate we found.
Finally, we use the function thing.displace() to move the being, and place it within OnEnter() so that it will occur whenever the being enters the same tile as the teleporter item. This example doesn't handle problems such as locations that exist in a cell that blocks movement, however, so it should be improved upon if you want a more useful random teleporter.
Armor (_ARMOR) and Boots (_BOOTS)
_ARMOR uses '[' _BOOTS uses ';' _PACK uses '+' _POWER uses '^' _AMMO uses '|' _AMMOPACK uses '!' _RANGED uses '}' _NRANGED uses '?' _MELEE uses '\' _LEVER uses '&' _NONE has no default