#include common_scripts\utility; #include maps\_utility; #include maps\_anim; /* ============= ///ScriptDocBegin "Name: stealth_default()" "Summary: runs default stealth behavior on AI or the player" "Module: Stealth" "CallOn: An ai or the player" "Example: level.price stealth_default();" "SPMP: singleplayer" ///ScriptDocEnd ============= */ stealth_default() { self stealth_plugin_basic(); if ( isplayer( self ) ) return; switch( self.team ) { case "axis": case "team3": self stealth_plugin_threat(); self stealth_enable_seek_player_on_spotted(); self stealth_plugin_corpse(); self stealth_plugin_event_all(); break; case "allies": self stealth_plugin_aicolor(); self stealth_plugin_accuracy(); self stealth_plugin_smart_stance(); } } /* ============= ///ScriptDocBegin "Name: stealth_set_default_stealth_function( , )" "Summary: sets the function in to a key. The KEY is referenced in radient with script_stealth_function. any spawner with that key will run the function referenced here. This function should be similar in form to stealth_default " "Module: Stealth" "CallOn: " "MandatoryArg: : the reference which matches the script_stealth_function key set on a spawner in radient" "MandatoryArg: : the pointer to a function which will be called at spawn" "Example: stealth_set_default_stealth_function( "top guys", ::stealth_cliffhanger );" "SPMP: singleplayer" ///ScriptDocEnd ============= */ stealth_set_default_stealth_function( key, func ) { level.stealth_default_func[ key ] = func; } /* ============= ///ScriptDocBegin "Name: stealth_plugin_basic()" "Summary: runs BASIC stealth logic on AI. Handles proper animations, and setting the '_stealth_spotted' flag" "Module: Stealth" "CallOn: An ai" "Example: level.price stealth_plugin_basic()" "SPMP: singleplayer" ///ScriptDocEnd ============= */ stealth_plugin_basic( custom_state_funcs ) { assertex( isdefined( level._stealth.logic ), "call maps\_stealth::main()" ); if ( isplayer( self ) ) { self maps\_stealth_visibility_friendly::stealth_visibility_friendly_main(); return; } if ( !isdefined( self._stealth ) || !isdefined( self._stealth.plugins.basic ) ) { switch( self.team ) { case "allies": self maps\_stealth_visibility_friendly::stealth_visibility_friendly_main(); self maps\_stealth_behavior_friendly::stealth_behavior_friendly_main(); break; case "axis": case "team3": self maps\_stealth_visibility_enemy::stealth_visibility_enemy_main(); self maps\_stealth_behavior_enemy::stealth_behavior_enemy_main(); break; } } if ( isdefined( custom_state_funcs ) ) self stealth_basic_states_custom( custom_state_funcs ); self._stealth.plugins.basic = true; } /* ============= ///ScriptDocBegin "Name: stealth_basic_states_custom( )" "Summary: " "Module: Entity" "CallOn: An entity" "MandatoryArg: : " "OptionalArg: : " "Example: " "SPMP: singleplayer" ///ScriptDocEnd ============= */ stealth_basic_states_custom( array ) { switch( self.team ) { case "allies": self maps\_stealth_behavior_friendly::friendly_custom_state_behavior( array ); break; case "axis": case "team3": self maps\_stealth_behavior_enemy::enemy_custom_state_behavior( array ); break; } } /* ============= ///ScriptDocBegin "Name: stealth_basic_states_default()" "Summary: " "Module: Entity" "CallOn: An entity" "MandatoryArg: : " "OptionalArg: : " "Example: " "SPMP: singleplayer" ///ScriptDocEnd ============= */ stealth_basic_states_default() { switch( self.team ) { case "allies": self maps\_stealth_behavior_friendly::friendly_default_state_behavior(); break; case "axis": case "team3": self maps\_stealth_behavior_enemy::enemy_default_state_behavior(); break; } } /* ============= ///ScriptDocBegin "Name: stealth_pre_spotted_function_custom( )" "Summary: replaces the default function for what an AI will do between the period he's realized there is a threat, and sets the flag for _stealth_spotted. Good for writing custom AI behavior like running to an alarm before alerting his buddies of _stealth_spotted" "Module: Stealth" "CallOn: An AI" "MandatoryArg: : a function pointer to the custom function" "Example: enemy stealth_pre_spotted_function_custom( ::run_to_alarm_func );" "SPMP: singleplayer" ///ScriptDocEnd ============= */ stealth_pre_spotted_function_custom( func ) { assertex( isdefined( self._stealth.plugins.basic ), "call maps\_stealth_utility::stealth_plugin_basic() on the AI first" ); self maps\_stealth_visibility_enemy::enemy_alert_level_set_pre_spotted_func( func ); } /* ============= ///ScriptDocBegin "Name: stealth_pre_spotted_function_default()" "Summary: sets the behavior for what to do between realizing a threat and setting the _stealth_spotted flag back to default. ( which is just waiting a couple seconds )" "Module: Stealth" "CallOn: An AI" "Example: enemy stealth_pre_spotted_function_default();" "SPMP: singleplayer" ///ScriptDocEnd ============= */ stealth_pre_spotted_function_default() { assertex( isdefined( self._stealth.plugins.basic ), "call maps\_stealth_utility::stealth_plugin_basic() on the AI first" ); self maps\_stealth_visibility_enemy::enemy_alert_level_default_pre_spotted_func(); } /* ============= ///ScriptDocBegin "Name: stealth_plugin_threat( )" "Summary: Runs threat behavior logic on an AI -> basically all the 'huh, what was that, who's there' behavior. stealth_plugin_basic() needs to be called on the AI before this" "Module: Stealth" "CallOn: An AI" "OptionalArg: : array of functions that internally get's passed to 'stealth_threat_behavior_replace()'. please refer to stealth_threat_behavior_replace() for detailed help" "Example: enemy stealth_plugin_threat();" "SPMP: singleplayer" ///ScriptDocEnd ============= */ stealth_plugin_threat( custom_behavior_array ) { assertex( isdefined( self._stealth.plugins.basic ), "call maps\_stealth_utility::stealth_plugin_basic() on the AI first" ); assertex( self isBadGuy(), "stealth_plugin_accuracy is a plugin for enemies only" ); //this way scripters can just call this function to change the behavior array instead of remembering two functions if ( !isdefined( self._stealth.plugins.threat ) ) self maps\_stealth_threat_enemy::stealth_threat_enemy_main(); if ( isdefined( custom_behavior_array ) ) self stealth_threat_behavior_replace( custom_behavior_array ); } /* ============= ///ScriptDocBegin "Name: stealth_enable_seek_player_on_spotted()" "Summary: Runs behavior logic on AI where AI will slowly close in the player's position once stealth is broken" "Module: Stealth" "CallOn: An AI" "Example: enemy stealth_enable_seek_player_on_spotted();" "SPMP: singleplayer" ///ScriptDocEnd ============= */ stealth_enable_seek_player_on_spotted() { assertex( isdefined( self._stealth.plugins.threat ), "call maps\_stealth_utility::stealth_plugin_threat() on the AI first" ); self.script_stealth_dontseek = false; } /* ============= ///ScriptDocBegin "Name: stealth_disable_seek_player_on_spotted()" "Summary: Stops ai from slowly closing in on the player's postion once stealth is broken" "Module: Stealth" "CallOn: An AI" "Example: enemy stealth_disable_seek_player_on_spotted();" "SPMP: singleplayer" ///ScriptDocEnd ============= */ stealth_disable_seek_player_on_spotted() { assertex( isdefined( self._stealth.plugins.threat ), "call maps\_stealth_utility::stealth_plugin_threat() on the AI first" ); self.script_stealth_dontseek = true; } /* ============= ///ScriptDocBegin "Name: stealth_threat_behavior_custom( , )" "Summary: " "Module: Entity" "CallOn: An entity" "OptionalArg: : an array of functions which dictate the behavior for the AI based on their current state (which corrispond to the key values in the array)\n Valid key values are 'reset', 'normal' 'attack', 'warningX' where the X is a number between 1 and whatever. You can have as many warning behaviors as you like or none at all, but if you do have warnings they must start with warning1 and follow in consecutive numbers.\n You don't need to change all the behaviors, only the ones you want. But if you dont have any 'warningX' keys in the array then there will be NO WARNING behavior. If you do not make 'reset', 'normal', or 'attack' entries in the array, the system will pick the default ones because those are mandatory behavior options. \n reset is the function that occurs if an ai attacked you, and then lost you (right now defaults to going back to normal) \n normal is the function that handles going back to original behavior from any of the other states \n attack is the function that handles how the ai will attack once stealth is broken \n warning1 through X decide how many times and what kinds of behavior the AI will do when sighting an enemy before they attack." "OptionalArg: : an array of functions which dictate the animation reaction for the AI based on their current state (which corrispond to the key values in the array)\n Valid key values are 'reset', 'normal' 'attack', 'warning'. There is only one warning reaction anim for all the warning behaviors.\n You don't need to change all the behaviors, only the ones you want. The system fills in the default animation functions for ALL states, even warnings." "Example: \n custom_array = [];\n custom_array[ "attack" ] = ::attack_func;\n custom_array[ "warning1" ] = ::warning1_func;\n custom_array[ "warning2" ] = ::warning2_func;\n custom_array[ "warning3" ] = ::warning3_func;\n custom_array[ "warning4" ] = ::warning4_func;\n custom_array[ "warning5" ] = ::warning5_func;\n enemy stealth_threat_behavior_custom( custom_array )" "SPMP: singleplayer" ///ScriptDocEnd ============= */ stealth_threat_behavior_custom( threat_array, anim_array ) { assertex( isdefined( self._stealth.plugins.threat ), "call maps\_stealth_utility::stealth_plugin_threat() on the AI first" ); if ( isdefined( threat_array ) ) self maps\_stealth_threat_enemy::enemy_set_threat_behavior( threat_array ); if ( isdefined( anim_array ) ) self maps\_stealth_threat_enemy::enemy_set_threat_anim_behavior( anim_array ); } /* ============= ///ScriptDocBegin "Name: stealth_threat_behavior_replace( , )" "Summary: " "Module: Entity" "CallOn: An entity" "OptionalArg: : an array of functions which dictate the behavior for the AI based on their current state (which corrispond to the key values in the array)\n Valid key values are 'reset', 'normal' 'attack', 'warningX' where the X is a number between 1 and whatever. You can have as many warning behaviors as you like or none at all, but if you do have warnings they must start with warning1 and follow in consecutive numbers.\n You don't need to change all the behaviors, only the ones you want. unlike stealth_threat_behavior_custom, stealth_threat_behavior_replace will fill in any warning functions the ai already has. If you do not make 'reset', 'normal', or 'attack' entries in the array, the system will pick the default ones because those are mandatory behavior options. \n reset is the function that occurs if an ai attacked you, and then lost you (right now defaults to going back to normal) \n normal is the function that handles going back to original behavior from any of the other states \n attack is the function that handles how the ai will attack once stealth is broken \n warning1 through X decide how many times and what kinds of behavior the AI will do when sighting an enemy before they attack." "OptionalArg: : an array of functions which dictate the animation reaction for the AI based on their current state (which corrispond to the key values in the array)\n Valid key values are 'reset', 'normal' 'attack', 'warning'. There is only one warning reaction anim for all the warning behaviors.\n You don't need to change all the behaviors, only the ones you want. The system fills in the default animation functions for ALL states, even warnings." "Example: \n custom_array = [];\n custom_array[ "attack" ] = ::attack_func;\n custom_array[ "warning1" ] = ::warning1_func;\n custom_array[ "warning2" ] = ::warning2_func;\n custom_array[ "warning3" ] = ::warning3_func;\n custom_array[ "warning4" ] = ::warning4_func;\n custom_array[ "warning5" ] = ::warning5_func;\n enemy stealth_threat_behavior_replace( custom_array )" "SPMP: singleplayer" ///ScriptDocEnd ============= */ stealth_threat_behavior_replace( threat_array, anim_array ) { name = "threat"; string = "warning"; num = 1; key = string + num; if ( isdefined( threat_array ) ) { while ( isdefined( self._stealth.behavior.ai_functions[ name ][ key ] ) ) { if ( !isdefined( threat_array[ key ] ) ) threat_array[ key ] = maps\_stealth_shared_utilities::ai_get_behavior_function( name, key ); num++ ; key = string + num; } } self stealth_threat_behavior_custom( threat_array, anim_array ); } /* ============= ///ScriptDocBegin "Name: stealth_threat_behavior_default_no_warnings()" "Summary: uses standard attack and reset behavior for threats, but there are no warning behaviors -> no 'huh, what was that, who's there' behavior." "Module: Stealth" "CallOn: An AI" "Example: enemy stealth_threat_behavior_default_no_warnings();" "SPMP: singleplayer" ///ScriptDocEnd ============= */ stealth_threat_behavior_default_no_warnings() { array = []; self stealth_threat_behavior_custom( array ); } /* ============= ///ScriptDocBegin "Name: stealth_threat_behavior_default()" "Summary: resets an AI back to standard behaviors for threat detection" "Module: Stealth" "CallOn: An AI" "Example: enemy stealth_threat_behavior_default();" "SPMP: singleplayer" ///ScriptDocEnd ============= */ stealth_threat_behavior_default() { assertex( isdefined( self._stealth.plugins.threat ), "call maps\_stealth_utility::stealth_plugin_threat() on the AI first" ); self maps\_stealth_threat_enemy::enemy_default_threat_behavior(); self maps\_stealth_threat_enemy::enemy_default_threat_anim_behavior(); } /* ============= ///ScriptDocBegin "Name: stealth_alert_level_duration(