#include common_scripts\utility; #include maps\mp\_utility; //////////////////////// // Gas Station //////////////////////// #using_animtree( "animated_props" ); gas_station() { gas_station_precache(); flag_init( "gas_station_exploded" ); flag_init( "breach_connect_nodes" ); wait 0.05; structs = getstructarray( "gas", "targetname" ); array_thread( structs, ::gas_station_init ); } gas_station_init() { target_ents = GetEntArray( self.target, "targetname" ); target_structs = getstructarray( self.target, "targetname" ); target_ents = array_combine( target_ents, target_structs ); nodes = self getLinknameNodes(); targets = array_combine( target_ents, nodes ); self.clip_up = []; self.clip_down = []; self.launch_ents = []; self.linked_ents = []; if ( GetDvar( "r_reflectionProbeGenerate" ) == "1" ) return; foreach ( target_ent in targets ) { if ( !IsDefined( target_ent.script_noteworthy ) ) continue; if ( !IsDefined( target_ent.script_parameters ) ) target_ent.script_parameters = "corner1_hit"; switch ( target_ent.script_noteworthy ) { case "clip_up": self.clip_up [ self.clip_up.size ] = target_ent; self.linked_ents[ self.linked_ents.size ] = target_ent; break; case "clip_down_traverse": target_ent.nodisconnect = true; //Fallthrough case "clip_down": self.clip_down[ self.clip_down.size ] = target_ent; target_ent SetAISightLineVisible( 0 ); target_ent ConnectPaths(); target_ent trigger_off(); break; case "link_to_launch": self thread gas_station_run_func_on_notify( target_ent.script_parameters, ::gas_station_launch_ent, target_ent ); self.launch_ents[ self.launch_ents.size ] = target_ent; //Fallthrough case "link_to": self.linked_ents[ self.linked_ents.size ] = target_ent; break; case "fx": self thread gas_station_run_func_on_notify( target_ent.script_parameters, ::gas_station_play_fx, target_ent ); break; case "animated": self.animated_model = target_ent; break; case "earthquake": self thread gas_station_run_func_on_notify( target_ent.script_parameters, ::gas_station_earthquake, target_ent ); break; case "sound": self thread gas_station_run_func_on_notify( target_ent.script_parameters, ::gas_station_playSound, target_ent ); break; case "connect_node": target_ent DisconnectNode(); self thread gas_station_run_func_on_notify( target_ent.script_parameters, ::gas_station_connect_node, target_ent ); break; case "disconnect_node": self thread gas_station_run_func_on_notify( target_ent.script_parameters, ::gas_station_disconnect_node, target_ent ); break; case "prone_kill_trigger": self.prone_kill_trigger = target_ent; target_ent trigger_off(); break; case "killcam": self.killCamEnt = Spawn( "script_model", target_ent.origin); self.killCamEnt SetModel( "tag_origin" ); break; default: break; } } if ( IsDefined( self.animated_model ) ) { foreach ( ent in self.linked_ents ) { ent LinkTo( self.animated_model, "j_awning_main" ); } } self thread care_package_watch(); gas_pumps = GetScriptableArray( "gaspump", "targetname" ); level.last_player_to_damage_gas_pump = undefined; level.player_who_caused_gas_station_explosion = undefined; foreach ( pump in gas_pumps ) { pump thread gas_pump_damage_monitor( self ); pump thread notify_explode( self, gas_pumps ); } self waittill( "gas_station_explode", exploded_pump ); flag_set( "gas_station_exploded" ); foreach ( player in level.players ) { player.present_for_gas_station_explosion = true; } foreach ( pump in gas_pumps ) { if ( pump == exploded_pump ) continue; if( IsDefined( level.player_who_caused_gas_station_explosion ) ) { pump.attacker = level.player_who_caused_gas_station_explosion; if( IsDefined( level.player_who_caused_gas_station_explosion.team ) ) { pump.team = level.player_who_caused_gas_station_explosion.team; } } if( IsDefined( pump.attacker ) ) { pump SetScriptableDamageOwner( pump.attacker ); } pump SetScriptablePartState( 0, "destroyed" ); } //Play fx on pump that exploded // PlayFX( level._effect[ "vfx_gas_station_explosion" ], exploded_pump.origin ); time = GetAnimLength( %mp_dart_gas_awning_fall ); self.gas_station_events = []; // note time self gas_station_add_event( "start" , 0.0 ); self gas_station_add_event( "beam_break" , 0.1 ); self gas_station_add_event( "corner1_hit", 1.9 ); self gas_station_add_event( "corner2_hit", 2.15 ); self gas_station_add_event( "sign_hit" , 2.5 ); self gas_station_add_event( "end" , time ); self thread gas_station_run_func_on_notify( "corner1_hit", ::gas_station_update_clip ); self thread gas_station_run_events(); if ( IsDefined( self.animated_model ) ) { self.animated_model ScriptModelPlayAnimDeltaMotion( "mp_dart_gas_awning_fall" ); exploder( 22 ); sound_origins = GetEntArray( "gas_pump_fire_sound_origin", "targetname" ); foreach ( sound_origin in sound_origins ) { sound_origin PlayLoopSound( "emt_dart_fire_small_ext_lp" ); } } } gas_station_run_func_on_notify( note, func, param1 ) { self waittill( note ); if ( IsDefined( param1 ) ) { self thread [[ func ]]( param1 ); } else { self thread [[ func ]](); } } gas_station_update_clip() { killcam_struct = getstruct( "gas_station_killcam", "targetname" ); foreach ( clip in self.clip_up ) { clip SetAISightLineVisible( 0 ); clip Delete(); } foreach ( clip in self.clip_down ) { clip SetAISightLineVisible( 1 ); clip.unresolved_collision_func = maps\mp\_movers::unresolved_collision_void; clip trigger_on(); if ( !IsDefined( clip.nodisconnect ) || !clip.nodisconnect ) clip DisconnectPaths(); foreach ( character in level.characters ) { if ( character IsTouching( clip ) && IsAlive( character ) ) { if ( IsDefined( self.attacker ) && IsDefined( self.attacker.team ) && ( self.attacker.team == character.team ) ) { character maps\mp\_movers::mover_suicide(); } else { clip.killCamEnt = self.killCamEnt; //HAVE to kill them, not just damage them if( IsDefined( level.player_who_caused_gas_station_explosion ) ) { character DoDamage( character.health + 10000, character.origin, level.player_who_caused_gas_station_explosion, clip, "MOD_EXPLOSIVE" ); } else { character DoDamage( character.health + 10000, character.origin, self.attacker, clip, "MOD_EXPLOSIVE" ); } } } } foreach ( vanguard in level.remote_uav ) { if ( vanguard IsTouching( clip ) ) { vanguard notify( "death" ); } } } if ( IsDefined( self.prone_kill_trigger ) ) { self.prone_kill_trigger trigger_on(); foreach ( character in level.characters ) { if ( character IsTouching( self.prone_kill_trigger ) && IsAlive( character ) ) { if ( IsDefined( self.attacker ) && IsDefined( self.attacker.team ) && ( self.attacker.team == character.team ) ) { character maps\mp\_movers::mover_suicide(); } else { self.prone_kill_trigger.killCamEnt = self.killCamEnt; if( IsDefined( level.player_who_caused_gas_station_explosion ) ) { character DoDamage( character.health + 20, character.origin, level.player_who_caused_gas_station_explosion, self.prone_kill_trigger, "MOD_EXPLOSIVE" ); } else { character DoDamage( character.health + 20, character.origin, self.attacker, self.prone_kill_trigger, "MOD_EXPLOSIVE" ); } } } } wait( 10 ); self.prone_kill_trigger Delete(); } } gas_station_launch_ent( ent ) { angles = self.animated_model GetTagAngles( "j_awning_main" ); launch_dir = AnglesToUp( angles ); ent Unlink(); org_offset = ( RandomFloatRange( -1, 1 ), RandomFloatRange( -1, 1 ), 0 ); //give object rotation ent PhysicsLaunchClient( ent.origin + org_offset, launch_dir * 15000 ); } gas_station_play_fx( ent ) { if ( !IsDefined( ent.script_fxid ) || !IsDefined( level._effect[ ent.script_fxid ] ) ) return; PlayFX( level._effect[ ent.script_fxid ], ent.origin, AnglesToForward( ent.angles ) ); } gas_station_earthquake( ent ) { Earthquake( 0.3, .5, ent.origin, 800 ); } gas_station_playSound( ent ) { if ( !IsDefined( ent.script_sound ) ) return; playSoundAtPos( ent.origin, ent.script_sound ); } gas_station_connect_node( node ) { node ConnectNode(); } gas_station_disconnect_node( node ) { node DisconnectNode(); } gas_station_run_events() { start_time = GetTime(); while ( 1 ) { foreach ( event in self.gas_station_events ) { if ( event.done ) continue; if ( ( GetTime() -start_time ) / 1000 >= event.time ) { self notify( event.note ); event.done = true; if ( event.note == "end" ) return; } } wait 0.05; } } gas_station_add_event( note, time ) { if ( !IsDefined( self.gas_station_events ) ) self.gas_station_events = []; s = SpawnStruct(); s.time = time; s.note = note; s.done = false; self.gas_station_events[ self.gas_station_events.size ] = s; } // gas_station_precache() { PrecacheMpAnim( "mp_dart_gas_awning_fall" ); } gas_pump_damage_monitor( gas_station ) { gas_station endon( "gas_station_explode" ); self.killCamEnt = gas_station.killCamEnt; while( 1 ) { self waittill( "damage", damage, attacker, direction_vec, point, meansOfDeath, modelName, tagName, partName, iDFlags, weapon ); if( IsPlayer( attacker ) || IsAgent( attacker ) ) { if( IsAgent( attacker ) && IsDefined( attacker.owner ) ) { attacker = attacker.owner; } level.last_player_to_damage_gas_pump = attacker; self SetScriptableDamageOwner( attacker ); } } } notify_explode( gas_station, gas_pumps ) { self waittill( "death", attacker, mod, weapon ); if( !IsDefined( level.player_who_caused_gas_station_explosion ) ) { if( IsPlayer( attacker ) || IsAgent( attacker ) ) { if( IsAgent( attacker ) && IsDefined( attacker.owner ) ) { attacker = attacker.owner; } level.player_who_caused_gas_station_explosion = attacker; } else if( IsDefined( level.last_player_to_damage_gas_pump ) ) { level.player_who_caused_gas_station_explosion = level.last_player_to_damage_gas_pump; } self SetScriptableDamageOwner( level.player_who_caused_gas_station_explosion ); } self.attacker = level.player_who_caused_gas_station_explosion; gas_station.attacker = level.player_who_caused_gas_station_explosion; if( IsDefined( level.player_who_caused_gas_station_explosion.team ) ) { self.team = level.player_who_caused_gas_station_explosion.team; gas_station.team = level.player_who_caused_gas_station_explosion.team; } gas_station notify( "gas_station_explode", self ); } ///////////////////////////////////////////// // Broken Walls //////////////////////////////////////////// broken_walls() { walls = getstructarray( "broken_wall", "targetname" ); array_thread( walls, ::broken_wall_init ); } broken_wall_init( requires_explosive ) { self.trigger_show = []; //May not be a trigger, just needs to be hidden like a trigger (origin +/- 10000) self.delete_ents = []; self.show_ents = []; self.trigger_damage = []; targets = GetEntArray( self.target, "targetname" ); foreach ( target in targets ) { if ( !IsDefined( target.script_noteworthy ) ) { target.script_noteworthy = target.classname; } switch( target.script_noteworthy ) { case "delete": self.delete_ents[ self.delete_ents.size ] = target; break; case "trigger_damage": self.trigger_damage[ self.trigger_damage.size ] = target; self thread broken_wall_damage_watch( target ); break; case "show": target Hide(); self.show_ents[ self.show_ents.size ] = target; break; case "trigger_show": target trigger_off(); self.trigger_show[ self.trigger_show.size ] = target; break; case "trigger_use_touch": target UseTriggerRequireLookAt(); target.script_noteworthy = "trigger_use"; // <- purely for consistency with the breach stuff break; default: break; } } } broken_wall_damage_watch( trigger, requires_explosive ) { self endon( "break_wall" ); trigger waittill( "trigger" ); array_thread( self.show_ents, ::broken_wall_show ); array_call( self.trigger_damage, ::Delete ); // entities process array_thread( self.delete_ents , ::broken_wall_delete ); array_thread( self.trigger_show, ::trigger_on ); self notify( "break_wall" ); } broken_wall_delete() { if ( IsDefined( self.script_index ) ) { exploder( self.script_index ); } self SetAISightLineVisible( 0 ); self Delete(); } broken_wall_show() { self SetAISightLineVisible( 1 ); self Show(); } /////////////// // Breach /////////////// breach() { if ( GetDvar( "r_reflectionProbeGenerate" ) == "1" ) return; maps\mp\_breach::breach_precache(); dart_breach_precache(); dart_breach_anims_init(); waitframe(); breaches = getstructarray( "breach", "targetname" ); proxy = getstructarray( "breach_proxy", "targetname" ); foreach ( p in proxy ) { if ( !IsDefined( p.target ) ) continue; breach = getstruct( p.target, "targetname" ); if ( !IsDefined( breach ) ) continue; // We need to make sure the breach already happened for this game mode // Since we can't edit the map/prefabs, we will have to add this in through script breach = setExtraBreachExceptions( breach ); breaches[ breaches.size ] = breach; } // entities process array_thread( breaches , ::breach_init ); array_thread( breaches , maps\mp\_breach::breach_init ); } setExtraBreachExceptions( breach ) { if ( !IsDefined( breach.script_noteworthy ) ) return breach; // Append an exception to the script_noteworthy that contains existing ones // The exceptions in the script_noteworthy do not need to be in any specific order, so we can just add it to the end if ( level.gametype == "siege" ) breach.script_noteworthy = breach.script_noteworthy + "," + "not_in_siege"; return breach; } dart_breach_precache() { PrecacheMpAnim( "mp_dart_container_breach_side1" ); PrecacheMpAnim( "mp_dart_container_breach_side2" ); PrecacheMpAnim( "mp_dart_container_breach_top" ); PrecacheMpAnim( "mp_dart_container_idle_side1" ); PrecacheMpAnim( "mp_dart_container_idle_side2" ); PrecacheMpAnim( "mp_dart_container_idle_top" ); } dart_breach_anims_init() { level.breach_anims = []; level.breach_anims[ "mp_dart_container_breach_side1" ] = "mp_dart_container_breach_side1"; level.breach_anims[ "mp_dart_container_breach_side1_idle" ] = "mp_dart_container_idle_side1"; level.breach_anims[ "mp_dart_container_breach_side2" ] = "mp_dart_container_breach_side2"; level.breach_anims[ "mp_dart_container_breach_side2_idle" ] = "mp_dart_container_idle_side2"; level.breach_anims[ "mp_dart_container_breach_top" ] = "mp_dart_container_breach_top"; level.breach_anims[ "mp_dart_container_breach_top_idle" ] = "mp_dart_container_idle_top"; } breach_init() { self.animated_doors = []; self.care_packages = []; self.delete_ents = []; self.doors = []; self.notsolid_ents = []; self.solid_ents = []; target_ents = GetEntArray( self.target, "targetname" ); target_structs = getstructarray( self.target, "targetname" ); targets = array_combine( target_structs, target_ents ); foreach ( target in targets ) { if ( IsDefined(target.classname) && target.classname == "trigger_use_touch" ) add_to_bot_use_targets( target, 1.5 ); if ( !IsDefined( target.script_noteworthy ) ) continue; switch( target.script_noteworthy ) { case "door": self.doors[ self.doors.size ] = target; self breach_door_init( target ); break; case "triggers_with": if ( IsDefined( target.target ) ) { other_breach = getstruct( target.target, "targetname" ); if ( IsDefined( other_breach ) ) self thread breach_other_watch( other_breach ); } break; case "care_package": self.care_packages[ self.care_packages.size ] = target; break; case "animated_door": door = GetEnt( target.target, "targetname" ); self.animated_doors[ self.animated_doors.size ] = door; self breach_animated_door_init( door ); break; default: break; } } foreach ( door in self.doors ) { self thread breach_close_door( door ); } self thread breach_open_watch(); } add_care_package( origin, angles, owner, owner_team, crateType, dropType ) { if ( !IsDefined( dropType ) ) { dropType = "airdrop_assault"; if ( IsDefined( crateType ) ) { possible_dropTypes = [ "airdrop_assault", "airdrop_support" ]; foreach ( possible_dropType in possible_dropTypes ) { if ( is_valid_crateType( possible_dropType, crateType ) ) { dropType = possible_dropType; break; } } } } if ( !is_valid_dropType( dropType ) ) return; if ( !IsDefined( crateType ) ) { crateType = random( GetArrayKeys( level.crateTypes[ dropType ] ) ); } if ( !is_valid_crateType( dropType, crateType ) ) return; if ( !IsDefined( angles ) ) angles = ( 0, 0, 0 ); dropCrate = Spawn( "script_model", origin ); dropCrate SetModel( maps\mp\killstreaks\_airdrop::get_friendly_crate_model() ); dropCrate.angles = angles; dropCrate.crateType = crateType; dropCrate.owner = owner; if ( IsDefined( owner_team ) ) { dropCrate.team = owner_team; } else { dropCrate.team = owner.team; } dropCrate.targetname = "care_package"; dropCrate.droppingToGround = false; dropCrate.id = "care_package"; dropCrate CloneBrushmodelToScriptmodel( level.airDropCrateCollision ); dropCrate thread entity_path_disconnect_thread( 1.0 ); dropCrate PhysicsLaunchServer( ( 0, 0, 0 ), ( 0, 0, 1 ) ); dropCrate thread [[ level.crateTypes[ dropType ][ crateType ].func ]]( dropType ); if ( IsBot( owner ) ) { wait( 0.1 ); owner notify( "new_crate_to_take" ); } } is_valid_dropType( dropType ) { if ( !IsDefined( dropType ) ) return false; foreach ( key, value in level.crateTypes ) { if ( key == dropType ) return true; } return false; } is_valid_crateType( dropType, crateType ) { if ( !is_valid_dropType( dropType ) ) return false; if ( !IsDefined( crateType ) ) return false; foreach ( key, value in level.crateTypes[ dropType ] ) { if ( key == crateType ) return true; } return false; } breach_animated_door_init( door ) { breach_struct = self; AssertEx( IsDefined( door.script_noteworthy ), "animated_door in breach without animation defined in door.script_noteworthy" ); if ( IsDefined( level.breach_anims[ door.script_noteworthy + "_idle" ] ) ) { door ScriptModelPlayAnimDeltaMotion( level.breach_anims[ door.script_noteworthy + "_idle" ] ); } door thread clear_attached_items( breach_struct ); } clear_attached_items( breach_struct ) { breach_struct waittill( "breach_activated" ); self maps\mp\_movers::notify_moving_platform_invalid(); } breach_door_init( door ) { target_ents = GetEntArray( door.target, "targetname" ); target_structs = getstructarray( door.target, "targetname" ); targets = array_combine( target_structs, target_ents ); door_parts = []; pivot = undefined; foreach ( target in targets ) { if ( !IsDefined( target.script_noteworthy ) ) continue; switch( target.script_noteworthy ) { case "open": door.open_pos = target; break; case "closed": door.closed_pos = target; break; case "door_part": door_parts[ door_parts.size ] = target; break; case "pivot": pivot = target; break; default: break; } } if ( !IsDefined( door.open_pos ) || !IsDefined( door.closed_pos ) || !IsDefined( pivot ) || door_parts.size == 0 ) return false; //ERROR door.closed_pos.move_angles = get_rotate_angle( door.open_pos.angles, door.closed_pos.angles, pivot.angles ); door.open_pos.move_angles = -1 * door.closed_pos.move_angles; link_ent = Spawn( "script_model", pivot.origin ); link_ent SetModel( "tag_origin" ); link_ent.angles = pivot.angles; foreach ( ent in door_parts ) { ent LinkTo( link_ent ); } door.link_ent = link_ent; return true; //Great success } breach_other_watch( other ) { other waittill( "breach_activated", player, no_fx, breaching_team ); self notify( "breach_activated", player, no_fx, breaching_team ); } breach_open_watch() { self waittill( "breach_activated", player, no_fx, breaching_team ); target_ents = GetEntArray( self.target, "targetname" ); foreach ( target_ent in target_ents ) { if ( IsDefined(target_ent.classname) && target_ent.classname == "trigger_use_touch" ) remove_from_bot_use_targets( target_ent ); } if ( IsDefined( player ) && !isMLGMatch() ) { foreach ( package in self.care_packages ) { crateType = random( [ "uplink_support", "deployable_vest", "deployable_ammo", "ball_drone_radar", "aa_launcher", "jammer", "ims" ] ); add_care_package( package.origin, package.angles, player, breaching_team, crateType ); } } door_time = 0.2; foreach ( door in self.doors ) { self thread breach_open_door( door, door_time ); } foreach ( animated_door in self.animated_doors ) { animated_door ScriptModelPlayAnimDeltaMotion( level.breach_anims[ animated_door.script_noteworthy ] ); switch( animated_door.script_noteworthy ) { case "mp_dart_container_breach_side1": playSoundAtPos( animated_door.origin, "scn_dart_trailer_breach_side" ); break; case "mp_dart_container_breach_side2": playSoundAtPos( animated_door.origin, "scn_dart_trailer_breach_side" ); break; case "mp_dart_container_breach_top": playSoundAtPos( animated_door.origin, "scn_dart_trailer_breach_top" ); break; default: break; } } wait door_time; // entities process array_call( self.notsolid_ents, ::NotSolid ); array_call( self.delete_ents , ::Delete ); array_call( self.solid_ents, ::Solid ); foreach ( ent in self.solid_ents ) { ent Solid(); if ( IsDefined ( level.players ) ) { foreach ( player in level.players ) { if ( player IsTouching( ent ) ) { self thread breach_kill_player( player ); } } } } flag_set( "breach_connect_nodes" ); } breach_kill_player( player ) { RadiusDamage( player.origin, 8, 1000, 1000, self.owner, "MOD_CRUSH" ); } breach_open_door( door, time ) { breach_move_door( door, door.open_pos, time ); } breach_close_door( door, time ) { breach_move_door( door, door.closed_pos, time ); } breach_move_door( door, pos, time ) { angles = pos.angles; origin = pos.origin; if ( IsDefined( time ) && time > 0 ) { if ( IsDefined( angles ) && angles != door.link_ent.angles ) door.link_ent RotateBy( pos.move_angles, time, time ); if ( IsDefined( origin ) && origin != door.link_ent.origin ) door.link_ent MoveTo( origin, time ); } else { if ( IsDefined( angles ) ) door.link_ent.angles = angles; if ( IsDefined( origin ) ) door.link_ent.origin = origin; } } //////////// // Util /////////// is_explosive( cause ) { if ( !IsDefined( cause ) ) return false; cause = ToLower( cause ); switch( cause ) { case "mod_grenade_splash": case "mod_projectile_splash": case "mod_explosive": case "splash": return true; default: return false; } return false; } normalize_angles_180( angles ) { return ( AngleClamp180( angles[ 0 ] ), AngleClamp180( angles[ 1 ] ), AngleClamp180( angles[ 2 ] ) ); } get_rotate_angle( start, end, through ) { delta = end - start; delta = normalize_angles_180( delta ); if ( IsDefined( through ) ) { dir = through - start; dir = normalize_angles_180( dir ); for ( i = 0;i < 3;i++ ) { //check if dir and delta have the same sign //if they dont the shortest path doesn't go through if ( dir[ i ] * delta[ i ] < 0 ) { change = 360; if ( dir[ i ] < 0 ) change = -360; delta = ( delta[ 0 ] +( change * ( i == 0 ) ), delta[ 1 ] +( change * ( i == 1 ) ), delta[ 2 ] +( change * ( i == 2 ) ) ); } } } return delta; } ////////////////////////// // Ceiling Rubble ///////////////////////// ceiling_rubble() { level thread ceiling_rubble_onPlayerConnect(); wait 0.05; if ( !IsDefined( level.fx_tag_origin ) ) level.fx_tag_origin = spawn_tag_origin(); rubbles = []; //Validate structs fxvolumes = GetEntArray( "fx_building_impact", "targetname" ); //foreach(volume in volumes) //{ // if(IsDefined(rubble.script_index)) // { // rubble.radius_squared = rubble.radius*rubble.radius; // rubbles[rubbles.size] = rubble; // } //} level thread do_rubble( fxvolumes ); } wait_and_trigger_fx() { wait( RandomFloatRange( 0.0, 0.4 ) ); TriggerFX( self ); } do_rubble( fxvolumes ) { while ( 1 ) { level waittill( "do_rubble", position ); //tag_origin = spawn_tag_origin(); foreach ( volume in fxvolumes ) { if ( IsDefined( volume.script_index ) ) { level.fx_tag_origin.origin = position; if ( level.fx_tag_origin IsTouching( volume ) ) { if ( IsDefined( volume.script_index ) ) { if ( !IsDefined( volume.playing_effect ) ) volume.playing_effect = false; if ( volume.playing_effect == false ) { volume.playing_effect = true; exploder(volume.script_index); // //foreach ( effect in level.scripted_exploders[ volume.script_index ] ) //{ // effect thread wait_and_trigger_fx(); //} volume thread clear_volume_flag(); } } } } } //tag_origin delete(); } } clear_volume_flag() { wait( 1.5 ); self.playing_effect = false; } ceiling_rubble_onPlayerConnect() { while ( 1 ) { level waittill( "connected", player ); player thread ceiling_rubble_watchUsage( "missile_fire" ); player thread ceiling_rubble_watchUsage( "grenade_fire" ); } } ceiling_rubble_watchUsage( note ) { self endon( "disconnect" ); while ( 1 ) { self waittill( note, missile, weaponName ); if ( IsDefined( weaponName ) ) { switch ( weaponName ) { case "ac130_25mm_mp": case "flash_grenade_mp": case "concussion_grenade_mp": case "smoke_grenade_mp": case "smoke_grenadejugg_mp": continue; default: break; } } missile thread ceiling_rubble_missile_explode_watch(); } } endOnDeath() { self waittill( "death" ); waittillframeend; self notify ( "end_of_frame_death" ); } ceiling_rubble_missile_explode_watch() { self thread endOnDeath(); self endon( "end_of_frame_death" ); self waittill( "explode", position ); level notify( "do_rubble", position ); } search_bot() { while ( !IsDefined( level.players ) || level.players.size == 0 ) wait 0.05; allnodes = GetAllNodes(); current_node = random( allnodes ); player = level.players[ 0 ]; search_bot = Spawn( "script_model", current_node.origin ); search_bot SetModel( "com_deploy_ballistic_vest_friend_world" ); while ( 1 ) { path_nodes = GetNodesOnPath( current_node.origin, player.origin ); if ( !IsDefined( path_nodes ) || path_nodes.size == 0 ) { wait 0.1; continue; } goal_node = path_nodes[ 0 ]; if ( Distance( search_bot.origin, path_nodes[ 0 ].origin ) < 6 ) { if ( path_nodes.size <= 1 ) { wait 0.1; continue; } goal_node = path_nodes[ 1 ]; } dir = goal_node.origin - current_node.origin; dir_angles = VectorToAngles( dir ); speed = 180; dist = Length( dir ); time = dist / speed; if ( time <= 0 ) { wait 0.1; continue; } search_bot RotateTo( dir_angles, min( 0.5, time ) ); search_bot MoveTo( goal_node.origin, time ); search_bot waittill( "movedone" ); current_node = goal_node; } } player_connect_watch() { while ( 1 ) { level waittill( "connected", player ); if ( flag( "gas_station_exploded" ) ) { hide_gas_station_physics_pieces(); } } } hide_gas_station_physics_pieces() { structs = getstructarray( "gas", "targetname" ); foreach ( struct in structs ) { foreach ( ent in struct.launch_ents ) { ent Hide(); foreach ( player in level.players ) { if ( IsDefined( player.present_for_gas_station_explosion ) && ( player.present_for_gas_station_explosion == true ) ) { ent ShowToPlayer( player ); } } } } } care_package_watch() { self endon( "end" ); watch_volume = GetEnt( "care_package_volume", "targetname" ); flag_wait( "gas_station_exploded" ); care_packages = level.carePackages; if ( IsDefined( care_packages ) ) { foreach ( package in care_packages ) { if( IsDefined(package.inUse) && package.inUse ) continue; if ( ( IsDefined(package.droppingtoground) && !package.droppingtoground ) && ( IsDefined( package.friendlyModel) && package.friendlyModel IsTouching( watch_volume ) ) ) { owner = package.owner; dropType = package.dropType; crateType = package.crateType; origin = package.origin; package maps\mp\killstreaks\_airdrop::deleteCrate(); newCrate = owner maps\mp\killstreaks\_airdrop::createAirDropCrate( owner, dropType, crateType, origin + ( 0, 0, 250 ) , origin + ( 0, 0, 250 ) ); newCrate.droppingtoground = true; newCrate thread [[ level.crateTypes[ newCrate.dropType ][ newCrate.crateType ].func ]]( newCrate.dropType ); waitframe(); newCrate CloneBrushmodelToScriptmodel( level.airDropCrateCollision ); newCrate thread entity_path_disconnect_thread( 1.0 ); newCrate PhysicsLaunchServer( newCrate.origin, ( 0, -20000, 20000 ) ); if ( IsBot( newCrate.owner ) ) { wait( 0.1 ); newCrate.owner notify( "new_crate_to_take" ); } } } } } deleteOnOwnerDeath( owner ) { wait ( 0.25 ); self LinkTo( owner, "tag_origin", ( 0, 0, 0 ), ( 0, 0, 0 ) ); owner waittill ( "death" ); self Delete(); } container_pathnode_watch() { node_array = GetNodeArray( "disconnect_until_container_opens", "targetname" ); foreach( pathnode in node_array ) { pathnode DisconnectNode(); } flag_wait( "breach_connect_nodes" ); foreach( pathnode in node_array ) { pathnode ConnectNode(); } }