#include common_scripts\utility; #include maps\mp\_utility; HEALTH_PACK_MODEL = "paris_chase_pharmacie_sign_02"; player_healthbar_update() { // player HP bar: rewrite with LUI for HUD self endon( "death" ); waittillframeend; while ( true ) { player_health_ratio = self.health / self.maxhealth; SetDvar( "alien_player_health", self.health / self.maxhealth ); while ( player_health_ratio == ( self.health / self.maxhealth ) ) wait 0.1; // best if regen notifies when health changes // self waittill( "damage" ); } } /* NONPLAYER_MELEE_DAMAGE = 100; apply_damage( num_bar, source, apply_player_view_rip ) { if ( !isPlayer( self ) ) { self DoDamage( NONPLAYER_MELEE_DAMAGE, source.origin, source ); return; } self.last_alien_melee_time = GetTime(); self playRumbleOnEntity ( "damage_light" ); self PlaySound( "player_hit_sfx_alien" ); self thread play_damage_overlay(); damage_amount = ceil ( num_bar * level.health_amount_per_health_bar ); if ( IsDefined( self.damagemultiplier ) ) { damage_amount /= self.damagemultiplier; } enemy_blocked = self check_for_block( source ); if ( enemy_blocked ) { return; } else { self DoDamage( damage_amount, source.origin, source ); GetDvarInt ( "enable_player_view_rip" ); if ( GetDvarInt ( "enable_player_view_rip" ) == 1 ) { if ( isDefined ( apply_player_view_rip ) && apply_player_view_rip == true ) { source thread player_view_rip( self ); } } } } check_for_block( source ) { enemy_blocked = false; currentweapon = self GetcurrentWeapon(); player_is_ADS = isADS(); enemy_in_front = false; melee_in_hand = false; melee_weapon_health = 0; playerForwardVector = anglesToForward( self.angles ); playerToEnemyVector = VectorNormalize( source.origin - self.origin ); dotProduct = VectorDot( playerToEnemyVector, playerForwardVector ); if ( dotProduct > 0.5 ) { enemy_in_front = true; } if ( currentweapon == "axe_alien" ) { melee_weapon_health = self GetCurrentWeaponClipAmmo(); melee_in_hand = true; } if ( melee_in_hand && player_is_ADS && enemy_in_front && ( melee_weapon_health > 0 ) ) { self SetWeaponAmmoClip( "axe_alien", ( melee_weapon_health - 1 )); self PlaySound( "crate_impact" ); Earthquake( 0.75,0.5,self.origin, 100 ); enemy_blocked = true; if ( self GetCurrentWeaponClipAmmo() == 0 ) { self TakeWeapon( currentweapon ); weapon_list = self GetWeaponsList( "primary" ); if ( weapon_list.size > 0 ) { self SwitchToWeapon( weapon_list[0] ); } } } return enemy_blocked; } play_damage_overlay() { self endon ( "death" ); self.combatDamageOverlay.alpha = 1; self.combatDamageOverlay fadeOverTime( 0.5 ); self.combatDamageOverlay.alpha = 0; } player_view_rip( enemy ) { enemy endon ( "death" ); enemy notify ( "kill previous player view rip" ); enemy endon ( "kill previous player view rip" ); AssertEx ( isPlayer ( enemy ), "Invalid player" ); if ( !isAlive ( enemy ) ) { return; } //These two values are assumed alien speed and the amount of time which the alien will take to land. They are used to //determine roughly the landing location of the alien alien_speed = 200; time_after_melee = 1.5; alien_forward_vector = AnglesToForward ( self.angles ); alien_position_after_melee = self.origin + alien_forward_vector * alien_speed * time_after_melee; //level thread draw_debugLine ( self.origin, alien_position_after_melee, ( 1, 0, 0), 3600 ); player_to_alien_pos_vector = alien_position_after_melee - enemy.origin; player_to_alien_pos_yaw = VectorToYaw ( player_to_alien_pos_vector ); player_forward_yaw = enemy.angles [ 1 ]; yaw_difference = player_to_alien_pos_yaw - player_forward_yaw; yaw_difference = AngleClamp180 ( yaw_difference ); rip_percent = ( GetDvarFloat ( "percent_player_view_rip" ) ) / 100; yaw_difference = yaw_difference * rip_percent; player_rig = spawn_anim_model( "player_rig", enemy.origin ); player_rig hide(); player_rig.angles = player_rig.angles * ( 1, 0, 1 ); player_yaw = enemy.angles * ( 0, 1, 0 ); player_rig.angles = player_rig.angles + player_yaw * ( 0, 1, 0 ); enemy playerlinkto ( player_rig, "tag_origin", 1, 180, 180, 180, 180, true ); player_rig RotateYaw ( yaw_difference, 0.3, 0, 0 ); wait ( 0.3 ); enemy unlink(); player_rig delete(); } */ /* ============= ///ScriptDocBegin "Name: enable_alien_scripted()" "Summary: Puts the alien into a scripted state that allows level scripts to set their goals and control them directly" "Module: Alien" "CallOn: Alien actor" "Example: alien enable_alien_scripted()" "SPMP: multiplayer" ///ScriptDocEnd ============= */ enable_alien_scripted() { self.alien_scripted = true; self notify( "alien_main_loop_restart" ); } /* ============= ///ScriptDocBegin "Name: disable_alien_scripted()" "Summary: Clears the alien's scripted state" "Module: Alien" "CallOn: Alien actor" "Example: alien disable_alien_scripted()" "SPMP: multiplayer" ///ScriptDocEnd ============= */ disable_alien_scripted() { self.alien_scripted = false; } /* ============= ///ScriptDocBegin "Name: set_alien_emissive()" "Summary: Sets alien glowiness." "Module: Alien" "MandatoryArg: Duration of the blend to a new intensityvalue." "MandatoryArg: Emissive intensity, 0.0 - 1.0." "Example: alien set_alien_emissive( 0.2, 1.0 );" "SPMP: multiplayer" ///ScriptDocEnd ============= */ set_alien_emissive( blend_duration, intensity ) { /# if ( GetDvarInt( "scr_useMaxEmissive", 0 ) == 1 ) { self EmissiveBlend( 0.1, 1.0 ); return; } #/ // Min and max actual intensity defined per alien type valid_range = self.maxEmissive - self.defaultEmissive; actual_intensity = intensity * valid_range + self.defaultEmissive; self EmissiveBlend( blend_duration, actual_intensity ); } /* ============= ///ScriptDocBegin "Name: set_alien_emissive_default()" "Summary: Sets alien glowiness to default value." "Module: Alien" "MandatoryArg: Duration of the blend to default intensity." "Example: alien set_alien_emissive_default( 0.2 );" "SPMP: multiplayer" ///ScriptDocEnd ============= */ set_alien_emissive_default( blend_duration ) { /# if ( GetDvarInt( "scr_useMaxEmissive", 0 ) == 1 ) { self EmissiveBlend( 0.1, 1.0 ); return; } #/ assert( IsDefined( self.defaultEmissive ) ); self EmissiveBlend( blend_duration, self.defaultEmissive ); } /* ============= ///ScriptDocBegin "Name: get_players()" "Summary: Returns connected players. Preparing for MP transition" "Module: Alien" "Example: foreach ( player in get_players() ){ ... }" "SPMP: multiplayer" ///ScriptDocEnd ============= */ get_players() { return level.players; } /* ============= ///ScriptDocBegin "Name: any_player_nearby()" "Summary: Returns whether any player is within a certain distance." "Module: Alien" "MandatoryArg: The origin from which to check." "MandatoryArg: Square of max distance." "Example: result = any_player_nearby( self.origin, MAX_DISTANCE )" "SPMP: multiplayer" ///ScriptDocEnd ============= */ any_player_nearby( origin, dist_sqr ) { foreach ( player in level.players ) { if ( DistanceSquared( player.origin, origin ) < dist_sqr ) { return true; } } return false; } min_dist_from_all_locations( ent, location_array, min_dist ) { min_dist_sqr = min_dist * min_dist; foreach ( location in location_array ) { if ( Distance2DSquared( ent.origin, location.origin ) < min_dist_sqr ) { return false; } } return true; } /* ============= ///ScriptDocBegin "Name: set_vision_set_player( , )" "Summary: Sets the vision set over time for a specific player in coop" "Module: Utility" "MandatoryArg: : Visionset file to use" "OptionalArg: : Time to transition to the new vision set. Defaults to 1 second." "Example: level.player2 set_vision_set_player( "blackout_darkness", 0.5 );" "SPMP: multiplayer" ///ScriptDocEnd ============= */ set_vision_set_player( visionset, transition_time ) { if ( init_vision_set( visionset ) ) return; Assert( IsDefined( self ) ); Assert( level != self ); if ( !isdefined( transition_time ) ) transition_time = 1; self VisionSetNakedForPlayer( visionset, transition_time ); } init_vision_set( visionset ) { level.lvl_visionset = visionset; if ( !isdefined( level.vision_cheat_enabled ) ) level.vision_cheat_enabled = false; return level.vision_cheat_enabled; } restore_client_fog( transition_time ) { if ( !isdefined( level.restore_fog_setting ) ) return; ent = level.restore_fog_setting; self PlayerSetExpFog( ent.startDist, ent.halfwayDist, ent.red, ent.green, ent.blue, ent.HDRColorIntensity, ent.maxOpacity, transition_time, ent.sunRed, ent.sunGreen, ent.sunBlue, ent.HDRSunColorIntensity, ent.sunDir, ent.sunBeginFadeAngle, ent.sunEndFadeAngle, ent.normalFogScale, ent.skyFogIntensity, ent.skyFogMinAngle, ent.skyFogMaxAngle ); } // TEMP: Resides here until flawless, then move to maps\mp\_utility // Since ent_flag can be called on players who can disconnect, // TODO: make sure flag functions end well on player disconnect or game end // ======================================================================= // ENTITY FLAG // ======================================================================= /* ============= ///ScriptDocBegin "Name: ent_flag_wait( )" "Summary: Waits until the specified flag is set on self. Even handles some default flags for ai such as 'goal' and 'damage'" "Module: Flag" "CallOn: Any entity (script_origin, script_struct, ai, script_model, script_brushmodel, player)" "MandatoryArg: : name of the flag to wait on" "Example: enemy ent_flag_wait( "goal" );" "SPMP: multiplayer" ///ScriptDocEnd ============= */ ent_flag_wait( msg ) { if ( isplayer( self ) ) self endon( "disconnect" ); AssertEx( ( !IsSentient( self ) && IsDefined( self ) ) || IsAlive( self ), "Attempt to check a flag on entity that is not alive or removed" ); while ( IsDefined( self ) && !self.ent_flag[ msg ] ) self waittill( msg ); } /* ============= ///ScriptDocBegin "Name: ent_flag_wait_either( , )" "Summary: Waits until either of the the specified flags are set on self. Even handles some default flags for ai such as 'goal' and 'damage'" "Module: Flag" "CallOn: Any entity (script_origin, script_struct, ai, script_model, script_brushmodel, player)" "MandatoryArg: : name of one flag to wait on" "MandatoryArg: : name of the other flag to wait on" "Example: enemy ent_flag_wait( "goal", "damage" );" "SPMP: multiplayer" ///ScriptDocEnd ============= */ ent_flag_wait_either( flag1, flag2 ) { if ( isplayer( self ) ) self endon( "disconnect" ); AssertEx( ( !IsSentient( self ) && IsDefined( self ) ) || IsAlive( self ), "Attempt to check a flag on entity that is not alive or removed" ); while ( IsDefined( self ) ) { if ( ent_flag( flag1 ) ) return; if ( ent_flag( flag2 ) ) return; self waittill_either( flag1, flag2 ); } } /* ============= ///ScriptDocBegin "Name: ent_flag_wait_or_timeout( , )" "Summary: Waits until either the flag gets set on self or the timer elapses. Even handles some default flags for ai such as 'goal' and 'damage'" "Module: Flag" "CallOn: Any entity (script_origin, script_struct, ai, script_model, script_brushmodel, player)" "MandatoryArg: : Amount of time to wait before continuing regardless of flag." "Example: ent_flag_wait_or_timeout( "time_to_go", 3 );" "SPMP: multiplayer" ///ScriptDocEnd ============= */ ent_flag_wait_or_timeout( flagname, timer ) { if ( isplayer( self ) ) self endon( "disconnect" ); AssertEx( ( !IsSentient( self ) && IsDefined( self ) ) || IsAlive( self ), "Attempt to check a flag on entity that is not alive or removed" ); start_time = GetTime(); while ( IsDefined( self ) ) { if ( self.ent_flag[ flagname ] ) break; if ( GetTime() >= start_time + timer * 1000 ) break; self ent_wait_for_flag_or_time_elapses( flagname, timer ); } } ent_wait_for_flag_or_time_elapses( flagname, timer ) { self endon( flagname ); wait( timer ); } /* ============= ///ScriptDocBegin "Name: ent_flag_waitopen( )" "Summary: " "Module: Entity" "CallOn: An entity" "MandatoryArg: : " "OptionalArg: : " "Example: " "SPMP: multiplayer" ///ScriptDocEnd ============= */ ent_flag_waitopen( msg ) { AssertEx( ( !IsSentient( self ) && IsDefined( self ) ) || IsAlive( self ), "Attempt to check a flag on entity that is not alive or removed" ); while ( IsDefined( self ) && self.ent_flag[ msg ] ) self waittill( msg ); } ent_flag_assert( msg ) { AssertEx( !self ent_flag( msg ), "Flag " + msg + " set too soon on entity" ); } /* ============= ///ScriptDocBegin "Name: ent_flag_waitopen_either( , )" "Summary: Waits until either of the the specified flags are open on self. Even handles some default flags for ai such as 'goal' and 'damage'" "Module: Flag" "CallOn: Any entity (script_origin, script_struct, ai, script_model, script_brushmodel, player)" "MandatoryArg: : name of one flag to waitopen on" "MandatoryArg: : name of the other flag to waitopen on" "Example: enemy ent_flag_waitopen_either( "goal", "damage" );" "SPMP: multiplayer" ///ScriptDocEnd ============= */ ent_flag_waitopen_either( flag1, flag2 ) { AssertEx( ( !IsSentient( self ) && IsDefined( self ) ) || IsAlive( self ), "Attempt to check a flag on entity that is not alive or removed" ); while ( IsDefined( self ) ) { if ( !ent_flag( flag1 ) ) return; if ( !ent_flag( flag2 ) ) return; self waittill_either( flag1, flag2 ); } } /* ============= ///ScriptDocBegin "Name: ent_flag_init( )" "Summary: Initialize a flag to be used. All flags must be initialized before using ent_flag_set or ent_flag_wait. Some flags for ai are set by default such as 'goal', 'death', and 'damage'" "Module: Flag" "CallOn: Any entity (script_origin, script_struct, ai, script_model, script_brushmodel, player)" "MandatoryArg: : name of the flag to create" "Example: enemy ent_flag_init( "hq_cleared" );" "SPMP: multiplayer" ///ScriptDocEnd ============= */ ent_flag_init( message ) { if ( !isDefined( self.ent_flag ) ) { self.ent_flag = []; self.ent_flags_lock = []; } /# if ( IsDefined( level.first_frame ) && level.first_frame == -1 ) AssertEx( !isDefined( self.ent_flag[ message ] ), "Attempt to reinitialize existing message: " + message + " on entity." ); #/ self.ent_flag[ message ] = false; /# self.ent_flags_lock[ message ] = false; #/ } /* ============= ///ScriptDocBegin "Name: ent_flag_exist( )" "Summary: checks to see if a flag exists" "Module: Flag" "CallOn: Any entity (script_origin, script_struct, ai, script_model, script_brushmodel, player)" "MandatoryArg: : name of the flag to check" "Example: if( enemy ent_flag_exist( "hq_cleared" ) );" "SPMP: multiplayer" ///ScriptDocEnd ============= */ ent_flag_exist( message ) { if ( IsDefined( self.ent_flag ) && IsDefined( self.ent_flag[ message ] ) ) return true; return false; } /* ============= ///ScriptDocBegin "Name: ent_flag_set( )" "Summary: Sets the specified flag on self, all scripts using ent_flag_wait on self will now continue." "Module: Flag" "CallOn: Any entity (script_origin, script_struct, ai, script_model, script_brushmodel, player)" "MandatoryArg: : name of the flag to set" "Example: enemy ent_flag_set( "hq_cleared" );" "SPMP: multiplayer" ///ScriptDocEnd ============= */ ent_flag_set( message ) { /# AssertEx( IsDefined( self ), "Attempt to set a flag on entity that is not defined" ); AssertEx( IsDefined( self.ent_flag[ message ] ), "Attempt to set a flag before calling flag_init: " + message + " on entity." ); Assert( self.ent_flag[ message ] == self.ent_flags_lock[ message ] ); self.ent_flags_lock[ message ] = true; #/ self.ent_flag[ message ] = true; self notify( message ); } /* ============= ///ScriptDocBegin "Name: ent_flag_clear( )" "Summary: Clears the specified flag on self." "Module: Flag" "CallOn: Any entity (script_origin, script_struct, ai, script_model, script_brushmodel, player)" "MandatoryArg: : name of the flag to clear" "OptionalArg: : free the flag completely, use this when you want to save a variable after you're never going to use the flag again." "Example: enemy ent_flag_clear( "hq_cleared" );" "SPMP: multiplayer" ///ScriptDocEnd ============= */ ent_flag_clear( message, remove ) { /# AssertEx( IsDefined( self ), "Attempt to clear a flag on entity that is not defined" ); AssertEx( IsDefined( self.ent_flag[ message ] ), "Attempt to set a flag before calling flag_init: " + message + " on entity." ); Assert( self.ent_flag[ message ] == self.ent_flags_lock[ message ] ); self.ent_flags_lock[ message ] = false; #/ //do this check so we don't unneccessarily send a notify if ( self.ent_flag[ message ] ) { self.ent_flag[ message ] = false; self notify( message ); } if ( IsDefined( remove ) && remove ) self.ent_flag[ message ] = undefined; } /* ============= ///ScriptDocBegin "Name: ent_flag( )" "Summary: Checks if the flag is set on self. Returns true or false." "Module: Flag" "CallOn: Any entity (script_origin, script_struct, ai, script_model, script_brushmodel, player)" "MandatoryArg: : name of the flag to check" "Example: enemy ent_flag( "death" );" "SPMP: multiplayer" ///ScriptDocEnd ============= */ ent_flag( message ) { AssertEx( IsDefined( message ), "Tried to check flag but the flag was not defined." ); AssertEx( IsDefined( self.ent_flag[ message ] ), "Tried to check flag " + message + " but the flag was not initialized." ); return self.ent_flag[ message ]; } /* ============= ///ScriptDocBegin "Name: alien_mode_has( )" "Summary: Checks to see if alien mode as a specific feature active. Returns true or false." "Module: Alien" "MandatoryArg: : airdrop, wave, lurker, collectible, loot (more coming!)" "Example: if( !alien_mode_has( "airdrop" ) { return; }" "SPMP: multiplayer" ///ScriptDocEnd ============= */ alien_mode_has( feature_str ) { feature_str = toLower( feature_str ); if ( !isdefined( level.alien_mode_feature ) ) return false; if ( !isdefined( level.alien_mode_feature[ feature_str ] ) ) return false; return level.alien_mode_feature[ feature_str ]; } /* ============= ///ScriptDocBegin "Name: alien_mode_enable( str_1, str_2, str_3, str_4, str_5, str_6, str_7, str_8, str_9, str_10 )" "Summary: Enables features in alien mode." "Module: Alien" "MandatoryArg: : airdrop, wave, lurker, collectible, loot, mist (more coming!)" "Example: alien_mode_enable( "airdrop" );" "SPMP: Multiplayer" ///ScriptDocEnd ============= */ alien_mode_enable( str_1, str_2, str_3, str_4, str_5, str_6, str_7, str_8, str_9, str_10 ) { assertex( isdefined( str_1 ), "alien_mode_enable() called without parameters!" ); if ( !isdefined( level.alien_mode_feature ) ) level.alien_mode_feature = []; // list of all supported features, also update: check_feature_dependencies(); if ( !isdefined( level.alien_mode_feature_strings ) ) level.alien_mode_feature_strings = [ "kill_resource", "nogame", "airdrop", "loot", "wave", "lurker", "collectible", "mist", "pillage", "challenge", "outline", "scenes" ]; // ====== maybe not a good idea, people might not be aware of new features =========== if ( str_1 == "all" ) { foreach ( param in level.alien_mode_feature_strings ) alien_mode_enable_raw( param ); return; } // =================================================================================== combined_param = []; if ( isdefined( str_1 ) ) combined_param[ combined_param.size ] = toLower( str_1 ); if ( isdefined( str_2 ) ) combined_param[ combined_param.size ] = toLower( str_2 ); if ( isdefined( str_3 ) ) combined_param[ combined_param.size ] = toLower( str_3 ); if ( isdefined( str_4 ) ) combined_param[ combined_param.size ] = toLower( str_4 ); if ( isdefined( str_5 ) ) combined_param[ combined_param.size ] = toLower( str_5 ); if ( isdefined( str_6 ) ) combined_param[ combined_param.size ] = toLower( str_6 ); if ( isdefined( str_7 ) ) combined_param[ combined_param.size ] = toLower( str_7 ); if ( isdefined( str_8 ) ) combined_param[ combined_param.size ] = toLower( str_8 ); if ( isdefined( str_9 ) ) combined_param[ combined_param.size ] = toLower( str_9 ); if ( isdefined( str_10 ) ) combined_param[ combined_param.size ] = toLower( str_10 ); check_feature_dependencies( combined_param ); foreach ( param in combined_param ) alien_mode_enable_raw( param ); } check_feature_dependencies( combined_param ) { foreach ( param in combined_param ) { if ( param == "loot" && !array_contains( combined_param, "collectible" ) ) assertmsg( "Feature [loot] requires [collectible]" ); if ( param == "airdrop" && !array_contains( combined_param, "wave" ) ) assertmsg( "Feature [airdrop] requires feature [wave]" ); if ( param == "lurker" && !array_contains( combined_param, "wave" ) ) assertmsg( "Feature [lurker] requires feature [wave]" ); if ( param == "mist" && !array_contains( combined_param, "wave" ) ) assertmsg( "Feature [mist] requires feature [wave]" ); } } alien_mode_enable_raw( feature_str ) { if ( !array_contains( level.alien_mode_feature_strings, feature_str ) ) { supported_mode_strings = ""; foreach ( feature in level.alien_mode_feature_strings ) supported_mode_strings = supported_mode_strings + feature + " "; assertmsg( feature_str + " is not a supported feature. [ " + supported_mode_strings + "]" ); } level.alien_mode_feature[ feature_str ] = true; } /* ============= ///ScriptDocBegin "Name: alien_area_init()" "Summary: Register distinct areas for item spawning management. Call before _load" "Module: Alien" "Example: alien_area_init( areas )" "SPMP: multiplayer" ///ScriptDocEnd ============= */ alien_area_init( area_array ) { AssertEx( !isDefined( level.world_areas ), "alien_area_init() is called multiple times in the same level" ); level.world_areas = []; level.area_array = area_array; level.current_area_index = 0; foreach ( area in area_array ) { area_volume = GetEnt( area, "targetname" ); assert( IsDefined( area_volume ) ); level.world_areas[ area ] = area_volume; } } get_current_area_name() { return level.area_array[level.current_area_index]; } inc_current_area_index() { level.current_area_index++; } /* ============= ///ScriptDocBegin "Name: store_weapons_status()" "Summary: Store the weapon and the ammo status." "Module: Alien" "Example: player store_weapons_status()" "SPMP: multiplayer" ///ScriptDocEnd ============= */ store_weapons_status( weapons_excluded ) { //weapons self.copy_fullweaponlist = self GetWeaponsListAll(); self.copy_weapon_current = self GetCurrentWeapon(); //ammo foreach( weapon in self.copy_fullweaponlist ) { self.copy_weapon_ammo_clip[ weapon ] = self GetWeaponAmmoClip( weapon ); self.copy_weapon_ammo_stock[ weapon ] = self GetWeaponAmmoStock( weapon ); } //weapons not kept, ex: alienbomb_mp if ( isdefined( weapons_excluded ) ) { //update fullweapon list to remove weapons not kept allowed_fullweaponlist = []; foreach ( weapon in self.copy_fullweaponlist ) { skip = false; foreach ( not_allowed_weapon in weapons_excluded ) { if ( weapon == not_allowed_weapon ) { skip = true; break; } } if ( skip ) continue; allowed_fullweaponlist[ allowed_fullweaponlist.size ] = weapon; } self.copy_fullweaponlist = allowed_fullweaponlist; //if current weapon was one not kept, reset to "none" foreach ( not_allowed_weapon in weapons_excluded ) { if ( self.copy_weapon_current == not_allowed_weapon ) { self.copy_weapon_current = "none"; break; } } } } /* ============= ///ScriptDocBegin "Name: restore_weapons_status()" "Summary: Put the weapon and ammo status back to the last time store_weapons_status is called." "Module: Alien" "Example: player restore_weapons_status()" "SPMP: multiplayer" ///ScriptDocEnd ============= */ restore_weapons_status( inclusion_list ) { if( !isDefined( self.copy_fullweaponlist ) || !isDefined( self.copy_weapon_current ) || !isDefined( self.copy_weapon_ammo_clip ) || !isDefined( self.copy_weapon_ammo_stock ) ) AssertMsg( "Call store_weapons_status() before restore_weapons_status()" ); //weapons //remove any they didn't have myWeapons = self GetWeaponsListAll(); foreach( weapon in myWeapons ) { if ( !array_contains( self.copy_fullweaponlist, weapon ) && !in_inclusion_list( inclusion_list, weapon ) ) { self TakeWeapon( weapon ); } } //Give weapon and ammo back foreach( weapon in self.copy_fullweaponlist ) { if ( !(self HasWeapon( weapon )) ) { self GiveWeapon( weapon ); } self SetWeaponAmmoClip( weapon, self.copy_weapon_ammo_clip[ weapon ] ); self SetWeaponAmmoStock( weapon, self.copy_weapon_ammo_stock[ weapon ] ); } WeaponToSwitch = self.copy_weapon_current; if ( !isDefined ( weaponToSwitch) || WeaponToSwitch == "none" ) WeaponToSwitch = self.copy_fullweaponlist[ 0 ]; self SwitchToWeapon( WeaponToSwitch ); //clean up self.copy_fullweaponlist = undefined; self.copy_weapon_current = undefined; self.copy_weapon_ammo_clip = undefined; self.copy_weapon_ammo_stock = undefined; } in_inclusion_list( inclusion_list, item_name ) { if ( !isDefined ( inclusion_list ) ) return false; return array_contains( inclusion_list, item_name ); } /* ============= ///ScriptDocBegin "Name: remove_weapons()" "Summary: Removes each weapon from the player's primary weaponlist" "Module: Alien" "Example: player remove_weapons()" "SPMP: multiplayer" ///ScriptDocEnd ============= */ remove_weapons() { weaponlist = self GetWeaponsListPrimaries(); // now take the weapons foreach( weapon in weaponlist ) { weaponTokens = StrTok( weapon, "_" ); if( weaponTokens[0] == "alt" ) continue; self TakeWeapon( weapon ); } } /* ============= ///ScriptDocBegin "Name: get_alien_type()" "Summary: Gets the type of this alien" "Module: Alien" "Example: alien get_alien_type()" "SPMP: multiplayer" ///ScriptDocEnd ============= */ get_alien_type() { AssertEx( isDefined ( self.alien_type ), "self.alien_type is not defined" ); return self.alien_type; } /* ============= ///ScriptDocBegin "Name: should_explode()" "Summary: Returns whether the alien can explode" "Module: Alien" "Example: alien should_explode()" "SPMP: multiplayer" ///ScriptDocEnd ============= */ should_explode() { switch ( maps\mp\alien\_utility::get_alien_type() ) { case "minion": return true; default: return false; } } /* ============= ///ScriptDocBegin "Name: is_normal_upright( normal )" "Summary: Determines if passed in normal is facing up" "Module: Alien" "Example: is_normal_upright( upVector )" "SPMP: multiplayer" ///ScriptDocEnd ============= */ is_normal_upright( normal ) { UPRIGHT_VECTOR = ( 0, 0, 1 ); UPRIGHT_DOT = 0.85; return ( VectorDot( normal, UPRIGHT_VECTOR ) > UPRIGHT_DOT ); } // TODO JW: Remove! These notetracks should be in the animations always_play_pain_sound( anime ) { if ( !AnimHasNotetrack( anime, "alien_pain_light" ) && !AnimHasNoteTrack( anime, "alien_pain_heavy" ) ) { self PlaySoundOnMovingEnt( "alien_pain_light" ); } } register_pain( anim_entry ) { /# AssertEx( !IsDefined( self.pain_registered ) || !self.pain_registered, "Shouldn't be able to register a pain when one already registered!" ); #/ self.pain_registered = true; self thread pain_interval_monitor( anim_entry ); } pain_interval_monitor( anim_entry ) { self endon ("death" ); alienType = self get_alien_type(); painInterval = level.alien_types[ alienType ].attributes[ "pain_interval" ]; wait painInterval + GetAnimLength( anim_entry ); self.pain_registered = false; } is_pain_available( attacker, sMeansOfDeath ) { if ( IsDefined( self.pain_registered ) && self.pain_registered ) return false; // Prevent pain when oriented in order to prevent stuck cases if( IsDefined( self.oriented ) && self.oriented ) return false; if ( sMeansOfDeath == "MOD_MELEE" ) return true; if ( isDefined ( attacker ) && isPlayer ( attacker ) && attacker has_stun_ammo() ) return true; return true; } // MP ents clean up mp_ents_clean_up() { // wait for padding wait 0.5; // "heli_start" script origins removed heli_start_nodes = getEntArray( "heli_start", "targetname" ); foreach( start_node in heli_start_nodes ) get_linked_nodes_and_delete( start_node ); // "heli_loop_start" script origins removed heli_loop_nodes = getEntArray( "heli_loop_start", "targetname" ); foreach( loop_node in heli_loop_nodes ) get_linked_nodes_and_delete( loop_node ); // "heli_crash_start" script origins removed heli_crash_nodes = getEntArray( "heli_crash_start", "targetname" ); foreach( crash_node in heli_crash_nodes ) get_linked_nodes_and_delete( crash_node ); } // grab all the nodes chained starting from start_node get_linked_nodes_and_delete( start_node ) { cur_node = start_node; while ( isdefined( cur_node.target ) ) { next_node = getent( cur_node.target, "targetname" ); if ( isdefined( next_node ) ) { cur_node delete(); cur_node = next_node; } else { break; } } if ( isdefined( cur_node ) ) cur_node delete(); } /* ============= ///ScriptDocBegin "Name: is_holding_deployable()" "Summary: Returns if player is holding any deployables." "Module: Alien" "Example: return level.players[0] is_holding_deployable();" "SPMP: multiplayer" ///ScriptDocEnd ============= */ is_holding_deployable() { return self.is_holding_deployable; } has_special_weapon() { return self.has_special_weapon; } type_has_head_armor( type ) { switch( type ) { case "brute1": case "brute2": case "brute3": case "brute4": return true; default: return false; } return false; } get_closest_living_player() { closest_distance_sqr = 1073741824; closest_player = undefined; foreach ( player in level.players ) { dist_sqr = DistanceSquared( self.origin, player.origin ); if ( IsReallyAlive( player ) && dist_sqr < closest_distance_sqr ) { closest_player = player; closest_distance_sqr = dist_sqr; } } return closest_player; } // this is called when a player grabs any of the specialized ammo types. // Make sure we don't store existing special ammo, but rather just replace it and zero out the previous special ammo for that weapon should_store_ammo_check( exclude_type, special_ammo_weapon ) { should_store_ammo = true; switch ( exclude_type ) { case "explosive": //check for AP, Incendiary & Stun & combined if ( isDefined ( self.special_ammocount ) && isDefined ( self.special_ammocount[special_ammo_weapon] ) && self.special_ammocount[special_ammo_weapon] > 0 ) { self.special_ammocount[special_ammo_weapon] = 0; self _unsetPerk( "specialty_bulletdamage" ); return false; } else if ( isDefined ( self.special_ammocount_ap ) && isDefined ( self.special_ammocount_ap[special_ammo_weapon] ) && self.special_ammocount_ap[special_ammo_weapon] > 0 ) { self.special_ammocount_ap[special_ammo_weapon] = 0; self _unsetPerk( "specialty_armorpiercing" ); return false; } else if ( isDefined ( self.special_ammocount_in ) && isDefined ( self.special_ammocount_in[special_ammo_weapon] ) && self.special_ammocount_in[special_ammo_weapon] > 0 ) { self.has_incendiary_ammo = undefined; self.special_ammocount_in[special_ammo_weapon] = 0; return false; } else if ( isDefined ( self.special_ammocount_comb ) && isDefined ( self.special_ammocount_comb[special_ammo_weapon] ) && self.special_ammocount_comb[special_ammo_weapon] > 0 ) { self.special_ammocount_comb[special_ammo_weapon] = 0; self _unsetPerk( "specialty_explosivebullets" ); self _unsetPerk( "specialty_armorpiercing" ); self _unsetPerk( "specialty_bulletdamage" ); self.has_incendiary_ammo = undefined; return false; } return true; case "ap": //check for Explosive, Incendiary & Stun & combined case "piercing": if ( isDefined ( self.special_ammocount ) && isDefined ( self.special_ammocount[special_ammo_weapon] ) && self.special_ammocount[special_ammo_weapon] > 0 ) { self.special_ammocount[special_ammo_weapon] = 0; self _unsetPerk( "specialty_bulletdamage" ); return false; } else if ( isDefined ( self.special_ammocount_explo ) && isDefined ( self.special_ammocount_explo[special_ammo_weapon] ) && self.special_ammocount_explo[special_ammo_weapon] > 0 ) { self.special_ammocount_explo[special_ammo_weapon] = 0; self _unsetPerk( "specialty_explosivebullets" ); return false; } else if ( isDefined ( self.special_ammocount_in ) && isDefined ( self.special_ammocount_in[special_ammo_weapon] ) && self.special_ammocount_in[special_ammo_weapon] > 0 ) { self.has_incendiary_ammo = undefined; self.special_ammocount_in[special_ammo_weapon] = 0; return false; } else if ( isDefined ( self.special_ammocount_comb ) && isDefined ( self.special_ammocount_comb[special_ammo_weapon] ) && self.special_ammocount_comb[special_ammo_weapon] > 0 ) { self.special_ammocount_comb[special_ammo_weapon] = 0; self _unsetPerk( "specialty_explosivebullets" ); self _unsetPerk( "specialty_armorpiercing" ); self _unsetPerk( "specialty_bulletdamage" ); self.has_incendiary_ammo = undefined; return false; } return true; case "stun": //check for AP, Incendiary & Explosive & combined if ( isDefined ( self.special_ammocount_explo ) && isDefined ( self.special_ammocount_explo[special_ammo_weapon] ) && self.special_ammocount_explo[special_ammo_weapon] > 0 ) { self.special_ammocount_explo[special_ammo_weapon] = 0; self _unsetPerk( "specialty_explosivebullets" ); return false; } else if ( isDefined ( self.special_ammocount_ap ) && isDefined ( self.special_ammocount_ap[special_ammo_weapon] ) && self.special_ammocount_ap[special_ammo_weapon] > 0 ) { self.special_ammocount_ap[special_ammo_weapon] = 0; self _unsetPerk( "specialty_armorpiercing" ); return false; } else if ( isDefined ( self.special_ammocount_in ) && isDefined ( self.special_ammocount_in[special_ammo_weapon] ) && self.special_ammocount_in[special_ammo_weapon] > 0 ) { self.has_incendiary_ammo = undefined; self.special_ammocount_in[special_ammo_weapon] = 0; return false; } else if ( isDefined ( self.special_ammocount_comb ) && isDefined ( self.special_ammocount_comb[special_ammo_weapon] ) && self.special_ammocount_comb[special_ammo_weapon] > 0 ) { self.special_ammocount_comb[special_ammo_weapon] = 0; self _unsetPerk( "specialty_explosivebullets" ); self _unsetPerk( "specialty_armorpiercing" ); self _unsetPerk( "specialty_bulletdamage" ); self.has_incendiary_ammo = undefined; return false; } return true; case "incendiary": ////check for AP, explosive & Stun & combined if ( isDefined ( self.special_ammocount ) && isDefined ( self.special_ammocount[special_ammo_weapon] ) && self.special_ammocount[special_ammo_weapon] > 0 ) { self.special_ammocount[special_ammo_weapon] = 0; self _unsetPerk( "specialty_bulletdamage" ); return false; } else if ( isDefined ( self.special_ammocount_ap ) && isDefined ( self.special_ammocount_ap[special_ammo_weapon] ) && self.special_ammocount_ap[special_ammo_weapon] > 0 ) { self.special_ammocount_ap[special_ammo_weapon] = 0; self _unsetPerk( "specialty_armorpiercing" ); return false; } else if ( isDefined ( self.special_ammocount_explo ) && isDefined ( self.special_ammocount_explo[special_ammo_weapon] ) && self.special_ammocount_explo[special_ammo_weapon] > 0 ) { self.special_ammocount_explo[special_ammo_weapon] = 0; self _unsetPerk( "specialty_explosivebullets" ); return false; } else if ( isDefined ( self.special_ammocount_comb ) && isDefined ( self.special_ammocount_comb[special_ammo_weapon] ) && self.special_ammocount_comb[special_ammo_weapon] > 0 ) { self.special_ammocount_comb[special_ammo_weapon] = 0; self _unsetPerk( "specialty_explosivebullets" ); self _unsetPerk( "specialty_armorpiercing" ); self _unsetPerk( "specialty_bulletdamage" ); self.has_incendiary_ammo = undefined; return false; } return true; case "combined": ////check for AP, explosive & Stun & incendiary if ( isDefined ( self.special_ammocount ) && isDefined ( self.special_ammocount[special_ammo_weapon] ) && self.special_ammocount[special_ammo_weapon] > 0 ) { self.special_ammocount[special_ammo_weapon] = 0; self _unsetPerk( "specialty_bulletdamage" ); return false; } else if ( isDefined ( self.special_ammocount_ap ) && isDefined ( self.special_ammocount_ap[special_ammo_weapon] ) && self.special_ammocount_ap[special_ammo_weapon] > 0 ) { self.special_ammocount_ap[special_ammo_weapon] = 0; self _unsetPerk( "specialty_armorpiercing" ); return false; } else if ( isDefined ( self.special_ammocount_explo ) && isDefined ( self.special_ammocount_explo[special_ammo_weapon] ) && self.special_ammocount_explo[special_ammo_weapon] > 0 ) { self.special_ammocount_explo[special_ammo_weapon] = 0; self _unsetPerk( "specialty_explosivebullets" ); return false; } else if ( isDefined ( self.special_ammocount_in ) && isDefined ( self.special_ammocount_in[special_ammo_weapon] ) && self.special_ammocount_in[special_ammo_weapon] > 0 ) { self.has_incendiary_ammo = undefined; self.special_ammocount_in[special_ammo_weapon] = 0; return false; } return true; } } /* ============= ///ScriptDocBegin "Name: is_ammo_already_stored( )" "Summary: Checks to see if a player already has ammo stored for this weapon" "Module: Entity" "CallOn: An entity" "MandatoryArg: : " "Example: " "SPMP: coop" ///ScriptDocEnd ============= */ is_ammo_already_stored( weaponName ) { if ( isDefined ( self.stored_ammo[weaponName] ) ) { return ( isDefined( self.stored_ammo[weaponName].clipammo ) && isDefined ( self.stored_ammo[weaponName].ammoStock ) ); } return false; } give_special_ammo_by_weaponclass( boxent , primary_weapon , pillage ) { if ( !isDefined ( primary_weapon ) ) { primary_weapon = self GetCurrentPrimaryWeapon(); } class = getWeaponClass( primary_weapon ); ratio = 0; if ( isDefined ( boxent ) ) { if ( boxent.boxtype != "deployable_specialammo_comb" ) { switch ( boxent.upgrade_rank ) { case 0: ratio = .3; break; case 1: ratio = .4; break; case 2: ratio = .5; break; case 3: ratio = .6; break; case 4: ratio = .7; break; } } else { switch (boxEnt.upgrade_rank) { case 0: ratio = 0.4; break; case 1: ratio = 0.7; break; case 2: ratio = 1.0; break; case 3: ratio = 1.0; self maps\mp\alien\_deployablebox_functions::addFullCombinedClipToAllWeapons(); break; case 4: ratio = 1.0; self maps\mp\alien\_deployablebox_functions::addFullCombinedClipToAllWeapons(); break; } } } nerf_min_ammo_scalar = self maps\mp\alien\_deployablebox_functions::check_for_nerf_min_ammo(); if ( nerf_min_ammo_scalar != 1.0 ) { ratio = nerf_min_ammo_scalar; } switch( class ) { case "weapon_smg": // 1 clip for SMG , assault or LMG case "weapon_assault": case "weapon_shotgun": // 2 for the shotgun, pistol & sniper case "weapon_pistol": case "weapon_sniper": case "weapon_lmg": case "weapon_dmr": if ( isDefined ( pillage ) && pillage ) { if ( level.use_alternate_specialammo_pillage_amounts ) { clip = WeaponClipSize( primary_weapon ); return ( int( clip * 2 ) ); } return ( int ( WeaponMaxAmmo ( primary_weapon ) * 0.2 ) );//always finds 20% max } else { return ( int ( WeaponMaxAmmo ( primary_weapon ) * ratio ) ); } default: return 0; } } player_has_specialized_ammo( special_ammo_weapon ) { has_special_ammo = false; //stun if ( isDefined ( self.special_ammocount ) && isDefined ( self.special_ammocount[special_ammo_weapon] ) && self.special_ammocount[special_ammo_weapon] > 0 ) { has_special_ammo = true; } //armor piercing if ( isDefined ( self.special_ammocount_ap ) && isDefined ( self.special_ammocount_ap[special_ammo_weapon] ) && self.special_ammocount_ap[special_ammo_weapon] > 0 ) { has_special_ammo = true; } //incendiary if ( isDefined ( self.special_ammocount_in ) && isDefined ( self.special_ammocount_in[special_ammo_weapon] ) && self.special_ammocount_in[special_ammo_weapon] > 0 ) { has_special_ammo = true; } //explosive if ( isDefined ( self.special_ammocount_explo ) && isDefined ( self.special_ammocount_explo[special_ammo_weapon] ) && self.special_ammocount_explo[special_ammo_weapon] > 0 ) { has_special_ammo = true; } //combined if ( isDefined ( self.special_ammocount_comb ) && isDefined ( self.special_ammocount_comb[special_ammo_weapon] ) && self.special_ammocount_comb[special_ammo_weapon] > 0 ) { has_special_ammo = true; } return has_special_ammo; } has_stun_ammo( weapon_to_check ) { if ( !isDefined ( weapon_to_check ) ) weapon = self GetCurrentWeapon(); else weapon = weapon_to_check; if ( weapon == "none" ) { weapon = self GetWeaponsListPrimaries()[0]; } base_weapon = getRawBaseWeaponName( weapon ); if ( is_chaos_mode() && self HasPerk( "specialty_bulletdamage", true ) ) return true; if ( isDefined ( self.special_ammocount ) && isDefined ( self.special_ammocount[base_weapon] ) && self.special_ammocount[base_weapon] > 0 ) //player has stun ammo return true; if ( isDefined ( self.special_ammocount_comb ) && isDefined ( self.special_ammocount_comb[base_weapon] ) && self.special_ammocount_comb[base_weapon] > 0 ) //player has combined ammo return true; return false; } has_ap_ammo( weapon_to_check ) { if ( !isDefined ( weapon_to_check ) ) weapon = self GetCurrentWeapon(); else weapon = weapon_to_check; if ( weapon == "none" ) { weapon = self GetWeaponsListPrimaries()[0]; } base_weapon = getRawBaseWeaponName( weapon ); if ( isDefined ( self.special_ammocount_ap ) && isDefined ( self.special_ammocount_ap[base_weapon] ) && self.special_ammocount_ap[base_weapon] > 0 ) //player has ap ammo return true; if ( isDefined ( self.special_ammocount_comb ) && isDefined ( self.special_ammocount_comb[base_weapon] ) && self.special_ammocount_comb[base_weapon] > 0 ) //player has combined ammo return true; return false; } has_explosive_ammo( weapon_to_check ) { if ( !isDefined ( weapon_to_check ) ) weapon = self GetCurrentWeapon(); else weapon = weapon_to_check; if ( weapon == "none" ) { weapon = self GetWeaponsListPrimaries()[0]; } base_weapon = getRawBaseWeaponName( weapon ); if ( isDefined ( self.special_ammocount_explo ) && isDefined ( self.special_ammocount_explo[base_weapon] ) && self.special_ammocount_explo[base_weapon] > 0 ) //player has ap ammo return true; if ( isDefined ( self.special_ammocount_comb ) && isDefined ( self.special_ammocount_comb[base_weapon] ) && self.special_ammocount_comb[base_weapon] > 0 ) //player has combined ammo return true; return false; } has_incendiary_ammo( weapon_to_check ) { if ( !isDefined ( weapon_to_check ) ) weapon = self GetCurrentWeapon(); else weapon = weapon_to_check; if ( weapon == "none" ) { weapon = self GetWeaponsListPrimaries()[0]; } base_weapon = getRawBaseWeaponName( weapon ); if ( isDefined ( self.special_ammocount_in ) && isDefined ( self.special_ammocount_in[base_weapon] ) && self.special_ammocount_in[base_weapon] > 0 ) //player has ap ammo return true; if ( isDefined ( self.special_ammocount_comb ) && isDefined ( self.special_ammocount_comb[base_weapon] ) && self.special_ammocount_comb[base_weapon] > 0 ) //player has combined ammo return true; return false; } has_combined_ammo( weapon_to_check ) { if ( !isDefined ( weapon_to_check ) ) weapon = self GetCurrentWeapon(); else weapon = weapon_to_check; if ( weapon == "none" ) { weapon = self GetWeaponsListPrimaries()[0]; } base_weapon = getRawBaseWeaponName( weapon ); if ( isDefined ( self.special_ammocount_comb ) && isDefined ( self.special_ammocount_comb[base_weapon] ) && self.special_ammocount_comb[base_weapon] > 0 ) //player has combined ammo return true; return false; } remove_specialized_ammo( special_ammo_weapon ) { has_special_ammo = false; //stun if ( isDefined ( self.special_ammocount ) && isDefined ( self.special_ammocount[special_ammo_weapon] ) && self.special_ammocount[special_ammo_weapon] > 0 ) { self.special_ammocount[special_ammo_weapon] = 0; } //armor piercing if ( isDefined ( self.special_ammocount_ap ) && isDefined ( self.special_ammocount_ap[special_ammo_weapon] ) && self.special_ammocount_ap[special_ammo_weapon] > 0 ) { self.special_ammocount_ap[special_ammo_weapon] = 0; } //incendiary if ( isDefined ( self.special_ammocount_in ) && isDefined ( self.special_ammocount_in[special_ammo_weapon] ) && self.special_ammocount_in[special_ammo_weapon] > 0 ) { self.special_ammocount_in[special_ammo_weapon] = 0; } //explosive if ( isDefined ( self.special_ammocount_explo ) && isDefined ( self.special_ammocount_explo[special_ammo_weapon] ) && self.special_ammocount_explo[special_ammo_weapon] > 0 ) { self.special_ammocount_explo[special_ammo_weapon] = 0; } //combined if ( isDefined ( self.special_ammocount_comb ) && isDefined ( self.special_ammocount_comb[special_ammo_weapon] ) && self.special_ammocount_comb[special_ammo_weapon] > 0 ) { self.special_ammocount_comb[special_ammo_weapon] = 0; } } get_specialized_ammo_type() { weapon = self GetCurrentWeapon(); if ( weapon == "none" ) { weapon = self GetWeaponsListPrimaries()[0]; } base_weapon = getRawBaseWeaponName( weapon ); has_special_ammo = false; //stun if ( isDefined ( self.special_ammocount ) && isDefined ( self.special_ammocount[base_weapon] ) && self.special_ammocount[base_weapon] > 0 ) { return "stun_ammo"; } //armor piercing if ( isDefined ( self.special_ammocount_ap ) && isDefined ( self.special_ammocount_ap[base_weapon] ) && self.special_ammocount_ap[base_weapon] > 0 ) { return "ap_ammo"; } //incendiary if ( isDefined ( self.special_ammocount_in ) && isDefined ( self.special_ammocount_in[base_weapon] ) && self.special_ammocount_in[base_weapon] > 0 ) { return "incendiary_ammo"; } //explosive if ( isDefined ( self.special_ammocount_explo ) && isDefined ( self.special_ammocount_explo[base_weapon] ) && self.special_ammocount_explo[base_weapon] > 0 ) { return "explosive_ammo"; } return "none"; } mark_dangerous_nodes( dangerous_origin, radius, duration ) { MarkDangerousNodes( dangerous_origin, radius, true ); wait duration; MarkDangerousNodes( dangerous_origin, radius, false ); } /* catch_alien_on_fire( player ) { self endon( "death" ); if ( isDefined( self.is_burning ) ) return; BURN_TIME = 3.0; //self thread alien_on_fire( burn_time ); self maps\mp\alien\_alien_fx::alien_fire_on(); self thread damage_alien_over_time( BURN_TIME, player ); wait BURN_TIME; self maps\mp\alien\_alien_fx::alien_fire_off(); } //self = an alien damage_alien_over_time( burn_time, player ) { self endon( "death" ); total_time = 0; while ( total_time <= burn_time ) { self DoDamage( 10,self.origin, player, player, "MOD_UNKNOWN"); total_time += 1; wait 1; } } */ /* ============= ///ScriptDocBegin "Name: is_in_laststand()" "Summary: Returns true if the player is in last stand" "Module: Alien" "Example: if ( self is_in_laststand() )" "SPMP: multiplayer" ///ScriptDocEnd ============= */ is_in_laststand() { return self.inLastStand; } is_hardcore_mode() { return ( level.hardcoreMode ); } is_ricochet_damage() { return ( level.ricochetDamage ); } is_chaos_mode() { return ( level.isChaosMode == 1 ); } is_casual_mode() { return ( level.casualMode == 1 ); } get_chaos_area() { return level.chaos_area; } deployable_box_onuse_message( boxent ) { msg_text = ""; if ( isDefined ( boxEnt ) && isDefined( boxEnt.boxType ) && isDefined ( level.boxSettings [ boxEnt.boxtype ].eventString ) ) msg_text = level.boxSettings [ boxEnt.boxtype ].eventString; self thread setLowerMessage( "deployable_use",msg_text ,3 ); } set_attack_sync_direction( offset_direction, enter_anim, looping_anim, exit_anim, attacker_anim_state, attacker_anim_label ) { attack_sync = []; attack_sync["enterAnim"] = enter_anim; attack_sync["loopAnim"] = looping_anim; attack_sync["exitAnim"] = exit_anim; attack_sync["attackerAnimState"] = attacker_anim_state; attack_sync["attackerAnimLabel"] = attacker_anim_label; attack_sync["offset_direction"] = offset_direction; return attack_sync; } set_synch_attack_setup( synch_directions, type_specific, end_notifies, can_synch_attack_func, begin_attack_func, loop_attack_func, end_attack_func, identifier ) { attackSetup = SpawnStruct(); attackSetup.synch_directions = synch_directions; attackSetup.type_specific = type_specific; attackSetup.primary_attacker = undefined; attackSetup.can_synch_attack_func = can_synch_attack_func; attackSetup.begin_attack_func = begin_attack_func; attackSetup.end_attack_func = end_attack_func; attackSetup.loop_attack_func = loop_attack_func; attackSetup.end_notifies = end_notifies; attackSetup.identifier = identifier; self.synch_attack_setup = attackSetup; } get_synch_direction_list( synch_enemy ) { if ( !IsDefined( self.synch_attack_setup ) ) return []; if ( !IsDefined( self.synch_attack_setup.synch_directions ) ) return []; if ( !self.synch_attack_setup.type_specific ) return self.synch_attack_setup.synch_directions; alienType = synch_enemy get_alien_type(); if ( !IsDefined( self.synch_attack_setup.synch_directions[alienType] ) ) { msg = "Synch attack on " + self.synch_attack_setup.identifier + " doesn't handle type: " + alienType; AssertMsg( msg ); } return self.synch_attack_setup.synch_directions[alienType]; } /* ============= ///ScriptDocBegin "Name: is_alien_agent()" "Summary: Returns whether self is an alien agent." "Module: Alien" "Example: ent is_alien_agent()" "SPMP: multiplayer" ///ScriptDocEnd ============= */ is_alien_agent() { return IsAgent( self ) && IsDefined( self.alien_type ); } /* ============= ///ScriptDocBegin "Name: isPlayingSolo()" "Summary: Returns true if game is in Solo match." "Module: Alien" "Example: if ( isPlayingSolo() ) { IPrintLnBold( "I'm so lonely T_T" ); }" "SPMP: multiplayer" ///ScriptDocEnd ============= */ isPlayingSolo() { if ( getDvarInt ( "sv_maxclients" ) == 1 ) return true; return false; } /* ============= ///ScriptDocBegin "Name: riotShieldName()" "Summary: Returns the name of the riotshield the player is carrying" "Module: Entity" "CallOn: Player" "Example: " "SPMP: singleplayer" ///ScriptDocEnd ============= */ riotShieldName() { weapons = self GetWeaponsList( "primary" ); if ( !self.hasRiotShield ) return; foreach( weapon in weapons ) { if ( WeaponType( weapon ) == "riotshield" ) { return weapon; } } } /* ============= ///ScriptDocBegin "Name: get_array_of_valid_players( , )" "Summary: Returns an array of valid ( alive and playing ) players. Can optionally return a sorted array closest to a point " "Module: Entity" "CallOn: An entity" "OptionalArg: : " "OptionalArg: : " "Example: closest_players = get_array_of_valid_players( true, thing.origin )" "SPMP: multiplayer" ///ScriptDocEnd ============= */ get_array_of_valid_players( sort_by_closest, sort_by_closest_org ) { valid_players = []; foreach ( player in level.players ) { if ( player is_valid_player() ) valid_players[valid_players.size] = player; } if ( !isDefined ( sort_by_closest ) || !sort_by_closest ) return valid_players; return get_array_of_closest( sort_by_closest_org, valid_players ); } /* ============= ///ScriptDocBegin "Name: is_valid_player()" "Summary: Returns false if a player is not considered to be 'valid' ( alive and playing )" "Module: Entity" "CallOn: An entity" "Example: " "SPMP: singleplayer" ///ScriptDocEnd ============= */ is_valid_player() { if ( !isDefined ( self ) ) return false; if ( self maps\mp\alien\_utility::is_in_laststand() ) return false; if ( !isAlive ( self ) ) return false; if ( self.sessionstate == "spectator" ) return false; return true; } /* ============= ///ScriptDocBegin "Name: getRawBaseWeaponName( )" "Summary: Returns only the name of the weapon. iw6_alienp226_mp_akimbo will return alienp226" "Module: Entity" "CallOn: An entity" "MandatoryArg: : " "Example: " "SPMP: singleplayer" ///ScriptDocEnd ============= */ getRawBaseWeaponName( weaponName ) { tokens = strTok( weaponName, "_" ); if ( tokens[0] == "iw5" || tokens[0] == "iw6" ) { weaponName = tokens[1]; } else if( tokens[0] == "alt" ) { weaponName = tokens[1] + "_" + tokens[2]; } return weaponName; } /* ============= ///ScriptDocBegin "Name: get_in_world_area()" "Summary: Return the name for the FIRST world area which the entity is in" "Module: Entity" "CallOn: An entity" "MandatoryArg: none" "Example: area_name = player get_in_world_area()" "SPMP: multiplayer" ///ScriptDocEnd ============= */ get_in_world_area() { assertEx( isDefined( level.world_areas ), "Register world area with alien_area_init()" ); foreach( area_name, area_volumn in level.world_areas ) { if ( self isTouching( area_volumn ) ) return area_name; } return "none"; } /* ============= ///ScriptDocBegin "Name: is_true( )" "Summary: Returns true if a value is both defined & true. " "Module: Entity" "CallOn: An entity" "MandatoryArg: : " "Example: if ( is_true( level.somevalue ) ) " "SPMP: coop" ///ScriptDocEnd ============= */ is_true( arg ) { if( IsDefined( arg ) && arg ) return true; return false; } /* ============= ///ScriptDocBegin "Name: is_akimbo_weapon( )" "Summary: Returns true if this weapon is one of the akimbo weapons used for Extinction" "Module: Entity" "CallOn: An entity" "MandatoryArg: : " "Example: if ( is_akimbo_weapon ( weapon ) )" "SPMP: coop" ///ScriptDocEnd ============= */ is_akimbo_weapon( weapon ) { switch ( weapon ) { case "iw5_alienp226_mp_akimbo_barrelrange02_xmags": case "iw5_alienmagnum_mp_akimbo_barrelrange02_xmags": case "iw5_alienm9a1_mp_akimbo_barrelrange02_xmags": case "iw5_alienmp443_mp_akimbo_barrelrange02_xmags": return true; } if ( getWeaponClass ( weapon ) == "weapon_pistol" ) return issubstr( weapon,"akimbo" ); return false; } /* ============= ///ScriptDocBegin "Name: specialammo_weaponchange_monitor( )" "Summary: " "Module: Entity" "CallOn: An entity" "MandatoryArg: : " "Example: " "SPMP: singleplayer" ///ScriptDocEnd ============= */ special_ammo_weapon_change_monitor( special_ammo_type ) { self endon( "disconnect" ); level endon( "game_ended" ); self notify ( "special_weapons_monitor" ); self endon ( "special_weapons_monitor" ); while ( 1 ) { self waittill( "weapon_change", newWeapon ); if ( newWeapon == "none" ) continue; baseweapon = getRawBaseWeaponName( newWeapon ); has_special_ammo = false; perk = undefined; icon_index = undefined; switch ( special_ammo_type ) { case "stun": has_special_ammo = self has_stun_ammo( baseweapon ); perk = "specialty_bulletdamage"; icon_index = 1; break; case "piercing": has_special_ammo = self has_ap_ammo( baseweapon ); perk = "specialty_armorpiercing"; icon_index = 4; break; case "incendiary": has_special_ammo = self has_incendiary_ammo ( baseweapon ); icon_index = 2; break; case "explosive": has_special_ammo = self has_explosive_ammo ( baseweapon ); perk = "specialty_explosivebullets"; icon_index = 3; break; case "combined": has_special_ammo = self has_combined_ammo ( baseweapon ); icon_index = 5; break; } if ( is_true ( has_special_ammo ) ) { if ( isDefined ( perk ) ) self givePerk( perk, false ); if ( special_ammo_type == "combined" ) { self.has_incendiary_ammo = true; self giveperk( "specialty_bulletdamage", false ); self giveperk( "specialty_armorpiercing", false ); self giveperk( "specialty_explosivebullets", false ); } if ( special_ammo_type == "incendiary" ) self.has_incendiary_ammo = true; self SetClientOmnvar("ui_alien_specialammo", icon_index ); } else { if ( isDefined ( perk ) ) { if ( self _hasPerk ( perk ) ) self _unsetPerk( perk ); } if ( special_ammo_type == "combined" ) { self.has_incendiary_ammo = undefined; if ( self _hasPerk ( "specialty_bulletdamage" ) ) self _unsetPerk( "specialty_bulletdamage" ); if ( self _hasPerk ( "specialty_armorpiercing" ) ) self _unsetPerk( "specialty_armorpiercing" ); if ( self _hasPerk ( "specialty_explosivebullets" ) ) self _unsetPerk( "specialty_explosivebullets" ); } if ( special_ammo_type == "incendiary" ) self.has_incendiary_ammo = undefined; self SetClientOmnvar("ui_alien_specialammo", -1 ); } } } special_ammo_weapon_fire_monitor( special_ammo_type ) { self notify ( "weaponfire_monitor" ); self endon ( "weaponfire_monitor" ); while ( 1 ) { self waittill( "weapon_fired",wpnName ); baseweaponName = getRawBaseWeaponName( wpnName ); has_special_ammo = false; perk = undefined; switch ( special_ammo_type ) { case "stun": has_special_ammo = self has_stun_ammo( baseweaponName ); perk = "specialty_bulletdamage"; ammo_array = self.special_ammocount; break; case "piercing": has_special_ammo = self has_ap_ammo( baseweaponName ); perk = "specialty_armorpiercing"; ammo_array = self.special_ammocount_ap; break; case "incendiary": has_special_ammo = self has_incendiary_ammo ( baseweaponName ); ammo_array = self.special_ammocount_in; break; case "explosive": has_special_ammo = self has_explosive_ammo ( baseweaponName ); perk = "specialty_explosivebullets"; ammo_array = self.special_ammocount_explo; break; case "combined": has_special_ammo = self has_combined_ammo ( baseweaponName ); ammo_array = self.special_ammocount_comb; break; } if ( is_true ( has_special_ammo) ) { weapon_clip = self GetWeaponAmmoClip( wpnName ); weapon_stock = self GetWeaponAmmoStock( wpnName ); if ( is_akimbo_weapon( wpnname ) ) { weapon_clip_left = self GetWeaponAmmoClip( wpnName,"left" ); weapon_clip_right = self GetWeaponAmmoClip ( wpnname,"right" ); weapon_clip = weapon_clip_left + weapon_clip_right; } switch ( special_ammo_type ) { case "stun": self.special_ammocount[baseweaponName] = weapon_clip + weapon_stock; break; case "piercing": self.special_ammocount_ap[baseweaponName] = weapon_clip + weapon_stock; break; case "incendiary": self.special_ammocount_in[baseweaponName] = weapon_clip + weapon_stock; break; case "explosive": self.special_ammocount_explo[baseweaponName] = weapon_clip + weapon_stock; break; case "combined": self.special_ammocount_comb[baseweaponName] = weapon_clip + weapon_stock; break; } if ( weapon_clip + weapon_stock < 1 ) { self SetClientOmnvar("ui_alien_specialammo",-1 ); if ( isDefined ( perk ) ) { if ( self _hasPerk ( perk ) ) self _unsetPerk( perk ); } if ( special_ammo_type == "combined" ) { self.has_incendiary_ammo = undefined; if ( self _hasPerk ( "specialty_bulletdamage" ) ) self _unsetPerk( "specialty_bulletdamage" ); if ( self _hasPerk ( "specialty_armorpiercing" ) ) self _unsetPerk( "specialty_armorpiercing" ); if ( self _hasPerk ( "specialty_explosivebullets" ) ) self _unsetPerk( "specialty_explosivebullets" ); } if ( special_ammo_type == "incendiary" ) self.has_incendiary_ammo = undefined; if ( isDefined( self.stored_ammo[baseweaponName] ) ) { //add existing clip ammo to the stock, then set the clip to 0 so it forces a reload self.stored_ammo[baseweaponName].ammoStock += self.stored_ammo[baseweaponName].clipammo; self setweaponammoclip( wpnName, 0); self setweaponammostock( wpnName,self.stored_ammo[baseweaponName].ammoStock ); self.stored_ammo[baseweaponName] = undefined; self SwitchToWeapon( wpnName ); } continue; } } } } /* ============= ///ScriptDocBegin "Name: disable_special_ammo()" "Summary: Disable any specialized ammo that the player has" "Module: Entity" "CallOn: An entity" "Example: self disable_special_ammo() " "SPMP: coop" ///ScriptDocEnd ============= */ disable_special_ammo() { self endon( "disconnect" ); //determine the type of special ammo to disable primaries = self GetWeaponsListPrimaries(); foreach ( weapon in primaries ) { baseweapon = getRawBaseWeaponName( weapon ); special_ammo_type = undefined; perk = undefined; icon_index = undefined; if ( self has_stun_ammo( baseweapon ) ) { perk = "specialty_bulletdamage"; icon_index = 1; special_ammo_type = "stun"; } else if ( self has_ap_ammo( baseweapon ) ) { perk = "specialty_armorpiercing"; icon_index = 4; special_ammo_type = "piercing"; } else if( self has_incendiary_ammo ( baseweapon ) ) { special_ammo_type = "incendiary"; icon_index = 2; } else if ( self has_explosive_ammo ( baseweapon ) ) { special_ammo_type = "explosive"; perk = "specialty_explosivebullets"; icon_index = 3; } else if ( self has_combined_ammo ( baseweapon ) ) { special_ammo_type = "combined"; icon_index = 5; } if ( isDefined ( special_ammo_type ) ) { if ( isDefined ( perk ) ) { if ( self _hasPerk ( perk ) ) self _unsetPerk( perk ); } if ( special_ammo_type == "combined" ) { self.has_incendiary_ammo = undefined; if ( self _hasPerk ( "specialty_bulletdamage" ) ) self _unsetPerk( "specialty_bulletdamage" ); if ( self _hasPerk ( "specialty_armorpiercing" ) ) self _unsetPerk( "specialty_armorpiercing" ); if ( self _hasPerk ( "specialty_explosivebullets" ) ) self _unsetPerk( "specialty_explosivebullets" ); } if ( special_ammo_type == "incendiary" ) self.has_incendiary_ammo = undefined; self SetClientOmnvar("ui_alien_specialammo", -1 ); return; //break out here since it's possible that not all weapons have specialized ammo, but not possible to have multiple types } } } /* ============= ///ScriptDocBegin "Name: enable_special_ammo()" "Summary: Enables specialized ammo on the player" "Module: Entity" "CallOn: An entity" "Example: self enable_special_ammo()" "SPMP: coop" ///ScriptDocEnd ============= */ enable_special_ammo() { self endon( "disconnect" ); //determine the type of special ammo to enable weapon = self GetCurrentPrimaryWeapon(); baseweapon = getRawBaseWeaponName( weapon ); special_ammo_type = undefined; perk = undefined; icon_index = undefined; if ( self has_stun_ammo( baseweapon ) ) { perk = "specialty_bulletdamage"; icon_index = 1; special_ammo_type = "stun"; } else if ( self has_ap_ammo( baseweapon ) ) { perk = "specialty_armorpiercing"; icon_index = 4; special_ammo_type = "piercing"; } else if( self has_incendiary_ammo ( baseweapon ) ) { special_ammo_type = "incendiary"; icon_index = 2; } else if ( self has_explosive_ammo ( baseweapon ) ) { special_ammo_type = "explosive"; perk = "specialty_explosivebullets"; icon_index = 3; } else if ( self has_combined_ammo ( baseweapon ) ) { special_ammo_type = "combined"; icon_index = 5; } if ( isDefined ( special_ammo_type ) ) { if ( isDefined ( perk ) ) self givePerk( perk, false ); if ( special_ammo_type == "combined" ) { self.has_incendiary_ammo = true; self giveperk( "specialty_bulletdamage", false ); self giveperk( "specialty_armorpiercing", false ); self giveperk( "specialty_explosivebullets", false ); } if ( special_ammo_type == "incendiary" ) self.has_incendiary_ammo = true; self SetClientOmnvar("ui_alien_specialammo", icon_index ); } } /* ============= ///ScriptDocBegin "Name: show_turret_icon()" "Summary: Shows the turret icon on the hud" "Module: Entity" "CallOn: An entity" "Example: player show_turret_icon()" "SPMP: coop" ///ScriptDocEnd ============= */ show_turret_icon( value ) { self SetClientOmnvar( "ui_alien_turret", value ); } /* ============= ///ScriptDocBegin "Name: hide_turret_icon()" "Summary: Hides both the icon & the counter for the turrets" "Module: Entity" "CallOn: An entity" "Example: player hide_turret_icon()" "SPMP: coop" ///ScriptDocEnd ============= */ hide_turret_icon() { self SetClientOmnvar( "ui_alien_turret", -1 ); self SetClientOmnvar( "ui_alien_turret_ammo", -1 ); } /* ============= ///ScriptDocBegin "Name: set_turret_ammocount( )" "Summary: Sets the amount of ammo to display for the turret ammo counter" "Module: Entity" "CallOn: An entity" "MandatoryArg: : " "Example: player set_turret_ammocount( 200 ) " "SPMP: coop" ///ScriptDocEnd ============= */ set_turret_ammocount( ammo ) { self SetClientOmnvar( "ui_alien_turret_ammo", ammo ); } /* ============= ///ScriptDocBegin "Name: add_hive_dependencies()" "Summary: The given hive will not be able to be planted until all dependent hives are destroyed." "Module: Alien" "MandatoryArg: The hive in question." "MandatoryArg: All hives that hive is dependent on" "Example: result = add_hive_dependencies( "crater_lung", [ "lake_lung_1", "lake_lung_2" ] )" "SPMP: coop" ///ScriptDocEnd ============= */ add_hive_dependencies( hive, dependent_hives ) { if ( !isDefined( level.hive_dependencies ) ) level.hive_dependencies = []; level.hive_dependencies[ hive ] = dependent_hives; } should_snare( player ) { if ( !self is_alien_agent() || is_chaos_mode() ) return false; if ( player maps\mp\alien\_persistence::is_upgrade_enabled( "no_snare_upgrade" ) ) return false; type = self get_alien_type(); if ( type == "brute" || type == "minion" ) return true; else return false; } buildAlienWeaponName( baseName, attachment1, attachment2, attachment3, attachment4, camo, reticle ) { //hack for current menu bug - remove before ship if ( isDefined( reticle ) && reticle != 0 && getAttachmentType( attachment1 ) != "rail" && getAttachmentType( attachment2 ) != "rail" && getAttachmentType( attachment3 ) != "rail" && getAttachmentType( attachment4 ) != "rail" ) { reticle = undefined; } if ( attachment1 == "alienvksscope" ) attachment1 = "scope"; else if ( attachment1 == "alienl115a3vzscope" ) attachment1 = "vzscope"; if ( attachment2 == "alienvksscope" ) attachment2 = "scope"; else if ( attachment2 == "alienl115a3vzscope" ) attachment2 = "vzscope"; if ( attachment3 == "alienvksscope" ) attachment3 = "scope"; else if ( attachment3 == "alienl115a3vzscope" ) attachment3 = "vzscope"; if ( attachment4 == "alienvksscope" ) attachment4 = "scope"; else if ( attachment4 == "alienl115a3vzscope" ) attachment4 = "vzscope"; attachment1 = attachmentMap_toUnique( attachment1, baseName ); attachment2 = attachmentMap_toUnique( attachment2, baseName ); attachment3 = attachmentMap_toUnique( attachment3, baseName ); attachment4 = attachmentMap_toUnique( attachment4, baseName ); bareWeaponName = ""; if ( IsSubStr( baseName, "iw5" ) || IsSubStr( baseName, "iw6" ) ) { weaponName = baseName + "_mp"; endIndex = baseName.size; bareWeaponName = GetSubStr( baseName, 4, endIndex ); } else { weaponName = baseName; } weapClass = getWeaponClass( baseName ); needScope = weapClass == "weapon_sniper" || baseName == "aliendlc23"; attachments = []; if ( attachment1 != "none" ) attachments[ attachments.size ] = attachment1; if ( attachment2 != "none" ) attachments[ attachments.size ] = attachment2; if ( attachment3 != "none" ) attachments[ attachments.size ] = attachment3; if ( attachment4 != "none" ) attachments[ attachments.size ] = attachment4; // If the gun needs a scope and doesn't have a rail attachment if ( needScope ) { hasAttachRail = false; foreach ( attachment in attachments ) { if ( getAttachmentType( attachment ) == "rail" ) { hasAttachRail = true; break; } } if ( !hasAttachRail ) { attachments[ attachments.size ] = bareWeaponName + "scope"; } } if ( IsDefined( attachments.size ) && attachments.size ) { attachments = alphabetize( attachments ); } foreach ( attachment in attachments ) { weaponName += "_" + attachment; } if ( IsSubStr( weaponName, "iw5" ) || IsSubStr( weaponName, "iw6" ) ) { weaponName = buildAlienWeaponNameCamo( weaponName, camo ); weaponName = buildAlienWeaponNameReticle( weaponName, reticle ); } else if ( !isValidAlienWeapon( weaponName + "_mp" ) ) { weaponName = baseName + "_mp"; } else { weaponName = buildALienWeaponNameCamo( weaponName, camo ); weaponName = buildAlienWeaponNameReticle( weaponName, reticle ); weaponName += "_mp"; } return weaponName; } buildALienWeaponNameCamo( weaponName, camo ) { if ( !IsDefined( camo ) ) return weaponName; if ( camo <= 0 ) return weaponName; if ( camo < 10 ) weaponName += "_camo0"; else weaponName += "_camo"; weaponName += camo; return weaponName; } buildAlienWeaponNameReticle( weaponName, reticle ) { if ( !IsDefined( reticle ) ) { return weaponName; } // 0 and 1 are none and default if ( reticle <= 1 ) { return weaponName; } // The index in the reticleTable is offset up one // because of the default category reticle--; weaponName += "_scope"; weaponName += reticle; return weaponName; } isValidAlienWeapon( refString ) { if ( !isDefined( level.weaponRefs ) ) { level.weaponRefs = []; foreach ( weaponRef in level.weaponList ) level.weaponRefs[ weaponRef ] = true; } if ( isDefined( level.weaponRefs[ refString ] ) ) return true; assertMsg( "Replacing invalid weapon/attachment combo: " + refString ); return false; } _detachAll() { if ( isDefined( self.hasRiotShield ) && self.hasRiotShield ) { if ( self.hasRiotShieldEquipped ) { self DetachShieldModel( "weapon_riot_shield_iw6", "tag_weapon_right" ); self.hasRiotShieldEquipped = false; } else { self DetachShieldModel( "weapon_riot_shield_iw6", "tag_shield_back" ); } self.hasRiotShield = false; } self detachAll(); } hasRiotShield() { result = false; weaponList = self GetWeaponsListPrimaries(); foreach ( weapon in weaponList ) { if ( maps\mp\gametypes\_weapons::isRiotShield( weapon ) ) { result = true; break; } } return result; } trackRiotShield() { self endon ( "death" ); self endon ( "disconnect" ); self endon ( "faux_spawn" ); self.hasRiotShield = self hasRiotShield(); curweapon = self GetCurrentWeapon(); self.hasRiotShieldEquipped = maps\mp\gametypes\_weapons::isRiotShield( curweapon ); // note this function must play nice with _detachAll(). if ( self.hasRiotShield ) { if ( maps\mp\gametypes\_weapons::isRiotShield( self.primaryWeapon ) && maps\mp\gametypes\_weapons::isRiotShield( self.secondaryWeapon ) ) { self AttachShieldModel( "weapon_riot_shield_iw6", "tag_weapon_right" ); self AttachShieldModel( "weapon_riot_shield_iw6", "tag_shield_back" ); } else if ( self.hasRiotShieldEquipped ) { self AttachShieldModel( "weapon_riot_shield_iw6", "tag_weapon_right" ); } else { self AttachShieldModel( "weapon_riot_shield_iw6", "tag_shield_back" ); } } for ( ;; ) { self waittill ( "weapon_change", newWeapon ); // need to check both, player can be 'juggernaut' by game setup default class specification now, not only killstreak if ( maps\mp\gametypes\_weapons::isRiotShield( newWeapon ) ) { // defensive check in case we somehow get an extra "weapon_change" if ( self.hasRiotShieldEquipped ) continue; // Both weapons are riotshields so down't swap if ( maps\mp\gametypes\_weapons::isRiotShield( self.primaryWeapon ) && maps\mp\gametypes\_weapons::isRiotShield( self.secondaryWeapon ) ) { continue; } else if ( self.hasRiotShield ) { self MoveShieldModel( "weapon_riot_shield_iw6", "tag_shield_back", "tag_weapon_right" ); } else { self AttachShieldModel( "weapon_riot_shield_iw6", "tag_weapon_right" ); } self.hasRiotShield = true; self.hasRiotShieldEquipped = true; } else if ( ( self IsMantling() ) && ( newWeapon == "none" ) ) { // Do nothing, we want to keep that weapon on their arm. } else if ( self.hasRiotShieldEquipped ) { Assert( self.hasRiotShield ); self.hasRiotShield = self hasRiotShield(); if ( self.hasRiotShield ) self MoveShieldModel( "weapon_riot_shield_iw6", "tag_weapon_right", "tag_shield_back" ); else self DetachShieldModel( "weapon_riot_shield_iw6", "tag_weapon_right" ); self.hasRiotShieldEquipped = false; } else if ( self.hasRiotShield && !self hasRiotShield() ) { // we probably just lost all of our weapons (maybe switched classes) self DetachShieldModel( "weapon_riot_shield_iw6", "tag_shield_back" ); self.hasRiotShield = false; } else if ( !self.hasRiotShield && self hasRiotShield() ) { // we just acquired a riot shield but our current weapon is something else self AttachShieldModel( "weapon_riot_shield_iw6", "tag_shield_back" ); self.hasRiotShield = true; } } } tryAttach( placement ) // deprecated; hopefully we won't need to bring this defensive function back { if ( !isDefined( placement ) || placement != "back" ) tag = "tag_inhand"; else tag = "tag_shield_back"; attachSize = self getAttachSize(); for ( i = 0; i < attachSize; i++ ) { attachedTag = self getAttachTagName( i ); if ( attachedTag == tag && self getAttachModelName( i ) == "weapon_riot_shield_iw6" ) { return; } } self AttachShieldModel( "weapon_riot_shield_iw6", tag ); } weapon_change_monitor() { self endon( "disconnect" ); self.has_special_weapon = false; self.is_holding_deployable = false; self.is_holding_crate_marker = false; self.should_track_weapon_fired = true; while ( 1 ) { self waittill( "weapon_change",wpn ); switch( wpn ) { case "none": case "alienbomb_mp": case "mortar_detonator_mp": case "switchblade_laptop_mp": case "aliendeployable_crate_marker_mp": case "iw5_alienriotshield_mp": case "iw5_alienriotshield1_mp": case "iw5_alienriotshield2_mp": case "iw5_alienriotshield3_mp": case "iw5_alienriotshield4_mp": self.should_track_weapon_fired = false; break; default: self.should_track_weapon_fired = true; break; } if ( wpn == "none" ) continue; self.has_special_weapon = false; self.is_holding_deployable = false; self.is_holding_crate_marker = false; switch ( wpn ) { case "iw6_alienminigun_mp": case "iw6_alienminigun1_mp": case "iw6_alienminigun2_mp": case "iw6_alienminigun3_mp": case "iw6_alienminigun4_mp": case "iw6_alienmk32_mp": case "iw6_alienmk321_mp": case "iw6_alienmk322_mp": case "iw6_alienmk323_mp": case "iw6_alienmk324_mp": case "iw6_alienmaaws_mp": self.has_special_weapon = true; break; case "alienbomb_mp": case "alienclaymore_mp": case "bouncingbetty_mp": case "alientrophy_mp": case "deployable_vest_marker_mp": case "alienpropanetank_mp": case "alien_turret_marker_mp": case "switchblade_laptop_mp": case "mortar_detonator_mp": self.is_holding_deployable = true; break; case "aliendeployable_crate_marker_mp": self.is_holding_deployable = true; self.is_holding_crate_marker = true; break; } //check to make sure we really don't have a special weapon stashed if ( !self.has_special_weapon ) { primaries = self GetWeaponsListPrimaries(); foreach ( weapon in primaries ) { switch ( weapon ) { case "iw6_alienminigun_mp": case "iw6_alienminigun1_mp": case "iw6_alienminigun2_mp": case "iw6_alienminigun3_mp": case "iw6_alienminigun4_mp": case "iw6_alienmk32_mp": case "iw6_alienmk321_mp": case "iw6_alienmk322_mp": case "iw6_alienmk323_mp": case "iw6_alienmk324_mp": case "iw6_alienmaaws_mp": self.has_special_weapon = true; } if ( self.has_special_weapon ) break; } } } } is_trap( ent ) { if ( !isDefined( ent ) ) return false; //tesla trap kills if( isDefined( ent.tesla_type ) ) return true; if ( !isDefined ( ent.script_noteworthy ) && !isDefined ( ent.targetname ) ) return false; if( isDefined ( ent.targetname ) && ( ent.targetname == "fence_generator" || ent.targetname == "puddle_generator" ) ) return true; if ( isDefined( ent.script_noteworthy ) && ent.script_noteworthy == "fire_trap" ) return true; return false; } /* ============= ///ScriptDocBegin "Name: zero_out_specialammo_clip( )" "Summary: forces a reload when aquiring special ammo" "Module: Player" "CallOn: A player" "MandatoryArg: : " "Example: self zero_out_specialammo_clip( weapon )" "SPMP: singleplayer" ///ScriptDocEnd ============= */ zero_out_specialammo_clip( weapon ) { if ( is_akimbo_weapon( weapon ) ) { self SetWeaponAmmoClip( weapon, 0, "left" ); //this forces a reload self SetWeaponAmmoClip( weapon,0, "right" ); } else { self SetWeaponAmmoClip(weapon, 0 ); //this forces a reload } } /* ============= ///ScriptDocBegin "Name: handle_existing_ammo( , , )" "Summary: handle existing non-specialized ammo when a user picks up special ammo" "Module: Player" "CallOn: A player" "MandatoryArg: : " "MandatoryArg: : " "MandatoryArg: : " "Example: " "SPMP: coop" ///ScriptDocEnd ============= */ handle_existing_ammo( special_ammo_weapon , weapon, ammo_type ) { if ( !isDefined ( self.stored_ammo ) ) self.stored_ammo = []; if ( !isDefined( self.stored_ammo[special_ammo_weapon] ) ) { self.stored_ammo[special_ammo_weapon] = spawnstruct(); } // check to see if the player already has another type of special ammo loaded for this weapon, if so just replace it should_store_ammo = should_store_ammo_check( ammo_type, special_ammo_weapon ); //store the ammo if ( should_store_ammo && !is_ammo_already_stored( special_ammo_weapon ) ) { clipAmmo_stored = self GetWeaponAmmoClip( weapon ); ammoStock_stored = self GetWeaponAmmoStock( weapon ); if ( is_akimbo_weapon( weapon ) ) { weapon_clip_left = self GetWeaponAmmoClip( weapon,"left" ); weapon_clip_right = self GetWeaponAmmoClip ( weapon,"right" ); clipAmmo_stored = weapon_clip_left + weapon_clip_right; } self.stored_ammo[special_ammo_weapon].clipammo = clipAmmo_stored; self.stored_ammo[special_ammo_weapon].ammoStock = ammoStock_stored; } } wait_for_player_to_dismount_turret() { self endon( "death" ); self endon( "disconnect" ); self setLowerMessage( "disengage_turret", &"ALIEN_COLLECTIBLES_DISENGAGE_TURRET",0 ); while ( self IsUsingTurret() ) wait .5; self clearLowerMessage( "disengage_turret" ); } /* ============= ///ScriptDocBegin "Name: disable_weapon_timeout()" "Summary: Disables weapon, and re-enables weapon after timeout." "Module: Alien" "MandatoryArg: time in seconds (float)." "MandatoryArg: notify message that uniquely identifies this instance of weapon disable (string)." "Example: player disable_weapon_timeout( useTime + 0.05, "drill_repair_weapon_management" );" "SPMP: multiplayer" ///ScriptDocEnd ============= */ disable_weapon_timeout( timeout, notify_msg ) { assert( isdefined( timeout ) && isdefined( notify_msg ) ); self thread enable_weapon_after_timeout( timeout, notify_msg ); self _disableWeapon(); } enable_weapon_after_timeout( timeout, notify_msg ) { self endon( "death" ); self endon( notify_msg ); // ends on enable_weapon_wrapper() with same message wait timeout; /# IPrintLnBold( "^1[WARNING] Disable weapon timed out!" ); #/ self _enableWeapon(); //self thread enable_weapon_wrapper_check(); } //enable weapon doesn't handle enabling a weapon that was taken away while it was disabled. //enable_weapon_wrapper_check() //{ // self endon( "disconnect" ); // self endon( "death" ); // // waittill_any_timeout( 2, "weapon_change" ); // necessary for the weapons to be re-enabled after _enableweapons has happened // // if ( self GetCurrentPrimaryWeapon() == "none" ) // { // primaries = self GetWeaponsListPrimaries(); // self SwitchToWeapon ( primaries[0] ); // } //} /* ============= ///ScriptDocBegin "Name: enable_weapon_wrapper()" "Summary: Enables weapon and notifies." "Module: Alien" "MandatoryArg: notify message that uniquely identifies this instance of weapon enable, to reset timeouts called earlier (string)." "Example: player enable_weapon_wrapper( "drill_repair_weapon_management" );" "SPMP: multiplayer" ///ScriptDocEnd ============= */ enable_weapon_wrapper( notify_msg ) { assert( isdefined( notify_msg ) ); self notify( notify_msg ); // kills timeout with the same message self _enableWeapon(); //self thread enable_weapon_wrapper_check(); } /* ============= ///ScriptDocBegin "Name: GetMultipleRandomIndex( , )" "Summary: Return an array of random array index based on the probability weights assigned to each index." "Module: Alien" "MandatoryArg: Array of probability weights. the number of index that are returned" "Example: randIndexArray = GetMultipleRandomIndex( animWeights, 2 );" "SPMP: multiplayer" ///ScriptDocEnd ============= */ GetMultipleRandomIndex( weights, numOfIndex ) { Assert( weights.size >= numOfIndex ); result = []; for( i = 0; i < numOfIndex; i++ ) { randomIndex = GetRandomIndex( weights ); result[result.size] = randomIndex; weights = array_remove_index( weights, randomIndex, true ); } return result; } /* ============= ///ScriptDocBegin "Name: array_remove_index( , , )" "Summary: Removes the element in the array with this index, resulting array order is intact." "Module: Entity" "CallOn: An entity" "MandatoryArg: , " "OptionalArg: : If true, the new array will keep all the original index from the old array " "Example: locations = array_remove_index( locations, 3, true );" "SPMP: multiplayer" ///ScriptDocEnd ============= */ array_remove_index( array, index, keepOriginalIndex ) { newArray = []; foreach ( arrayIndex, value in array ) { if ( arrayIndex == index ) continue; if ( is_true( keepOriginalIndex ) ) newArray_index = arrayIndex; else newArray_index = newArray.size; newArray[newArray_index] = value; } return newArray; } /* ============= ///ScriptDocBegin "Name: GetRandomIndex( )" "Summary: Return a random array index based on the probability weights assigned to each index." "Module: Alien" "MandatoryArg: Array of probability weights" "Example: randIndex = GetRandomIndex( animWeights );" "SPMP: multiplayer" ///ScriptDocEnd ============= */ GetRandomIndex( weights ) { weightSum = 0; foreach ( weight in weights ) weightSum += weight; randIndex = RandomIntRange( 0, weightSum ); weightSum = 0; foreach ( i, weight in weights ) { weightSum += weight; if ( randIndex <= weightSum ) return i; } assertmsg( "should not get here." ); return 0; } /* ============= ///ScriptDocBegin "Name: _enableAdditionalPrimaryWeapon()" "Summary: allows the player to carry an additional primary weapon " "Module: Entity" "CallOn: A Player" "Example: " "SPMP: singleplayer" ///ScriptDocEnd ============= */ _enableAdditionalPrimaryWeapon() { if ( !IsDefined( self.numAdditionalPrimaries ) ) { self.numAdditionalPrimaries = 0; } self.numAdditionalPrimaries++; } /* ============= ///ScriptDocBegin "Name: is_incompatible_weapon( )" "Summary: check to see if this weapon is compatible with standard ammo types" "Module: Entity" "CallOn: An entity" "MandatoryArg: : " "Example: " "SPMP: singleplayer" ///ScriptDocEnd ============= */ is_incompatible_weapon( weapon ) { //for special weapons ( i.e. unique weapons for each level ) if ( isDefined( level.ammoIncompatibleWeaponsList ) ) { if ( array_contains ( level.ammoIncompatibleWeaponsList, weapon ) ) return true; } return false; } is_door() { return self.targetname == "stronghold_door_loc"; } is_door_hive() { return is_true ( level.hive_is_really_a_door ); } has_tag( model, tag ) { partCount = GetNumParts( model ); for ( i = 0; i < partCount; i++ ) { if( toLower( GetPartName( model, i)) == toLower( tag )) return true; } return false; } level_uses_MAAWS() { switch ( level.script ) { case "mp_alien_beacon": return true; default: break; } return false; } is_flaming_stowed_riotshield_damage( sMeansOfDeath, sWeapon, eInflictor ) { if( isDefined( einflictor ) && is_trap( eInflictor ) ) return false; if ( sMeansOfDeath == "MOD_UNKNOWN" && sWeapon != "none" ) return true; else return false; } ark_attachment_transfer_to_locker_weapon( fullweaponname, current_attachments, should_take_weapon ) { has_ark_attachment = undefined; weaponAttachments = getWeaponAttachmentsBaseNames( fullweaponname ); if(isdefined(weaponAttachments[0])) attachment1 = weaponAttachments[0]; else attachment1 = "none"; if(isdefined(weaponAttachments[1])) attachment2 = weaponAttachments[1]; else attachment2 = "none"; if(isdefined(weaponAttachments[2])) attachment3 = weaponAttachments[2]; else attachment3 = "none"; if(isdefined(weaponAttachments[3])) attachment4 = weaponAttachments[3]; else attachment4 = "none"; if ( is_true( should_take_weapon ) ) { foreach( piece in current_attachments ) { piece = attachmentMap_toBase( piece ); if ( piece == "alienmuzzlebrake" ) { has_ark_attachment = true; break; } } if ( is_true( has_ark_attachment ) ) { locker_weapon_attachments = getWeaponAttachments( fullweaponname ); for ( i=0; i < locker_weapon_attachments.size; i++ ) { locker_weapon_attachments[i] = replace_barrelrange_with_ark( locker_weapon_attachments[i] ); if ( i == 0 ) attachment1 = attachmentMap_toBase ( locker_weapon_attachments[i] ); if ( i == 1 ) attachment2 = attachmentMap_toBase ( locker_weapon_attachments[i] ); if ( i == 2 ) attachment3 = attachmentMap_toBase ( locker_weapon_attachments[i] ); if ( i == 3 ) attachment4 = attachmentMap_toBase ( locker_weapon_attachments[i] ); } } } baseweapon = GetWeaponBaseName( fullweaponname ); weaponname = strip_suffix( baseweapon, "_mp" ); camo = RandomIntRange( 1, 10 ); //new-type camos don't work for these guns if ( IsSubStr( baseweapon,"alienfp6" ) || IsSubStr( baseweapon, "alienmts255" ) || IsSubStr( baseweapon, "aliendlc12" ) || IsSubStr( baseweapon, "aliendlc13" ) || IsSubStr( baseweapon, "aliendlc14" ) || IsSubStr( baseweapon, "aliendlc15" ) || IsSubStr( baseweapon, "aliendlc23" ) || IsSubStr( baseweapon, "altalienlsat" ) || IsSubStr( baseweapon, "altaliensvu" ) || IsSubStr( baseweapon, "altalienarx" ) || IsSubStr( baseweapon, "arkalienr5rgp" ) || IsSubStr( baseweapon, "arkaliendlc15" ) || IsSubStr( baseweapon, "arkaliendlc23" ) || IsSubStr( baseweapon, "arkalienk7" ) || IsSubStr( baseweapon, "arkalienuts15" ) || IsSubStr( baseweapon, "arkalienmaul" ) || IsSubStr( baseweapon, "arkalienmk14" ) || IsSubStr( baseweapon, "arkalienimbel" ) || IsSubStr( baseweapon, "arkalienkac" ) || IsSubStr( baseweapon, "arkalienameli" ) ) camo = 0; reticle = RandomIntRange( 1, 7 ); weapon_string = undefined; if ( attachment1 != "thermal" && attachment1 != "thermalsmg" && attachment2 != "thermal" && attachment2 != "thermalsmg" && attachment3 != "thermal" && attachment3 != "thermalsmg" && attachment4 != "thermal" && attachment4 != "thermalsmg" && baseweapon != "iw6_aliendlc23_mp") fullweaponname = maps\mp\alien\_utility::buildAlienWeaponName( weaponname, attachment1, attachment2, attachment3, attachment4, camo, reticle ); else fullweaponname = maps\mp\alien\_utility::buildAlienWeaponName( weaponname, attachment1, attachment2, attachment3, attachment4, camo ); self.locker_weapon = fullweaponname; return fullweaponname; } replace_barrelrange_with_ark( attachment ) { if( isDefined( attachment ) && string_starts_with( attachment, "barrelrange" ) ) return "alienmuzzlebrake"; else return attachment; } return_weapon_with_like_attachments( fullweaponname, current_attachments ) { baseweapon = GetWeaponBaseName( fullweaponname ); player = self; attachment1 = "none"; attachment2 = "none"; attachment3 = "none"; attachment4 = "none"; weaponclass = getWeaponClass( baseweapon ); possible_attachments = maps\mp\alien\_pillage::get_possible_attachments_by_weaponclass( weaponclass , baseweapon ); valid_attachments = []; foreach( piece in current_attachments ) { piece = attachmentMap_toBase( piece ); if ( array_contains( possible_attachments, piece ) ) { if ( player maps\mp\alien\_persistence::is_upgrade_enabled( "keep_attachments_upgrade" ) ) valid_attachments = array_add( valid_attachments, piece ); else if ( piece == "alienmuzzlebrake" ) valid_attachments = array_add( valid_attachments, piece ); } } if ( valid_attachments.size > 0 && valid_attachments.size < 5 ) //only allow 4 attachments { for ( i=0; i < valid_attachments.size; i++ ) { if ( i == 0 ) attachment1 = valid_attachments[i]; if ( i == 1 ) attachment2 = valid_attachments[i]; if ( i == 2 ) attachment3 = valid_attachments[i]; if ( i == 3 ) attachment4 = valid_attachments[i]; } } weaponname = strip_suffix( baseweapon, "_mp" ); base_scope_attachment = base_scope_weapon_attachment( weaponname ); if( isDefined( base_scope_attachment ) ) { switch( valid_attachments.size + 1 ) { case 1: attachment1 = base_scope_attachment; break; case 2: attachment2 = base_scope_attachment; break; case 3: attachment3 = base_scope_attachment; break; case 4: attachment4 = base_scope_attachment; break; } } newweapon = buildAlienWeaponName( weaponname, attachment1, attachment2, attachment3, attachment4 ); return newweapon; } base_scope_weapon_attachment( weaponname ) { switch( weaponname ) { case "iw6_arkalienvks": case "iw6_alienvks": return "alienvksscope"; case "iw6_arkalienusr": case "iw6_alienusr": return "usrvzscope"; case "iw6_arkaliendlc23": case "iw6_aliendlc23": return "dlcweap02scope"; case "iw6_alienl115a3": return "alienl115a3scope"; default: break; } } can_hypno( attacker, petTrapKill, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, timeOffset, inflictor ) { if ( isDefined( self.cannotHypno ) && self.cannotHypno ) return false; switch ( self.alien_type ) { case "goon": case "brute": case "spitter": case "locust": case "seeder": return true; case "elite": if ( attacker maps\mp\alien\_persistence::is_upgrade_enabled( "hypno_rhino_upgrade" ) || petTrapKill ) return true; default: return false; } } has_fragile_relic_and_is_sprinting() { if ( self maps\mp\alien\_prestige::prestige_getSlowHealthRegenScalar() != 1.0 && self IsSprinting() ) return true; else return false; } update_player_initial_spawn_info( coordinate, angles ) { /# AssertEx( isDefined( coordinate) && isDefined( angles ), "Both coordinate and angles need to be defined" ); #/ level.playerInitialSpawnOriginOverride = coordinate; level.playerInitialSpawnAnglesOverride = angles; } get_player_initial_spawn_origin() { return level.playerInitialSpawnOriginOverride; } get_player_initial_spawn_angles() { return level.playerInitialSpawnAnglesOverride; } has_pistols_only_relic_and_no_deployables() { if ( self maps\mp\alien\_prestige::prestige_getPistolsOnly() == 1 && self maps\mp\alien\_prestige::prestige_getNoDeployables() == 1 ) return true; else return false; } get_current_pistol() { primaries = self GetWeaponsListPrimaries(); foreach ( weapon in primaries ) { weap_class = getWeaponClass( weapon ); if ( weap_class == "weapon_pistol" ) { return weapon; } } } is_idle_state_locked() { return ( self.currentAnimState == "idle" && IsDefined( self.idle_state_locked ) && self.idle_state_locked ); } return_nerf_scaled_ammo( new_weapon_string ) { //checks the nerf for min_ammo and returns the amount nerf_min_ammo_scalar = self maps\mp\alien\_deployablebox_functions::check_for_nerf_min_ammo(); max_stock = WeaponMaxAmmo( new_weapon_string ); return int( max_stock * nerf_min_ammo_scalar ); } weapon_has_alien_attachment( weaponName, achievement_flag, eAttacker ) { if ( !IsDefined( weaponName ) || weaponName == "none" || WeaponInventoryType( weaponName ) != "primary" || weaponclass( weaponName ) == "item" || weaponclass( weaponName ) == "rocketlauncher" || weaponclass( weaponName ) == "none" ) { return false; } if ( is_true( achievement_flag ) && self is_holding_pistol( eAttacker ) ) return false; weaponAttachments = getWeaponAttachmentsBaseNames( weaponName ); foreach ( attachment in weaponAttachments ) { if ( attachment == "alienmuzzlebrake" || attachment == "alienmuzzlebrakesg" || attachment == "alienmuzzlebrakesn" ) return true; } return false; } is_holding_pistol( eAttacker ) { cur_weapon = eAttacker GetCurrentPrimaryWeapon(); if ( getWeaponClass( cur_weapon ) == "weapon_pistol" ) return true; else return false; } setup_class_nameplates() { perk = self maps\mp\alien\_persistence::get_selected_perk_0(); material = undefined; switch ( perk ) { case "perk_bullet_damage": material = "player_name_bg_weapon_specialist"; break; case "perk_health": material = "player_name_bg_tank"; break; case "perk_rigger": material = "player_name_bg_engineer"; break; case "perk_medic": material = "player_name_bg_medic"; break; case "perk_none": material = "player_name_bg_mortal"; break; } if( isDefined( material ) ) self SetNameplateMaterial( material, material ); }