Difference between revisions of "Modding:Tutorial/Custom Beings"

From DoomRL Wiki

Jump to: navigation, search
m (Engine Hooks: minor details)
m (small fixes and clarifications)
Line 49: Line 49:
 
*''ascii'' is the ASCII character used to represent the being in the console.
 
*''ascii'' is the ASCII character used to represent the being in the console.
 
*''color'' is one of 16 (4-bit) [[Modding:Constants#Colors|colors]] that you can use to distinguish the being on the map.
 
*''color'' is one of 16 (4-bit) [[Modding:Constants#Colors|colors]] that you can use to distinguish the being on the map.
*''sound_id'' is what you want the being's sound bindings to map to. If the being's id is not registered for sound bindings, it will use this key instead (useful when mapping several beings to a single set of sounds).
+
*''sound_id'' is what you want the being's sound bindings to map to. If the being's id is not registered for sound bindings, it will use this key instead (useful when mapping several beings to a single set of sounds). (Note that in the current version, registering sound bindings for custom beings requires direct manipulation of the prototype. This will be explained later on.)
 
*''desc'' is the description of the enemy, as seen when using the 'more' command while looking.
 
*''desc'' is the description of the enemy, as seen when using the 'more' command while looking.
 
*''kill_desc'' is what shows at the top of a mortem if the player was killed by this being's ranged attack.
 
*''kill_desc'' is what shows at the top of a mortem if the player was killed by this being's ranged attack.
 
*''kill_desc_melee'' is what shows at the top of a mortem if the player was killed by this being's melee attack.
 
*''kill_desc_melee'' is what shows at the top of a mortem if the player was killed by this being's melee attack.
 
*''weight'' affects the frequency that the being will appear, for random monster generation purposes.  
 
*''weight'' affects the frequency that the being will appear, for random monster generation purposes.  
*''danger'' is the capacity by which this being can be added to the map, for random monster generation purposes.
+
*''danger'' is the capacity by which the being can be added to the map, for random monster generation purposes.
 
*''minLev'' is the earliest floor on which the being can appear, for random monster generation purposes.
 
*''minLev'' is the earliest floor on which the being can appear, for random monster generation purposes.
 
*''maxLev'' is the latest floor on which the being can appear, for random monster generation purposes. ''weight'', ''danger'', ''minLev'', and ''maxLev'' are only important on levels that randomly generate beings using Level.flood_monsters().  
 
*''maxLev'' is the latest floor on which the being can appear, for random monster generation purposes. ''weight'', ''danger'', ''minLev'', and ''maxLev'' are only important on levels that randomly generate beings using Level.flood_monsters().  
*''corpse'' determines if the being will generate a corpse upon death. Alternatively, you can choose a cell (by referencing its id here) that the being will leave upon death (e.g., setting this to "acid" or "lava" to make an enemy that leaves a hazardous tile when it dies).
+
*''corpse'' determines if the being will generate a corpse upon death. Alternatively, you can choose a cell (by referencing its id here) that the being will leave upon death.
 
*''HP'' determines how much damage the being can take before it dies.
 
*''HP'' determines how much damage the being can take before it dies.
*''armor'' determines how much damage the being absorbs before HP is subtracted. Without BF_HARDY, armor can only reduce damage to 1.
+
*''armor'' determines how much damage the being absorbs before HP is subtracted, modified by the damage type of the source. Note that, without BF_HARDY, armor can only reduce damage to 1.
*''res_[damage_type]'' sets the internal resistance of the being for damage_type. Internal resistance affects both torso and foot sources.
+
*''res_[damage_type]'' sets the internal [[resistances|resistance]] of the being for damage_type. Internal resistance affects both torso and foot sources. Note that amount of damage absorbed by resistance is calculated before any damage absorption due to ''armor'', and that 100% resistance can reduce damage to 0 (though anything less will not).
 
*''weapon'' sets the being's default weapon (in its weapon equipment slot). This can either be an id for a separate [[Modding:Item|item prototype]], or it can be inlined into the being prototype. If inlined, the following is true by default for the item prototype:
 
*''weapon'' sets the being's default weapon (in its weapon equipment slot). This can either be an id for a separate [[Modding:Item|item prototype]], or it can be inlined into the being prototype. If inlined, the following is true by default for the item prototype:
 
**''type'' is set to ITEMTYPE_NRANGED
 
**''type'' is set to ITEMTYPE_NRANGED
**''id'' is automatically assigned (although no callable id (sid) will exist)
+
**''id'' is automatically assigned (although no lua-based id (sid) will exist)
 
**''weight'' and ''sprite'' are set to 0
 
**''weight'' and ''sprite'' are set to 0
 
**IF_NODROP and IF_NOAMMO are added to the ''flags'' table
 
**IF_NODROP and IF_NOAMMO are added to the ''flags'' table
 
*''toDam'' is the damage modifier to the being's natural melee attack. It deals 1d3 damage unmodified.
 
*''toDam'' is the damage modifier to the being's natural melee attack. It deals 1d3 damage unmodified.
 
*''toHit'' is the [[accuracy]] modifier to all of the being's attacks.
 
*''toHit'' is the [[accuracy]] modifier to all of the being's attacks.
*''toHitMelee'' is the accuracy modifier to the being's melee attack. toHit and toHitMelee can have negative values (e.g., setting the melee to-hit to 0 while keeping the ranged to-hit at some positive value).
+
*''toHitMelee'' is the accuracy modifier to the being's melee attack. toHit and toHitMelee can have negative values (e.g., in order to set melee to-hit to 0 while keeping ranged to-hit at some positive value).
 
*''attackchance'' is the chance that the being will attack on a given turn. This can be overridden with custom AI.
 
*''attackchance'' is the chance that the being will attack on a given turn. This can be overridden with custom AI.
 
*''vision'' is the [[distance]] in which the being can see, assuming no cells that block vision are present.
 
*''vision'' is the [[distance]] in which the being can see, assuming no cells that block vision are present.
Line 101: Line 101:
 
**''tohitmelee'' is the property of ''toHitMelee''
 
**''tohitmelee'' is the property of ''toHitMelee''
 
**''expvalue'' is the property of ''XP''
 
**''expvalue'' is the property of ''XP''
 
+
*There are also a number of properties that are instantiated by default without automatic customization. They are as follows:
There are also a number of properties that are instantiated by default without automatic customization. They are as follows:
+
**''proto'' is the being's prototype. Don't change this unless you're planning on doing something really hacky.
 
+
**''hp'' is the being's current health. It defaults to the ''HP'' prototype key, but changes whenever the being takes damage.
*''proto'' is the being's prototype. Don't change this unless you're planning on doing something really hacky.
+
**''scount'' is the being's speed count, or [[Time#Fractional_Time|energy]]. For each turn that passes, all beings' ''scount'' is increased 100 (modified by each's ''speed''); whenever a particular being takes an action, its ''scount'' is decreased by the amount of game seconds it takes for the action, multiplied by 1000. (For custom actions, ''scount'' must be modified manually in order for the action to take any time.)
*''hp'' is the being's current health. It defaults to the ''HP'' prototype key, but changes whenever the being takes damage.
+
**''todamall'' is a damage modifer applied to all of the being's attack (melee and ranged). (When the player invests in [[Son of a Bitch]], this property is modified.)
*''scount'' is the being's speed count, or [[Time#Fractional_Time|energy]]. For each turn that passes, all beings' speed count is decreased by 100; whenever a particular being takes an action, its speed count is increased by an amount equal to the being's ''speed'' (excluding other factors).
+
**Three properties affect the time in which particular actions are taken, given as a percentage relative to ''speed'':
*''todamall'' is a damage modifer applied to all of the being's attack (melee and ranged). (When the player invests in [[Son of a Bitch]], this property is modified.)
+
***''movetime'' affects how much time it takes for the being to move: for the player, this also corresponds to an increased dodge chance. (When the player invests in [[Hellrunner]], this property is modified.)
*Three properties affect the time in which particular actions are taken, given as a percentage relative to ''speed'':
+
***''reloadtime'' affects how much time it takes for the being to reload its weapon. (When the player invests in [[Reloader]], this property is modified.
**''movetime'' affects how much time it takes for the being to move: for the player, this also corresponds to an increased dodge chance. (When the player invests in [[Hellrunner]], this property is modified.)
+
***''firetime'' affect how much time it takes for the being to attack. (When the player invests in [[Finesse]], this property is modified.)
**''reloadtime'' affects how much time it takes for the being to reload its weapon. (When the player invests in [[Reloader]], this property is modified.
+
**''bodybonus'' reduces knockback by the number given, and any value greater than 0 will prevent health decay above 100%. (When the player invests in [[Badass]], this property is modified.)
**''firetime'' affect how much time it takes for the being to attack. (When the player invests in [[Finesse]], this property is modified.)
+
**''pistolbonus'' lowers firetime and increases damage whenever the being is using a weapon with the item flag IF_PISTOL. (When the player invests in [[Son of a Gun]], this property is modified.)
*''bodybonus'' reduces knockback by the number given, and any value greater than 0 will prevent health decay above 100%. (When the player invests in [[Badass]], this property is modified.)
+
**''rapidbonus'' modifies the number of shots fired from a weapon whose "shots" property is greater than one. (When the player invests in [[Triggerhappy]], this property is modified.)
*''pistolbonus'' lowers firetime and increases damage whenever the being is using a weapon with the item flag IF_PISTOL. (When the player invests in [[Son of a Gun]], this property is modified.)
+
**''techbonus'' increases the number of mods that can be added to the being's equipment, as well as what tier of assemblies the being can create. (When the player invests in [[Whizkid]], this property is modified.)
*''rapidbonus'' modifies the number of shots fired from a weapon whose "shots" property is greater than one. (When the player invests in [[Triggerhappy]], this property is modified.)
+
*Finally, there are the properties that beings inherit from [[Modding:Thing|things]]. (Some of the thing properties are readonly, meaning they can't be changed once the instantiated object is initialized. These will be bolded for clarification.)
*''techbonus'' increases the number of mods that can be added to the being's equipment, as well as what tier of assemblies the being can create. (When the player invests in [[Whizkid]], this property is modified.)
+
**The following properties are the same as the prototype keys:
 
+
***''color''
Finally, there are the properties that beings inherit from [[Modding:Thing|things]]. (Some of the thing properties are readonly, meaning they can't be changed once the instantiated object is initialized. These will be bolded for clarification.)
+
***'''''id'''''
 
+
***''name''
*The following properties are the same as the prototype keys:
+
***''sprite''
**''color''
+
***''res_bullet''
**'''''id'''''
+
***''res_shrapnel''
**''name''
+
***''res_melee''
**''sprite''
+
***''res_acid''
**''res_bullet''
+
***''res_fire''
**''res_shrapnel''
+
***''res_plasma''
**''res_melee''
+
**The following properties have a different name than a prototype key, but function exactly the same as the key:
**''res_acid''
+
***''picture'' is the property of ''ascii''
**''res_fire''
+
***''nameplural'' is the property of ''name_plural''
**''res_plasma''
+
**The following properties are automatically given by default:
*The following properties have a different name than a prototype key, but function exactly the same as the key:
+
***'''''sid''''' is a string identifier, similar to '''''id'''''. This is what is used dominantly by modders, and is set based on the being's ''id'' key.  
**''picture'' is the property of ''ascii''
+
***'''''uid''''' is a unique identifier across all instantiated objects. This is often used to save the state of a game.
**''nameplural'' is the property of ''name_plural''
+
***'''''x''''' is the x-coordinate of the being on the map.
*The following properties are automatically given by default:
+
***'''''y''''' is the y-coordinate of the being on the map. '''''x''''' and '''''y''''' make up a being's [[Modding:Coord|coordinate]] indirectly.
**'''''sid''''' is a string identifier, similar to '''''id'''''. This is what is used dominantly by modders, and is set based on the being's ''id'' key.  
+
***'''''__ptr''''' is a pointer to the object in the engine: you'll never have to worry about this property.
**'''''uid''''' is a unique identifier across all instantiated objects. This is often used to save the state of a game.
+
**'''''x''''' is the x-coordinate of the being on the map.
+
**'''''y''''' is the y-coordinate of the being on the map. '''''x''''' and '''''y''''' make up a being's [[Modding:Coord|coordinate]] indirectly.
+
**'''''__ptr''''' is a pointer to the object in the engine: you'll never have to worry about this property.
+
  
 
==Engine Hooks==
 
==Engine Hooks==

Revision as of 18:53, 7 October 2011

In the following tutorial you will learn the basics of being objects. Beings are anything in the game that can act independently on the map, without the need to specifically interact with with it. The player object is also a being, and so all of the topics mentioned here will also apply to the player (with some exceptions). We will learn how to create new beings, as well as how to apply various modifications in order to produce special and unique varieties.

Prototype

The following is a complete list of the being prototype table:

Beings{
    name            = "evil marine",                --required field
    name_plural     = "evil marines",               --defaults to name with an appended 's'
    id              = "badclone",                   --defaults to lowercased first word of 'name'
    ascii           = "@",                          --required field
    color           = DARKGRAY,                     --required field
    sound_id        = "soldier",                    --checked if 'id' has no sound bindings
    desc            = "It's you, but evil."         --required field
    kill_desc       = "fragged by your evil clone", --defaults to ""
    kill_desc_melee = "mauled by your evil clone",  --defaults to ""
    weight          = 1,                            --required field
    danger          = 12,                           --required field
    minLev          = 20,                           --required field
    maxLev          = 100,                          --defaults to 200
    corpse          = true,                         --defaults to true
    HP              = 100,                          --defaults to 10
    armor           = 2,                            --defaults to 0
    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
    weapon          = "bazooka",                    --defaults to "" (no weapon)
    toDam           = 5,                            --defaults to 0
    toHit           = 5,                            --defaults to 0
    toHitMelee      = 0,                            --defaults to 0
    attackchance    = 60,                           --defaults to 75
    vision          = 11,                           --defaults to 9
    speed           = 100,                          --defaults to 100
    XP              = 2000,                         --defaults to 3*'danger'^2+20
    ai_type         = "cyberdemon_ai",              --defaults to ""
    group           = 0,                            --defaults to 0
    flags           = {},                           --defaults to {}
    bulk            = 100,                          --defaults to 100
    sprite          = 0,                            --required field, set to 0
    overlay         = {0,0,0,0},                    --defaults to {0,0,0,0}
}
  • name is what the being appears to be in-game (e.g., using the 'look' command).
  • name_plural is what the game uses when a pluralized form of the name is required (e.g., in the kills section of the mortem).
  • id is the being identifier, to be used in lua whenever you want to call the item prototype.
  • ascii is the ASCII character used to represent the being in the console.
  • color is one of 16 (4-bit) colors that you can use to distinguish the being on the map.
  • sound_id is what you want the being's sound bindings to map to. If the being's id is not registered for sound bindings, it will use this key instead (useful when mapping several beings to a single set of sounds). (Note that in the current version, registering sound bindings for custom beings requires direct manipulation of the prototype. This will be explained later on.)
  • desc is the description of the enemy, as seen when using the 'more' command while looking.
  • kill_desc is what shows at the top of a mortem if the player was killed by this being's ranged attack.
  • kill_desc_melee is what shows at the top of a mortem if the player was killed by this being's melee attack.
  • weight affects the frequency that the being will appear, for random monster generation purposes.
  • danger is the capacity by which the being can be added to the map, for random monster generation purposes.
  • minLev is the earliest floor on which the being can appear, for random monster generation purposes.
  • maxLev is the latest floor on which the being can appear, for random monster generation purposes. weight, danger, minLev, and maxLev are only important on levels that randomly generate beings using Level.flood_monsters().
  • corpse determines if the being will generate a corpse upon death. Alternatively, you can choose a cell (by referencing its id here) that the being will leave upon death.
  • HP determines how much damage the being can take before it dies.
  • armor determines how much damage the being absorbs before HP is subtracted, modified by the damage type of the source. Note that, without BF_HARDY, armor can only reduce damage to 1.
  • res_[damage_type] sets the internal resistance of the being for damage_type. Internal resistance affects both torso and foot sources. Note that amount of damage absorbed by resistance is calculated before any damage absorption due to armor, and that 100% resistance can reduce damage to 0 (though anything less will not).
  • weapon sets the being's default weapon (in its weapon equipment slot). This can either be an id for a separate item prototype, or it can be inlined into the being prototype. If inlined, the following is true by default for the item prototype:
    • type is set to ITEMTYPE_NRANGED
    • id is automatically assigned (although no lua-based id (sid) will exist)
    • weight and sprite are set to 0
    • IF_NODROP and IF_NOAMMO are added to the flags table
  • toDam is the damage modifier to the being's natural melee attack. It deals 1d3 damage unmodified.
  • toHit is the accuracy modifier to all of the being's attacks.
  • toHitMelee is the accuracy modifier to the being's melee attack. toHit and toHitMelee can have negative values (e.g., in order to set melee to-hit to 0 while keeping ranged to-hit at some positive value).
  • attackchance is the chance that the being will attack on a given turn. This can be overridden with custom AI.
  • vision is the distance in which the being can see, assuming no cells that block vision are present.
  • speed is the speed of any of the being's internal actions (e.g., movement and attacking). Values greater than 100 result in a faster being, while values less than 100 result in a slower being. The maximum value this can be set to is 255.
  • XP determines how much experience the player receives upon killing the enemy. Only the player can benefit from experience.
  • ai_type sets the AI of the being. There are a number of pre-defined AI for the base monsters, but it is possible to define your own.
  • group assigns the being to a particular group of other beings that it will not attack. Beings of different groups, by default, will attack each other. In the base game, all monsters are in group 0, while the player is in group 1.
  • flags defines what being flags you give the being.
  • bulk is an unused parameter, so you can ignore it entirely.
  • sprite is what will eventually be the graphical tile of the being. Set to 0 and ignore it for now.
  • overlay, like sprite, is based on there being graphical tiles in DoomRL. You can ignore this key entirely for the time being.

Properties

Several of the being object properties are identical to their prototype counterparts, others differ only by name. The comparisons are given here:

  • The following properties are the same as the prototype keys:
    • attackchance
    • vision
    • speed
    • armor
  • The following properties have a different name than a prototype key, but function exactly the same as the key:
    • The key sound_id is broken up into the following properties:
      • soundact is heard occasionally whenever the being acts
      • soundhit is heard whenever the being takes damage
      • sounddie is heard whenever the being dies
      • soundattack is heard whenever the being uses a ranged attack
      • soundmelee is heard whenever the being uses a melee attack
      • soundhoof is heard whenever the being moves (often disabled on most beings)
    • hpmax is the property of HP
    • tohit is the property of toHit
    • todam is the property of toDam
    • tohitmelee is the property of toHitMelee
    • expvalue is the property of XP
  • There are also a number of properties that are instantiated by default without automatic customization. They are as follows:
    • proto is the being's prototype. Don't change this unless you're planning on doing something really hacky.
    • hp is the being's current health. It defaults to the HP prototype key, but changes whenever the being takes damage.
    • scount is the being's speed count, or energy. For each turn that passes, all beings' scount is increased 100 (modified by each's speed); whenever a particular being takes an action, its scount is decreased by the amount of game seconds it takes for the action, multiplied by 1000. (For custom actions, scount must be modified manually in order for the action to take any time.)
    • todamall is a damage modifer applied to all of the being's attack (melee and ranged). (When the player invests in Son of a Bitch, this property is modified.)
    • Three properties affect the time in which particular actions are taken, given as a percentage relative to speed:
      • movetime affects how much time it takes for the being to move: for the player, this also corresponds to an increased dodge chance. (When the player invests in Hellrunner, this property is modified.)
      • reloadtime affects how much time it takes for the being to reload its weapon. (When the player invests in Reloader, this property is modified.
      • firetime affect how much time it takes for the being to attack. (When the player invests in Finesse, this property is modified.)
    • bodybonus reduces knockback by the number given, and any value greater than 0 will prevent health decay above 100%. (When the player invests in Badass, this property is modified.)
    • pistolbonus lowers firetime and increases damage whenever the being is using a weapon with the item flag IF_PISTOL. (When the player invests in Son of a Gun, this property is modified.)
    • rapidbonus modifies the number of shots fired from a weapon whose "shots" property is greater than one. (When the player invests in Triggerhappy, this property is modified.)
    • techbonus increases the number of mods that can be added to the being's equipment, as well as what tier of assemblies the being can create. (When the player invests in Whizkid, this property is modified.)
  • Finally, there are the properties that beings inherit from things. (Some of the thing properties are readonly, meaning they can't be changed once the instantiated object is initialized. These will be bolded for clarification.)
    • The following properties are the same as the prototype keys:
      • color
      • id
      • name
      • sprite
      • res_bullet
      • res_shrapnel
      • res_melee
      • res_acid
      • res_fire
      • res_plasma
    • The following properties have a different name than a prototype key, but function exactly the same as the key:
      • picture is the property of ascii
      • nameplural is the property of name_plural
    • The following properties are automatically given by default:
      • sid is a string identifier, similar to id. This is what is used dominantly by modders, and is set based on the being's id key.
      • uid is a unique identifier across all instantiated objects. This is often used to save the state of a game.
      • x is the x-coordinate of the being on the map.
      • y is the y-coordinate of the being on the map. x and y make up a being's coordinate indirectly.
      • __ptr is a pointer to the object in the engine: you'll never have to worry about this property.

Engine Hooks

Beings come with three hooks:

  • OnCreate(being) is called when being is allocated to memory (i.e., created but not necessarily placed on the map). Use this function to add or modify properties, or potentially cause special cases to occur depending on the circumstances of the creation.
  • OnAction(being) is called whenever being takes an action. This is where a great deal of code used to be added when a modder wanted to manipulate the being's special abilities and/or AI, but is now mostly used as a means to have abilities that should be activated on every action. For more complicated setups, the modder should create a special AI for the being (explained later).
  • OnDie(being,overkill) is called whenever being dies. The overkill parameter is a boolean that only triggers OnDie() if being was gibbed on death. (In this way you can set up two separate OnDie() hooks to the same being prototype.)
Personal tools