|
|
An entityDef is literally nothing more than a collection of key/value pairs with a name. They are generally used to define entities (hence the name), but they can really be used to define anything that can be defined with a list of key/value pairs The meaning of the keys and values depends completely on the type of object it is, but there are two key/value pairs that remain constant regardless of type. The "spawnclass" key defines the C++ class that 'spawns' this entity. Items use idItem, trigger_once uses idTrigger_Multiple, monsters use idAI, etc. If you know C++, you can add new spawn classes to the game code if existing ones don't suit your needs. Entities without the "spawnclass" key cannot be spawned. The "inherit" key tells the game to copy all the key/value pairs from another entityDef. Circular references are impossible because each entityDef is only parsed once (you will get an error). This is an incredibly useful key. You can do things like create a default monster that all monsters inherit from. This not only saves typing, but it allows you to change something in one place and have it affect a bunch of objects (which is both a blessing and a curse).
Editor Keys
Any key that begins with editor_ is used by the editor. Some of the keys
it specifially looks for are:
The Shotgun
Let's take a look at an example entityDef for the shotgun entityDef weapon_shotgun { // Global "spawnclass" "idItem" // Used by the Editor "editor_color" ".3 .3 1" "editor_mins" "-16 -16 0" "editor_maxs" "16 16 32" "editor_usage" "Shotgun" "editor_rotatable" "1" // Used by idItem "def_dropItem" "moveable_item_shotgun" "inv_name" "Shotgun" "inv_weapon" "weapon_shotgun" "inv_ammo_shells" "4" "inv_item" "5" "snd_acquire" "sound_weapon_acquire" "snd_respawn" "sound_weapon_respawn" // Used by idEntity "size" "32 32 32" "model" "models/weapons/shotgun/w_shotgun2.lwo" // Used by idWeapon "model_view" "viewmodel_shotgun" "model_world" "worldmodel_shotgun" "joint_attach" "SHOTGUN_ATTACHER" "icon" "guis/assets/hud/wpn_2" "weapon_scriptobject" "weapon_shotgun" "def_projectile" "projectile_bullet_shotgun" "ammoType" "ammo_shells" "ammoRequired" "1" "clipSize" "8" "lowAmmo" "2" "mtr_flashShader" "muzzleflash" "flashColor" "1 0.8 0.4" "flashRadius" "120" "silent_fire" "0" "recoilTime" "325" "recoilAngles" "-1 0 0" "weaponAngleOffsetAverages" "15" "weaponAngleOffsetScale" ".40" "weaponAngleOffsetMax" "20" "weaponOffsetTime" "500" "weaponOffsetScale" "0.005" "hide_time" "0.3" "hide_distance" "-15" "smoke_muzzle" "shotgunmuzzlesmoke.prt" "def_ejectBrass" "debris_shotgunbrass" "ejectBrassDelay" "650" // Used by scripts "spread" "22" "skin_invisible" "skins/shotgun_invis" } Looking at this script, we begin to see there are a 3 distinct sections of the code that all use this entityDef. The first is the editor, which we can pretty much ignore. The next piece of code is idItem. This makes sense because we specify 'idItem' as the spawnclass, so naturally that class will want to peek at some values to spawn the object properly. The reason idEntity cares about this entity is idItem derives from idEntity. This means every idItem is an idEntity. Almost everything in the game code is derived from idEntity. (It's similar to how we can use 'inherit' to copy common attributes from another entityDef). The confusing part is where idWeapon fits in to the picture. We know a shotgun is a weapon, but there doesn't appear to be any place where we tell the code that. The magic key here is inv_weapon. That key tells idItem that the item is a weapon, and uses the weapon_shotgun entityDef to define the parameters for idWeapon. It just so happens that the entityDef for the idItem is named the same as the entityDef for the idWeapon. It is important to note that although they are all set to "weapon_shotgun" they don't have to be. In fact they aren't for items like the backpack. That is an item that gives you health, armor, and a crapload of ammo. The backpack entityDef defines the object in the world, but the other stuff is defined elsewhere. To test this, you can add "inv_weapon" "weapon_shotgun" to the "item_medkit" entityDef and notice you get a shotgun everytime you pick up a med kit. Another real important key is "weapon_scriptobject" This tells the game code which script to run to make the shotgun work. In this case, the object name is the same as the entity name, but again, it doesn't have to be. When you equip the shotgun, it tells the weapon code to start using the "weapon_shotgun" object (defined in weapon_shotgun.script). An interesting aside is there is only ever one weapon script running. When you switch weapons, it doesn't destroy the script object and create a new one, it merely tells the script object to morph into a new type. The missing part to our puzzle is the damage. After all, a shotgun without damage is just a toy. The way the damage gets linked in seems odd, but it actually works really nicely. When you press the attack button, the shotgun script calls launchProjectiles(13), which launches 13 projectiles. These projectiles are also entities, defined by the "def_projectile" key to be "projectile_bullet_shotgun". If we look at "projectile_bullet_shotgun", we see it is an idProjectile, and it has a boatload of properties that define how it looks, to how it flies, how it explodes, how it sounds when it hits various types of surfaces, and a bunch of other stuff. One thing it defines is "def_damage", which is an entityDef that defines damage. Turns out there's a lot more to damage than just how much it hurts. There's also how it looks in first person, how it looks in third person, how it knocks you back, and whether or not it can gib a body. Looking at "damage_shotgun" we see each pellet does 14 points of damage. Multiply that by 13 pellets and you get lots of pain.
Precache
entityDefs play a very important role during level load time. The assets a level loads is determined
by walking the entityDefs defined in the level, and in the code. It is very important to follow these
naming guides when creating new entityDefs in order for the precache to work right:
There are a few other ones you can find by looking in the game code, but they are pretty much depreciated
and should not be used. Failure to use these prefixes means not all assets will get loaded at map load.
They will be loaded when referenced, causing hitches in game play (that's bad).
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
Copyright © 2004 id software |