|
|
(15 intermediate revisions by 2 users not shown) |
Line 1: |
Line 1: |
− | ''{{about|the engine feature|a list of characters in the Overgrowth universe|Characters (lore)}}''<br> | + | ''{{about|the engine feature|a list of characters in the Overgrowth universe|Characters (lore)|character scripting|Character Scripting}}''<br> |
| | | |
| [[Category:Modding]] | | [[Category:Modding]] |
Line 5: |
Line 5: |
| | | |
| = Overview = | | = Overview = |
| + | Characters are a game entities that are controllable by a player or by AI. In the editor you place spawn points for characters, which look like boxes. When a level starts, each character will be created in its spawn point. |
| | | |
− | Characters are a game entities that are directly controllable by a player or by the AI.
| + | Every character has a number of script parameters associated with it that can be used to change how its AI behaves, how fast it is, how big it is and other things like that. Read the [[Script_Parameters#Character|Script Prameters]] article for more information. |
| | | |
− | Characters have ''Rigged Objects'' attached, which support skeletal animation, rag doll animation, blends of those two, and character physics.
| + | = Creating a Spawn Point = |
| + | In the editor, in the top menu bar, press "Load → Character" and click one in the list, then click where you want to create the spawn point. |
| | | |
− | '''TODO''': More in depth description, akin to that in [[Hotspots]] and [[LevelScripts]]
| + | If you press 8 while there is no player-controlled character in the level, the editor will create a Turner character spawn point on the camera and set it to player-controlled before entering play mode. |
| | | |
− | = Documentation =
| + | You can set or unset any character as player-controlled, which is covered in the next section. |
| | | |
− | == Callable functions and data available inside character scripts == | + | = Set Player-Controlled Character = |
| + | To toggle wether a character is player-controlled or not, select exactly one spawn point and press cmd-shift-P. If the box is green it's player-controlled, if it's white it's AI controlled. |
| | | |
− | A list of functions, data, etc, is created automatically whenever you run the game, in a file on your hard drive. This lists what external code you get "for free" and can call from inside a character script.
| + | If you want the level to be multiplayer you simply set more spawn points to player-controlled. Up to four spawn points can be player controlled. |
| | | |
− | * '''Windows''': <code>My Documents\Wolfire\Overgrowth\aschar_docs.h</code>
| + | = Races = |
− | * '''Mac''': <code>~/Library/Application Support/Overgrowth/aschar_docs.h</code>
| + | Each race in Overgrowth has certain characteristics that make them different. Here you can read about some of the differences. |
− | * '''Linux''': <code>~/.local/share/Overgrowth/aschar_docs.h</code>
| |
| | | |
− | This documentation will change with each version of the game, so keep checking back on this <code>aschar_docs.h</code> file to see the most up to date information.
| + | == Cat == |
| + | * Has extra quiet footsteps |
| + | * Can throw weapons when controlled by AI |
| | | |
− | There are also wiki pages which have more detailed documentation many of these functions. These pages have a danger of going out of date, but give more detailed documentation on some of the code:
| + | == Dog == |
| + | * Cannot be strangled or held hostage, is shoulder thrown instead |
| + | * Falls over when attacked with sword when unaware |
| + | * Takes less damage to passive block from all other races (except wolf) |
| + | * Can throw weapons when controlled by AI |
| | | |
− | * [[Character Script External Code|These functions are unique to character scripts]] | + | == Rabbit == |
− | * [[Common Script External Code|These functions are shared with other script types]] | + | * Jumps high and far |
| + | * Hears extra well |
| + | * Can do leg cannon |
| | | |
− | == Character instances in other scripts == | + | == Rat == |
| + | * Takes more damage to passive block from all other races |
| | | |
− | Characters are exposed to other scripts as instances of the <code>MovementObject</code> class.
| + | == Wolf == |
− | | + | * Cannot be strangled or held hostage, is shoulder thrown instead |
− | <code>MovementObject</code> instances are like other objects in the game. They support everything that is supported by <code>Object</code>, and also have their own special set of functions, properties, etc.
| + | * Cannot use weapons |
− | | + | * Does tons of damage |
− | If you have a handle to a <code>MovementObject@</code> object in angelscript, you can convert it to an <code>Object@</code> by calling <code>ReadObjectFromID(movement_object.GetID());</code>.
| + | * Cannot be harmed by unarmed attacks, except from other wolves or leg cannon |
− | | + | * Causes all other races controlled by AI except dogs to run away in terror |
− | == Working with Characters in editor == | + | ** This is configurable in each character's parameters |
− | | + | * Uses their KO shield as health |
− | '''TODO''': How to set a character as playable in the editor.
| |
− | | |
− | '''TODO''': List of supported character parameters and how to use them. Some of these things verge more into "game" territory and not "engine" territory, so should at the very least mention that it's fully changeable in script...
| |
− | | |
− | '''TODO''': List of species specific traits? Some of these things verge more into "game" territory and not "engine" territory, so should at the very least mention that it's fully changeable in script...
| |
− | | |
− | = How to create a character =
| |
− | | |
− | == Character XML files ==
| |
− | | |
− | '''TODO''': Description of XML format
| |
− | | |
− | == File path conventions ==
| |
− | | |
− | '''TODO''': Description of where to add files in mods so they don't conflict. Ala [[Hotspots#File_path_conventions]]
| |
− | | |
− | == Modeling ==
| |
− | | |
− | '''TODO''': Links to or docs on modeling, graphics features like fur fins, various texture channels and what their components (alpha etc) mean, UVs, object space normals, etc. Also, any export info that would be necessary.
| |
− | | |
− | == Rigging ==
| |
− | | |
− | '''TODO''': Links to or docs on rigging and rig export
| |
− | | |
− | == Hull ==
| |
− | | |
− | '''TODO''': Links to or docs on character hulls
| |
− | | |
− | == Animations ==
| |
− | | |
− | '''TODO''': Links to or docs on animations and export, tagging, etc
| |
− | | |
− | == Morph targets ==
| |
− | | |
− | '''TODO''': Links to or docs on morph target animations for hands, face, etc
| |
− | | |
− | == Eyes ==
| |
− | | |
− | '''TODO''': Links to or docs on morph target animations for eyes (might roll this up into other sections/other pages?)
| |
− | | |
− | == Attacks ==
| |
− | | |
− | '''TODO''': Links to or docs on attacks system and export, tagging, etc - related partly to animations.<br>
| |
− | | |
− | '''TODO''': Possibly also scripting attacks and animations, and character-bound input, etc - though maybe that should be in a different section?
| |
− | | |
− | = How to add a character to the spawner menu =
| |
− | | |
− | Short version:
| |
− | * You must add it in a mod.
| |
− | * You can add as many characters to the spawner menu as you want in a single mod, you just need to follow the below instructions for each, and add multiple <code><Item></code> tags to your mod.xml file.
| |
− | | |
− | In your mod.xml file, add this xml tag:
| |
− | ('''TODO''': Make these paths more specific to characters)
| |
− | | |
− | <pre><Item category="My Custom Mod Characters"
| |
− | title="Some Character To Spawn"
| |
− | path="Data/Objects/example_item_pack/mod_item_example.xml"
| |
− | thumbnail="Data/UI/example_item_pack/thumbs/mod_item_example.png" /></pre>
| |
− | | |
− | * '''<code>category</code>''' is the top level category where the character will show up, in the '''Load''' menu.
| |
− | * '''<code>title</code>''' is the name of the character, as it will show up in the spawner menu. | |
− | * '''<code>path</code>''' is the path to the character XML that will get spawned. See [[#How_to_create_a_character|the '''How to create a character''' section]] for which XML file to target (either the character XML itself, or a version you saved off that has modified default parameters). '''TODO''': Be careful to advise ''which'' character XML to add to the spawner - there are multiple character XML files! | |
− | * '''<code>thumbnail</code>''' is the image that will be used for a tooltip when you hover over your character in the spawner menu.
| |
− | | |
− | See '''<code>GameInstallDir/Data/ExampleMods/mod_xml_specification.txt</code>''' for full information.
| |
− | | |
− | = Character script hook functions =
| |
− | | |
− | These functions are '''required'''. If you override the character controller script for a character in your mod, you must include all of these functions:
| |
− | | |
− | * [[#Init function|<code>bool Init(string character_path) { return true; }</code>]]
| |
− | * [[#Reset function|<code>void Reset() { }</code>]]
| |
− | * [[#SetParameters function|<code>void SetParameters() { }</code>]]
| |
− | * [[#PostReset function|<code>void PostReset() { }</code>]]
| |
− | * [[#ScriptSwap function|<code>void ScriptSwap() { }</code>]]
| |
− | * [[#Update function|<code>void Update(int num_frames) { }</code>]]
| |
− | * [[#UpdatePaused function|<code>void UpdatePaused() { }</code>]]
| |
− | * [[#ReceiveMessage function|<code>void ReceiveMessage(string message) { }</code>]]
| |
− | * [[#SetEnabled function|<code>void SetEnabled(bool is_enabled) { }</code>]]
| |
− | * [[#MovementObjectDeleted function|<code>void MovementObjectDeleted(int character_id) { }</code>]]
| |
− | * [[#AttachWeapon function|<code>void AttachWeapon(int weapon_item_id) { }</code>]]
| |
− | * [[#AttachMisc function|<code>void AttachMisc(int misc_item_id) { }</code>]]
| |
− | * [[#HandleEditorAttachment function|<code>void HandleEditorAttachment(int item_id, int attachment_type, bool is_mirrored) { }</code>]]
| |
− | * [[#NotifyItemDetach function|<code>void NotifyItemDetach(int item_id) { }</code>]]
| |
− | * [[#GetTempHealth function|<code>float GetTempHealth() { return 1.0f; }</code>]]
| |
− | * [[#ForceApplied function|<code>void ForceApplied(vec3 force) { }</code>]]
| |
− | * [[#Contact function|<code>void Contact() { }</code>]]
| |
− | * [[#Collided function|<code>void Collided(float posx, float posy, float posz, float impulse, float hardness) { }</code>]]
| |
− | * [[#AboutToBeHitByItem function|<code>int AboutToBeHitByItem(int item_id) { return 1; }</code>]]
| |
− | * [[#HitByItem function|<code>void HitByItem(string material, vec3 point_of_impact, int item_id, int impact_type) { }</code>]]
| |
− | * [[#WasHit function|<code>int WasHit(string type, string attack_path, vec3 dir, vec3 pos, int attacker_id, float attack_damage_mult, float attack_knockback_mult) { return 1; }</code>]]
| |
− | * [[#HandleCollisionsBetweenTwoCharacters function|<code>void HandleCollisionsBetweenTwoCharacters(MovementObject@ other_character) { }</code>]] | |
− | * [[#PreDrawCamera function|<code>void PreDrawCamera(float curr_game_time) { }</code>]]
| |
− | * [[#PreDrawCameraNoCull function|<code>void PreDrawCameraNoCull(float curr_game_time) { }</code>]]
| |
− | * [[#PreDrawFrame function|<code>void PreDrawFrame(float curr_game_time) { }</code>]]
| |
− | * [[#DisplayMatrixUpdate function|<code>void DisplayMatrixUpdate() { }</code>]]
| |
− | * [[#FinalAnimationMatrixUpdate function|<code>void FinalAnimationMatrixUpdate(int num_frames) { }</code>]]
| |
− | * [[#FinalAttachedItemUpdate function|<code>void FinalAttachedItemUpdate(int num_frames) { }</code>]]
| |
− | * [[#HandleAnimationEvent function|<code>void HandleAnimationEvent(string event, vec3 world_pos) { }</code>]]
| |
− | * [[#WasBlocked function|<code>void WasBlocked() { }</code>]]
| |
− | | |
− | These functions are '''optional'''. These functions do not have to be added to your overridden character controller script, but will be called if they are present:
| |
− | | |
− | * [[#Dispose function|<code>void Dispose() { }</code>]]
| |
− | * [[#ResetWaypointTarget function|<code>void ResetWaypointTarget() { }</code>]]
| |
− | | |
− | == Init function ==
| |
− | | |
− | <pre style="white-space: pre-wrap;">bool Init(string character_path) { return true; }</pre>
| |
− | | |
− | [[#Character script hook functions|'''Required''']]
| |
− | | |
− | [[#Init function|<code>Init</code>]] is called when the character is first to be loaded, upon level load.
| |
− | | |
− | Must return '''<code>true</code>''' upon success, and '''<code>false</code>''' upon failure.
| |
− | | |
− | Important things to do in this call are to set the motion object character path, load the character (<code>character_getter.Load(character_path);</code>), read the species tag (<code>character_getter.GetTag("species")</code>), set up the skeleton, etc.
| |
− | | |
− | Be careful, this may be called before some objects or script params are present in the level.
| |
− | | |
− | == Reset function ==
| |
− | | |
− | <pre style="white-space: pre-wrap;">void Reset() { }</pre>
| |
− | | |
− | [[#Character script hook functions|'''Required''']]
| |
− | | |
− | '''TODO''': How much of this is correct?
| |
− | | |
− | [[#Reset function|<code>Reset</code>]] is called whenever the level is reset. This does ''not'' happen when a level is first loaded, or when undo/redo are fired in the editor.
| |
− | | |
− | This happens when the player hits the "L" debug key to manually reset the level.
| |
− | | |
− | This also happens upon player respawn (but this is up to the level script, and modded level scripts might not do that).
| |
− | | |
− | When Reset gets called for a character:
| |
− | | |
− | # [[#Reset function|<code>Reset();</code>]] is called
| |
− | # Physics for the character is set up
| |
− | # Global variables in the AS context are reset
| |
− | # [[#SetParameters function|<code>SetParameters();</code>]] is called
| |
− | # [[#PostReset function|<code>PostReset();</code>]] is called
| |
− | # Item attachements are done, and attachment callbacks are called ([[#HandleEditorAttachment function|<code>[1]</code>]], [[#AttachWeapon function|<code>[2]</code>]], [[#AttachMisc function|<code>[3]</code>]])
| |
− | | |
− | == SetParameters function ==
| |
− | | |
− | <pre style="white-space: pre-wrap;">void SetParameters() { }</pre>
| |
− | | |
− | [[#Character script hook functions|'''Required''']]
| |
− | | |
− | [[#SetParameters function|<code>SetParameters</code>]] is called when the character is first loaded, whenever the script parameter values are changed via the GUI, and whenever [[#Reset function|<code>Reset()</code>]] is called.
| |
− | | |
− | It is also called when an undo/redo is fired in the editor, to reload script params from that point in history.
| |
− | | |
− | This function allows the character script to work with script parameter values.
| |
− | You can use it to define, change, verify, protect (undo writes), or locally cache script parameter values.
| |
− | | |
− | You can also use this to work with game objects that you use character script params to control (if any - this is a trick usually done in hotspot scripts, with placeholder objects, but there isn't any reason why a character script couldn't do similar things, if it was somehow valuable).
| |
− | | |
− | == PostReset function ==
| |
− | | |
− | <pre style="white-space: pre-wrap;">void PostReset() { }</pre>
| |
− | | |
− | [[#Character script hook functions|'''Required''']]
| |
− | | |
− | '''TODO''': How much of this is correct?
| |
− | | |
− | [[#PostReset function|<code>PostReset</code>]] is called whenever the level is reset. This does ''not'' happen when a level is first loaded, or when undo/redo are fired in the editor.
| |
− | | |
− | This happens when the player hits the "L" debug key to manually reset the level.
| |
− | | |
− | This also happens upon player respawn (but this is up to the level script, and modded level scripts might not do that).
| |
− | | |
− | When Reset gets called for a character:
| |
− | | |
− | # [[#Reset function|<code>Reset();</code>]] is called
| |
− | # Physics for the character is set up
| |
− | # Global variables in the AS context are reset
| |
− | # [[#SetParameters function|<code>SetParameters();</code>]] is called
| |
− | # [[#PostReset function|<code>PostReset();</code>]] is called
| |
− | # Item attachements are done, and attachment callbacks are called ([[#HandleEditorAttachment function|<code>[1]</code>]], [[#AttachWeapon function|<code>[2]</code>]], [[#AttachMisc function|<code>[3]</code>]])
| |
− | | |
− | == ScriptSwap function ==
| |
− | | |
− | <pre style="white-space: pre-wrap;">void ScriptSwap() { }</pre>
| |
− | | |
− | [[#Character script hook functions|'''Required''']]
| |
− | | |
− | [[#ScriptSwap function|<code>ScriptSwap</code>]] is called before [[#Update function|<code>Update()</code>]], when the character control script gets swapped (caused by going from player control to AI control, or vice-versa).
| |
− | | |
− | This function gives the script an opportunity to properly adjust its variables after the transition to the new script, so updates happen smoothly. Existing global variables are copied over, but variables that aren't shared between the scripts might need to be derived and/or initialized in this function.
| |
− | | |
− | '''Note''': The character model, rigged object, etc, stay loaded when this script is swapped, so this is mostly just available to handle special on-swap behavior (if you want to add any).
| |
− | | |
− | '''Note''': The update frequency is based on whether the new script is a player control script (<code>Data/Scripts/playercontrol.as</code>, set to update 120-per-second) or an AI control script (any other script, set to update 30-per-second, with a random offset with 120hz frequency to spread out the updates).
| |
− | | |
− | When the script gets swapped:
| |
− | | |
− | # The global variables are saved from the old script
| |
− | # The new script is loaded
| |
− | # The global variables are restored to the new script
| |
− | # The update frequency gets selected, based on which script got loaded
| |
− | # [[#ScriptSwap function|this function is called]]
| |
− | | |
− | == Update function ==
| |
− | | |
− | <pre style="white-space: pre-wrap;">void Update(int num_frames) { }</pre>
| |
− | | |
− | [[#Character script hook functions|'''Required''']]
| |
− | | |
− | [[#Update function|<code>Update</code>]] is called regularly by the engine so you can perform work. It is only called while the game is unpaused.
| |
− | | |
− | It may be useful to do initialization once in this function, if you need objects or character script params to be present.
| |
− | | |
− | Be careful to keep this function short, sweet, and fast. <code>Update</code> gets called 120 times a second as of the time of this writing.
| |
− | | |
− | '''Note''': The update frequency is based on whether this script is a player control script (<code>Data/Scripts/playercontrol.as</code>, set to update 120-per-second) or an AI control script (any other script, set to update 30-per-second, with a random offset with 120hz frequency to spread out the updates).
| |
− | | |
− | == UpdatePaused function ==
| |
− | | |
− | <pre style="white-space: pre-wrap;">void UpdatePaused() { }</pre>
| |
− | | |
− | [[#Character script hook functions|'''Required''']]
| |
− | | |
− | [[#UpdatePaused function|<code>UpdatePaused</code>]] is called regularly by the engine while the game is paused so you can handle camera movements. It is only called for characters that are controlled by players.
| |
− | | |
− | While the game is paused, <code>Update</code> does not get called, and this function does.
| |
− | | |
− | Be careful to keep this function short, sweet, and fast. <code>UpdatePaused</code> gets called 120 times a second as of the time of this writing.
| |
− | | |
− | == ReceiveMessage function ==
| |
− | | |
− | <pre style="white-space: pre-wrap;">void ReceiveMessage(string message) { }</pre>
| |
− | | |
− | [[#Character script hook functions|'''Required''']]
| |
− | | |
− | [[#ReceiveMessage function|<code>ReceiveMessage</code>]] is called when messages have been sent to this character by the engine, level, or objects in levels.
| |
− | | |
− | Objects in levels (such as hotspots or other characters) can send this using <code>movement_object.SendMessage("some message string");</code>.
| |
− | | |
− | Parameters can be sent by separating them with spaces, and putting quotes around parameters that might contain spaces, then using the <code>TokenIterator</code> object. '''TODO''': Write a TokenIterator example and link to it.
| |
− | | |
− | '''Note''': If you're setting up the code to send a message to a character, you might want to choose to only send messages to player characters, or non-player characters. '''TODO''': Example of how to do this filtering.
| |
− | | |
− | == SetEnabled function ==
| |
− | | |
− | <pre style="white-space: pre-wrap;">void SetEnabled(bool is_enabled) { }</pre>
| |
− | | |
− | [[#Character script hook functions|'''Required''']]
| |
− | | |
− | [[#SetEnabled function|The <code>SetEnabled</code> hook function]] is called when <code>movement_object.SetEnabled(bool);</code> gets called on the character by another script.
| |
− | | |
− | This function allows the character to enable or disable any objects that should be associated with the character (such as fire ribbons, sounds, shadow objects, character camera item flashes, and water splashes).
| |
− | | |
− | This function can also be used to internally set variables so that its functions have no effect. The engine will generally not call the character if it is not enabled (except when it gets re-enabled), but other scripts could theoretically call functions on the character using <code>movement_object_instance.Execute("some code");</code>.
| |
− | | |
− | '''Note''': It may be viable to call [[#Dispose function|<code>Dispose()</code>]] from inside this function, as long as you're careful not to double-delete things.
| |
− | | |
− | == MovementObjectDeleted function ==
| |
− | | |
− | <pre style="white-space: pre-wrap;">void MovementObjectDeleted(int character_id) { }</pre>
| |
− | | |
− | [[#Character script hook functions|'''Required''']]
| |
− | | |
− | Callback to notify a character script that a different character got deleted, in case it was tracking that character and needs to stop tracking it.
| |
− | | |
− | == AttachWeapon function ==
| |
− | | |
− | <pre style="white-space: pre-wrap;">void AttachWeapon(int weapon_item_id) { }</pre>
| |
− | | |
− | [[#Character script hook functions|'''Required''']]
| |
− | | |
− | Called when the player picks up a weapon item off the ground. ('''TODO''': Is this correct? Verify by editing the script to add debug logging and run through the scenario. Maybe also check engine code?)
| |
− | | |
− | == AttachMisc function ==
| |
− | | |
− | <pre style="white-space: pre-wrap;">void AttachMisc(int misc_item_id) { }</pre>
| |
− | | |
− | [[#Character script hook functions|'''Required''']]
| |
− | | |
− | Called when the player picks up a miscelaneous (non-weapon) item off the ground. ('''TODO''': an example? Might be vestigial, but still required?)
| |
− | | |
− | == HandleEditorAttachment function ==
| |
− | | |
− | <pre style="white-space: pre-wrap;">void HandleEditorAttachment(int item_id, int attachment_type, bool is_mirrored) { }</pre>
| |
− | | |
− | [[#Character script hook functions|'''Required''']]
| |
− | | |
− | Called when the player attaches an item to a character in the editor.
| |
− | | |
− | '''attachment_type''' is a value from the AttachmentType enum. '''TODO''': Link to the docs for that enum.
| |
− | | |
− | == NotifyItemDetach function ==
| |
− | | |
− | <pre style="white-space: pre-wrap;">void NotifyItemDetach(int item_id) { }</pre>
| |
− | | |
− | [[#Character script hook functions|'''Required''']]
| |
− | | |
− | Called when the player drops an item or weapon, or detaches it in the editor. '''TODO''': Verify that this is all correct.
| |
− | | |
− | == GetTempHealth function ==
| |
− | | |
− | <pre style="white-space: pre-wrap;">float GetTempHealth() { return 1.0f; }</pre>
| |
− | | |
− | [[#Character script hook functions|'''Required''']]
| |
− | | |
− | Get the current health of the character (called "temp health" to distinguish from the character's current max health)
| |
− | | |
− | == ForceApplied function ==
| |
− | | |
− | <pre style="white-space: pre-wrap;">void ForceApplied(vec3 force) { }</pre>
| |
− | | |
− | [[#Character script hook functions|'''Required''']]
| |
− | | |
− | '''NOTE''': Vestigial function that is not called by the engine, but still required to be present. It could be called by another script, if so desired (via <code>movement_object.ApplyForce(vec3);</code>), but the base game doesn't currently do this. RiggedObject functions are used instead for this purpose, or other collision response callbacks that are more specialized (like [[#HitByItem function|<code>HitByItem</code>]]).
| |
− | | |
− | == Contact function ==
| |
− | | |
− | <pre style="white-space: pre-wrap;">void Contact() { }</pre>
| |
− | | |
− | [[#Character script hook functions|'''Required''']]
| |
− | | |
− | Called when any collision happens, including debouncing/resting collisions (which are filtered out and don't trigger other collision callbacks, such as [[#Collided function|<code>Collided(...)</code>]])
| |
− | | |
− | == Collided function ==
| |
− | | |
− | <pre style="white-space: pre-wrap;">void Collided(float posx, float posy, float posz, float impulse, float hardness) { }</pre>
| |
− | | |
− | [[#Character script hook functions|'''Required''']]
| |
− | | |
− | Called when a collision just happened that is stronger than a very light tap (light and resting collisions will be filtered out by this, but won't be by [[#Contact function|<code>Contact()</code>]]
| |
− | | |
− | == AboutToBeHitByItem function ==
| |
− | | |
− | <pre style="white-space: pre-wrap;">int AboutToBeHitByItem(int item_id) { return 1; }</pre>
| |
− | | |
− | [[#Character script hook functions|'''Required''']]
| |
− | | |
− | Called when a character is about to be hit by an item so deflection can be tested/triggered.
| |
− | | |
− | Return '''<code>-1</code>''' to specify that the collision was avoided (such as when the character deflects or catches the item). Make sure to handle the result of that avoidance as well inside this function, such as flinging the weapon to the side, or attaching it to the character's hand.
| |
− | | |
− | Return '''<code>1</code>''' to specify that the collision could not be avoided, and the collision handling should continue on. Handle the reactions to this case in the [[#HitByItem function|<code>HitByItem()</code>]] callback, instead of in this function.
| |
− | | |
− | == HitByItem function ==
| |
− | | |
− | <pre style="white-space: pre-wrap;">void HitByItem(string material, vec3 point_of_impact, int item_id, int impact_type) { }</pre>
| |
− | | |
− | [[#Character script hook functions|'''Required''']]
| |
− | | |
− | Called when the character is hit by an item so it can react to the impact, take damage, etc.
| |
− | | |
− | * '''<code>material</code>''': Per-polygon-edge material description for the edge that hit the character, in case the result of impact should be different (less or more damage, sharp vs not sharp, etc). Note that the base game doesn't do anything in response to this value. | |
− | * '''<code>point_of_impact</code>''': The point where the item impacted the character | |
− | * '''<code>item_id</code>''': The id of the game object that hit this character
| |
− | * '''<code>impact_type</code>''': '''<code>2</code>''' = sticks, '''<code>1</code>''' = cut, '''<code>0</code>''' = bounce off
| |
− | | |
− | '''Note''': Any avoidance of the collision (catching the item, deflecting it, etc) should happen in [[#AboutToBeHitByItem function|<code>AboutToBeHitByItem(int)</code>]] instead.
| |
− | | |
− | == WasHit function ==
| |
− | | |
− | <pre style="white-space: pre-wrap;">int WasHit(string type, string attack_path, vec3 dir, vec3 pos, int attacker_id, float attack_damage_mult, float attack_knockback_mult) { return 1; }</pre>
| |
− | | |
− | [[#Character script hook functions|'''Required''']]
| |
− | | |
− | Handles what happens if a character was hit. Includes blocking enemies' attacks, hit reactions, taking damage, going ragdoll and applying forces to ragdoll.
| |
− | | |
− | * '''<code>type</code>''': A string that identifies the action and thus the reaction
| |
− | * '''<code>attack_path</code>''': A path to the attack XML file for this attack
| |
− | * '''<code>dir</code>''': The vector from the attacker to the defender
| |
− | * '''<code>pos</code>''': The impact position
| |
− | * '''<code>attacker_id</code>''': The game object Id of the character who is attacking
| |
− | * '''<code>attack_damage_mult</code>''': The attack damage multiplier for the attack (specified in the base scripts in the attacking character's '''<code>Attack Damage</code>''' script param)
| |
− | * '''<code>attack_knockback_mult</code>''': The attack damage multiplier for the attack (specified in the base scripts in the attacking character's '''<code>Attack Knockback</code>''' script param) | |
− | | |
− | Return values: ('''TODO''': Verify that the whole two-pass thing here is accurate. This could just be a convention used by the scripts, and not values that are important to the engine itself)
| |
− | | |
− | * '''<code>0</code>''': miss - Return if the attack was a complete wiff, and did not land at all (dodged, ducked under, light attacks blocked with a knife, etc)
| |
− | * '''<code>1</code>''': going to block - Return if the block attempt was successfully executed (on the first pass of the attack)
| |
− | * '''<code>2</code>''': hit - Return if the attack landed, and was not countered (on the second pass of the attack)
| |
− | * '''<code>3</code>''': block impact - Return if the attack landed, but was blocked (on the second pass of the attack)
| |
− | * '''<code>4</code>''': invalid - Returned in the base scripts if <code>type</code> or <code>attack_path</code> have unexpected/unhandled values
| |
− | * '''<code>5</code>''': going to dodge - Return if the dodge attempt was successfully executed (on the first pass of the attack)
| |
− | | |
− | == HandleCollisionsBetweenTwoCharacters function ==
| |
− | | |
− | <pre style="white-space: pre-wrap;">void HandleCollisionsBetweenTwoCharacters(MovementObject@ other_character) { }</pre>
| |
− | | |
− | [[#Character script hook functions|'''Required''']]
| |
− | | |
− | Called when the game detects two characters have collided, so physics response impulses and possibly additional gameplay logic can be applied.
| |
− | | |
− | == PreDrawCamera function ==
| |
− | | |
− | <pre style="white-space: pre-wrap;">void PreDrawCamera(float curr_game_time) { }</pre>
| |
− | | |
− | [[#Character script hook functions|'''Required''']]
| |
− | | |
− | '''TODO''': What for, why? Looks like it is called to update UI elements, post-culling, and handle things that don't have to be called in PreDrawCameraNoCull?
| |
− | | |
− | == PreDrawCameraNoCull function ==
| |
− | | |
− | <pre style="white-space: pre-wrap;">void PreDrawCameraNoCull(float curr_game_time) { }</pre>
| |
− | | |
− | [[#Character script hook functions|'''Required''']]
| |
− | | |
− | '''TODO''': What for, why? Looks like it is used to apply global camera effects and update camera controls?
| |
− | | |
− | == PreDrawFrame function ==
| |
− | | |
− | <pre style="white-space: pre-wrap;">void PreDrawFrame(float curr_game_time) { }</pre>
| |
− | | |
− | [[#Character script hook functions|'''Required''']]
| |
− | | |
− | [[#PreDrawFrame function|<code>PreDrawFrame</code>]] is called to let scripts perform per-frame calculations before anything in the frame is drawn, like updating the character's blob shadows.
| |
− | | |
− | '''Note''': After [[#PreDrawFrame function|<code>PreDrawFrame</code>]] is called for this character, then all objects attached to this character are moved to their correct positions.
| |
− | | |
− | '''Note''': Once all objects have had [[#PreDrawFrame function|<code>PreDrawFrame</code>]] called on them, then the rest of the rendering is done for the frame.
| |
− | | |
− | == DisplayMatrixUpdate function ==
| |
− | | |
− | <pre style="white-space: pre-wrap;">void DisplayMatrixUpdate() { }</pre>
| |
− | | |
− | [[#Character script hook functions|'''Required''']]
| |
− | | |
− | Callback to handle time-based procedural skeletal animation effects that aren't animation controlled (in the base scripts, just breathing right now)
| |
− | | |
− | '''Note''': This function gets triggered at the <code>RiggedObject</code> level, not at the <code>MovementObject</code> level.
| |
− | | |
− | == FinalAnimationMatrixUpdate function ==
| |
− | | |
− | <pre style="white-space: pre-wrap;">void FinalAnimationMatrixUpdate(int num_frames) { }</pre>
| |
− | | |
− | [[#Character script hook functions|'''Required''']]
| |
− | | |
− | Callback to do character IK calculations
| |
− | | |
− | For the base unmodified game scripts, examples include rolling contact with ground and rolling animation transitions, turning torso towards target, planting feet on ground, ledge hanging, tethering when dragging bodies, eye look direction, foot balancing on "balance" collision painted surfaces. It is also called by base game in "FixDiscontinuity"
| |
− | | |
− | '''Note''': This function gets triggered at the <code>RiggedObject</code> level, not at the <code>MovementObject</code> level.
| |
− | | |
− | == FinalAttachedItemUpdate function ==
| |
− | | |
− | <pre style="white-space: pre-wrap;">void FinalAttachedItemUpdate(int num_frames) { }</pre>
| |
− | | |
− | [[#Character script hook functions|'''Required''']]
| |
− | | |
− | '''Note''': This function gets triggered at the <code>RiggedObject</code> level, not at the <code>MovementObject</code> level.
| |
− | | |
− | '''TODO''': What is this for? Weapon IK? It seems to be empty in the base game scripts right now, except it has some temporary testing code for doing some sword stab IK that affects the weapon?
| |
− | | |
− | == HandleAnimationEvent function ==
| |
− | | |
− | <pre style="white-space: pre-wrap;">void HandleAnimationEvent(string event, vec3 world_pos) { }</pre>
| |
− | | |
− | [[#Character script hook functions|'''Required''']]
| |
− | | |
− | Animation events are created by the animation files themselves. For example, when the run animation is played, it calls <code>HandleAnimationEvent("leftrunstep", left_foot_pos)</code> when the left foot hits the ground.
| |
− | | |
− | '''Note''': This function gets triggered at the <code>RiggedObject</code> level, not at the <code>MovementObject</code> level.
| |
− | | |
− | '''TODO''': List current animation events that are tagged in scripts? Is this system open for adding new items, and do any existing ones require behavior to be implemented, or could they be ignored?
| |
− | | |
− | == WasBlocked function ==
| |
− | | |
− | <pre style="white-space: pre-wrap;">void WasBlocked() { } </pre>
| |
− | | |
− | [[#Character script hook functions|'''Required''']]
| |
− | | |
− | Vestigial function not called by the engine or base game scripts. It is exposed to other scripts on the <code>MovementObject@</code> interface, and must be present if it gets called by game scripts.
| |
− | | |
− | '''TODO''': More details on what to use instead? Does [[#WasHit function|<code>WasHit(...)</code>]] handle everything this function would handle?
| |
− | | |
− | == Dispose function ==
| |
− | | |
− | <pre style="white-space: pre-wrap;">void Dispose() { }</pre>
| |
− | | |
− | [[#Character script hook functions|'''Optional''']]
| |
− | | |
− | [[#Dispose function|<code>Dispose</code>]] is called when the character is destroyed, either by manually deleting it, or when the level is unloaded.
| |
− | | |
− | '''WARNING:''' Do not DeleteObjectID for other game objects from this function! If you try to, then the game will likely crash on level unload when calling <code>Dispose()</code> on the object you deleted. Also don't try to <code>QueueDeleteObjectID()</code> through Dispose, or it will really mess with undo/redo state.
| |
− | | |
− | This function allows the character to free any non-game objects that are owned by this character (such as fire ribbons, sounds, shadow objects, character camera item flashes, and water splashes).
| |
− | | |
− | == ResetWaypointTarget function ==
| |
− | | |
− | <pre style="white-space: pre-wrap;">void ResetWaypointTarget() { }</pre>
| |
− | | |
− | [[#Character script hook functions|'''Optional''']]
| |
− | | |
− | [[#ResetWaypointTarget function|<code>ResetWaypointTarget</code>]] is called when a character or path point that this character is directed to follow (connected to) is changed.
| |
− | | |
− | This happens when the target gets deleted, this character is disconnected from it, or the connection target is updated to a new target. This can happen either through the editor, or through scripting logic.
| |