Modding Basics: Templates (and components.gas)
Submitted by Sharkull on Mon, 2006-03-27 14:18 | ||
If you want to start reading how some things are done in DS2, the best place to start is to look in the gas files... Also, here's a copy of components.gas, a very useful file that GPG has put comments in to help modders understand things ////////////////////////////////////////////////////////////////////////////// // // File : world:global:contentdb:rules:components.gas // Author(s): Scott Bilas // // Summary : Contains the definitions (schemas) for all possible components. // // Copyright © 2000 Gas Powered Games, Inc. All rights reserved. //---------------------------------------------------------------------------- // $Revision:: $ $Date:$ //---------------------------------------------------------------------------- ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // Documentation /* +++ +++ +++ COMPONENTS +++ +++ +++ *** Overview *** A 'component' is a basic building block of a game object. Various components are defined that implement certain tasks in the game engine. For example, the 'physics' component contains parameters that tune the physics engine for an object (fire parameters, gravity, etc.). Components are combined in a template to build up a game object that may be instantiated in the Siege Editor or from within C++/Skrit code. They will typically closely mirror their equivalent C++/Skrit code object. Data defined by components (directly or indirectly) will typically be used only for initialization purposes. A component specifies a set of parameters and attributes. For example, the 'body' component has a parameter named 'model', which is specified like this: [t:component,n:body] { //... [model] { type = string; default = m_i_glb_placeholder; doc = "What Nema aspect to use for visual representation"; } // ... } Here the 'model' parameter is defined as type 'string', has a default value of 'm_i_glb_placeholder', must be selected from one of the meshes found that start with 'm_', and is documented as given. This parameter definition is known as a 'schema' and serves several purposes. First it documents the game's data structure. All possible parameters, their types, and default values are given (with a few 'internal' exceptions). Second, it enables Siege Editor to treat the data generically by detecting types. *** Format *** [t:component,n:component_name] { // the type of 'component' is required. the name (replace // 'component_name' with your component's name) must be unique // across all components. it should be human-readable, as it's used // for unique addressing and data transfer. doc = "This component represents an object's ability to spew"; // this is a string that describes the component. siege editor // may use this to provide help in its dialogs where useful. required_component* = other_component_name; // this is a string or set of strings that defines a dependency. // a template that uses the component being defined must also // use the components in the required_component* set. internal* = sound; // this is a string or set of strings that says that a // particular name is allowed to be used as a block or value. in // order to maintain data integrity the content validator // routines will give errors upon finding entries that are not // part of the official schema. certain blocks and values will // be used by the c++ code but not be exposable via standard // schema, so tag those with "internal" and doc the format of // the block/value in place of the schema. internal_component = true; // this is a bool that says that the entire current component is // internal in the same way that internal* says that a // particular element of a component is internal. [parameter_name] { // this is the name of the parameter that is being added to this // component's schema. type = float; // this is the type of the parameter. generally this will be // a float, int, bool, or string. there are other special // types supported: Vector, SiegePos, Quat, and a set of // enums. default = 1.234; // (optional) this is the default value to use for the // parameter if not overridden in a template or chosen in // Siege Editor. always try to give a default value that // will allow construction of a valid component. flags = REQUIRED; // (optional) this sets particular flags for the parameter. // possible values are covered in a later section. doc = "This parameter controls happiness"; // this documents the parameter and is required. make it as // descriptive as possible - Siege Editor and various other // interfaces will use this attribute to give context and // help when modifying/dumping parameters on game objects. } } *** Parameter flags *** These are possible flags to be used in a component's 'flags' attribute. Combine flags together by using the '|' operator (example: flags = REQUIRED | LOCALIZE). REQUIRED This is a 'required' parameter that cannot accept a default value. For example, actors cannot be placed in the world without a valid SiegePos, so that parameter is marked as REQUIRED. Hopefully parameters flagged this way will be very rare. Try to always allow a default value to work. LOCALIZE This is a flag on a parameter that says it refers to a string that will potentially be printed on the screen. The parameter name, by the way, should follow the convention where 'screen_' is prefixed. This flag is used to tell the system to do a translation on the string when it's read in. It will also be scanned by an external tool to build the translation database for localization efforts. ADVANCED Flag a parameter with this to tell Siege Editor or other editing interfaces to put this parameter in an 'advanced' section of the editing dialogs. This will help to reduce clutter for infrequently-overridden parameters. This cannot be used with the REQUIRED or HIDDEN flags. HIDDEN Put this on parameters that should normally be hidden from the Siege Editor or other editing interfaces. This cannot be used with the REQUIRED or ADVANCED flags. Hidden parameters are meant to be tweaks that generally only engineers mess with during testing. */ ////////////////////////////////////////////////////////////////////////////// // Component definitions [t:component,n:actor] { doc = "Interactive intelligent actor"; required_component* = attack; required_component* = body; required_component* = defend; required_component* = physics; required_component* = inventory; required_component* = placement; // Options. [can_level_up] { type = bool; default = false; doc = "Can this object 'level up'?"; } [is_hero] { type = bool; default = false; doc = "Can this actor be chosen from the character screen as a hero?"; } [drops_spellbook] { type = bool; default = true; doc = "If killed with a spellbook in inventory, should we drop it or nuke it?"; } [can_show_health] { type = bool; default = false; doc = "Does this actor show its health status on cursor rollover?"; } [can_be_resurrected] { type = bool; default = true; doc = "If killed, can this actor be resurrected?"; } // Traditional RPG attributes. // inherent traits [alignment] { type = eActorAlignment; default = aa_neutral; doc = "Moral alignment of actor"; } [race] { type = string; default = other; doc = "Race of actor"; } [is_male] { type = bool; default = true; doc = "True for male character ( or undetermined ), false for female."; } [screen_class] { type = string; flags = LOCALIZE; doc = "Starting class for actor"; } // General. [portrait_icon] { type = string; doc = "Bitmap displayed when dragging or in inventory"; } [power_level] { type = float; default = 1.0; doc = "Power level of actor, used for tuning placement calculations."; } [spot_request_wait_time] { type = float; default = 0.0; doc = "How long this actor will set the spot request time after it successfully requests a go zone spot"; } [bonus_skill_points] { type = int; default = 0; doc = "Number of bonus skill points this actor starts out with."; } [can_save_member] { type = bool; default = true; doc = "If this actor is a party member, can we save their data out in the party save?"; } [magic_find_chance] { type = float; default = 0.0; doc = "The default magic find chance this character starts with."; } [bar_background_index] { type = int; default = 1; doc = "The status bar border used for enemies (can be 1-5, 5 being the strongest)."; } // Buff / Debuff Limitations [max_buffs] { type = int; default = 2.0; doc = "How many buffs are allowed on this actor?"; } [max_debuffs] { type = int; default = 1.0; doc = "How many debuffs are allowed on this actor?"; } // Skills [current_active_skill] { type = string; doc = "The skill the character will start out with (if any)."; } internal* = skills; /* the "skills" block is a list of skills for this actor. format: [skills] { // skill_name= Experience level, experience points, starting level // Calculations are based on the curve defined for the skill in formulas.gas skill_name = level, xp, optional starting level strength = 0, 0, 10; // CAN BE FORMULA: actual level is 10, no experience points were awarded, 100 xp needed to get to level 11 intelligence = 2, 0, 10; // CAN BE FORMULA: actual level is 12, leveled up 2 times starting from 10, 480 xp need to get to level 13 dexterity = 10, 0, 0; // CAN BE FORMULA: actual level is 10, has leveled up 10 times starting from 0, 2000 xp needed to get to level 11 monster_level = 0, 0, 0; // CAN BE FORMULA: [override] { skill_name = level, xp, optional starting level combat_magic = 100, 0; // level is 100, experience points are derived from level and awarded to strength, dexterity, and // intelligence according to the influences defined by the skill } } */ // Resistances internal* = resistances; /* the "resistances" block contains all resistances/vulnerabilities a particular actor may possess. Vulnerabilities are essentially negative resistances. Here are all the resistance "damage types" (DMT_) you may use to set resistances for: // Specific types dmt_melee dmt_ranged dmt_lightning dmt_ice dmt_fire dmt_death dmt_non_elemental // General types dmt_physical dmt_elemental dmt_magical All resistances are in the range of 0.0 being 0% to however high you want to go ( 0.4 = 40%, 2.0 = 200%, -0.5 = -50% ) You can use formulas to determine what the resistances are! example: dmt_physical = #is_easy ? 0.5 : 1; format: [resistances] { dmt_physical = 0.5; dmt_ice = 1.0; dmt_fire = 1.5; dmt_death = -100.0; } So in the above example, this actor would: + Absorb 50% of all physical damage + Be immune to ice damage + Fire damage would heal the actor +50% of what the damage was + Death damage would totally kick this actor's butt. */ internal* = state_resistances; /* the "state_resistances" block contains all resistances/vulnerabilities a particular actor may possess when a particular state is about to be applied to them. For example, you can make a generic state called "freeze" and then set the resistance to be 1.0, that actor can never be frozen (by any spell with the state name of "freeze"). Vulnerabilities are essentially negative resistances. All resistances are in the range of 0.0 being 0% to however high you want to go ( 0.4 = 40%, 2.0 = 200%, -0.5 = -50% ) You can use formulas to determine what the resistances are! example: freeze = #is_easy ? 0.5 : 1; format: [state_resistances] { freeze = 0.5; // Resistance to anything that freezes the actor in place. ( Ice themed ) ignite = 1.0; // Fire resistance to Ignite passive skill immobilize = 1.0; // Root resistance stun = 1.0; // Stun resistance silence = 1.0; // Silence resistance slow = 1.0; // Slow resistance. knockback = 1.0; // Resistance to knockback slide = 1.0; // Resistance to being slid death_event = 1.0; // Resistance to the affects of the death event controller. fear = 1.0; // Resistance to fear. taunt = 1.0; // Resistance to being taunted. power_damage = 1.0; // Reduction percentage multiplier of damage dealt via power damage. corpse_transmute = 0; // Resistance to corpse transmutation. Either on or off, 1.0 equals resistant. } */ // Power slots internal* = power_slots; /* The power slot definitions hold the power names that will appear in a character's power slots. [power_slots] { power_slot_1 = power_name_1; power_slot_2 = power_name_2; power_slot_3 = power_name_3; power_slot_4 = power_name_4; } */ } [t:component,n:aspect] { doc = "Runtime visual representation for an object"; required_component* = placement; // Options. // rendering [is_visible] { type = bool; default = true; doc = "Is this object visible (does it render)?"; } [draw_shadow] { type = bool; default = false; doc = "Should this object draw a shadow when rendered?"; } [interest_only] { type = bool; default = false; doc = "Should this object draw only when it is in the sphere of interest?"; } [rollover_highlight] { type = bool; default = true; doc = "Should this object highlight on rollover."; } // physics [is_collidable] { type = bool; default = false; doc = "Is this object collidable with other objects like projectiles?"; } [does_block_path] { type = bool; default = false; doc = "Does this object prevent another from walking through it?"; } [is_invincible] { type = bool; default = false; doc = "Is this object immune to damage?"; } // gui [is_selectable] { type = bool; default = false; doc = "Is object selectable from the GUI?"; } [does_block_camera] { type = bool; default = false; doc = "Does this object block the camera from moving through it?"; } [is_usable] { type = bool; default = false; doc = "Can this item be 'used?' i.e. opened, closed, turned on/off."; } [is_door] { type = bool; default = false; doc = "If this is set and the is_usable is true, you will get a special door opening cursor."; } [use_range] { type = float; default = 0; doc = "Range at which an actor must be to 'use' this object."; } // other [is_gagged] { type = bool; default = false; doc = "Is this object gagged from making sounds? Useful for quieting monsters until they activate."; } [dynamically_lit] { type = bool; default = true; doc = "Should this object be affected by dynamic light?"; } [occludes_light] { type = bool; default = false; doc = "Should this object occlude light on the terrain?"; } [terrain_shaded] { type = bool; default = true; doc = "Should this object use the terrain shading in its lighting calculations?"; } [terrain_orient] { type = bool; default = false; doc = "Should this object orient to the terrain?"; } // General. // rendering [model] { type = string; default = m_i_glb_placeholder; doc = "What Nema aspect to use for visual representation"; } [draw_selection_indicator] { type = bool; default = true; doc = "Specifies whether or not an indicator should be drawn"; } [draw_exclamation] { type = bool; default = false; doc = "Specifies whether or not to draw the exclamation mark above the aspect"; } [selection_indicator_scale] { type = float; default = 1.0; doc = "Scalar for determining selection indicator radius"; } [scale_base] { type = float; default = 1.0; doc = "Base scale to use for rendering - modify this in base template only"; } [scale_multiplier] { type = float; default = 1.0; doc = "Multiplier modifier to apply to the scale - modify this in instances only"; } [bounding_volume_scale] { type = float; default = 1.0; doc = "Scalar multiplier for adjusting the bounding volumes of objects"; } [display_cost] { type = float; default = 0; doc = "Cost to display this object, used for ingame HUDs"; } [lodfi_upper] { type = float; default = -1.0; doc = "Upper bound for level of detail for items - will always render if object detail level higher than this (set -1 for critical/global)"; } [lodfi_lower] { type = float; default = -1.0; doc = "Lower bound for level of detail for items - will not render at all if object detail level lower than this"; } [material] { type = string; doc = "Material that this is made from - used for sound map"; } [cam_fade_alpha] { type = int; default = 65; doc = "When this object is faded by the camera, this indicates what alpha level is will fade to ( 0 - invisible, 255 - fully opaque )."; } // life [life_state] { type = eLifeState; default = ls_ignore; doc = "Living state of the object, or life_ignore if not applicable"; } [max_life] { type = float; default = 0; doc = "CAN BE FORMULA: Maximum life (hit points) the object has or the amount of damage it can take before breaking apart"; } [life] { type = float; default = 0; doc = "CAN BE FORMULA: Initial hit points"; } [life_timed_restore_period] { type = float; default = 0.1; doc = "The restore period dictates how long until the next restore update takes place."; } [life_recovery_unit] { type = float; default = 0; doc = "Life recovery units added per period (calculated continuously)"; } [lru_bonus_percent] { type = float; default = 0.0; doc = "This will take whatever your life recovery unit is, multiply it by itself and then add it to your lru total."; } [life_recovery_period] { type = float; default = 0; doc = "Life recovery period in seconds"; } [expired_template_name] { type = string; doc = "Template to replace current object with when it expires"; } [manages_own_damage] { type = bool; default = false; doc = "If this is set, damage is NOT applied through rules.skrit (the damage will be calculated and set in the aspect, but you must apply it at a time you choose)."; } // $ max_mana is calculated for characters that can level up using the // formula: (str-9 * str_percent * constant) // + (dex-9 * dex_percent * constant) // + (int-9 * int_percent * constant) // mana [max_mana] { type = float; default = 0; doc = "CAN BE FORMULA: Maximum mana that this actor may acquire"; } [mana] { type = float; default = 0; doc = "CAN BE FORMULA: Initial mana (defaults to max_mana)"; } [mana_recovery_unit] { type = float; default = 0; doc = "Mana units added per period (calculated continuously)"; } [mru_bonus_percent] { type = float; default = 0.0; doc = "This will take whatever your mana recovery unit is, multiply it by itself and then add it to your mru total."; } [mana_recovery_period] { type = float; default = 0; doc = "Mana recovery period in seconds"; } // lighting [alive_light_scale_start] { type = float; default = 1.0; doc = "Start range to determine random lighting scalar when alive"; } [alive_light_scale_end] { type = float; default = 1.0; doc = "End range to determine random lighting scalar when alive"; } [dead_light_scale] { type = float; default = 1.0; doc = "Scalar value (0.0 - 1.0) used to scale lighting when dead"; } [light_scale_trans_time] { type = float; default = 0.75; doc = "Time (in seconds) to blend between light scales when killed/resurrected"; } // tracer [tracer_texture] { type = string; doc = "If this aspect draws tracers then this texture name will be the texture used"; } // misc [experience_value] { type = float; default = 0; doc = "CAN BE FORMULA: Number of experience points awarded if destroyed/killed"; } [gold_value] { type = int; default = 0; doc = "CAN BE FORMULA: Value of object in gold pieces"; } [use_pcontent_gold_value] { type = bool; default = true; doc = "If this is set to false, then the PContent system will not use its formulas to add to the existing gold value."; } [force_no_render] { type = bool; default = false; doc = "Force this object not to render, but do everything else"; } [is_transmutable] { type = bool; default = false; doc = "Can this item be transmuted with the transmute spell?"; } internal* = textures; /* the "textures" block is for texture replacement, where the number must match up with what nema is expecting. format: [textures] { 0 = b_c_gah_fb_skin_01; 1 = b_c_pos_a2_m_lthr-stud-grn; } */ internal* = voice; /* $ see docs in world/global/sounds/sounddb.gas. */ internal* = ornaments; /* DS 2.0 feature The "ornaments" component allows additional ornament meshes to be attached to an underlying mesh format: [ornaments] { attachmesh = spikes001,b_i_spikes; attachmesh = fins001,b_w_swords; } */ internal* = armor_ornaments; /* DS 2.0 feature The "armor_ornaments" component allows additional ornament meshes FOR ARMOR ONLY. The name is built from the information about the armor (armor_version and armor_race). format: [armor_ornaments] { * = type02_shoulder_02; // m_c_[armor_version]_orn_[armor_race]_type02_shoulder_02 } */ } [t:component,n:attack] { doc = "Parameters related to attacking"; required_component* = common; // Options. [requires_line_of_sight] { type = bool; default = false; doc = "Must have a line of sight on the target in order to attack it"; } [is_melee] { type = bool; default = false; doc = "Attack available in close combat"; } [is_projectile] { type = bool; default = false; doc = "Attack available to ranged combat"; } [is_one_shot] { type = bool; default = false; doc = "Attacks once and then is done - subsequent attacks must be explicit"; } [is_two_handed] { type = bool; default = false; doc = "Requires two hands to operate"; } [is_dual_wield] { type = bool; default = false; doc = "Can this weapon be wielded in both hands?"; } [is_thrown] { type = bool; default = false; doc = "Is this a weapon that is thrown (like throwing knives or javelins?)"; } [is_wielded_weapon] { type = bool; default = true; doc = "Is this weapon weilded in the hand? If false then weapon will not appear on the character."; } // General. [ammo_template] { type = string; doc = "Go clone source to spawn from for ammo"; } [ammo_attaches_to_weapon] { type = bool; default = false; doc = "True if attaching to projectile launcher, false if held in hand"; } [ammo_attach_bone] { type = string; default = "ap_grip"; doc = "Name of bone to use when attaching relative to ammo or projectile launcher"; } [ammo_appears_jit] { type = bool; default = false; doc = "True if ammo is created right before the instant that it is shot"; } [ammo_always_attached] { type = bool; default = true; doc = "Always keep ammo attached to this weapon instead of waiting for the attach ammo event in the attack."; } [area_damage_radius] { type = float; default = 0.0; doc = "Spherical collateral damage radius"; } [attack_class] { type = eAttackClass; flags = REQUIRED; doc = "Classification of attack"; } [attack_range] { type = float; default = 1.0; doc = "CAN BE FORMULA: Minimum range the GO must be to target in order to gamage it"; } [reload_delay] { type = float; default = 0.0; doc = "CAN BE FORMULA: Duration of each attack iteration, i.e. a single blow"; } [damage_min] { type = float; default = 1.0; doc = "CAN BE FORMULA: Minimum damage amount this object can do before modifiers"; } [damage_max] { type = float; default = 1.0; doc = "CAN BE FORMULA: Maximum damage amount this object can do before modifiers"; } // damage bonuses [damage_bonus_min_melee] { type = float; default = 0; doc = "CAN BE FORMULA: Additional damage to add to melee combat"; } [damage_bonus_max_melee] { type = float; default = 0; doc = "CAN BE FORMULA: Additional damage to add to melee combat"; } [damage_bonus_min_ranged] { type = float; default = 0; doc = "CAN BE FORMULA: Additional damage to add to ranged combat"; } [damage_bonus_max_ranged] { type = float; default = 0; doc = "CAN BE FORMULA: Additional damage to add to ranged combat"; } [damage_bonus_min_cmagic] { type = float; default = 0; doc = "CAN BE FORMULA: Additional damage to add to combat magic combat"; } [damage_bonus_max_cmagic] { type = float; default = 0; doc = "CAN BE FORMULA: Additional damage to add to combat magic combat"; } [damage_bonus_min_nmagic] { type = float; default = 0; doc = "CAN BE FORMULA: Additional damage to add to nature magic combat"; } [damage_bonus_max_nmagic] { type = float; default = 0; doc = "CAN BE FORMULA: Additional damage to add to nature magic combat"; } // $ skill_class is defined in the attack component as well! values that // may go here are defined in formulas.gas [skill_class] { type = string; doc = "What skill to award experience to for usage"; } [use_aiming_error] { type = bool; default = false; doc = "Attack will use aditional Error specified by aming_error_range_[x|y]"; } [aiming_error_range] { type = float; default = 0.0; doc = "Random range (-x,x)/(-y,y) in degrees to perturb aim by to make less accurate"; } [no_random_attack_sounds] { type = bool; default = false; doc = "Set this to true if attack sounds for this object should always play"; } } [t:component,n:body] { doc = "More complex representation for an object, typically used on actors"; required_component* = aspect; // General. [armor_version] { type = string; doc = "Modifier for shape of armor to use"; } [armor_race] { type = string; doc = "Race modifier used for generating suits/gauntlets/boots"; } [helmet_race] { type = string; doc = "Race modifier used for generating helmets"; } [angular_turning_velocity] { type = float; default = 360; doc = "Turning velocity of creature in degrees per second"; } [initial_chore] { type = eAnimChore; default = chore_none; doc = "Initial chore to run when the object is constructed"; } [initial_anim] { type = string; doc = "FOURCC code of initial animation"; } [min_move_velocity] { type = float; default = 1.0; doc = "Minimum movement velocity for this actor."; } [avg_move_velocity] { type = float; default = 1.0; doc = "Average movement velocity for this actor."; } [max_move_velocity] { type = float; default = 1.0; doc = "Maximum movement velocity for this actor."; } [terrain_movement_permissions] { type = eLogicalNodeFlags; default = lf_size1_mover | lf_size2_mover | lf_size3_mover | lf_size4_mover | lf_dirt; doc = "Walk-mask permissions for path-finding."; } internal* = bone_translator; /* the "bone_translator" block is a map of 3ds max bone names to the reserved names expected by the simulation. current possible names are (these are defined in the BoneTranslator::eBone enum): kill_bone weapon_bone shield_bone body_anterior body_mid body_posterior tip middle handle misc1 misc2 misc3 format: [bone_translator] { kill_bone = bip01_spine2; // native name = 3ds max name weapon_bone = weapon_grip; shield_bone = shield_grip; body_anterior = bip01_head; body_mid = bip01_spine2; body_posterior = bip01; } */ internal* = chore_dictionary; /* the "chore_dictionary" block is a set of subblocks that describe the set of available chores that this body can run and the parameters that define those chores. current possible names for the chores are (these are defined in the nema::eAnimChore enum): chore_default (this is required by all body components) chore_walk chore_die chore_defend chore_attack chore_magic chore_fidget chore_rotate chore_open chore_close format: [chore_dictionary] { chore_prefix = a_c_gah_fg_fs; // prefix (for convenience) on anim files [chore_default] // name of the chore { skrit = basic_default; // name of skrit to run the chore chore_stances = 2, 3; // comma-delimited list of stances that the set of anim files supports [anim_files] { 00 = rl; // name of prs file which prefix is prepended to (the key name is used only to order the anim names which is dependent upon the skrit that uses them) 10 = dfs; } } [chore_walk] { // ... } } */ internal* = weapon_scales; /* The "weapon_scales" component allows weapon meshes to be scaled to fit the characters that equip them In order to accomodate this, the characters need to have a lookup table that lists the scale values This is an OPTIONAL component, if it is missing all scales are assumed to be 1,1,1 (x,y,z). format: [weapon_scales] { as_single_melee = 0.8, 0.8, 0.8; as_two_handed_melee = 0.8, 0.8, 0.8; as_two_handed_sword = 0.8, 0.8, 0.8; as_staff = 1.0, 1.0, 1.0; as_bow_and_arrow = 0.8, 0.8, 0.8; as_minigun = 0.8, 0.8, 0.8; as_shield_only = 0.9, 0.9, 0.9; } */ } [t:component,n:coach] { doc = "A coach contains a group of actors and gives them high level AI goals."; [max_member_count] { type = int; default = 8; doc = "Maximum number of members that can join this coach."; } required_component* = mind; required_component* = placement; } [t:component,n:common] { doc = "Common attributes for all game objects"; [screen_name] { type = string; flags = LOCALIZE; doc = "Text seen in-game upon mouse over"; } [base_screen_name] { type = string; flags = LOCALIZE; doc = "Text seen in-game in the item labels"; } [description] { type = string; flags = LOCALIZE; doc = "Text seen in-game on some tooltips"; } [dev_instance_text] { type = qstring; flags = DEV; doc = "Extra instance-specific descriptive text that can be used for debug HUD, etc"; } [forced_expiration_class] { type = string; default = immediate; flags = ADVANCED; doc = "Forced expiration class (such as when killed) of this object for scheduled deletion"; } [auto_expiration_class] { type = string; default = immediate; flags = ADVANCED; doc = "Automatic expiration class (when cached out of world) of this object for scheduled deletion"; } [membership] { type = string; doc = "Comma-deliniated list of groups of which this Go is a member."; } [is_pcontent_allowed] { type = bool; default = true; flags = ADVANCED; doc = "Should this template be considered in a pcontent query?"; } [allow_modifiers] { type = bool; default = true; flags = ADVANCED; doc = "Allow modifiers to be attached to this when generating content?"; } [rollover_display] { type = bool; default = true; doc = "Will this object display its screenname in game on rollover?"; } [rollover_life] { type = bool; default = false; doc = "Will this object display its life stats on rollover?"; } [is_single_player] { type = bool; default = true; doc = "Whether or not this object is allowed in a single player game"; } [is_multi_player] { type = bool; default = true; doc = "Whether or not this object is allowed in a multi player game"; } [rollover_help_key] { type = string; doc = "Key value for user education tooltip to use, if any."; } [rarity] { type = ePClass; default = normal; doc = "What rarity class is this object? (unique, rare, set, normal)"; } [preserve_vitals] { type = bool; default = false; doc = "Should this object preserve its vital information in save games."; } internal* = template_triggers; internal* = instance_triggers; /* $$ FINISH condition* = ; // Condition such as, receive_world_message action* = ; // When activated do, such as call_sfx_script delay = ; // amount of time in seconds before trigger will activate poll_frequency = ; // amount of time in seoncds to elapsed before performing conditional evaluations reset_duration = ; // Duration in seconds before auto-reseting single_shot = ; // Should this trigger fire once only flip_flop = ; // boolean value true if flip_flop trigger type format: [template_triggers] { [*] { condition* = receive_world_message("WE_ENTERED_WORLD"); single_shot = true; action* = call_ffx_script("sight_light"); } [*] { condition* = receive_world_message("we_damaged"); action* = call_ffx_script("melee_hit_2"); } } instance_triggers is the same except it will appear in instances, not in templates and vice versa. */ [t:constraint,n:expiration_class] { // docs: // // delay_seconds - seconds to count down before expiring. // // range_seconds - this is a plus-or-minus modifier on the duration so // we can vary the expiration time a little. useful for // ammo and death & decay. [choose] { [normal] { delay_seconds = 600; doc = "Normal delay - non-magic items, monsters"; } [dead] { delay_seconds = 15; range_seconds = 1; doc = "Object that has died but not started decaying yet"; } [decay_fresh] { delay_seconds = 5; range_seconds = 1; doc = "Delay for freshly decaying object"; } [decay_bones] { delay_seconds = 5; range_seconds = 1; doc = "Delay for bones object"; } [decay_dust] { delay_seconds = 5; range_seconds = 1; doc = "Delay for dust object"; } [decay_thief] { delay_seconds = 5; doc = "Delay for loot thief"; } [siegefx_target] { delay_seconds = 60; doc = "Delay for reference points for SiegeFx static targets"; } [magic] { delay_seconds = 1800; doc = "Long delay - magic items"; } [never] { delay_seconds = -1; doc = "Permanent object - uniques, heroes, etc."; } [immediate] { delay_seconds = 1; doc = "(Mostly) immediate expiration for non-interactive content - give it a couple seconds actually to stabilize though"; } [tombstone] { delay_seconds = 60; doc = "Delay for tombstone expiration."; } [shop] { delay_seconds = 900; /* 15 minutes */ doc = "Delay for shop expiration."; } } } } [t:component,n:conversation] { doc = "Conversation data to use when talking to this object"; [can_talk] { type = bool; default = true; doc = "This says whether or not a person with a conversation is allowed to speak."; } [talk_flick] { type = string; doc = "Flick name to run instead of running the standard conversation code."; } internal* = conversations; /* format: // This block contains all the possible conversations an object can discuss [conversations] { // List all possible conversation names here. The body of the conversations // are located in the the region in which the go itself resides. * = ...; } */ } [t:component,n:corpse] { doc = "Corpse data to use when re-outfitting a character with his goodies"; required_component* = placement; required_component* = aspect; [disable_inventory] { type = bool; default = false; doc = "Do we also want to disable the inventory when this corpse is created?"; } [gold_percentage] { type = float; default = 0.25; doc = "Percentage of gold that is left with the corpse when you die."; } } [t:component,n:defend] { doc = "Parameters related to defending"; required_component* = common; [damage_threshold] { type = float; default = 0; doc = "Any damage below the specified amount has no effect"; } [defend_class] { type = eDefendClass; flags = REQUIRED; doc = "Classification of defense"; } [defense] { type = float; default = 0; doc = "CAN BE FORMULA: General toughness of this object to absorb damage from an attack"; } [armor_type] { type = string; doc = "Specific armor modifier type (for mesh) - a1, a7, etc."; } [armor_style] { type = string; doc = "Texture modifier to use for armor"; } } [t:component,n:edit] { doc = "Special edit component only used by tools"; } [t:component,n:fader] { doc = "A component that takes an aspect and fades it"; required_component* = placement; } [t:component,n:follower] { doc = "A component that can follow (carry out) an MCP plan"; required_component* = aspect; } [t:component,n:gizmo] { doc = "Development gizmo for representing/manipulating an object in non-retail modes"; required_component* = placement; [model] { type = string; default = m_i_glb_waypoint-10; doc = "What Nema aspect to use for visual representation of this gizmo"; } [texture] { type = string; default = ; doc = "What texture to map onto the gizmo model (only 1 allowed! blank for no texture)"; } [is_visible] { type = bool; default = true; doc = "Is this gizmo visible (does it render)?"; } [scale] { type = float; default = 1.0; doc = "Scale factor for rendering"; } [alpha] { type = float; default = 1.0; doc = "Global alpha level for this object"; } [diffuse_color] { type = Vector; default = 1.0, 1.0, 1.0; doc = "R/G/B diffuse color to use for rendering"; } [use_diffuse_color] { type = bool; default = true; doc = "Set this to render using diffuse color"; } } [t:component,n:gold] { doc = "Gold that may change its appearance based on count"; required_component* = aspect; internal* = ranges; /* the "ranges" block is a *required* set of ranges to use when defining the appearance of gold based on its quantity. the quantity is the minimum amount of gold required to show that aspect. note that the format is min = model, texture; where model is always required and is the aspect to use, and texture is the optional texture to use for slot 0. texture can be left out. format: [ranges] { 0 = m_i_glb_gold_small; // 0-99 (use default texture) 100 = m_i_glb_gold_medium; // 100-999 (use default texture) 1000 = m_i_glb_gold_big; // 1000-4999 (use default texture) 5000 = m_i_glb_gold_big, b_i_glb_gold_extrabig; // 5000+ note that we're overriding the texture here } */ } [t:component,n:gui] { doc = "Objects with GUI may be placed in inventory"; required_component* = aspect; [inventory_icon] { type = string; default = b_gui_ig_i_it_def; doc = "Bitmap displayed when dragging or in inventory"; } [active_icon] { type = string; default = b_gui_ig_i_ic_def; doc = "Bitmap displayed in quick-select window"; } [mini_icon] { type = string; default = b_gui_ig_i_ic_def; doc = "Bitmap displayed on the AWP chiclets"; } [inventory_max_stackable] { type = int; default = 1; doc = "Maximum items of this type that may be stacked in an inventory slot"; } [inventory_width] { type = int; default = 1; doc = "Width in boxes inside inventory"; } [inventory_height] { type = int; default = 1; doc = "Height in boxes inside inventory"; } [equip_requirements] { type = string; doc = "Minimum skill requirements in order to equip this item"; } [equip_slot] { type = eEquipSlot; default = es_none; doc = "Equipment slot this object uses"; } [is_droppable] { type = bool; default = true; doc = "Can this item be dropped on the ground?"; } [is_lorebook] { type = bool; default = false; doc = "Is this a lore book? ( Right-click on to use )"; } [lore_key] { type = string; doc = "Name of lore that this lore book refers to. ( stored in the map )"; } [is_identified] { type = bool; default = true; doc = "Is this object identified."; } [tooltip_color] { type = string; doc = "Color of the tooltip for this object, leave empty to use default. Color is looked up at config:global_settings:tooltip_colors."; } [can_sell] { type = bool; default = true; doc = "Is this item able to be sold in stores?"; } [use_class] { type = eItemSkillType; default = ist_none; doc = "Allows you to specify if this particular item is meant for a certain skill type ( ist_fighter, ist_ranger, ist_mage )."; } [set] { type = string; doc = "What set does this item belong to (if any)?"; } [is_pet_consumable] { type = bool; default = true; doc = "Can this item be consumed by a pet?"; } [item_level] { type = float; default = 0.0; doc = "What is the item level of this object?"; } [is_reagent] { type = bool; default = false; doc = "Can this item be used as a reagent (for an item enchanter store)?"; } [can_save_in_inventory] { type = bool; default = true; doc = "If this is set to false, it will not be saved out if it is inside someone's inventory."; } /* docs for equip_requirements: use a comma-delimited format, where each entry is of the form skill:number where skill is the name of the skill required, and number is the minimum level of that skill required in order to equip the item. sample: equip_requirements = strength:10,nature magic:5; note that the requirement levels can be negative for modifiers if you want to have a modifier decrease the requirements for an item. */ } [t:component,n:hire] { doc = "Allows the owner to generate and sell npcs."; required_component* = aspect; required_component* = store; [screen_name] { type = string; doc = "Name that you want the NPC store to display in the UI."; } } [t:component,n:inventory] { doc = "Defines contents and size of inventory"; required_component* = common; [custom_head] { type = string; doc = "Different characters can have different heads - h1, h2, etc. (or blank)"; } [grid_width] { type = int; default = 1; flags = ADVANCED; doc = "Width of object's inventory in grid squares"; } [grid_height] { type = int; default = 1; flags = ADVANCED; doc = "Height of object's inventory in grid squares"; } [is_pack_only] { type = bool; default = false; doc = "Set to true if this object cannot equip anything"; } [inventory_pages] { type = int; default = 1; doc = "Specifies how many pages of inventory this character can have. Currently only used for pets. No UI support for humans."; } [gold] { type = int; default = 0; doc = "How many gold pieces in this inventory"; } [selected_active_location] { type = eInventoryLocation; default = il_hand_1; doc = "Which active slot has been selected (by the user from the active box)"; } [spew_equipped_kill_count] { type = string; default = 1,5; doc = "Comma-delimited list of kill counts for this template that will result in an equipped item spew (rather than simple inventory spew)"; } [drop_at_use_point] { type = bool; default = false; doc = "When this object drops its contents, will it use a use point ( if any ) for the drop position?"; } [create_pcontent_on_drop] { type = bool; default = true; doc = "When this object is killed/opened, it will create its pcontent at that point instead of when it streams into the world if this is set to true."; } [render_equipment] { type = bool; default = true; doc = "Does this object render its equipment?"; } [is_container] { type = bool; default = false; doc = "Is this object made to be a container that can be opened/broken?"; } internal* = equipment; /* the "equipment" block is a set of equipped items mapped from equipment slot to item template name. format: [equipment] { es_weapon_hand = ax_1h1b_low; es_ring_0 = super_ring; } */ internal* = other; /* the "other" block is a set of non-equipped items that are just in the inventory. just a set of template names. format: [other] { il_main = a_potion; il_active_melee_weapon = sd_1h_ss; } */ internal* = ranges; /* the "ranges" block is a *required* set of ranges to use when defining the appearance of a go's aspect based on the fullness of its inventory (il_main). the ratio is from 0.0 to 1.0 and each level defines the maximum fullness required to use that aspect/texture. note that the format is min = model, texture; where model is always required and is the aspect to use, and texture is the optional texture to use for slot 0. texture can be left out. format: [ranges] { 0.25 = m_c_na_pm_pos_1; // empty pack mule 0.50 = m_c_na_pm_pos_2; // pack mule with some stuff 0.75 = m_c_na_pm_pos_3; // mid-full pack mule 1.00 = m_c_na_pm_pos_4; // full pack mule } */ internal* = pcontent; /* the "pcontent" block is an additional set of parameterized content that is randomly generated, guided by these rules. pcontent is added to an inventory by selecting from groups, where we will either select all of the groups' entries as candidates for inclusion or will choose one from the list. entries in a group may either be an item for individual template choice (assigned to an inventory location or equip slot), or may be subgroups for recursive fun. note that the inventory locations are the "preferred" locations, and if a slot is already full then it will end up unequipped, sitting in il_main if a weapon, and il_all_spells if a spell. if an "all" group is selected, then all of its items and groups are available as candidates for adding to inventory. if a subgroup has a "chance" defined, then that will be evaluated to decide whether or not to include the group. if a "oneof" group is selected, then one of its items or groups is selected based on probability. by default, all have the same chance of being selected (a group with 3 items would give each item a 33% chance of selection) but by assigning "chance" values to the subgroups you can change this. the total chance for a group must be <= 1.0. note that a total chance of < 1.0 means that it's possible none of the items will be selected and the group will be ignored. if a "gold" group is selected, then you get gold. umm, yeah. it pays attention to min, max and chance for whether or not you get gold, and how much. no items or subgroups within the gold group will get any attention from the pcontent system. if a group is selected, then min/max is used to multiply the group's final subselections for addition to the inventory. note that the top-level group (called pcontent) is treated as an "all". format: [pcontent] { [all*|oneof*] { il_main = template_name; es_weapon_hand = pcontent_name; [all*] { ... } min = 20; max = 20; chance = 0.2; } [gold*] { min = 100; max = 1000; chance = 0.5; } } */ internal* = delayed_pcontent; /* this is exactly the same as the "pcontent" block except that it is not automatically executed when the object it's part of is created. instead, the delayed pcontent is created and added to inventory when AddDelayedPcontent() is called on the GoInventory component. */ internal* = store_pcontent; /* this is exactly the same as the "pcontent" block except that it is used for stores. just take the contents of the [pcontent] block above and put it all into subblocks, one for each tab, where the name can be anything, but it probably will make more sense to name them after the actual tabs. each block can have one extra field "full_ratio", which is a 0.0-1.0 float that determines how full the tab may be. it defaults to the setting in the store_pcontent block, which itself defaults to 1.0. upon adding content, the store will repeatedly query its pcontent system, adding items until it reaches the full_ratio. set the full_ratio to 0 to disable this repeated-add feature. format: [store_pcontent] { full_ratio = 0.8; [armor] { [all*] { ... } } [weapons] { ... } [magic] { ... } [shields] { ... } } */ } // (continued in next two posts) forums: |
||
» |
components.gas, part 2 of 3:
components.gas, part 3 of 3:
Sorry about the wide page... but it reads easier without the word wrap.
Why is this needed here?
Everyone can look in the original components.gas.
I'm thinking of three reasons:
1. Not everyone knows about components.gas (especially newbie's).
2. Helps StheD.org be found by modders using search engines...
3. The original has poor spacing / alignment, making things difficult to read (unless you are looking up something specific, in which case this doesn't really matter).
Hmm, I think it would be nice as an article. It is a wealth of information. Harder to read in forums. Hard to read in skritpad too. Html also shows up better in google . I'm not sure how much of this is translated into html.
/me shrugs... perhaps as part of the knowledge base, once that is set up.
BTW, I checked Google yesterday and there was no match on something that should have linked to this thread. :?
What program did you use to get it in that type of format, Atm I am using Wordpad, and mine dont come out as good as yours,
thats almost like Ds1 type of format.
I used Notepad (with word wrap turned off), and manually edited the spacing before posting it...
Oh okay :P
Is it possible to add my own component to this list and have ds2 "now" about it? Like, say I wanted to add a counter type variable to the [aspect] block, whould I need to write my own functions to access that variable, or does ds2 have some build in general function to access stuff like that?
eg:
[mycomponent] { type int, default = 0; } (or whatever the format is)
and then in skrit
go.aspect.setgenericcomponent("mycomponent", value);
go.aspect.getgenericcomponent("mycomponent");
Does that make sense?
you can't add variables to existing go components like goaspect (without a dsdll that is :p) but you can create your own (skrit) components and add variables to them, and then access those variables.
to create your own (skrit) component just:
1. create a skrit file called something like mycomponent.skrit
2. have the proper headers a normal skrit file does (owner=GoSkritComponent; or whatever, i forget, just read any skrit file)
3. create your properties via "property vartype varname = defaultvalue" (for example; property bool has_j00ky$ = false;)
to access your variables just use the getcomponentvariable functions, check the exact syntax in the fubi.log or some such, but its gonna be something like bool has_jooky$ = someGo$.GetComponentBool ( "mycomponent", "has_j00ky" ); or something
thats the jist, just check fubi.log and other skrit files for the exact details on syntax