#include maps\_utility; #include maps\_vehicle; #include maps\_vehicle_spline; #include maps\_anim; #include maps\_hud_util; #include common_scripts\utility; become_soap() { AssertEx( !isdefined( level.soap ), "Too much soap!" ); level.soap = self; self.animname = "soap"; //self thread magic_bullet_shield(); self make_hero(); } become_price() { level.price = self; self.health = 5000; self.animname = "price"; self magic_bullet_shield(); self make_hero(); self.attackeraccuracy = 0; self.IgnoreRandomBulletDamage = true; //self forceUseWeapon( "ak47", "primary" ); self gun_remove(); //self Attach( "gulag_price_ak47", "tag_weapon_chest" ); /* self waittill_any_timeout( 5, "death" ); if ( !isalive( self ) ) { // the pow was killed SetDvar( "ui_deadquote", "@GULAG_PRICE_KILLED" ); //maps\_utility::missionFailedWrapper(); return; } */ self notify( "saved" ); self waittill( "change_to_regular_weapon" ); //self detach( "gulag_price_ak47", "tag_weapon_chest" ); self forceUseWeapon( "ak47", "primary" ); //self magic_bullet_shield(); } become_redshirt() { self.animname = "redshirt"; level.redshirt = self; self magic_bullet_shield(); self make_hero(); } moderate_ai_moveplaybackrate() { level endon( "cafeteria_sequence_begins" ); ai = getaiarray( "allies" ); min_playback = 1.00; min_dist = 50; max_playback = 1.00; max_dist = 200; // how much can the player sprint? min_sprint = 1; max_sprint = 1.5; min_sprint_dist = 100; max_sprint_dist = 200; range_dist = max_dist - min_dist; range_playback = max_playback - min_playback; range_sprint = max_sprint - min_sprint; range_sprint_dist = max_sprint_dist - min_sprint_dist; if ( flag( "match_up_for_final_room" ) ) return; level endon( "match_up_for_final_room" ); max_speed_dif = 0.45; // the maximum difference in speed adjustment between the lead and last ai max_dist_dif = 200; // the distance at which to differ by max speed dif // the distance mods make the AI get a speed boost/slowdown to get them to the right place distance_mods = []; distance_mods[ "soap" ] = 20; distance_mods[ "redshirt" ] = -40; distance_mods[ "price" ] = -10; for ( ;; ) { ai = []; ai[ "soap" ] = level.soap; ai[ "price" ] = level.price; ai[ "redshirt" ] = level.redshirt; if ( flag( "exit_collapses" ) ) { distance_mods[ "soap" ] = 75; distance_mods[ "redshirt" ] = -25; distance_mods[ "price" ] = -40; } center = (0,0,0); ai_dist = []; foreach ( index, guy in ai ) { center += guy.origin; // for adjusting the speed of the individual AI dist = distance( guy.origin, level.friendly_endpoint ); ai_dist[ index ] = dist + distance_mods[ index ]; } center /= ai.size; // ========================================================================================== // for adjusting the speed of the individual AI // ========================================================================================== lowest = 99999999; foreach ( dist in ai_dist ) { if ( dist < lowest ) lowest = dist; } ai_speedmod = []; foreach ( index, dist in ai_dist ) { ai_dist[ index ] -= lowest; } highest = 0; foreach ( dist in ai_dist ) { if ( dist > highest ) highest = dist; } // 0.4 // 200 ourdist current_speed_dif = highest * max_speed_dif / max_dist_dif; current_speed_dif *= 0.5; // lower the speed dif a bit //current_speed_dif *= 0.5; // you actually want it to be half cause we adjust it by the range from -1 to 1 if ( current_speed_dif > max_speed_dif ) current_speed_dif = max_speed_dif; // 0 of 200 // - half the range = // -100 // half_range = highest * 0.5; ai_speedmod = []; foreach ( index, dist in ai_dist ) { dist -= half_range; dist /= abs( half_range ); ai_speedmod[ index ] = dist * current_speed_dif; } // ========================================================================================== dist1 = distance( center, level.friendly_endpoint ); dist2 = distance( level.player.origin, level.friendly_endpoint ); dist = dist2 - dist1; level notify( "player_dist_from_squad", dist ); // if ( dist > 1000 ) // thread player_dies_to_cavein( 2 ); old_dist = dist; dist -= min_dist; scale = dist / range_dist; if ( scale < 0 ) scale = 0; else if ( scale > 1 ) scale = 1; scale = 1 - scale; ai_playback = min_playback + range_playback * scale; //println( "dist " + old_dist + " ai_playback " + ai_playback ); dist = old_dist - min_sprint_dist; scale = dist / range_sprint_dist; if ( scale < 0 ) scale = 0; else if ( scale > 1 ) scale = 1; sprint_speed = min_sprint + range_sprint * scale; if ( !flag( "exit_collapses" ) ) setsaveddvar( "player_sprintSpeedScale", sprint_speed ); if ( flag( "modify_ai_moveplaybackrate" ) ) { foreach ( index, guy in ai ) { guy.moveplaybackrate = ai_playback + ai_speedmod[ index ]; if ( guy.moveplaybackrate > 1.15 ) guy.moveplaybackrate = 1.15; //Print3d( guy.origin + (0,0,64), ai_speedmod[ index ], (1,1,0), 1, 1, 1 ); } } /* foreach ( guy in ai ) { guy.moveplaybackrate = ai_playback; } */ /* foreach ( guy in ai ) { if ( guy == level.price && flag( "price_speed_boost" ) ) guy.moveplaybackrate += 0.15; } */ wait( 0.05 ); } } //println( "dist " + int( dist ) + " playback " + int ( ai_playback * 100 ) ); // myrange //range_dist range_playback adjust_be_behind( guy ) { desired_dist = level.cafe_run_distances[ self.animname ][ guy.animname ]; dist = distance( self.origin, guy.origin ); speed_change = undefined; dot = get_dot( self.origin, self.angles, guy.origin ); if ( dot < 0.8 ) { // he should be in front of me, slow down speed_change = -0.15; } else { dist_dif = desired_dist - dist; dist_offset = 50; speed_offset = 0.15; /* dist_dif dist_offset speed_offset 35 50 0.15 */ speed_change = dist_dif * speed_offset / dist_offset; if ( speed_change > speed_offset ) { speed_change = speed_offset; } else if ( speed_change < speed_offset * -1 ) { speed_change = speed_offset * -1; } } self.moveplaybackrate = 1 + speed_change; num1 = self.moveplaybackrate; num2 = speed_change; num1 = int( num1 * 100 ) * 0.01; num2 = int( num2 * 100 ) * 0.01; Print3d( self geteye(), num1 + " (" + num2 + ")", (1,1,1), 1, 0.7 ); } adjust_be_ahead_of( guy ) { desired_dist = level.cafe_run_distances[ self.animname ][ guy.animname ]; dist = distance( self.origin, guy.origin ); dot = get_dot( self.origin, self.angles, guy.origin ); if ( dot > 0 ) { // if he's ahead of us then we're negative distance relative to where we want to be dist *= -1; } dist_dif = desired_dist - dist; dist_offset = 50; speed_offset = 0.15; /* dist_dif dist_offset speed_offset 35 50 0.15 */ speed_change = dist_dif * speed_offset / dist_offset; if ( speed_change > speed_offset ) { speed_change = speed_offset; } else if ( speed_change < speed_offset * -1 ) { speed_change = speed_offset * -1; } self.moveplaybackrate = 1 + speed_change; num1 = self.moveplaybackrate; num2 = speed_change; num1 = int( num1 * 100 ) * 0.01; num2 = int( num2 * 100 ) * 0.01; Print3d( self geteye(), num1 + " (" + num2 + ")", (1,1,1), 1, 1 ); } my_color_trail( color ) { self endon( "death" ); org = self.origin; for ( ;; ) { Line( self.origin, org, color, 1, 1, 50 ); org = self.origin; wait( 0.05 ); } } minor_earthquakes() { level endon( "stop_minor_earthquakes" ); min_eq = 0.15; max_eq = 0.25; dif_eq = max_eq - min_eq; min_phys = 0.20; max_phys = 0.30; dif_phys = max_phys - min_phys; first = true; for ( ;; ) { scale = randomfloat( 1 ); if ( first ) { first = false; scale = 1; } eq = min_eq + scale * dif_eq; phys = min_phys + scale * dif_phys; if ( randomint( 100 ) < 35 ) player_gets_hit_by_rock(); quake( eq, 3 + scale * 2, level.player.origin + randomvector( 1000 ), 5000 ); angles = level.player getplayerangles(); forward = anglestoforward( angles ); org = level.player.origin + forward * 180; org = set_z( org, level.player.origin[2] + 64 ); //PhysicsJitter( org, 350, 250, 0.05, 0.2 ); vec = randomvector( phys ); if ( vec[2] < 0 ) { vec = set_z( vec, vec[2] * -1 ); } PhysicsJolt( org, 350, 250, vec ); //PhysicsExplosionSphere( org, 350, 250, 0.5 ); // Print3d( org, ".", (1,0,0), 1, 1, 5 ); wait( RandomFloatRange( 1, 5 ) ); } } gulag_player_loadout() { level.player takeallweapons(); //level.player GiveWeapon( "m14_scoped" ); level.player GiveWeapon( "m4m203_reflex_arctic" ); //level.player GiveWeapon( "fraggrenade" ); //level.player GiveWeapon( "flash_grenade" ); //level.player SetOffhandSecondaryClass( "flash" ); level.player SetViewModel( "viewhands_udt" ); level.player SwitchToWeapon( "m4m203_reflex_arctic" ); //level.player GiveWeapon( "claymore" ); //level.player SetActionSlot( 4, "weapon", "claymore" ); //level.player GiveMaxAmmo( "claymore" ); level.player SwitchToWeapon( "m14_scoped_arctic" ); } stumble_trigger_think() { level endon( "skip_stumble_trigger_think" ); wait( 3 ); // for start points // the roller does the actual rotation eq_view_roller = getent( "eq_view_roller", "targetname" ); player_ent = spawn_tag_origin(); // move the roller to the ent that the player refers to for ground eq_view_roller.origin = player_ent.origin; player_ent linkto( eq_view_roller ); level.player PlayerSetGroundReferenceEnt( player_ent ); ent = spawn_tag_origin(); if ( !flag( "exit_collapses" ) ) { self waittill( "trigger", other ); thread ceiling_collapse_begins(); ducks = []; ducks[ ducks.size ] = "run_duck"; ducks[ ducks.size ] = "run_flinch"; ducks[ ducks.size ] = "run_stumble"; ai = getaiarray( "allies" ); assertex( ai.size == 3, "Huh, wasnt 3!" ); foreach ( index, guy in ai ) { guy thread stumble_anim( ducks[ index ] ); } quake( 0.25, 4, self.origin, 5000 ); vec = randomvector( 0.6 ); jolt_origin = level.player.origin; PhysicsJolt( jolt_origin, 350, 250, vec ); /* angles = level.player getplayerangles(); angles = ( 0, angles[ 1 ], 0 ); ent.angles = angles; */ start_angles = eq_view_roller.angles; // spawn a reference ent to do the rotation on, because this rotation is at server framerate ent.angles = eq_view_roller.angles; ent addpitch( 30 ); ent addroll( 5 ); eq_view_roller RotateTo( ent.angles, 1, 0.5, 0.5 ); wait( 1 ); ent addpitch( -35 ); ent addroll( -15 ); eq_view_roller RotateTo( ent.angles, 1, 0.5, 0.5 ); wait( 1 ); eq_view_roller RotateTo( start_angles, 1, 0.5, 0.5 ); flag_wait( "exit_collapses" ); flag_set( "controlled_player_rumble" ); level.player PlayRumbleOnEntity( "heavy_3s" ); delaythread( 3.0, ::flag_clear, "controlled_player_rumble" ); thread stumble_baddie(); } if ( !flag( "big_earthquake_hits" ) ) { flag_wait( "big_earthquake_hits" ); // this is actually the second big earthquake trigger = getentwithflag( "big_earthquake_hits" ); eq_view_roller = getent( trigger.target, "targetname" ); jolt_origin = eq_view_roller.origin; start_angles = eq_view_roller.angles; // move the roller to the ent that the player refers to for ground eq_view_roller.origin = player_ent.origin; player_ent linkto( eq_view_roller ); quake( 0.25, 4, self.origin, 5000 ); vec = randomvector( 0.6 ); PhysicsJolt( jolt_origin, 350, 250, vec ); } flag_wait( "player_falls_down" ); // during cafeteria ending quake( 0.35, 4, self.origin, 5000 ); vec = randomvector( 0.6 ); jolt_origin = level.player.origin; PhysicsJolt( jolt_origin, 350, 250, vec ); flag_set( "controlled_player_rumble" ); level.player PlayRumbleOnEntity( "light_3s" ); level.player delaycall( 1.5, ::PlayRumbleOnEntity, "heavy_2s" ); delaythread( 3.5, ::flag_clear, "controlled_player_rumble" ); start_angles = eq_view_roller.angles; // move the roller to the ent that the player refers to for ground eq_view_roller.origin = player_ent.origin; // angle the ents with the player so its relative to the player's current view player_angles = level.player getplayerAngles(); eq_view_roller.angles = ( 0, player_angles[ 1 ], 0 ); ent.angles = eq_view_roller.angles; player_ent linkto( eq_view_roller ); forward = anglestoforward( eq_view_roller.angles ); right = anglestoright( eq_view_roller.angles ); above_player = level.player.origin + (0,0,100 ) + forward * 50; level.player enabledeathshield( true ); level.player setmovespeedscale( 0.25 ); level.player DoDamage( ( level.player.health - 5 ) / level.player.damageMultiplier, above_player ); level.player thread player_blur_manager(); level.player disableweapons(); time_until_buried = 1.9; // set up the mix track we're going to blend to thread maps\_ambient::use_eq_settings( "gulag_cavein", level.eq_mix_track ); level.player SetEqLerp( 1, level.eq_main_track ); // blend out the ambient and blend in to the mix track noself_delaycall( time_until_buried, ::AmbientStop, 2 ); delaythread( time_until_buried, maps\_ambient::blend_to_eq_track, level.eq_mix_track, 2 ); /* for ( i = 0; i < 3; i++ ) { ent addyaw( 250 ); ent addpitch( 18 ); ent addroll( 18 ); // player gets knocked sideways timer = 0.5; eq_view_roller RotateTo( ent.angles, timer, 0, 0 ); wait( timer ); } */ // Line( fx_org, fx_org + (0,0,-32), (1,0,0), 1, 0, 500 ); // Line( fx_org, level.player.origin, (1,0,1), 1, 0, 500 ); /* level.player delaycall( 0.05, ::setstance, "prone" ); level.player delaycall( 0.5, ::allowcrouch, false ); level.player delaycall( 0.5, ::allowstand, false ); level.player delaycall( 0.5, ::ShellShock, "gulag_attack", 5, false ); */ ent addyaw( 20 ); ent addpitch( 35 ); ent addroll( 25 ); // player gets knocked sideways timer = 0.2; eq_view_roller RotateTo( ent.angles, timer, timer * 0.5, timer * 0.5 ); wait( timer ); thread fx_fall_around_player( eq_view_roller.angles ); // Line( fx_org, fx_org + (0,0,-32), (1,0,0), 1, 0, 500 ); // Line( fx_org, level.player.origin, (1,0,1), 1, 0, 500 ); wait( 0.75 ); // player wobbles left timer = 0.5; // ent addyaw( 20 ); ent addpitch( -35 ); ent addroll( -25 ); eq_view_roller RotateTo( ent.angles, timer, timer * 0.5, timer * 0.5 ); wait( timer ); timer = 0.5; // ent addyaw( 20 ); ent addpitch( 5 ); ent addroll( -15 ); eq_view_roller RotateTo( ent.angles, timer, 0, timer ); wait( timer ); timer = 0.55; ent addpitch( 15 ); ent addroll( -60 ); eq_view_roller RotateTo( ent.angles, timer, 0, 0 ); level.player setstance( "prone" ); wait( 0.65 ); black_overlay = create_client_overlay( "black", 0, level.player ); black_overlay.alpha = 1; // level.player Shellshock( "nosound", 1, false ); /* level.player delaycall( 0.05, ::setstance, "prone" ); level.player delaycall( 0.05, ::allowcrouch, false ); level.player delaycall( 0.05, ::allowstand, false ); level.player delaycall( 0.05, ::ShellShock, "gulag_attack", 5, false ); */ level.player allowcrouch( true ); level.player allowstand( true ); flag_clear( "player_falls_down" ); // during cafeteria ending wait( 1 ); black_overlay destroy(); // timer = 0.3; // eq_view_roller RotateTo( start_angles, timer, timer * 0.5, timer * 0.5 ); } player_blur_manager() { level endon( "time_to_evac" ); level.player ent_flag_set( "player_no_auto_blur" ); level.player SetBlurForPlayer( 12, 0.05 ); clear_time = 0.8; clear_blur = 0.4; very_blur = 7; blur_time = 1; for ( ;; ) { level.player SetBlurForPlayer( clear_blur, clear_time ); wait( clear_time ); level.player SetBlurForPlayer( very_blur, blur_time ); wait( blur_time ); very_blur *= 1.5; } } fx_fall_around_player( angles ) { forward = anglestoforward( angles ); right = anglestoright( angles ); above_player = level.player.origin + (0,0,100 ) + forward * 50; fx_org = level.player.origin + forward * 35 + right * -10 + ( 0, 0, 32 ); /* fx = getfx( "0_ceiling_rock_explosion" ); // thread player_ending_cavein(); //thread player_dies_to_cavein( 2 ); noself_delaycall( 0.05, ::PlayFX, fx, fx_org ); noself_delaycall( 0.05, ::PlayFX, fx, fx_org ); noself_delaycall( 0.05, ::PlayFX, fx, fx_org ); noself_delaycall( 0.05, ::PlayFX, fx, fx_org ); */ // fx = getfx( "0_ceiling_rock" ); fx = getfx( "hallway_collapsing_huge" ); for ( i = 0; i < 10; i++ ) { fx_org = level.player.origin + forward * 35 + right * -10 + ( 0, 0, 180 ); noself_delaycall( 0.05, ::PlayFX, fx, fx_org ); wait( randomfloatrange( 0.1, 0.25 ) ); } } /* fx = []; fx[ fx.size ] = "0_ceiling_collapse"; fx[ fx.size ] = "0_ceiling_collapse_big"; fx[ fx.size ] = "0_ceiling_collapse_huge"; fx[ fx.size ] = "0_ceiling_collapse_huge"; index = start_index; if ( !isdefined( index ) ) index = 0; counts = []; counts[ 0 ] = 12; counts[ 1 ] = 15; counts[ 2 ] = 10; counts[ 3 ] = 20; thread black_death(); last_org = level.player.origin; for ( ;; ) { for ( i = 0; i < counts[ index ]; i++ ) { angles = level.player getplayerangles(); forward = anglestoforward( angles ); vec = level.player.origin - last_org; org = level.player.origin + forward * 100 + vec * 10; org = set_z( org, level.player.origin[2] ); trace = BulletTrace( org, org + (0,0,3000), false, undefined ); current_fx = getfx( fx[ index ] ); PlayFX( current_fx, trace[ "position" ] ); last_org = level.player.origin; if ( randomint( 100 ) > 40 ) { if ( index == 1 ) level.player DoDamage( 5, randomvector( 500 ) ); if ( index > 1 ) level.player DoDamage( 15, randomvector( 500 ) ); } wait( 0.05 ); } if ( index == 2 ) { level.player kill(); } index++; if ( index >= fx.size ) break; } */ /* ent.angles = eq_view_roller.angles; ent addpitch( 10 ); ent addroll( 12 ); timer = 0.3; eq_view_roller RotateTo( ent.angles, timer, timer * 0.5, timer * 0.5 ); wait( timer ); ent addpitch( -15 ); ent addroll( -18 ); timer = 0.4; eq_view_roller RotateTo( ent.angles, timer, timer * 0.5, timer * 0.5 ); wait( timer ); timer = 0.3; eq_view_roller RotateTo( start_angles, timer, timer * 0.5, timer * 0.5 ); */ /* eq_view_roller RotateRoll( -10, 1, 0.5, 0.5 ); wait( 1 ); eq_view_roller RotateRoll( 20, 1, 0.5, 0.5 ); wait( 1 ); eq_view_roller RotateRoll( -10, 1, 0.5, 0.5 ); */ /* // each guy that hits the trigger does a unique stumble doing_anim = []; ducks = []; ducks[ ducks.size ] = "run_duck"; ducks[ ducks.size ] = "run_flinch"; ducks[ ducks.size ] = "run_stumble"; index = 0; ent = spawnstruct(); ent.eq = false; for ( ;; ) { self waittill( "trigger", guy ); if ( !isalive( guy ) ) return; if ( isdefined( doing_anim[ guy.unique_id ] ) ) continue; doing_anim[ guy.unique_id ] = true; animation = ducks[ index ]; index++; if ( index >= ducks.size ) index = 0; guy thread guy_ducks( animation, ent ); } */ stumble_anim( animation ) { animation = getgenericanim( animation ); self.run_overrideanim = animation; self SetFlaggedAnimKnob( "stumble_run", animation, 1, 0.2, 1, true ); wait( 1.5 ); run_root = getgenericanim( "run_root" ); old_time = 0; for ( ;; ) { if ( self getAnimTime( run_root ) < old_time ) break; old_time = self getAnimTime( run_root ); wait( 0.05 ); } self.run_overrideanim = undefined; self notify( "movemode" ); } turnaround_trigger_think() { // each guy that hits the trigger does a unique stumble doing_anim = []; ducks = []; ducks[ ducks.size ] = "reaction_180"; ducks[ ducks.size ] = "reaction_180"; ducks[ ducks.size ] = "run_180"; index = 0; eq = false; for ( ;; ) { self waittill( "trigger", guy ); if ( !isalive( guy ) ) return; if ( isdefined( doing_anim[ guy.unique_id ] ) ) continue; doing_anim[ guy.unique_id ] = true; animation = ducks[ index ]; index++; if ( index >= ducks.size ) index = 0; guy thread guy_animates( animation ); } } guy_animates( animation ) { orgs = getentarray( "friendly_changedirection_org", "targetname" ); orgs = array_index_by_parameters( orgs ); self thread maps\_spawner::go_to_node( orgs[ self.animname ], "struct" ); self anim_generic( self, animation ); } eq_happens() { wait( 0.3 ); quake( 0.25, 4, self.origin, 5000 ); } guy_ducks( animation, ent ) { self endon( "death" ); run_root = getgenericanim( "run_root" ); old_time = self getAnimTime( run_root ); for ( ;; ) { if ( self getAnimTime( run_root ) < old_time ) break; old_time = self getAnimTime( run_root ); wait( 0.05 ); } if ( isdefined( ent ) && !ent.eq ) { ent.eq = true; quake( 0.25, 4, self.origin, 5000 ); } self.run_overrideanim = getgenericanim( animation ); old_time = self getAnimTime( run_root ); for ( ;; ) { if ( self getAnimTime( run_root ) < old_time ) break; old_time = self getAnimTime( run_root ); wait( 0.05 ); } self.run_overrideanim = undefined; self notify( "movemode" ); // runAnim = animscripts\run::GetRunAnim(); // self setFlaggedAnimKnobLimited( "runanim", runAnim, 1, 0.1, 1, true ); } hallway_flicker_light() { off = "com_floodlight"; on = "com_floodlight_on"; model = self; light = getent( model.target, "targetname" ); intensity = light getLightIntensity(); /* for ( ;; ) { off_count = randomint( 3 ) + 1; for ( p = 0; p < off_count; p++ ) { count = randomint( 4 ) + 2; for ( i = 0; i < count; i++ ) { light setLightIntensity( 0 ); model setmodel( off ); wait( 0.05 ); light setLightIntensity( intensity ); model setmodel( on ); wait( 0.05 ); } light setLightIntensity( 0 ); model setmodel( off ); wait( randomfloatrange( 0.2, 0.3 ) ); } count = randomint( 4 ) + 2; for ( i = 0; i < count; i++ ) { light setLightIntensity( 0 ); model setmodel( off ); wait( 0.05 ); light setLightIntensity( intensity ); model setmodel( on ); wait( 0.05 ); } light setLightIntensity( intensity ); model setmodel( on ); wait( randomfloatrange( 0.35, 0.45 ) ); if ( flag( "exit_collapses" ) ) break; } */ for ( ;; ) { count = randomint( 3 ) + 2; for ( i = 0; i < count; i++ ) { light setLightIntensity( 0 ); model setmodel( off ); wait( randomfloatrange( 0.05, 0.1 ) ); light setLightIntensity( intensity ); model setmodel( on ); wait( 0.05 ); } light setLightIntensity( intensity ); model setmodel( on ); wait( randomfloatrange( 1.2, 2 ) ); } } ending_window_littlebird() { self godon(); hover = 50; self SetYawSpeed( 140, 80, 80 ); //, 60, overshoot percent ); self SetHoverParams( 5, 5, hover ); } ptest() { for ( ;; ) { angles = level.player getplayerangles(); forward = anglestoforward( angles ); org = level.player.origin + forward * 180; org = set_z( org, level.player.origin[2] + 64 ); //PhysicsJitter( org, 350, 250, 0.05, 0.2 ); vec = randomvector( 0.3 ); PhysicsJolt( org, 350, 250, vec ); //PhysicsExplosionSphere( org, 350, 250, 0.5 ); Print3d( org, ".", (1,0,0), 1, 1, 5 ); wait( 0.5 ); } } first_hallway_collapse( pos ) { // 11.6 wait( 10.3 ); if ( distance( level.player.origin, pos ) > 700 ) exploder( "first_hallway_collapse" ); } stumble_baddie() { spawner = getent( "stumble_baddie_spawner", "targetname" ); // don't do it if the player is looking this way if ( within_fov_of_players( spawner.origin, 0.7 ) ) return; if ( distance( spawner.origin, level.player.origin ) < 500 ) return; thread first_hallway_collapse( spawner.origin ); guy = spawner stalingradspawn(); guy.animname = "stumble_baddie"; ent = getstruct( guy.target, "targetname" ); guy gun_remove(); guy.allowDeath = true; guy endon( "death" ); guy.health = 1; guy.ignoreme = true; guy.diequietly = true; setsaveddvar( "ragdoll_explode_force", 0 ); ent anim_first_frame_solo( guy, "stumble" ); wait( 8.4 ); ent anim_single_solo( guy, "stumble" ); guy kill(); } trash_sound_think() { self waittill( "trigger" ); self play_sound_in_space( "scn_gulag_exp_trashcan_debris", self.org ); } file_cabinet_show() { models = getentarray( "file_cabinet_anim", "targetname" ); array_thread( models, ::path_anim_setup ); models = array_index_by_parameters( models ); flag_wait( "enter_final_room" ); //flag_wait( "reach_mound" ); wait( 3 ); models[ "1" ] path_anim( 0.2 ); wait( 0.1 ); models[ "1" ] path_anim( 0.1 ); models[ "2" ] path_anim( 0.1 ); wait( 0.1 ); models[ "1" ] path_anim( 0.3 ); models[ "2" ] path_anim( 0.3 ); models[ "3" ] path_anim( 0.3 ); } path_anim_setup() { self.paths = self get_anim_paths(); self.path_index = 0; } path_anim( time, time_in, time_out ) { path = self.paths[ self.path_index ]; if ( !isdefined( path ) ) return; self.path_index++; if ( isdefined( time_in ) ) { self moveto( path[ "origin" ], time, time_in, time_out ); self rotateto( path[ "angles" ], time, time_in, time_out ); } else { self moveto( path[ "origin" ], time ); self rotateto( path[ "angles" ], time ); } } pillar_anim_show() { models = getentarray( "pillar_anim", "targetname" ); models = array_index_by_parameters( models ); model1targ = getent( models["1"].target, "targetname" ); model2targ = getent( models["2"].target, "targetname" ); //model1targ thread maps\_debug::drawOriginForever(); //model2targ thread maps\_debug::drawOriginForever(); models["1"] linkto( model1targ ); models["2"] linkto( models["1"] ); model2targ linkto( model1targ ); flag_wait( "enter_final_room" ); //flag_wait( "reach_mound" ); wait( 1 ); targ2 = getent( model1targ.target, "targetname" ); model1targ moveto( targ2.origin, 5, 1, 2 ); model1targ rotateto( targ2.angles, 5, 1, 2 ); wait( 5 ); pillar_rotater = getent( "pillar_rotater", "targetname" ); model1targ linkto( pillar_rotater ); pillar_targ = getent( pillar_rotater.target, "targetname" ); pillar_rotater rotateto( pillar_targ.angles, 2, 2, 0 ); pillar_rotater moveto( pillar_targ.origin, 2, 2, 0 ); wait( 2 ); pillar_rotater = getent( pillar_rotater.target, "targetname" ); model1targ linkto( pillar_rotater ); timer = 0.75; pillar_targ = getent( pillar_rotater.target, "targetname" ); pillar_rotater rotateto( pillar_targ.angles, timer ); pillar_rotater moveto( pillar_targ.origin, timer ); wait( timer ); targets = getentarray( pillar_targ.target, "targetname" ); targets = array_index_by_classname( targets ); models["2"] linkto( model2targ ); model2targ linkto( targets[ "script_origin_pillar2" ] ); models["1"] linkto( model1targ ); model1targ linkto( targets[ "script_origin_pillar1" ] ); timer = 0.4; model1targ unlink(); model1targ rotateto( targets[ "script_origin_pillar1" ].angles, timer ); model1targ moveto( targets[ "script_origin_pillar1" ].origin, timer ); timer = 1.5; model2targ unlink(); model2targ rotateto( targets[ "script_origin_pillar2" ].angles, timer, 0, timer ); model2targ moveto( targets[ "script_origin_pillar2" ].origin, timer, 0, timer ); /* models = getentarray( "pillar_anim", "targetname" ); array_thread( models, ::path_anim_setup ); models = array_index_by_parameters( models ); //flag_wait( "reach_mound" ); wait( 1 ); ents = []; foreach ( model in models ) { ent = spawn( "script_origin", (0,0,0) ); path = model.paths[ 0 ]; ent.paths = model.paths; ent.origin = path[ "origin" ]; ent.angles = path[ "angles" ]; ent.path_index = 0; model linkto( ent ); ents[ model.script_parameters ] = ent; } //fakeseys on the first one ents[ "1" ] path_anim( 0.1 ); ents[ "2" ] path_anim( 0.1 ); // first grind in ents[ "1" ] path_anim( 2, 0.2, 0.2 ); ents[ "2" ] path_anim( 2, 0.2, 0.2 ); wait( 2.5 ); // now start to fall ents[ "1" ] path_anim( 2, 2, 0 ); ents[ "2" ] path_anim( 2, 2, 0 ); wait( 2 ); // falling ents[ "1" ] path_anim( 0.25 ); ents[ "2" ] path_anim( 0.25 ); wait( 0.25 ); // falling ents[ "1" ] path_anim( 0.25 ); ents[ "2" ] path_anim( 0.25 ); wait( 0.25 ); // BAM, slide apart ents[ "1" ] path_anim( 2, 0, 2 ); ents[ "2" ] path_anim( 2, 0, 2 ); */ } delete_tree_think() { // this ent is just for ref, delete all links ent = self; for ( ;; ) { if ( !isdefined( ent.target ) ) break; newent = getent( ent.target, "targetname" ); ent delete(); ent = newent; } ent delete(); } eqtest() { /* channels = []; channels[ "item" ] = true; channels[ "menu" ] = true; channels[ "weapon" ] = true; channels[ "voice" ] = true; channels[ "body" ] = true; channels[ "physics" ] = true; channels[ "local" ] = true; channels[ "music" ] = true; channels[ "announcer" ] = true; channels[ "auto" ] = true; channels[ "physics" ] = true; channels[ "ambdist1" ] = true; channels[ "ambdist2" ] = true; channels[ "auto" ] = true; channels[ "auto2" ] = true; channels[ "auto2d" ] = true; channels[ "autodog" ] = true; channels[ "explosiveimpact" ] = true; channels[ "element" ] = true; channels[ "vehicle" ] = true; channels[ "vehiclelimited" ] = true; channels[ "body" ] = true; channels[ "reload" ] = true; channels[ "effects1" ] = true; channels[ "effects2" ] = true; channels[ "voice" ] = true; channels[ "mission" ] = true; */ /* main_track = level.eq_main_track; mix_track = level.eq_mix_track; // put the player on the mixtrack first level.player SetEqLerp( 1, main_track ); filter = "highshelf"; db = -25; freq = 1100; a = 5; foreach ( channel, _ in channels ) { level.player seteqbands( channel, mix_track, "highshelf", db, freq, 1, "lowshelf", 2, freq, 1 ); } */ AmbientStop( 0.5 ); thread maps\_ambient::use_eq_settings( "gulag_cavein", level.eq_mix_track ); // now blend to the mix track, which is our filter maps\_ambient::blend_to_eq_track( level.eq_mix_track, 2 ); } player_dies_to_cavein( start_index ) { // buried if ( flag( "player_died_to_cave_in" ) ) return; level.player PlayRumbleLoopOnEntity( "damage_light" ); flag_set( "player_died_to_cave_in" ); level.player enabledeathshield( false ); fx = []; fx[ fx.size ] = "hallway_collapsing"; fx[ fx.size ] = "hallway_collapsing_big"; fx[ fx.size ] = "hallway_collapsing_huge"; fx[ fx.size ] = "hallway_collapsing_huge"; index = start_index; if ( !isdefined( index ) ) index = 0; counts = []; counts[ 0 ] = 12; counts[ 1 ] = 15; counts[ 2 ] = 10; counts[ 3 ] = 20; AmbientStop( 0.5 ); thread maps\_ambient::use_eq_settings( "gulag_cavein", level.eq_mix_track ); thread maps\_ambient::blend_to_eq_track( level.eq_mix_track, 2 ); thread black_death(); last_org = level.player.origin; for ( ;; ) { for ( i = 0; i < counts[ index ]; i++ ) { angles = level.player getplayerangles(); forward = anglestoforward( angles ); vec = level.player.origin - last_org; org = level.player.origin + forward * 100 + vec * 10; org = set_z( org, level.player.origin[2] ); trace = BulletTrace( org, org + (0,0,3000), false, undefined ); current_fx = getfx( fx[ index ] ); PlayFX( current_fx, trace[ "position" ] ); last_org = level.player.origin; if ( randomint( 100 ) > 40 ) { if ( index == 1 ) level.player DoDamage( 5 / level.player.damageMultiplier, randomvector( 500 ) ); if ( index > 1 ) level.player DoDamage( 15 / level.player.damageMultiplier, randomvector( 500 ) ); level.player PlayRumbleOnEntity( "damage_heavy" ); } wait( 0.05 ); } if ( index == 2 ) { level.player kill(); } index++; if ( index >= fx.size ) break; } } player_ending_cavein() { level endon( "stop_cavein" ); fx = getfx( "player_cavein" ); /* tag_origin = spawn_tag_origin(); tag_origin.origin = level.player.origin + (0,0,60); tag_origin linkto( level.player ); PlayFXOnTag( fx, tag_origin, "tag_origin" ); */ // thread black_death(); // wait( 1.2 ); delay = 1.5; for ( ;; ) { wait( delay ); PlayFX( fx, level.player.origin + (0,0,60 ) ); delay -= 0.75; if ( delay <= 0.2 ) delay = 0.2; } /* fx = []; fx[ fx.size ] = "hallway_collapsing"; fx[ fx.size ] = "hallway_collapsing_big"; fx[ fx.size ] = "hallway_collapsing_huge"; index = 0; counts = []; counts[ 0 ] = 4; counts[ 1 ] = 80; counts[ 2 ] = 80; thread black_death(); last_org = level.player.origin; for ( ;; ) { for ( i = 0; i < counts[ index ]; i++ ) { angles = level.player getplayerangles(); forward = anglestoforward( angles ); vec = level.player.origin - last_org; org = level.player.origin + forward * 100 + vec * 10; org = set_z( org, level.player.origin[2] ); trace = BulletTrace( org, org + (0,0,3000), false, undefined ); current_fx = getfx( fx[ index ] ); PlayFX( current_fx, trace[ "position" ] ); last_org = level.player.origin; wait( 0.1 ); } index++; if ( index >= fx.size ) break; } */ } black_death() { wait( 4.5 ); black_overlay = create_client_overlay( "black", 0, level.player ); black_overlay fadeOverTime( 2.5 ); black_overlay.alpha = 1; black_overlay.foreground = false; level waittill( "stop_cavein" ); wait( 0.05 ); black_overlay destroy(); } trigger_damage_think() { self waittill( "trigger" ); ent = getstruct( self.target, "targetname" ); RadiusDamage( ent.origin + (0,0,16), 32, 500, 500, level.player ); wait( 0.2 ); RadiusDamage( ent.origin - (0,0,16), 32, 500, 500, level.player ); // Print3d( ent.origin, "x", (1,0,0), 1, 1, 50 ); } chase_player_dies_if_goes_wrong_way() { level.player endon( "death" ); flag_wait( "chase_brush_kill_volume_activates" ); wait( 2.5 ); // 2.3 volume = getent( "player_cavein_kill_volume", "targetname" ); time = 5; frames = time * 20; for ( i = 0; i < frames; i++ ) { if ( level.player istouching( volume ) ) { thread player_dies_to_cavein( 2 ); return; } wait( 0.05 ); } } chase_train_chases( dist, starter ) { level endon( "stop_chase_fx" ); min_speed = 6.0; // 8.0; max_speed = 16; // 20; min_dist = dist; max_dist = dist + 75; range_speed = max_speed - min_speed; range_dist = max_dist - min_dist; level.chasers[ starter ] = []; for ( ;; ) { ai = getaiarray( "allies" ); guy = getClosest( self.origin, ai ); dist = distance( self.origin, guy.origin ); level.chasers[ starter ][ "dist" ] = dist; dist -= min_dist; scale = dist / range_dist; if ( scale < 0 ) scale = 0; else if ( scale > 1 ) scale = 1; speed = min_speed + range_speed * scale; level.chasers[ starter ][ "speed" ] = speed; self Vehicle_SetSpeed( speed, 5, 5 ); wait( 0.05 ); } } chase_brush_accellerates_to_max_speed( chase_vehicle, time, max_speed ) { frames = time * 20; for ( i = 0; i <= frames; i++ ) { scale = i / frames; speed = max_speed * scale; if ( speed <= 0 ) speed = 0.1; chase_vehicle Vehicle_SetSpeedImmediate( speed, speed, speed ); wait( 0.05 ); } wait( time ); } chase_train() { level notify( "collapse_fx_stop" ); speed = 190; //186; speed = 270; //186; speed /= 19.76; speed = 6; chase_vehicle_spawner = getent( "chase_brush_vehicle", "targetname" ); fx_vehicle = chase_vehicle_spawner vehicle_dospawn(); level.fx_vehicle = fx_vehicle; fx_vehicle thread chase_train_fx(); path = getvehiclenode( fx_vehicle.target, "targetname" ); fx_vehicle attachpath( path ); fx_vehicle startpath(); time = 4; thread chase_brush_accellerates_to_max_speed( fx_vehicle, time, speed ); thread chase_player_dies_if_goes_wrong_way(); level.chasers = []; fx_vehicle thread chase_train_chases( 400, true ); wait( 3.5 ); // wait( 1.25 + 3.25 ); chase_brush = getent( "chase_brush", "targetname" ); chase_brush show(); chase_vehicle_spawner = getent( "chase_brush_vehicle", "targetname" ); chase_vehicle = chase_vehicle_spawner vehicle_dospawn(); chase_vehicle thread chase_train_kills_player_if_it_gets_close(); level.chase_vehicle = chase_vehicle; chase_vehicle attachpath( path ); chase_vehicle startpath(); chase_brush linkto( chase_vehicle ); chase_vehicle thread chase_train_chases( 900, false ); //chase_vehicle Vehicle_SetSpeedImmediate( speed, speed, speed ); //fx_vehicle Vehicle_SetSpeedImmediate( speed, speed, speed ); level waittill( "stop_chase_fx" ); chase_vehicle delete(); } chase_train_fx() { level endon( "stop_chase_fx" ); ent = spawn_tag_origin(); fx = getfx( "hallway_collapsing_chase" ); ent linkto( self, "tag_origin", (0,0,0), (0,0,-90) ); //ent thread maps\_debug::drawtagforever( "tag_origin" ); count = 5; for ( ;; ) { angles = self.angles; forward = anglestoforward( angles ); count--; if ( count <= 0 ) { vec = randomvector( 0.125 ); PhysicsJolt( level.player.origin + forward * 250, 250, 250, vec ); count = randomint( 10 ); } PlayFXOnTag( fx, ent, "tag_origin" ); wait( 0.1 ); } } chase_train_kills_player_if_it_gets_close() { level endon( "stop_chase_fx" ); black_screen(); max_black = 400; min_black = 700; black_range = abs( max_black - min_black ); for ( ;; ) { org1 = level.player.origin; org1 = set_z( org1, 0 ); org2 = self.origin; org2 = set_z( org2, 0 ); level.chase_distance = distance( org1, org2 ); chase_dist = level.chase_distance; // algebra! //1 - ( ( min_black - max_black ) / black_range ) = 1 - ( ( chase_dist - max_black ) / black_range ); alpha = 1 - ( ( chase_dist - max_black ) / black_range ); alpha = clamp( alpha, 0, 1 ); level.black_overlay.alpha = alpha; level.black_overlay fadeOverTime( 0.2 ); //Line( level.player.origin, self.origin, (1,0,1), 1, 0, 2 ); //println( "distance " + distance( org1, org2 ) ); if ( chase_dist < 260 ) { // this function automatically early outs on second call thread player_dies_to_cavein( 2 ); } wait( 0.1 ); } } black_screen( _ ) { if ( isdefined( level.black_overlay ) ) { level.black_overlay destroy(); return; } hud = create_client_overlay( "black", 0, level.player ); hud.alpha = 1; hud.foreground = false; level.black_overlay = hud; } ceiling_collapse_think() { flag_wait( "rescue_begins" ); org = self.origin; self.origin += (0,0,300); flag_wait( "exit_collapses" ); self CastShadows(); script_delay(); self moveto( org, 1, 0.2, 0 ); Earthquake( 1.0, 4, org, 1000 ); } set_friendly_endpoint_think() { level.friendly_endpoint = self.origin; flag_wait( "exit_collapses" ); new_org = getstruct( self.target, "targetname" ); level.friendly_endpoint = new_org.origin; flag_clear( "friendlies_turn_corner" ); flag_wait( "friendlies_turn_corner" ); // This way this way!!! level.redshirt thread dialogue_queue( "gulag_wrm_thisway" ); hall_org = getstruct( new_org.target, "targetname" ); level.friendly_endpoint = hall_org.origin; flag_wait( "friendlies_turn_to_cafeteria" ); level.friendly_endpoint = self.origin; } ending_run_fx() { if ( flag( "enter_final_room" ) ) return; level endon( "enter_final_room" ); level endon( "stop_ending_run_fx" ); rocks = get_exploder_array( "wall_rock" ); level.max_rocks = 3; level.ending_fx_min_dist = 280; level.ending_fx_max_dist = 700; level.ending_fx_dot = 0.8; foreach ( ent in rocks ) { ent.flat_origin = flat_origin( ent.v[ "origin" ] ); ent.last_occurred_time = 0; } for ( ;; ) { exit_flag = flag( "exit_collapses" ); rocks = array_randomize( rocks ); origin = flat_origin( level.player.origin ); angles = level.player.angles; forward = anglestoforward( angles ); origin += forward * -350; array = []; foreach ( ent in rocks ) { if ( !exit_flag && ent.v[ "fxid" ] == "ceiling_collapse_dirt1" ) continue; if ( ent.last_occurred_time > gettime() - 1000 ) continue; dist = distance( ent.flat_origin, origin ); if ( dist < level.ending_fx_min_dist ) continue; if ( dist < level.ending_fx_max_dist ) continue; normal = vectorNormalize( ent.flat_origin - origin ); dot = vectorDot( forward, normal ); if ( dot < level.ending_fx_dot ) continue; array[ array.size ] = ent; if ( array.size >= level.max_rocks ) break; } foreach ( ent in array ) { ent activate_individual_exploder(); ent.last_occurred_time = gettime(); wait( 0.1 ); } wait( 0.1 ); } } cafe_fx() { flag_wait( "enter_final_room" ); level endon( "stop_ending_run_fx" ); rocks = get_exploder_array( "cafe_rock" ); level.fx_fall_time = 0.07; for ( ;; ) { rocks = array_randomize( rocks ); foreach ( ent in rocks ) { ent activate_individual_exploder(); //ent.last_occurred_time = gettime(); wait( level.fx_fall_time ); } wait( 0.1 ); } } ceiling_collapse_begins() { level endon( "collapse_fx_stop" ); org = getstruct( "ceiling_collapse_org", "targetname" ); target = getstruct( org.target, "targetname" ); angles = vectortoangles( target.origin - org.origin ); dist = distance( org.origin, target.origin ); forward = anglestoforward( angles ); fx = []; fx[ fx.size ] = "hallway_collapsing"; fx[ fx.size ] = "hallway_collapsing_big"; fx[ fx.size ] = "hallway_collapsing_huge"; thread playfx_collapse( org.origin, forward, dist, fx[0], 6 ); wait( 3.5 ); thread playfx_collapse( org.origin, forward, dist, fx[1], 3 ); wait( 2.5 ); thread playfx_collapse( org.origin, forward, 0, fx[2], 8 ); } playfx_collapse( origin, forward, dist, fx_msg, time ) { level endon( "collapse_fx_stop" ); ent = spawnstruct(); ent endon( "stop" ); ent delaythread( time, ::send_notify, "stop" ); fx = getfx( fx_msg ); wait_time = 0.5; for ( ;; ) { org = origin + forward * randomfloat( dist ); PlayFX( fx, org ); wait( wait_time ); wait_time -= 0.35; if ( wait_time < 0.5 ) wait_time = 0.5; } } get_anim_paths() { path = self; paths = []; for ( ;; ) { if ( !isdefined( path.target ) ) break; path = getent( path.target, "targetname" ); array = []; array[ "angles" ] = path.angles; array[ "origin" ] = path.origin; array[ "model" ] = path; paths[ paths.size ] = array; } foreach ( path in paths ) { path[ "model" ] delete(); } return paths; } friendly_car_slide_trigger() { targ = getent( self.target, "targetname" ); targ thread price_slide_box_topples(); flag_wait( "exit_collapses" ); for ( ;; ) { self waittill( "trigger", other ); if ( !isalive( other ) ) continue; if ( other == level.redshirt ) break; } if ( flag( "do_not_flip_box" ) ) { wait( 0.35 ); wait( 1.7 ); flag_set( "match_up_for_final_room" ); return; } targ notify( "topple" ); targ waittill( "trigger" ); thread price_hurdles(); } price_slide_box_topples() { targets = getentarray( self.target, "targetname" ); models = []; foreach ( target in targets ) { models[ target.classname ] = target; } crate = models[ "script_model" ]; models[ "script_brushmodel" ] linkto( crate ); paths = crate get_anim_paths(); self waittill( "topple" ); crate delaythread( 0.25, ::play_sound_on_entity, "door_cargo_container_burst_open" ); models[ "script_brushmodel" ] thread kill_player_on_touch(); foreach ( path in paths ) { crate moveto( path[ "origin" ], 0.1 ); crate rotateto( path[ "angles" ], 0.1 ); wait( 0.1 ); } models[ "script_brushmodel" ] notify( "stop_killing" ); } kill_player_on_touch() { level.touchkill = self; // for debugging self endon( "stop_killing" ); for ( ;; ) { if ( level.player istouching( self ) ) { level.player kill(); return; } wait( 0.05 ); } } price_hurdles() { car_slide_org = getstruct( "car_slide_org", "targetname" ); wait( 0.35 ); car_slide_org thread anim_generic( level.redshirt, "slide_across_car" ); wait( 1.7 ); level.redshirt anim_stopanimscripted(); flag_set( "match_up_for_final_room" ); setsaveddvar( "player_sprintSpeedScale", level.default_sprint ); } ambient_flicker_light_think() { ent = spawnstruct(); light = getent( self.target, "targetname" ); turn_on[ "ch_street_wall_light_01_on" ] = "ch_street_wall_light_01_on"; turn_on[ "ch_street_wall_light_01_off" ] = "ch_street_wall_light_01_on"; turn_off[ "ch_street_wall_light_01_off" ] = "ch_street_wall_light_01_off"; turn_off[ "ch_street_wall_light_01_on" ] = "ch_street_wall_light_01_off"; turn_on[ "com_floodlight_on" ] = "com_floodlight_on"; turn_on[ "com_floodlight" ] = "com_floodlight_on"; turn_off[ "com_floodlight" ] = "com_floodlight"; turn_off[ "com_floodlight_on" ] = "com_floodlight"; ent.turn_on = turn_on; ent.turn_off = turn_off; ent.light = light; flicker_funcs = []; flicker_funcs[ "slow_flicker" ] = ::flicker_slow; ent.intensity = light getLightIntensity(); if ( !isdefined( self.script_parameters ) ) thread flicker_default( ent ); else thread [[ flicker_funcs[ self.script_parameters ] ]]( ent ); } flicker_default( ent ) { for ( ;; ) { count = randomint( 5 ) + 2; for ( i = 0; i < count; i++ ) { ent.light setLightIntensity( 0 ); self setModel( ent.turn_off[ self.model ] ); wait( 0.05 ); ent.light setLightIntensity( ent.intensity ); self setModel( ent.turn_on[ self.model ] ); wait( 0.05 ); } ent.light setLightIntensity( 0 ); self setModel( ent.turn_off[ self.model ] ); wait( randomfloatrange( 0.2, 0.3 ) ); count = randomint( 5 ) + 2; for ( i = 0; i < count; i++ ) { ent.light setLightIntensity( 0 ); self setModel( ent.turn_off[ self.model ] ); wait( 0.05 ); ent.light setLightIntensity( ent.intensity ); self setModel( ent.turn_on[ self.model ] ); wait( 0.05 ); } ent.light setLightIntensity( ent.intensity ); self setModel( ent.turn_on[ self.model ] ); wait( randomfloatrange( 0.2, 0.3 ) ); } } flicker_slow( ent ) { for ( ;; ) { count = randomint( 5 ) + 2; for ( i = 0; i < count; i++ ) { ent.light setLightIntensity( 0 ); self setModel( ent.turn_off[ self.model ] ); wait( 0.1 ); ent.light setLightIntensity( ent.intensity ); self setModel( ent.turn_on[ self.model ] ); wait( 0.1 ); } ent.light setLightIntensity( ent.intensity ); self setModel( ent.turn_on[ self.model ] ); wait( randomfloatrange( 0.2, 0.3 ) ); } } cafe_table_org_think() { // these ents are associated by distance because a set of ents are in a prefab index = get_closest_index( self.origin, level.cafe_tables, 32 ); if ( !isdefined( index ) ) return; table = level.cafe_tables[ index ]; level.cafe_tables[ index ] = undefined; ent = spawn( "script_origin", (0,0,0) ); ent.origin = self.origin; ent.angles = self.angles; table linkto( ent ); //ent thread maps\_debug::drawOriginForever(); wait( 1 ); target = getstruct( self.target, "targetname" ); timer = 5; ent moveto( target.origin, timer, timer * 0.1, timer * 0.1 ); ent rotateto( target.angles, timer, timer * 0.1, timer * 0.1 ); frames = timer * 20; org = ent.origin + (0,0,32); for ( i = 0; i < frames; i++ ) { PhysicsJolt( org, 350, 250, randomvector( 0.05 ) ); wait( 0.05 ); } } cafe_table_think() { model = getent( self.target, "targetname" ); model linkto( self ); } cafe_table_eq_org_think() { for ( ;; ) { wait( randomfloatrange( 3, 17 ) ); count = randomintrange( 4, 8 ); for ( i = 0; i < count; i++ ) { vec = randomvector( 0.18 ); if ( vec[2] < 0 ) { vec = set_z( vec, vec[2] * -1 ); } PhysicsJolt( self.origin, 120, 80, vec ); wait( 0.05 ); } } } light_destructible_think() { wait( randomfloatrange( 7, 20 ) ); RadiusDamage( self.origin, 32, 500, 500 ); } swing_light_think() { ref_ent = spawn_tag_origin(); old_angles = self.angles; range = 25; self SetLightFovRange( 50, 25 ); for ( ;; ) { ref_ent.angles = old_angles; pitch = randomfloatrange( range * -1, range ); ref_ent addpitch( pitch ); yaw = randomfloatrange( range * -1, range ); ref_ent addyaw( yaw ); self rotateto( ref_ent.angles, 1, 0.3, 0.3 ); forward = anglestoforward( ref_ent.angles ); // Line( self.origin, self.origin + forward * 100, (1,1,1), 1, 0, 20 ); wait( 1 ); } } evil_hidden_spawner() { self hide(); self setcontents( 0 ); self.health = 50000; ent = getstruct( "weapon_drop_org", "targetname" ); org = spawn_taG_origin(); org.origin = ent.origin; org.angles = ent.angles; self linkto( org, "tag_origin", (0,0,0),(0,0,0) ); self.team = "neutral"; self.ignoreme = true; self.ignoreall = true; animation = getgenericanim( "gundrop_death" ); org anim_generic_first_frame( self, "gundrop_death" ); weapon = level.player getcurrentweapon(); self forceUseWeapon( weapon, "primary" ); wait( 0.05 ); self unlink(); // self Detach( "weapon_m4", "tag_weapon_right" ); level waittill( "dropit" ); wait( 0.30 ); self SetAnim( animation, 1, 0, 0.55 ); wait( 0.05 ); self DropWeapon( weapon, "right", 50000 ); wait( 0.3 ); org delete(); self delete(); weapon_impact_org = getstruct( "weapon_impact_org", "targetname" ); delaythread( 0.20, ::play_sound_in_space, "physics_brick_default", weapon_impact_org.origin ); delaythread( 0.20, ::play_sound_in_space, "physics_brick_default", weapon_impact_org.origin ); delaythread( 0.20, ::play_sound_in_space, "physics_brick_default", weapon_impact_org.origin ); delaythread( 0.20, ::play_sound_in_space, "physics_brick_default", weapon_impact_org.origin ); delaythread( 0.20, ::play_sound_in_space, "physics_brick_default", weapon_impact_org.origin ); /* wait( 0.30 ); self SetAnim( animation, 1, 0, 0.95 ); wait( 0.05 ); self DropWeapon( weapon, "right", 0 ); */ } players_view_opens( player_rig ) { wait( 0.5 ); //( linkto entity, tag, viewpercentag fraction, right arc, left arc, top arc, bottom arc, use tag angles ); level.player PlayerLinkToDelta( player_rig, "tag_player", 1, 0, 0, 0, 0, true ); wait( 3.2 - 0.5 ); // wait( 0.05 ); //LerpViewAngleClamp( time, accel time, decel time, right arc, left arc, top arc, bottom arc ); level.player LerpViewAngleClamp( 1, 0.5, 0.5, 17, 17, 12, 8 ); } unslowmo() { level.forced_slowmo_breach_slowdown = false; } white_punch_screen() { white = create_client_overlay( "white", 0, level.player ); white.alpha = 1; white fadeovertime( 1 ); white.alpha = 0; wait 1; white destroy(); } player_gets_knocked_out_by_price( player_rig ) { tag_origin = spawn_tag_origin(); tag_origin LinkTo( player_rig, "tag_player", (0,0,0), (0,0,0) ); //evil_hidden_spawner = getent( "evil_hidden_spawner", "targetname" ); //evil_hidden_spawner thread add_spawn_function( ::evil_hidden_spawner ); //evil_hidden_spawner spawn_ai(); thread spawn_ak47(); queue = gettime(); level.queue_time = queue; level.q = level.queue_time; wait( 0.5 ); delaythread( 0.5, ::unslowmo ); level.forced_slowmo_breach_lerpout = 2; wait_for_buffer_time_to_pass( queue, 2.8 ); level notify( "dropit" ); level.player delaycall( 0.05, ::disableweapons ); time = 0.25; level.price_breach_ent unlink(); level.price_breach_ent moveto( level.price_breach_struct.origin, 0.5, 0.2, 0.2 ); level.price_breach_ent rotateto( level.price_breach_struct.angles, 0.5, 0.2, 0.2 ); level.price_breach_ent notify( "stop_following_player" ); //noself_delayCall( 0.0, ::Earthquake, 0.2, 0.5, level.player.origin, 128 ); // Earthquake( scale, duration, source, radius ); noself_delayCall( 0.1, ::Earthquake, 1.0, 0.6, level.player.origin, 128 ); delaythread( 0.0, ::white_punch_screen ); // level.player delaycall( 0.1, ::SetBlurForPlayer, 20, 0 ); // level.player delaycall( 0.3, ::SetBlurForPlayer, 0, 1.5 ); // level.player delaycall( 0.5, ::SetBlurForPlayer, 0, 0.5 ); // noself_delayCall( 0.1, ::SetBlur, 2.5, 0.1 ); // noself_delayCall( 0.21, ::SetBlur, 0, 1 ); // level.player PlayerSetGroundReferenceEnt( tag_origin ); level.player PlayerLinkToBlend( player_rig, "tag_player", time, time * 0.4, time * 0.4 ); delaythread( time, ::players_view_opens, player_rig ); level notify( "breach_concludes" ); level.player DoDamage( 50 / level.player.damageMultiplier, level.price.origin ); // slow mo for a bit wait_for_buffer_time_to_pass( queue, 6.7 ); //slowmo_start(); //slowmo_setspeed_slow( 0.1 ); //slowmo_setlerptime_in( 0.2 ); //slowmo_lerp_in(); // soap enters scene wait_for_buffer_time_to_pass( queue, 7.3 ); //slowmo_setlerptime_out( 0.2 ); //slowmo_lerp_out(); //slowmo_end(); wait_for_buffer_time_to_pass( queue, 24.6 ); thread radio_dialogue( "gulag_hqr_getout" ); } spawn_ak47() { queue = gettime(); wait( 4.2 ); ak47 = spawn( "script_model", (0,0,0) ); ak47.origin = (-4245.72, 1688.15, 167.671); ak47.angles = (63.0343, 48.6473, -14.4095); hide_parts = []; hide_parts[ "tag_acog_2" ] = true; hide_parts[ "tag_heartbeat" ] = true; hide_parts[ "tag_m203" ] = true; hide_parts[ "tag_red_dot_mars" ] = true; hide_parts[ "tag_shotgun" ] = true; hide_parts[ "tag_silencer" ] = true; hide_parts[ "tag_flash_silenced" ] = true; hide_parts[ "tag_motion_tracker" ] = true; // hide_parts[ "tag_heartbeat" ] = true; // hide_parts[ "tag_heartbeat" ] = true; ak47 setmodel( "gulag_price_ak47" ); foreach ( part, _ in hide_parts ) { //ak47 hidepart( part ); } // ak47.origin = level.price gettagorigin( "tag_weapon_chest" ); // ak47.angles = level.price gettagangles( "tag_weapon_chest" ); ak47 linkto( level.price, "tag_weapon_chest", (0,0,0), (0,0,0) ); wait( 1.4 ); // ak47 unlink(); println( "ak update info:" ); println( " ak47.origin = " + ak47.origin + ";" ); println( " ak47.angles = " + ak47.angles + ";" ); wait_for_buffer_time_to_pass( queue, 11.3 ); ak47 linkto( level.price, "tag_weapon_chest", (0,0,0), (0,0,0) ); level.price waittill( "change_to_regular_weapon" ); ak47 delete(); } calculate_cafe_run_distances() { // grab the required distances from placed ents cafe_distance_trackersA = getentarray( "cafe_distance_tracker", "targetname" ); cafe_distance_trackersB = cafe_distance_trackersA; dists = []; foreach ( dist1 in cafe_distance_trackersA ) { foreach ( dist2 in cafe_distance_trackersB ) { if ( dist1 == dist2 ) continue; name1 = dist1.script_parameters; name2 = dist2.script_parameters; dist = distance( dist1.origin, dist2.origin ); dists[ name1 ][ name2 ] = dist; } } level.cafe_run_distances = dists; foreach ( ent in cafe_distance_trackersA ) { ent delete(); } } cavein_spawner_think() { self endon( "death" ); flag_wait( "enemy_cavein" ); // exploder wait( 0.5 ); for ( ;; ) { RadiusDamage( self.origin, 35, 10, 10 ); wait( 0.05 ); } } new_interval() { wait( 10 ); self.interval = 64; } endlog_friendly_runout_settings() { self.interval = 16; //self.noDodgeMove = true; thread new_interval(); //self delaythread( 5.5, ::ramp_interval, 64, 4 ); // self.run_overrideanim = getgenericanim( "panic_run" ); self ent_flag_init( "run_into_room" ); self.ignoresuppression = true; self.animplaybackrate = 1; self.moveTransitionRate = 1; self.moveplaybackrate = 1; self.sideStepRate = 1.35; self pushplayer( true ); self.dontavoidplayer = true; self disable_ai_color(); self.disablearrivals = true; self.goalradius = 45; self.pathrandompercent = 0; self.walkdist = 16; self.walkdistFacingMotion = 16; if ( self.animname == "redshirt" ) { self waittillmatch( "single anim", "end" ); self.moveplaybackrate = 1.1; wait( 1 ); self.moveplaybackrate = 1.0; } /* if ( self.animname == "soap" ) { self waittillmatch( "single anim", "end" ); wait( 8 ); self.moveplaybackrate = 0.96; wait( 12 ); self.moveplaybackrate = 1.0; } */ } ramp_interval( num, time ) { frames = time * 20; for ( i = 0; i < frames; i++ ) { dif = i / frames; self.interval = num * dif; wait( 0.05 ); } } gulag_glass_shatter() { default_delay = 0.3; delays = []; delays[ 0 ] = default_delay; delays[ 1 ] = default_delay; delays[ 2 ] = default_delay; delays[ 3 ] = default_delay; delays[ 4 ] = default_delay; index = 0; struct = getstruct( "glass_shatter_struct", "targetname" ); for ( ;; ) { RadiusDamage( struct.origin, 64, 350, 250 ); delay = delays[ index ]; index++; if ( !isdefined( delay ) ) { delay = randomfloatrange( 0.3, 1.5 ); } wait( delay ); if ( !isdefined( struct.target ) ) return; struct = getstruct( struct.target, "targetname" ); } } evac_slowmo() { wait( 3.5 ); slowmo_start(); slowmo_setspeed_slow( 0.4 ); slowmo_setlerptime_in( 0.05 ); slowmo_lerp_in(); /* //wait( 8 ); //wait( 1.75 ); wait( 1.1 ); slowmo_setspeed_slow( 0.8 ); slowmo_setlerptime_in( 0.05 ); slowmo_lerp_in(); wait( 0.5 ); //wait( 3 ); slowmo_setspeed_slow( 0.4 ); slowmo_setlerptime_in( 0.05 ); slowmo_lerp_in(); wait ( 3 - 1.6 ); */ wait( 3 ); outblend = 0.5; level notify( "blend_out_dof", outblend ); slowmo_setlerptime_in( outblend ); slowmo_lerp_out(); slowmo_end(); } evac_dof() { start = level.dofDefault; dof_all_blur = []; dof_all_blur[ "nearStart" ] = 50; dof_all_blur[ "nearEnd" ] = 100; dof_all_blur[ "nearBlur" ] = 10; dof_all_blur[ "farStart" ] = 100; dof_all_blur[ "farEnd" ] = 200; dof_all_blur[ "farBlur" ] = 4; level.dofDefault = dof_all_blur; wait( 1.25 ); dof_see_price = []; dof_see_price[ "nearStart" ] = 1; dof_see_price[ "nearEnd" ] = 1; dof_see_price[ "nearBlur" ] = 4; dof_see_price[ "farStart" ] = 100; dof_see_price[ "farEnd" ] = 200; dof_see_price[ "farBlur" ] = 4; thread blend_dof( dof_all_blur, dof_see_price, 0.9 ); wait( 1.5 ); dof_see_soap = []; dof_see_soap[ "nearStart" ] = 0; dof_see_soap[ "nearEnd" ] = 150; dof_see_soap[ "nearBlur" ] = 10; dof_see_soap[ "farStart" ] = 300; dof_see_soap[ "farEnd" ] = 800; dof_see_soap[ "farBlur" ] = 4; thread blend_dof( dof_see_price, dof_see_soap, 0.3 ); level waittill( "blend_out_dof", outblend ); thread blend_dof( dof_see_soap, start, outblend ); } die_soon() { self endon( "death" ); wait( RandomFloat( 3 ) ); self.dieQuietly = true; self Kill(); } soap_talks_to_heli() { /* // Viper Six-Four, this is Bravo Six Actual! We're trapped in the mess hall at the northeast corner of the gulag, depth 100 meters!!! I need a four-point SPIE rig for emergency extraction over! level.soap anim_single_solo( level.soap, "gulag_cmt_depth100" ); // Roger on the SPIE rig - we're on the way, give us fifteen seconds. radio_dialogue( "gulag_plp_15secs" ); // We'll be dead in five!!! Move your arse man!!! level.soap dialogue_queue( "gulag_cmt_deadinfive" ); level waittill( "more_soap_dialogue" ); */ wait( 0.5 ); // Six-Four, where the hell are you, over?!!!! // level.soap dialogue_queue( "gulag_cmt_whereareyou" ); wait( 2.8 ); // wait( 3.2 ); // Bravo Six, there's too much smoke, I can't see you I can't see you - radio_dialogue( "gulag_plp_cantsee" ); } set_new_ending_fx_dists() { level.ending_fx_min_dist = 0; level.ending_fx_max_dist = 800; level.ending_fx_dot = 0.3; } cafe_falls_apart() { thread fx_become_more_intense(); thread earthquake_buildup(); maps\_utility::fog_set_changes( "gulag_cafe_falls_apart", 5 ); /* wait( 8 ); black_overlay = create_client_overlay( "black", 0, level.player ); black_overlay.alpha = 0; black_overlay fadeOverTime( 3 ); black_overlay.alpha = 1; level waittill( "stop_cavein" ); wait( 0.05 ); black_overlay destroy(); */ } earthquake_buildup() { level notify( "stop_minor_earthquakes" ); time = gettime(); wait_for_buffer_time_to_pass( time, 2.9 ); quake( 0.3, 1.4, level.soap.origin, 5000 ); wait_for_buffer_time_to_pass( time, 4.2 ); thread player_ending_cavein(); wait_for_buffer_time_to_pass( time, 6.45 ); quake( 0.45, 4, level.soap.origin, 5000 ); wait( 1 ); quake( 0.45, 3, level.player.origin, 5000 ); } quake_rumble() { if ( flag( "controlled_player_rumble" ) ) return; level.player endon( "death" ); rumbles = []; rumbles[ rumbles.size ] = "heavy_1s"; rumbles[ rumbles.size ] = "heavy_2s"; rumbles[ rumbles.size ] = "heavy_1s"; rumbles[ rumbles.size ] = "heavy_2s"; rumbles[ rumbles.size ] = "heavy_3s"; rumbles[ rumbles.size ] = "light_1s"; rumbles[ rumbles.size ] = "light_2s"; rumbles[ rumbles.size ] = "light_1s"; rumbles[ rumbles.size ] = "light_2s"; rumbles[ rumbles.size ] = "light_1s"; rumbles[ rumbles.size ] = "light_2s"; rumbles[ rumbles.size ] = "light_1s"; rumbles[ rumbles.size ] = "light_2s"; rumbles[ rumbles.size ] = "light_3s"; rumbles[ rumbles.size ] = "light_3s"; rumble = random( rumbles ); vec = randomvector( 1700 ); PlayRumbleOnPosition( rumble, level.player.origin + vec ); } quake( mag, duration, org, range ) { //vec = randomvector( 5 ); //PlayRumbleOnPosition( "heavy_3s", level.player.origin + vec ); thread quake_rumble(); Earthquake( mag, duration, org, range ); level notify( "swing", mag ); // artillery sound angles = ( randomint( 360 ), randomint( 360 ), randomint( 360 ) ); forward = anglestoforward( angles ); range = randomfloatrange( 500, 1000 ); location = level.player.origin + forward * range; thread play_sound_in_space( "exp_artillery_underground", location ); } fx_become_more_intense() { time = 7; min = 0.01; max = level.fx_fall_time; range = max - min; frames = time * 20; for ( i = 0; i < frames; i++ ) { dif = i / frames; dif = 1 - dif; level.fx_fall_time = min + range * dif; wait( 0.05 ); } } cafe_lights_explode() { wait( 3 ); light_destructibles = getentarray( "light_destructible", "script_noteworthy" ); array_thread( light_destructibles, ::light_destructible_think ); } player_pushes_slab() { if ( flag( "time_to_evac" ) ) return; level endon( "time_to_evac" ); for ( ;; ) { flag_wait( "player_pushes_slab" ); level.player disableweapons(); flag_waitopen( "player_pushes_slab" ); level.player enableweapons(); } } rubble_think() { if ( level.start_point == "evac" ) return; offset = 240; self connectpaths(); self.origin += ( 0, 0, offset * -1 ); self hide(); self notsolid(); flag_wait( "enter_final_room" ); wait( 4 ); exploder( "cafeteria_collapse" ); chase_brush = getent( "chase_brush", "targetname" ); chase_brush unlink(); thread player_touch_kill(); self show(); self solid(); self moveto( self.origin + (0,0,offset), 4, 1, 3 ); chase_brush moveto( chase_brush.origin + (0,0,-300), 4, 2 ); wait( 4 ); level notify( "stop_chase_fx" ); chase_brush delete(); self disconnectpaths(); } player_touch_kill() { level endon( "stop_chase_fx" ); for ( ;; ) { if ( level.player istouching( self ) ) RadiusDamage( level.player.origin, 35, 10, 5 ); wait( 0.05 ); } } hunted_hanging_light() { fx = getfx( "gulag_cafe_spotlight" ); tag_origin = spawn_tag_origin(); tag_origin LinkTo( self.lamp, "j_hanging_light_04", (0,0,-32), (0,0,0) ); PlayFXOnTag( fx, tag_origin, "tag_origin" ); flag_wait( "time_to_evac" ); stopFXOnTag( fx, tag_origin, "tag_origin" ); } swing_light_org_think() { lamp = spawn_anim_model( "lamp" ); lamp thread lamp_animates( self ); } swing_light_org_off_think() { lamp = spawn_anim_model( "lamp_off" ); lamp thread lamp_animates( self ); } lamp_animates( root ) { root.lamp = self; self.animname = "lamp"; // uses one set of anims self.origin = root.origin; self dontcastshadows(); // cant blend to the same anim odd = true; anims = []; anims[ 0 ] = self getanim( "swing" ); anims[ 1 ] = self getanim( "swing_dup" ); thread lamp_rotates_yaw(); for ( ;; ) { level waittill( "swing", mag ); animation = anims[ odd ]; off = !odd; self SetAnimRestart( animation, 1, 0.3, 1 ); wait( 2.5 ); } } lamp_rotates_yaw() { ent = spawn_tag_origin(); for ( ;; ) { yaw = randomfloatrange( -30, 30 ); ent addyaw( yaw ); time = randomfloatrange( 0.5, 1.5 ); self rotateto( ent.angles, time, time * 0.4, time * 0.4 ); wait( time ); } } swap_world_fx() { wait( 3 ); flag_clear( "enable_endlog_fx" ); flag_clear( "disable_exterior_fx" ); } orient_player_to_rig( player_rig ) { tag_origin = spawn_tag_origin(); // angles = player_rig gettagangles( "tag_player" ); // origin = player_rig gettagorigin( "tag_player" ); tag_origin.origin = level.player.origin; tag_origin.angles = level.player.angles; wait( 0.05 ); level.player PlayerSetGroundReferenceEnt( tag_origin ); wait( 5 ); wait( 0.05 ); tag_origin LinkToBlendToTag( player_rig, "tag_player", false ); // tag_origin linkto( player_rig, "tag_player", (0,0,0),(0,0,0) ); // tag_origin thread maps\_debug::drawtagforever( "tag_origin" ); } map_spawners_to_starts( orgs ) { spawner = GetEnt( "price_spawner", "targetname" ); spawner.origin = orgs[ "price" ].origin; spawner.angles = orgs[ "price" ].angles; spawner spawn_ai(); spawner = GetEnt( "endlog_soap_spawner", "targetname" ); spawner.origin = orgs[ "soap" ].origin; spawner.angles = orgs[ "soap" ].angles; spawner spawn_ai(); spawner = getentarray( "endlog_redshirt_spawner", "targetname" )[ 0 ]; spawner.origin = orgs[ "redshirt" ].origin; spawner.angles = orgs[ "redshirt" ].angles; spawner spawn_ai(); } set_cafeteria_spotlight_dvars() { setsaveddvar( "r_spotlightbrightness", "1.2" ); setsaveddvar( "r_spotlightendradius", "1200" ); setsaveddvar( "r_spotlightstartradius", "50" ); setsaveddvar( "r_spotlightfovinnerfraction", "0.8" ); setsaveddvar( "r_spotlightexponent", "2" ); } player_gets_hit_by_rock() { if ( flag( "time_to_evac" ) ) return; vec = randomvector( 16 ); vec = set_z( vec, 80 ); if ( level.player.health > 80 ) level.player DoDamage( 15 / level.player.damagemultiplier, level.player.origin + vec ); } blend_in_player_movespeed() { time = 2.5; dif = time / 20; for ( i = 0; i <= 1; i+= dif ) { level.player SetMoveSpeedScale( i ); wait( 0.05 ); } }