1593 lines
35 KiB
Plaintext
1593 lines
35 KiB
Plaintext
|
#include maps\_utility;
|
|||
|
#include maps\_vehicle;
|
|||
|
#include maps\_anim;
|
|||
|
#include maps\_blizzard;
|
|||
|
#include common_scripts\utility;
|
|||
|
#include maps\_hud_util;
|
|||
|
#include maps\_vehicle_spline;
|
|||
|
#include maps\cliffhanger_code;
|
|||
|
#include maps\cliffhanger;
|
|||
|
#include maps\cliffhanger_snowmobile;
|
|||
|
|
|||
|
RED = ( 1, 0, 0 );
|
|||
|
|
|||
|
/************************************************************************************************************/
|
|||
|
/* SNOWMOBILE */
|
|||
|
/************************************************************************************************************/
|
|||
|
|
|||
|
|
|||
|
enemy_snowmobile_chase_spawner_think()
|
|||
|
{
|
|||
|
self endon( "death" );
|
|||
|
self thread chase_player();
|
|||
|
|
|||
|
for ( ;; )
|
|||
|
{
|
|||
|
self.baseAccuracy = 0;
|
|||
|
flag_wait( "price_ditches_player" );
|
|||
|
self.baseAccuracy = 1000;
|
|||
|
|
|||
|
flag_waitopen( "price_ditches_player" );
|
|||
|
self.baseAccuracy = 0;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
chase_player()
|
|||
|
{
|
|||
|
self.goalradius = 250;
|
|||
|
target_ent = spawn( "script_origin", ( 0, 0, 0 ) );
|
|||
|
// shoot near the player if he is with price
|
|||
|
|
|||
|
for ( ;; )
|
|||
|
{
|
|||
|
if ( !isalive( self ) )
|
|||
|
return;
|
|||
|
|
|||
|
if ( flag( "player_slides_down_hill" ) )
|
|||
|
{
|
|||
|
self delete();
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
if ( flag( "price_ditches_player" ) )
|
|||
|
{
|
|||
|
self clearEntityTarget();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
self setentitytarget( target_ent );
|
|||
|
angles = vectortoangles( level.player.origin - self.origin );
|
|||
|
angles = ( 0, angles[ 1 ], 0 );
|
|||
|
|
|||
|
forward = anglestoforward( angles );
|
|||
|
target_ent.origin = level.player.origin + forward * 250;
|
|||
|
random_vec = randomvector( 200 );
|
|||
|
random_vec = ( random_vec[ 0 ], random_vec[ 1 ], 0 );
|
|||
|
target_ent.origin += random_vec;
|
|||
|
|
|||
|
target_ent.origin = drop_to_ground( target_ent.origin ) + ( 0, 0, 1 );
|
|||
|
}
|
|||
|
//Line( self.origin, target_ent.origin );
|
|||
|
self setgoalpos( level.player.origin );
|
|||
|
wait( randomfloatrange( 0.4, 0.7 ) );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
price_ditches_player_detection()
|
|||
|
{
|
|||
|
level endon( "player_slides_down_hill" );
|
|||
|
for ( ;; )
|
|||
|
{
|
|||
|
player_near_price = distance( level.price.origin, level.player.origin ) < 256;
|
|||
|
|
|||
|
if ( flag( "price_ditches_player" ) )
|
|||
|
{
|
|||
|
if ( player_near_price )
|
|||
|
{
|
|||
|
flag_clear( "price_ditches_player" );
|
|||
|
level.price.ignoreme = false;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if ( !player_near_price )
|
|||
|
{
|
|||
|
flag_set( "price_ditches_player" );
|
|||
|
level.price.ignoreme = true;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
wait( 0.05 );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
modulate_speed_based_on_distance()
|
|||
|
{
|
|||
|
// modulate speed based on distance until player gets on his bike
|
|||
|
if ( flag( "player_gets_on_snowmobile" ) )
|
|||
|
return;
|
|||
|
level endon( "player_gets_on_snowmobile" );
|
|||
|
|
|||
|
for ( ;; )
|
|||
|
{
|
|||
|
dist = distance( self.origin, level.player.origin );
|
|||
|
maxspeed = 60; // the speed the bike goes when it is near the player
|
|||
|
maxrange = 1000; // the distance at which to stop
|
|||
|
|
|||
|
dist = maxrange - dist;
|
|||
|
if ( dist < 0 )
|
|||
|
dist = 0;
|
|||
|
|
|||
|
speed = 60 * dist / 1000;
|
|||
|
self Vehicle_SetSpeed( speed, 1, 1 );
|
|||
|
wait( 0.05 );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
stop_modulation_at_big_hill()
|
|||
|
{
|
|||
|
//flag_wait( "player_reaches_hilltop" );
|
|||
|
|
|||
|
price_goes_down_hill = getent( "price_goes_down_hill", "targetname" );
|
|||
|
for ( ;; )
|
|||
|
{
|
|||
|
price_goes_down_hill waittill( "trigger", other );
|
|||
|
if ( !isalive( other ) )
|
|||
|
continue;
|
|||
|
if ( other == level.price )
|
|||
|
break;
|
|||
|
}
|
|||
|
// level.price.vehicle.veh_pathtype = "follow";
|
|||
|
|
|||
|
//level.price.vehicle notify( "stop_modulating_speed" );
|
|||
|
//level.price.vehicle vehicle_setspeed( 75, 30, 30 );
|
|||
|
/*
|
|||
|
for ( ;; )
|
|||
|
{
|
|||
|
if ( !isdefined( level.player.vehicle ) )
|
|||
|
return;
|
|||
|
|
|||
|
if ( flag( "price_takes_jump" ) )
|
|||
|
break;
|
|||
|
|
|||
|
min_speed = level.price.vehicle.veh_speed;
|
|||
|
if ( min_speed > 169 )
|
|||
|
break;
|
|||
|
|
|||
|
level.price.vehicle.min_speed = min_speed;
|
|||
|
wait( 0.05 );
|
|||
|
}
|
|||
|
*/
|
|||
|
|
|||
|
level.price.vehicle notify( "stop_modulating_speed" );
|
|||
|
// level.price.vehicle vehicle_setspeed( 0, 20, 20 );
|
|||
|
|
|||
|
// flag_wait( "price_gets_to_other_side" );
|
|||
|
level.price.vehicle resumespeed( 100 );
|
|||
|
//level.price.vehicle vehicle_setspeed( 50, 35, 35 );
|
|||
|
// level.price.vehicle.veh_pathtype = "constrained";
|
|||
|
// wait( 6 );
|
|||
|
// speed = 60;
|
|||
|
// level.price.vehicle Vehicle_SetSpeed( speed, speed * 0.25, speed * 0.25 );
|
|||
|
}
|
|||
|
|
|||
|
price_leads_player_to_heli()
|
|||
|
{
|
|||
|
level.price.vehicle = self;
|
|||
|
|
|||
|
flag_wait( "price_ready_for_auto_speed" );
|
|||
|
level.price forceUseWeapon( "kriss", "primary" );
|
|||
|
|
|||
|
modulate_speed_based_on_distance();
|
|||
|
thread modulate_speed_based_on_progress();
|
|||
|
thread stop_modulation_at_big_hill();
|
|||
|
|
|||
|
self waittill( "reached_end_node" );
|
|||
|
|
|||
|
thread unload_failsafe();
|
|||
|
wait( 1 );
|
|||
|
// self notify( "unload" );
|
|||
|
|
|||
|
level.price waittill( "jumpedout" );
|
|||
|
|
|||
|
flag_wait( "ending_heli_flies_in" );
|
|||
|
level.ending_heli ent_flag_wait( "landed" );
|
|||
|
|
|||
|
level.ending_heli anim_reach_solo( level.price, "evac", "tag_detach" );
|
|||
|
level.price linkto( level.ending_heli, "tag_detach" );
|
|||
|
delaythread( 6, ::flag_set, "price_enters_heli" );
|
|||
|
level.ending_heli anim_single_solo( level.price, "evac", "tag_detach" );
|
|||
|
}
|
|||
|
|
|||
|
unload_failsafe()
|
|||
|
{
|
|||
|
self endon( "unload" );
|
|||
|
level.price endon( "jumpedout" );
|
|||
|
wait( 4 );
|
|||
|
self vehicle_unload();
|
|||
|
}
|
|||
|
|
|||
|
banister_spawner_think()
|
|||
|
{
|
|||
|
self add_spawn_function( ::banister_spawn_func );
|
|||
|
flag_wait( "snowmobile_in_house" );
|
|||
|
self spawn_ai();
|
|||
|
}
|
|||
|
|
|||
|
banister_spawn_func()
|
|||
|
{
|
|||
|
self.ignoreall = true;
|
|||
|
self endon( "death" );
|
|||
|
|
|||
|
for ( ;; )
|
|||
|
{
|
|||
|
if ( !isdefined( level.player.vehicle ) )
|
|||
|
break;
|
|||
|
dist = distance( level.player.vehicle.origin, self.origin );
|
|||
|
if ( dist < 300 )
|
|||
|
{
|
|||
|
self.ignoreall = false;
|
|||
|
}
|
|||
|
|
|||
|
if ( dist < 210 )
|
|||
|
{
|
|||
|
self set_generic_deathanim( "balcony_death" );
|
|||
|
/*
|
|||
|
org = self.origin;
|
|||
|
org = ( org[0], org[1] - 15, org[2] );
|
|||
|
RadiusDamage( org, 20, 1500, 1500, self );
|
|||
|
wait( 0.2 );
|
|||
|
*/
|
|||
|
self kill();
|
|||
|
return;
|
|||
|
/*
|
|||
|
self kill();
|
|||
|
angles = level.player.vehicle.angles;
|
|||
|
forward = anglestoforward( angles );
|
|||
|
forward *= 50;
|
|||
|
self StartRagdollFromImpact( level.player.vehicle.origin, forward );
|
|||
|
*/
|
|||
|
}
|
|||
|
wait( 0.05 );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
player_jolts_house()
|
|||
|
{
|
|||
|
pulsetime = 0.05;
|
|||
|
timer = 2;
|
|||
|
timer /= pulsetime;
|
|||
|
for ( i = 0; i < timer; i++ )
|
|||
|
{
|
|||
|
if ( !isdefined( level.player.vehicle ) )
|
|||
|
return;
|
|||
|
forward = anglestoforward( level.player.vehicle.angles );
|
|||
|
org = level.player.vehicle.origin + forward * 55;
|
|||
|
org = ( org[ 0 ], org[ 1 ], level.player.vehicle.origin[ 2 ] );
|
|||
|
PhysicsExplosionSphere( org, 165, 125, 50 );
|
|||
|
wait( pulsetime );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
friends_drive()
|
|||
|
{
|
|||
|
self.hero = true;
|
|||
|
price_bike_path = getent( "price_bike_path", "targetname" );
|
|||
|
for ( ;; )
|
|||
|
{
|
|||
|
self vehicleDriveTo( price_bike_path.origin, 20 );
|
|||
|
if ( distance( self.origin, price_bike_path.origin ) < price_bike_path.radius )
|
|||
|
break;
|
|||
|
wait( 0.2 );
|
|||
|
}
|
|||
|
|
|||
|
flag_wait( "player_gets_on_snowmobile" );
|
|||
|
self.health = 5000;// need to use vehicle bullet shield
|
|||
|
//level.snowmobile_path[ 0 ] thread bike_drives_path( self );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
speed_print()
|
|||
|
{
|
|||
|
self.printspeed = 0;
|
|||
|
self.printprogress = 0;
|
|||
|
self endon( "death" );
|
|||
|
for ( ;; )
|
|||
|
{
|
|||
|
Print3d( self.origin + (0,0,36), self.printspeed + " " + self.printprogress, (1,0.2,0.2), 1, 1, int( 0.2 * 20 ) );
|
|||
|
wait( 0.2 );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
track_player_ride_progress()
|
|||
|
{
|
|||
|
avalanche_progress_org = getent( "avalanche_progress_org", "targetname" );
|
|||
|
targ = getent( avalanche_progress_org.target, "targetname" );
|
|||
|
dist = distance( avalanche_progress_org.origin, targ.origin );
|
|||
|
for ( ;; )
|
|||
|
{
|
|||
|
array = get_progression_between_points( self.origin, avalanche_progress_org.origin, targ.origin );
|
|||
|
progress = array[ "progress" ];
|
|||
|
level.player_ride_progress = progress;
|
|||
|
level.player_ride_progress_percent = progress / dist;
|
|||
|
wait( 0.2 );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
remove_from_chase_vehicles()
|
|||
|
{
|
|||
|
self waittill_either( "death", "veh_collision" );
|
|||
|
level.chase_vehicles = array_remove_nokeys( level.chase_vehicles, self );
|
|||
|
}
|
|||
|
|
|||
|
avalache_chase_vehicle_spawner_think()
|
|||
|
{
|
|||
|
self waittill( "spawned", vehicle );
|
|||
|
vehicle endon( "death" );
|
|||
|
//vehicle thread speed_print();
|
|||
|
vehicle thread vehicle_becomes_crashable();
|
|||
|
vehicle thread vehicle_tumble_in_avalanche();
|
|||
|
|
|||
|
// we would do this if drivers shooting looked good
|
|||
|
/*if ( vehicle.riders.size == 1 )
|
|||
|
{
|
|||
|
// no passenger, make the driver shoot
|
|||
|
vehicle.driver_shooting = true;
|
|||
|
vehicle.passenger_shooting = false;
|
|||
|
}*/
|
|||
|
|
|||
|
level.chase_vehicles[ level.chase_vehicles.size ] = vehicle;
|
|||
|
vehicle.personal_offset = 0;
|
|||
|
vehicle thread remove_from_chase_vehicles();
|
|||
|
|
|||
|
vehicle snowmobile_maintains_distance_behind_player();
|
|||
|
}
|
|||
|
|
|||
|
snowmobile_maintains_distance_behind_player()
|
|||
|
{
|
|||
|
avalanche_progress_org = getent( "avalanche_progress_org", "targetname" );
|
|||
|
targ = getent( avalanche_progress_org.target, "targetname" );
|
|||
|
start_time = gettime();
|
|||
|
|
|||
|
self Vehicle_SetSpeed( 35, 25, 25 );
|
|||
|
for ( ;; )
|
|||
|
{
|
|||
|
array = get_progression_between_points( self.origin, avalanche_progress_org.origin, targ.origin );
|
|||
|
progress = array[ "progress" ];
|
|||
|
progress_dif = progress - level.player_ride_progress;
|
|||
|
self.progress_dif = progress_dif;
|
|||
|
progress_dif += self.personal_offset;
|
|||
|
|
|||
|
if ( progress_dif > 250 )
|
|||
|
{
|
|||
|
speed = 0.25;
|
|||
|
}
|
|||
|
else
|
|||
|
if ( progress_dif > 50 )
|
|||
|
{
|
|||
|
// we're ahead so slow down
|
|||
|
speed = 0.75;
|
|||
|
}
|
|||
|
else
|
|||
|
if ( progress_dif < -400 )
|
|||
|
{
|
|||
|
speed = 2;
|
|||
|
}
|
|||
|
else
|
|||
|
if ( progress_dif < -200 )
|
|||
|
{
|
|||
|
speed = 1.2;
|
|||
|
}
|
|||
|
else
|
|||
|
if ( progress_dif < -100 )
|
|||
|
{
|
|||
|
speed = 1.05;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
speed = 1;
|
|||
|
}
|
|||
|
|
|||
|
if ( gettime() > start_time + 3000 )
|
|||
|
{
|
|||
|
player_speed = level.player_ride vehicle_getSpeed();
|
|||
|
self Vehicle_SetSpeed( player_speed * speed, 25, 25 );
|
|||
|
}
|
|||
|
|
|||
|
wait( 0.2 );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
chase_vehicles_get_personal_progress_offset()
|
|||
|
{
|
|||
|
// makes vehicles spread out behind player
|
|||
|
for ( ;; )
|
|||
|
{
|
|||
|
offset = 100;
|
|||
|
waittillframeend;// for chase_vehicles to be up to date
|
|||
|
if ( level.chase_vehicles.size )
|
|||
|
{
|
|||
|
array = get_array_of_closest( level.player_ride.origin, level.chase_vehicles );
|
|||
|
for ( i = 0; i < array.size; i++ )
|
|||
|
{
|
|||
|
array[ i ].personal_offset = offset;
|
|||
|
offset += randomintrange( 100, 200 );
|
|||
|
}
|
|||
|
}
|
|||
|
wait( 0.21 );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
avalanche_section()
|
|||
|
{
|
|||
|
node = getvehiclenode( self.target, "targetname" );
|
|||
|
self hide();
|
|||
|
|
|||
|
level.avalanche_vehicles[ level.avalanche_vehicles.size ] = self;
|
|||
|
fxmodel = spawn_tag_origin();
|
|||
|
fxmodel linkto( self, "tag_origin", ( 0, 0, 256 ), ( 0, 0, -90 ) );
|
|||
|
playfxontag( level._effect[ "avalanche_loop_large" ], fxmodel, "tag_origin" );
|
|||
|
thread gopath( self );
|
|||
|
self.personal_offset = 2000;
|
|||
|
self thread avalanche_maintains_distance_behind_player();
|
|||
|
|
|||
|
// self thread avlanche_node_think( node );
|
|||
|
}
|
|||
|
|
|||
|
avalanche_maintains_distance_behind_player()
|
|||
|
{
|
|||
|
if ( isdefined( self.script_noteworthy ) && self.script_noteworthy == "main_avalanche" )
|
|||
|
{
|
|||
|
// this trigger follows the avalanche and kills vehicles that get in it
|
|||
|
level.main_avalanche = self;
|
|||
|
avalanche_trigger = getent( "avalanche_trigger", "targetname" );
|
|||
|
avalanche_trigger playsound( "avalanche_ambiance_main" );
|
|||
|
self.progress = 0;
|
|||
|
avalanche_trigger thread trigger_follows_avalanche();
|
|||
|
avalanche_trigger thread trigger_kills_vehicles();
|
|||
|
}
|
|||
|
|
|||
|
avalanche_progress_org = getent( "avalanche_progress_org", "targetname" );
|
|||
|
targ = getent( avalanche_progress_org.target, "targetname" );
|
|||
|
for ( ;; )
|
|||
|
{
|
|||
|
array = get_progression_between_points( self.origin, avalanche_progress_org.origin, targ.origin );
|
|||
|
progress = array[ "progress" ];
|
|||
|
self.progress = progress;
|
|||
|
progress_dif = progress - level.player_ride_progress;
|
|||
|
self.progress_dif = progress_dif;
|
|||
|
progress_dif += self.personal_offset;
|
|||
|
|
|||
|
speed = 1;
|
|||
|
if ( progress_dif > -100 && progress_dif < 100 )
|
|||
|
{
|
|||
|
speed = 1;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if ( progress_dif < -200 )
|
|||
|
{
|
|||
|
speed = 1.5;
|
|||
|
}
|
|||
|
else
|
|||
|
if ( progress_dif < -400 )
|
|||
|
{
|
|||
|
speed = 2;
|
|||
|
}
|
|||
|
else
|
|||
|
if ( progress_dif > 120 )
|
|||
|
{
|
|||
|
speed = 0.25;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
player_speed = level.player_ride vehicle_getSpeed();
|
|||
|
self Vehicle_SetSpeed( player_speed * speed, 150, 150 );
|
|||
|
wait( 0.2 );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
trigger_follows_avalanche()
|
|||
|
{
|
|||
|
avalanche_progress_org = getent( "avalanche_progress_org", "targetname" );
|
|||
|
targ = getent( avalanche_progress_org.target, "targetname" );
|
|||
|
angles = vectortoangles( avalanche_progress_org.origin - targ.origin );
|
|||
|
self.angles = angles + (0,90,0);
|
|||
|
|
|||
|
dist = distance( avalanche_progress_org.origin, targ.origin );
|
|||
|
for ( ;; )
|
|||
|
{
|
|||
|
progress = level.main_avalanche.progress - 100;
|
|||
|
progress_percent = progress / dist;
|
|||
|
|
|||
|
self.origin = avalanche_progress_org.origin * ( 1 - progress_percent ) + targ.origin * progress_percent;
|
|||
|
//Line( self.origin, level.player.origin, (0,0.6,0.4), 1, 0, int(0.2*20));
|
|||
|
wait( 0.2 );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
avlanche_node_think( node )
|
|||
|
{
|
|||
|
wait 1;
|
|||
|
|
|||
|
gopath( self );
|
|||
|
|
|||
|
while ( 1 )
|
|||
|
{
|
|||
|
wait 12.5;
|
|||
|
|
|||
|
self.attachedpath = undefined;
|
|||
|
self notify( "newpath" );
|
|||
|
self attachpath( node );
|
|||
|
gopath( self );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
trigger_kills_vehicles()
|
|||
|
{
|
|||
|
for ( ;; )
|
|||
|
{
|
|||
|
self waittill( "trigger", other );
|
|||
|
other notify( "driver_died" );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
set_avalanche_offset( offset )
|
|||
|
{
|
|||
|
foreach( vehicle in level.avalanche_vehicles )
|
|||
|
{
|
|||
|
vehicle.personal_offset = offset;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
enemy_snowmobiles_spawn_and_attack()
|
|||
|
{
|
|||
|
level endon( "snowmobile_jump" );
|
|||
|
level endon( "enemy_snowmobiles_wipe_out" );
|
|||
|
wait_time = 3;
|
|||
|
flag_wait( "player_starts_snowmobile_trip" );
|
|||
|
|
|||
|
for ( ;; )
|
|||
|
{
|
|||
|
thread spawn_enemy_bike();
|
|||
|
wait( wait_time );
|
|||
|
wait_time -= 0.5;
|
|||
|
if ( wait_time < 0.5 )
|
|||
|
wait_time = 0.5;
|
|||
|
//wait( randomfloatrange( 2, 3 ) );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
rider_gains_accuracy()
|
|||
|
{
|
|||
|
self endon( "death" );
|
|||
|
wait 20;
|
|||
|
self.baseAccuracy = 1;
|
|||
|
}
|
|||
|
|
|||
|
become_price_snowmobile()
|
|||
|
{
|
|||
|
self VehPhys_DisableCrashing();
|
|||
|
}
|
|||
|
|
|||
|
price_snowmobile_riders_are_invulnerable_for_awhile()
|
|||
|
{
|
|||
|
self magic_bullet_shield();
|
|||
|
wait( 7.5 );
|
|||
|
self stop_magic_bullet_shield();
|
|||
|
}
|
|||
|
|
|||
|
die_on_snowmobile_mount()
|
|||
|
{
|
|||
|
self endon( "death" );
|
|||
|
flag_wait( "player_rides_snowmobile" );
|
|||
|
wait( randomfloat( 0.35 ) );
|
|||
|
self kill();
|
|||
|
}
|
|||
|
|
|||
|
icepick_vehicle_think()
|
|||
|
{
|
|||
|
self VehPhys_DisableCrashing();
|
|||
|
foreach ( rider in self.riders )
|
|||
|
{
|
|||
|
noteworthy = "";
|
|||
|
if ( isdefined( rider.script_noteworthy ) )
|
|||
|
noteworthy = rider.script_noteworthy;
|
|||
|
if ( noteworthy == "magic_bullet_spawner" )
|
|||
|
{
|
|||
|
rider thread die_on_snowmobile_mount();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
rider.health = 20;
|
|||
|
}
|
|||
|
|
|||
|
rider thread rider_gains_accuracy();
|
|||
|
}
|
|||
|
|
|||
|
price_snowmobile = isdefined( self.script_noteworthy ) && self.script_noteworthy == "god_vehicle_spawner";
|
|||
|
|
|||
|
if ( price_snowmobile )
|
|||
|
{
|
|||
|
self.riders[0] price_snowmobile_riders_are_invulnerable_for_awhile();
|
|||
|
|
|||
|
level.price_snowmobile = self;
|
|||
|
level.price_snowmobile_riders = self.riders;
|
|||
|
self waittill( "reached_end_node" );
|
|||
|
wait( 3 );
|
|||
|
self become_price_snowmobile();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
self thread vehicle_becomes_crashable();
|
|||
|
self icepick_ride_until_crash();
|
|||
|
}
|
|||
|
|
|||
|
if ( isalive( self.riders[ 0 ] ) )
|
|||
|
{
|
|||
|
//wait( 1 );
|
|||
|
//self vehicle_unload();
|
|||
|
foreach ( rider in self.riders )
|
|||
|
{
|
|||
|
if ( isalive( rider ) )
|
|||
|
rider.baseAccuracy = 1;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
self Vehicle_SetSpeed( 0, 35, 35 );
|
|||
|
|
|||
|
level.icepick_snowmobiles[ level.icepick_snowmobiles.size ] = self;
|
|||
|
level notify( "new_icepick_snowmobile" );
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
wait_for_end_node_or_player_rides()
|
|||
|
{
|
|||
|
level endon( "player_rides_snowmobile" );
|
|||
|
self waittill( "reached_end_node" );
|
|||
|
}
|
|||
|
|
|||
|
icepick_ride_until_crash()
|
|||
|
{
|
|||
|
self.riders[ 0 ] endon( "death" );
|
|||
|
//self endon( "reached_path_end" );
|
|||
|
self endon( "death" );
|
|||
|
self endon( "veh_collision" );
|
|||
|
|
|||
|
wait_for_end_node_or_player_rides();
|
|||
|
flag_wait( "player_starts_snowmobile_trip" );
|
|||
|
|
|||
|
node = self get_my_spline_node( self.origin );
|
|||
|
//Line( vehicle.origin, node.midpoint, (1, 0, 0 ), 1, 0, 5000 );
|
|||
|
node thread [[ level.drive_spline_path_fun ]]( self );
|
|||
|
|
|||
|
/*
|
|||
|
for ( ;; )
|
|||
|
{
|
|||
|
if ( self vehicle_getspeed() > 15 )
|
|||
|
{
|
|||
|
break;
|
|||
|
}
|
|||
|
wait( 0.05 );
|
|||
|
}
|
|||
|
|
|||
|
for ( ;; )
|
|||
|
{
|
|||
|
if ( self vehicle_getspeed() < 4 )
|
|||
|
{
|
|||
|
break;
|
|||
|
}
|
|||
|
wait( 0.05 );
|
|||
|
}
|
|||
|
*/
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/*
|
|||
|
HUNTER KILLER HELI chases player during snowmobile ride
|
|||
|
*/
|
|||
|
hk_heli()
|
|||
|
{
|
|||
|
/#
|
|||
|
if ( getdebugdvarint( "chasecam" ) )
|
|||
|
return;
|
|||
|
#/
|
|||
|
|
|||
|
if ( level.start_point != "snowspawn" )
|
|||
|
{
|
|||
|
flag_wait( "enemies_persue_on_bike" );
|
|||
|
}
|
|||
|
|
|||
|
hk_spawner = getent( "hunter_killer", "targetname" );
|
|||
|
/#
|
|||
|
if ( level.start_point == "snowspawn" )
|
|||
|
{
|
|||
|
hk_spawner = getent( "hunter_killer_start", "targetname" );
|
|||
|
wait( 1 );
|
|||
|
}
|
|||
|
#/
|
|||
|
|
|||
|
hk = hk_spawner spawn_vehicle();
|
|||
|
level.hk = hk;
|
|||
|
flag_set( "hk_gives_chase" );
|
|||
|
hk.attack_progress = 4000;
|
|||
|
hk.warnings = 0;
|
|||
|
hk.hover_warnings = 3; // warnings at which heli goes after you
|
|||
|
hk ent_flag_init( "firing" );
|
|||
|
|
|||
|
hk thread hk_moves();
|
|||
|
hk thread hk_wait_until_player_stops_progressing();
|
|||
|
/*
|
|||
|
for ( ;; )
|
|||
|
{
|
|||
|
// hk SetVehGoalPos( level.player.origin + (0,0,1200), false );
|
|||
|
angles = vectortoangles( level.player.origin - hk.origin );
|
|||
|
yaw = angles[ 1 ];
|
|||
|
if ( hk.warnings >= 8 )
|
|||
|
{
|
|||
|
hk SetGoalYaw( yaw );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
hk ClearGoalYaw();
|
|||
|
}
|
|||
|
|
|||
|
wait( 0.05 );
|
|||
|
}
|
|||
|
*/
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
hk_fires_on_player()
|
|||
|
{
|
|||
|
self endon( "death" );
|
|||
|
if ( !isdefined( level.player.vehicle ) )
|
|||
|
return;
|
|||
|
|
|||
|
// if ( flag( "bad_heli_goes_to_death_position" ) )
|
|||
|
// return;
|
|||
|
|
|||
|
self endon( "stop_tracking" );
|
|||
|
self setVehWeapon( "hind_turret" );
|
|||
|
//self setVehWeapon( "hunted_crash_missile" );
|
|||
|
|
|||
|
forward = anglesToForward( level.player.angles );
|
|||
|
level.hk_lookat_ent.origin = level.player.origin;
|
|||
|
target_guide = spawn( "script_origin", level.player.origin );
|
|||
|
|
|||
|
self setturrettargetent( level.hk_lookat_ent, ( 0, 0, 0 ) );
|
|||
|
//self setlookatent( level.hk_lookat_ent );
|
|||
|
self setlookatent( level.player );
|
|||
|
|
|||
|
|
|||
|
forward_dist = level.player.vehicle vehicle_getSpeed() * 80;
|
|||
|
if ( forward_dist < 2000 && self.warnings < 9 )
|
|||
|
forward_dist = 2000;
|
|||
|
else
|
|||
|
if ( forward_dist > 4000 )
|
|||
|
forward_dist = 4000;
|
|||
|
|
|||
|
forward_org = forward * forward_dist;
|
|||
|
level.hk_lookat_ent.origin = level.player.origin + forward_org;
|
|||
|
|
|||
|
// target_guide lets us plant the target and still keep it linked to the player
|
|||
|
target_guide.origin = level.hk_lookat_ent.origin;
|
|||
|
target_guide linkto( level.player );
|
|||
|
|
|||
|
printTime = 5;
|
|||
|
//Line( self.origin, target.origin, (0.8,1,0), 1, 1, int(printTime*20) );
|
|||
|
|
|||
|
for ( ;; )
|
|||
|
{
|
|||
|
level.hk_lookat_ent.origin = get_trace_pos( target_guide.origin, 0 );
|
|||
|
if ( within_fov_2d( self.origin, self.angles, level.hk_lookat_ent.origin, 0.9 ) )
|
|||
|
break;
|
|||
|
wait( 0.05 );
|
|||
|
}
|
|||
|
|
|||
|
burst = randomintrange( 6, 9 );
|
|||
|
start_pos = level.hk_lookat_ent.origin;
|
|||
|
|
|||
|
burst_break = burst;
|
|||
|
if ( self.warnings < 5 )
|
|||
|
{
|
|||
|
burst_break = burst - 2;
|
|||
|
}
|
|||
|
|
|||
|
for ( i = 0; i < burst_break; i++ )
|
|||
|
{
|
|||
|
/*
|
|||
|
dif = i / burst;
|
|||
|
dif = 1 - dif;
|
|||
|
forward_speed = 1000;
|
|||
|
forward_org = forward * forward_speed * ( dif + 1 );
|
|||
|
target.origin = level.player.origin + forward_org;
|
|||
|
*/
|
|||
|
|
|||
|
dif = i / burst;
|
|||
|
|
|||
|
pos = start_pos * ( 1 - dif ) + level.player.origin * dif;
|
|||
|
//target.origin = pos;
|
|||
|
|
|||
|
// once we start firing, the target homes in on the player
|
|||
|
//angles = vectortoangles( level.player.origin - target.origin );
|
|||
|
// forward = anglestoforward( angles );
|
|||
|
//target.origin += forward * 300;
|
|||
|
level.hk_lookat_ent.origin = get_trace_pos( pos, 0 );
|
|||
|
|
|||
|
|
|||
|
delay = randomfloatrange( 0.1, 0.3 );
|
|||
|
//Line( level.player.origin, target.origin, RED, 1, 1, int(delay*20) );
|
|||
|
//Line( self.origin, target.origin, RED, 1, 1, int(printTime*20) );
|
|||
|
maps\_helicopter_globals::fire_missile( "hind_zippy", 1, level.hk_lookat_ent, delay );
|
|||
|
}
|
|||
|
|
|||
|
target_guide delete();
|
|||
|
}
|
|||
|
|
|||
|
weighted_results( weights )
|
|||
|
{
|
|||
|
total = 0;
|
|||
|
foreach ( _, weight in weights )
|
|||
|
{
|
|||
|
total += weight;
|
|||
|
}
|
|||
|
|
|||
|
assertex( total > 0, "Did weighted results with no weight!" );
|
|||
|
|
|||
|
roll = randomfloat( total );
|
|||
|
total = 0;
|
|||
|
|
|||
|
foreach( type, weight in weights )
|
|||
|
{
|
|||
|
total += weight;
|
|||
|
if ( roll <= total )
|
|||
|
return type;
|
|||
|
}
|
|||
|
|
|||
|
assertEx( 0, "Impossible!" );
|
|||
|
}
|
|||
|
|
|||
|
hk_modulates_track_offset()
|
|||
|
{
|
|||
|
self endon( "death" );
|
|||
|
level endon( "avalanche_begins" );
|
|||
|
if ( flag( "avalanche_begins" ) )
|
|||
|
return;
|
|||
|
for ( ;; )
|
|||
|
{
|
|||
|
self.track_offset = randomfloatrange( -4, 4 );
|
|||
|
if ( self.warnings < self.hover_warnings )
|
|||
|
self.attack_progress = randomfloatrange( 1000, 5000 );
|
|||
|
wait( randomfloatrange( 4, 8 ) );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
hk_moves()
|
|||
|
{
|
|||
|
self endon( "death" );
|
|||
|
//level endon( "bad_heli_goes_to_death_position" );
|
|||
|
/# flag_assert( "bad_heli_goes_to_death_position" ); #/
|
|||
|
|
|||
|
self Vehicle_SetSpeed( 120, 50, 50 );
|
|||
|
self.track_offset = 0;
|
|||
|
thread hk_modulates_track_offset();
|
|||
|
|
|||
|
flag_wait( "player_gets_on_snowmobile" );
|
|||
|
|
|||
|
|
|||
|
for ( ;; )
|
|||
|
{
|
|||
|
// bit hacky way to wait for the player to link to the vehicle, only needed cause of start points
|
|||
|
if ( get_player_targ().index > 0 )
|
|||
|
break;
|
|||
|
wait( 0.05 );
|
|||
|
}
|
|||
|
|
|||
|
self SetYawSpeed( 300, 160, 160 );
|
|||
|
self Vehicle_SetSpeed( 350, 75, 275 );
|
|||
|
level.hk_lookat_ent = spawn( "script_origin", level.player.origin );
|
|||
|
self setlookatent( level.hk_lookat_ent );
|
|||
|
|
|||
|
for ( ;; )
|
|||
|
{
|
|||
|
dest_dist = randomfloatrange( 7500, 9500 );
|
|||
|
dest_offset = randomfloatrange( 550, 750 );
|
|||
|
if ( coinToss() )
|
|||
|
dest_offset *= -1;
|
|||
|
pos = get_position_from_spline_unlimited( get_player_targ(), get_player_progress() + dest_dist, dest_offset );
|
|||
|
pos = get_trace_pos( pos, 1200 );
|
|||
|
|
|||
|
//self clearlookatent();
|
|||
|
self setNearGoalNotifyDist( 1000 );
|
|||
|
|
|||
|
//self ent_flag_waitopen( "firing" );
|
|||
|
if ( !flag( "bad_heli_goes_to_death_position" ) )
|
|||
|
{
|
|||
|
hk_flies_to_pos_until_goal( pos );
|
|||
|
self SetVehGoalPos( pos, true );
|
|||
|
}
|
|||
|
|
|||
|
timer = gettime();
|
|||
|
hk_fires_on_player();
|
|||
|
delay = randomfloatrange( 2, 3 );
|
|||
|
wait_for_buffer_time_to_pass( timer, delay );
|
|||
|
//self thread hk_tracks_player();
|
|||
|
|
|||
|
/*
|
|||
|
add_wait( ::hk_waits_until_player_passes );
|
|||
|
add_wait( ::_wait, 4 );
|
|||
|
add_endon( "stop_tracking" );
|
|||
|
do_wait_any();
|
|||
|
*/
|
|||
|
self notify( "stop_tracking" );
|
|||
|
|
|||
|
//Line( self.origin, pos, (1,0,1), 1, 0, int( 0.5 * 20 ) );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
hk_waits_until_player_passes()
|
|||
|
{
|
|||
|
targ = get_my_spline_node( self.origin );
|
|||
|
array = get_progression_between_points( self.origin, targ.midpoint, targ.next_node.midpoint );
|
|||
|
|
|||
|
for ( ;; )
|
|||
|
{
|
|||
|
progress = array[ "progress" ];
|
|||
|
dif = progress_dif( targ, progress, get_player_targ(), get_player_progress() );
|
|||
|
if ( dif < 1200 )
|
|||
|
return;
|
|||
|
wait( 0.5 );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
hk_flies_to_pos_until_goal( target_pos )
|
|||
|
{
|
|||
|
level endon( "bad_heli_goes_to_death_position" );
|
|||
|
self endon( "death" );
|
|||
|
timer = 0.2;
|
|||
|
|
|||
|
for ( ;; )
|
|||
|
{
|
|||
|
if ( distance( self.origin, target_pos ) < 2500 )
|
|||
|
return;
|
|||
|
|
|||
|
my_pos = set_z( self.origin, 0 );
|
|||
|
|
|||
|
heading = vectortoangles( target_pos - my_pos );
|
|||
|
forward = anglestoforward( heading );
|
|||
|
pos = my_pos + forward * 600;
|
|||
|
pos = ( pos[0], pos[1], self.origin[2] );
|
|||
|
pos = get_trace_pos( pos, 1200 );
|
|||
|
self SetVehGoalPos( pos, false );
|
|||
|
//Line( self.origin, target_pos, (0.5,1,0), 1, 1, int(timer*20) );
|
|||
|
wait( timer );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
hk_tracks_player()
|
|||
|
{
|
|||
|
self notify( "stop_tracking" );
|
|||
|
self endon( "stop_tracking" );
|
|||
|
self endon( "death" );
|
|||
|
for ( ;; )
|
|||
|
{
|
|||
|
yaw = get_yaw( self.origin, level.player.origin );
|
|||
|
self SetGoalYaw( yaw );
|
|||
|
level.goalyaw = yaw;
|
|||
|
wait ( 0.05 );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
get_yaw( org1, org2 )
|
|||
|
{
|
|||
|
angles = vectortoangles( org2 - org1 );
|
|||
|
return angles[1];
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
get_trace_pos( pos, height )
|
|||
|
{
|
|||
|
trace = BulletTrace( pos + (0,0,2000), pos + (0,0,-15000), false, self );
|
|||
|
return trace["position"] + (0,0,height);
|
|||
|
}
|
|||
|
|
|||
|
hk_wait_until_player_stops_progressing()
|
|||
|
{
|
|||
|
self endon( "death" );
|
|||
|
old_index = get_player_targ().index;
|
|||
|
old_targ = get_player_targ();
|
|||
|
old_progress = get_player_progress();
|
|||
|
req_dist = 350;
|
|||
|
|
|||
|
for ( ;; )
|
|||
|
{
|
|||
|
new_index = get_player_targ().index;
|
|||
|
new_progress = get_player_progress();;
|
|||
|
|
|||
|
if ( new_index == old_index )
|
|||
|
{
|
|||
|
if ( new_progress < old_progress + req_dist )
|
|||
|
self.warnings++;
|
|||
|
else
|
|||
|
self.warnings = 0;
|
|||
|
}
|
|||
|
else
|
|||
|
if ( new_index < old_index )
|
|||
|
{
|
|||
|
self.warnings++;
|
|||
|
}
|
|||
|
else
|
|||
|
if ( new_index > old_index + 1 )
|
|||
|
{
|
|||
|
self.warnings = 0;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
assert( new_index == old_index + 1 );
|
|||
|
if ( new_progress + old_targ.dist_to_next_targ > old_index + req_dist )
|
|||
|
self.warnings = 0;
|
|||
|
}
|
|||
|
|
|||
|
if ( self.warnings == 0 )
|
|||
|
{
|
|||
|
old_index = get_player_targ().index;
|
|||
|
old_targ = get_player_targ();
|
|||
|
old_progress = get_player_progress();
|
|||
|
}
|
|||
|
|
|||
|
self.attack_player = self.warnings > 10;
|
|||
|
self.kill_player = self.warnings > 50;
|
|||
|
|
|||
|
if ( self.warnings > 3 )
|
|||
|
{
|
|||
|
flag_clear( "can_save" );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if ( !flag( "can_save" ) )
|
|||
|
flag_set( "can_save" );
|
|||
|
}
|
|||
|
|
|||
|
if ( self.warnings >= self.hover_warnings )
|
|||
|
self.attack_progress = 1000;
|
|||
|
|
|||
|
// else
|
|||
|
// self.attack_progress = 4000;
|
|||
|
wait( 0.5 );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
objective_ent_leads_player()
|
|||
|
{
|
|||
|
level.player_snowmobile endon( "death" );
|
|||
|
|
|||
|
for ( ;; )
|
|||
|
{
|
|||
|
targ = maps\_vehicle_spline::get_player_targ();
|
|||
|
progress = maps\_vehicle_spline::get_player_progress();
|
|||
|
progress += 7500;
|
|||
|
|
|||
|
pos = get_position_from_spline( targ, progress, 0 );
|
|||
|
pos = set_z( pos, level.player_snowmobile.origin[ 2 ] );
|
|||
|
pos = PhysicsTrace( pos + ( 0, 0, 5000 ), pos + ( 0, 0, -5000 ) );
|
|||
|
//bike_lookahead_pos = set_z( bike_lookahead_pos, z );
|
|||
|
//return PhysicsTrace( bike_lookahead_pos + ( 0, 0, 200 ), bike_lookahead_pos + ( 0, 0, -200 ) );
|
|||
|
//pos = get_bike_pos_from_spline( targ, progress, 0, level.player.origin[2] );
|
|||
|
|
|||
|
self.origin = pos;
|
|||
|
wait( 5 );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
set_obj_point_from_flag( index, flagname )
|
|||
|
{
|
|||
|
if ( !isdefined( level.player_snowmobile ) )
|
|||
|
return;
|
|||
|
|
|||
|
objective_end_org = getent( "objective_end_org", "targetname" );
|
|||
|
dist = distance( objective_end_org.origin, level.player_snowmobile.origin );
|
|||
|
|
|||
|
|
|||
|
trigger = getentwithflag( flagname );
|
|||
|
ent = getent( trigger.target, "targetname" );
|
|||
|
angles = vectortoangles( ent.origin - trigger.origin );
|
|||
|
forward = anglestoforward( angles );
|
|||
|
ent.origin = trigger.origin + forward * 500000;
|
|||
|
|
|||
|
angles = vectortoangles( ent.origin - level.player_snowmobile.origin );
|
|||
|
forward = anglestoforward( angles );
|
|||
|
end = level.player_snowmobile.origin + forward * dist;
|
|||
|
|
|||
|
objective_position( index, end );
|
|||
|
}
|
|||
|
|
|||
|
snowmobile_dialogue()
|
|||
|
{
|
|||
|
flag_wait( "enemies_persue_on_bike" );
|
|||
|
|
|||
|
// <20>More tangos to the rear! Just outrun them! Go! Go!<21>
|
|||
|
radio_dialogue( "outrunthem" );
|
|||
|
|
|||
|
wait( 4 );
|
|||
|
// <20>Don<6F>t slow down! Keep moving or you<6F>re dead!<21>
|
|||
|
radio_dialogue( "keepmoving" );
|
|||
|
|
|||
|
wait( 3 );
|
|||
|
// <20>Go! Go! Go!<21>
|
|||
|
radio_dialogue( "gogogo" );
|
|||
|
|
|||
|
flag_wait( "snowmobile_price_full_speed" );
|
|||
|
|
|||
|
// <20>Come on! Come on!<21>
|
|||
|
radio_dialogue( "comeoncomeon" );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
price_progress_dialogue()
|
|||
|
{
|
|||
|
for ( ;; )
|
|||
|
{
|
|||
|
if ( level.player_ride_progress_percent > 0.6 )
|
|||
|
break;
|
|||
|
wait( 0.1 );
|
|||
|
}
|
|||
|
|
|||
|
// <20>We<57>re gonna make it! Just hang on!<21>
|
|||
|
thread radio_dialogue_queue( "gonnamakeit" );
|
|||
|
|
|||
|
for ( ;; )
|
|||
|
{
|
|||
|
if ( level.player_ride_progress_percent > 0.7 )
|
|||
|
break;
|
|||
|
wait( 0.1 );
|
|||
|
}
|
|||
|
|
|||
|
// <20>Come on! Come on!<21>
|
|||
|
thread radio_dialogue_queue( "comeoncomeon" );
|
|||
|
|
|||
|
for ( ;; )
|
|||
|
{
|
|||
|
if ( level.player_ride_progress_percent > 0.9 )
|
|||
|
break;
|
|||
|
wait( 0.1 );
|
|||
|
}
|
|||
|
|
|||
|
// <20>Hang ooonnn!!!<21>
|
|||
|
thread radio_dialogue_queue( "hangon2" );
|
|||
|
}
|
|||
|
|
|||
|
missile_repulser()
|
|||
|
{
|
|||
|
repulse = Missile_CreateRepulsorEnt( level.player, 10000, 2000 );
|
|||
|
}
|
|||
|
|
|||
|
track_player_position()
|
|||
|
{
|
|||
|
for ( ;; )
|
|||
|
{
|
|||
|
self waittill( "trigger" );
|
|||
|
level.player.position = self.script_noteworthy;
|
|||
|
level notify( "new_player_position", self.script_noteworthy );
|
|||
|
wait( 2 );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
cliff_attacker_think()
|
|||
|
{
|
|||
|
startPos = self.origin;
|
|||
|
targ = getent( self.target, "targetname" );
|
|||
|
angles = targ.angles;
|
|||
|
deathanim = level.cliffdeath_anims[ level.cliffdeath_anims_index ];
|
|||
|
level.cliffdeath_anims_index++;
|
|||
|
if ( level.cliffdeath_anims_index >= level.cliffdeath_anims.size )
|
|||
|
level.cliffdeath_anims_index = 0;
|
|||
|
|
|||
|
self set_generic_deathanim( deathanim );
|
|||
|
|
|||
|
cliff_attackers_wait_for_death_or_flag();
|
|||
|
|
|||
|
if ( !isalive( self ) )
|
|||
|
{
|
|||
|
level.cliffdeaths++;
|
|||
|
level notify( "cliff_death" );
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
wait randomfloatrange( 0.2, 0.7 );
|
|||
|
if ( isalive( self ) )
|
|||
|
{
|
|||
|
self setgoalpos( startPos );
|
|||
|
self.goalradius = distance( self.origin, startPos ) / 2;
|
|||
|
self waittill_either( "goal", "death" );
|
|||
|
}
|
|||
|
level.cliffdeaths++;
|
|||
|
level notify( "cliff_death" );
|
|||
|
|
|||
|
if ( !isalive( self ) )
|
|||
|
return;
|
|||
|
|
|||
|
self endon( "death" );
|
|||
|
self.goalradius = 8;
|
|||
|
self waittill( "goal" );
|
|||
|
self delete();
|
|||
|
}
|
|||
|
|
|||
|
cliff_attackers_wait_for_death_or_flag()
|
|||
|
{
|
|||
|
self endon( "death" );
|
|||
|
flag_wait( "clifftop_snowmobile_guys_die" );
|
|||
|
wait( randomfloatrange( 0.1, 0.3 ) );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
init_cliff_deaths()
|
|||
|
{
|
|||
|
level.cliffdeaths = 0;
|
|||
|
level.cliffdeath_anims = [];
|
|||
|
level.cliffdeath_anims[ level.cliffdeath_anims.size ] = "cliffdeath_1";
|
|||
|
level.cliffdeath_anims[ level.cliffdeath_anims.size ] = "cliffdeath_2";
|
|||
|
level.cliffdeath_anims[ level.cliffdeath_anims.size ] = "cliffdeath_3";
|
|||
|
level.cliffdeath_anims[ level.cliffdeath_anims.size ] = "cliffdeath_4";
|
|||
|
level.cliffdeath_anims = array_randomize( level.cliffdeath_anims );
|
|||
|
level.cliffdeath_anims_index = 0;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
slope_tree_think()
|
|||
|
{
|
|||
|
//foliage_tree_pine_snow_lg_b
|
|||
|
yaw = randomint( 360 );
|
|||
|
self.angles = ( 0, yaw, 0 );
|
|||
|
range = 64;
|
|||
|
offset = randomint( range * 2 ) - range;
|
|||
|
|
|||
|
//Line( self.origin, self.origin + ( offset, 0, 0 ), (1,0,0), 1, 0, 5000 );
|
|||
|
self.origin += ( offset, 0, 0 );
|
|||
|
trace = BulletTrace( self.origin + (0,0,64), self.origin + (0,0,-64), false, undefined );
|
|||
|
self.origin = trace[ "position" ] + (0,0,-8);
|
|||
|
// self hide();
|
|||
|
self.clip hide();
|
|||
|
self.clip.origin = self.origin;
|
|||
|
//Line( self.origin, self.clip.origin + ( offset, 0, 0 ), (0,1,0), 1, 0, 5000 );
|
|||
|
|
|||
|
ent = common_scripts\_createfx::createLoopSound();
|
|||
|
ent.v[ "origin" ] = self.origin;
|
|||
|
ent.v[ "angles" ] = ( 270, 0, 0 );
|
|||
|
ent.v[ "soundalias" ] = "velocity_whitenoise_loop";
|
|||
|
}
|
|||
|
|
|||
|
end_camp_spawner_think()
|
|||
|
{
|
|||
|
self endon( "death" );
|
|||
|
self.baseAccuracy = 0.2;
|
|||
|
for ( ;; )
|
|||
|
{
|
|||
|
vehicles = getentarray( "script_vehicle_littlebird_armed", "classname" );
|
|||
|
if ( vehicles.size )
|
|||
|
{
|
|||
|
closest_vehicle = getClosest( self.origin, vehicles, 8000 );
|
|||
|
self SetEntityTarget( closest_vehicle, 0.75 );
|
|||
|
}
|
|||
|
wait( randomfloatrange( 0.5, 1 ) );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
speedy_littlebird_spawner_think()
|
|||
|
{
|
|||
|
wait( 2 );
|
|||
|
|
|||
|
maps\_helicopter_globals::fire_missile( "hind_zippy", 1, level.hk );
|
|||
|
wait( 0.35 );
|
|||
|
maps\_helicopter_globals::fire_missile( "hind_zippy", 1, level.hk );
|
|||
|
wait( 0.35 );
|
|||
|
maps\_helicopter_globals::fire_missile( "hind_zippy", 1, level.hk );
|
|||
|
wait( 0.35 );
|
|||
|
flag_set( "bad_heli_missile_killed" );
|
|||
|
maps\_helicopter_globals::fire_missile( "hind_zippy", 1, level.hk );
|
|||
|
wait( 0.35 );
|
|||
|
maps\_helicopter_globals::fire_missile( "hind_zippy", 1, level.hk );
|
|||
|
|
|||
|
|
|||
|
flag_wait( "end_camp_player_leaves_camp" );
|
|||
|
waittillframeend; // wait until the littlebird starts moving cause its waiting on the same flag
|
|||
|
if ( player_looking_at( self.origin ) )
|
|||
|
return;
|
|||
|
|
|||
|
// speed up this littlebird if the player isnt looking at it
|
|||
|
self vehicle_setspeedImmediate( 120, 50, 35 );
|
|||
|
self set_heli_move( "instant" );
|
|||
|
wait( 2 );
|
|||
|
self set_heli_move( "fast" );
|
|||
|
}
|
|||
|
|
|||
|
ending_heli_think()
|
|||
|
{
|
|||
|
level.ending_heli = self;
|
|||
|
self ent_flag_init( "landed" );
|
|||
|
self attach_vehicle_triggers();
|
|||
|
flag_set( "ending_heli_flies_in" );
|
|||
|
|
|||
|
if ( isdefined( self.vehicle_triggers[ "trigger_multiple" ] ) )
|
|||
|
array_thread( self.vehicle_triggers[ "trigger_multiple" ], ::ending_heli_trigger_multiple );
|
|||
|
|
|||
|
if ( isdefined( self.vehicle_triggers[ "trigger_use" ] ) )
|
|||
|
array_thread( self.vehicle_triggers[ "trigger_use" ], ::ending_heli_trigger_use );
|
|||
|
|
|||
|
// thread dismount_player_when_he_gets_close();
|
|||
|
self waittill( "reached_dynamic_path_end" );
|
|||
|
self waittill( "near_goal" );
|
|||
|
self disconnectPaths();
|
|||
|
self ent_flag_set( "landed" );
|
|||
|
|
|||
|
flag_wait( "player_boards" );
|
|||
|
|
|||
|
if ( 1 ) return;
|
|||
|
|
|||
|
model = spawn_anim_model( "player_rig" );
|
|||
|
model hide();
|
|||
|
|
|||
|
model linkto( self, "tag_detach", (0,0,0), (0,0,0) );
|
|||
|
self thread anim_single_solo( model, "player_evac", "tag_detach" );
|
|||
|
level.player PlayerLinkToBlend( model, "tag_origin", 0.5, 0.2, 0.2 );
|
|||
|
delaythread( 0.5, ::reset_player_fov, model, "tag_origin" );
|
|||
|
//self waittill( "player_evac" );
|
|||
|
wait( 6 );
|
|||
|
flag_wait( "price_enters_heli" );
|
|||
|
path = getstruct( "ending_heli_escape_path", "targetname" );
|
|||
|
self thread vehicle_paths( path );
|
|||
|
flag_wait( "ending_heli_leaves" );
|
|||
|
|
|||
|
nextmission();
|
|||
|
}
|
|||
|
|
|||
|
ending_heli_trigger_multiple()
|
|||
|
{
|
|||
|
for ( ;; )
|
|||
|
{
|
|||
|
self waittill( "trigger" );
|
|||
|
if ( flag( "player_boards" ) )
|
|||
|
break;
|
|||
|
if ( level.player getvelocity()[ 2 ] > 8 )
|
|||
|
break;
|
|||
|
}
|
|||
|
self delete();
|
|||
|
flag_set( "player_boards" );
|
|||
|
}
|
|||
|
|
|||
|
ending_heli_trigger_use()
|
|||
|
{
|
|||
|
// "Press and hold ^3&&1^7 to board."
|
|||
|
self setHintString( &"CLIFFHANGER_BOARD" );
|
|||
|
add_wait( ::waittill_msg, "trigger" );
|
|||
|
level add_wait( ::waittill_msg, "player_boards" );
|
|||
|
do_wait_any();
|
|||
|
|
|||
|
flag_set( "player_boards" );
|
|||
|
self delete();
|
|||
|
}
|
|||
|
|
|||
|
dismount_player_when_he_gets_close()
|
|||
|
{
|
|||
|
for ( ;; )
|
|||
|
{
|
|||
|
if ( !isdefined( level.player.vehicle ) )
|
|||
|
return;
|
|||
|
|
|||
|
if ( distance( level.player.origin, self.origin ) < 800 )
|
|||
|
{
|
|||
|
level.player.vehicle Vehicle_SetSpeed( 0, 5, 35 );
|
|||
|
if ( level.player.vehicle vehicle_getspeed() < 5 )
|
|||
|
break;
|
|||
|
}
|
|||
|
wait( 0.05 );
|
|||
|
}
|
|||
|
|
|||
|
level.player player_dismount_vehicle();
|
|||
|
level.player.vehicle Vehicle_SetSpeed( 0, 5, 25 );
|
|||
|
}
|
|||
|
|
|||
|
reset_player_fov( ent, tag )
|
|||
|
{
|
|||
|
level.player PlayerLinkToDelta( ent, tag, 1, 90, 90, 35, 45 );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
magic_bullet_spawner_think()
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
god_vehicle_spawner_think()
|
|||
|
{
|
|||
|
// self VehPhys_DisableCrashing();
|
|||
|
// self waittill( "reached_end_node" );
|
|||
|
}
|
|||
|
|
|||
|
price_snowmobile_icon()
|
|||
|
{
|
|||
|
if ( !isalive( level.price ) )
|
|||
|
return;
|
|||
|
level.price endon( "death" );
|
|||
|
|
|||
|
icon = newHudElem();
|
|||
|
icon setShader( "overhead_obj_icon_world", 10, 10 );
|
|||
|
icon.alpha = 1.0;
|
|||
|
icon.color = ( 1, 1, 1 );
|
|||
|
icon setWayPoint( true, false );
|
|||
|
icon SetTargetEnt( level.price );
|
|||
|
|
|||
|
flag_wait( "player_boards" );
|
|||
|
icon destroy();
|
|||
|
}
|
|||
|
|
|||
|
ending_heli_fly_off_trigger_think()
|
|||
|
{
|
|||
|
// ending heli hits a trigger then flies off and deletes
|
|||
|
flag_wait( "hk_gives_chase" );
|
|||
|
|
|||
|
for ( ;; )
|
|||
|
{
|
|||
|
self waittill( "trigger", other );
|
|||
|
if ( level.hk != other )
|
|||
|
continue;
|
|||
|
break;
|
|||
|
}
|
|||
|
flag_set( "bad_heli_goes_to_death_position" );
|
|||
|
|
|||
|
path = getstruct( self.target, "targetname" );
|
|||
|
level.hk SetVehGoalPos( path.origin, true );
|
|||
|
//level.hk thread vehicle_paths( path );
|
|||
|
}
|
|||
|
|
|||
|
player_top_speed_limit_trigger_think()
|
|||
|
{
|
|||
|
assertex( isdefined( self.script_speed ), "Trigger at " + self.origin + " has no .script_speed" );
|
|||
|
|
|||
|
for ( ;; )
|
|||
|
{
|
|||
|
self waittill( "trigger", other );
|
|||
|
assert( isPlayer( other ) );
|
|||
|
//other.vehicle.veh_topspeed = self.script_speed;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
kill_enemy_snowmobile_think()
|
|||
|
{
|
|||
|
for ( ;; )
|
|||
|
{
|
|||
|
self waittill( "trigger", other );
|
|||
|
if ( !isdefined( level.player.vehicle ) )
|
|||
|
continue;
|
|||
|
if ( !isdefined( level.price.vehicle ) )
|
|||
|
continue;
|
|||
|
if ( other == level.player.vehicle )
|
|||
|
continue;
|
|||
|
if ( other == level.price.vehicle )
|
|||
|
continue;
|
|||
|
if ( !isdefined( other.wipeout ) )
|
|||
|
continue;
|
|||
|
if ( other.wipeout )
|
|||
|
continue;
|
|||
|
|
|||
|
other.wipeout = true;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
player_path_trigger_think()
|
|||
|
{
|
|||
|
self waittill( "trigger" );
|
|||
|
node = getvehiclenode( self.target, "targetname" );
|
|||
|
// level.player.vehicle attachPath( node );
|
|||
|
level.player.vehicle.veh_pathType = "follow";
|
|||
|
level.player.vehicle startPath( node );
|
|||
|
}
|
|||
|
|
|||
|
recover_vehicle_path_trigger()
|
|||
|
{
|
|||
|
for ( ;; )
|
|||
|
{
|
|||
|
trigger = getent( "recover_vehicle_path_trigger", "targetname" );
|
|||
|
trigger waittill( "trigger", other );
|
|||
|
if ( other.vehicletype == "snowmobile_friendly" )
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
node = getvehiclenode( trigger.target, "targetname" );
|
|||
|
|
|||
|
other thread vehicle_paths( node );
|
|||
|
other startpath( node );
|
|||
|
}
|
|||
|
|
|||
|
player_is_protected_on_trip_to_objective( objective, org )
|
|||
|
{
|
|||
|
level notify( "new_player_protection_trip" );
|
|||
|
|
|||
|
self player_is_protected_on_trip_to_objective_think( objective, org );
|
|||
|
|
|||
|
// clear existing changes
|
|||
|
level.player maps\_gameskill::resetSkill();
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
player_is_protected_on_trip_to_objective_think( objective, org )
|
|||
|
{
|
|||
|
level endon( "new_player_protection_trip" );
|
|||
|
|
|||
|
org = get_org_from_self( org );
|
|||
|
original_org = org;
|
|||
|
dist = distance( level.player.origin, org );
|
|||
|
|
|||
|
run_delay = [];
|
|||
|
run_delay[ 0 ] = 1.25;
|
|||
|
run_delay[ 1 ] = 1.0;
|
|||
|
run_delay[ 2 ] = 0.75;
|
|||
|
run_delay[ 3 ] = 0.75;
|
|||
|
|
|||
|
delay = run_delay[ level.gameskill ];
|
|||
|
|
|||
|
old_protection_time = gettime() + 3000;
|
|||
|
start_org = level.player.origin;
|
|||
|
|
|||
|
protection_dist = 150;
|
|||
|
|
|||
|
for ( ;; )
|
|||
|
{
|
|||
|
org = get_org_from_self( org );
|
|||
|
if ( org != original_org )
|
|||
|
{
|
|||
|
original_org = org;
|
|||
|
dist = distance( level.player.origin, org );
|
|||
|
dist -= 55; // give the player a pseudo freeby for the update
|
|||
|
}
|
|||
|
|
|||
|
//Line( level.player.origin, org, (1,0,0), 1, 0 );
|
|||
|
//Print3d( org, level.player.attackeraccuracy, (1,0,0), 1, 1 );
|
|||
|
|
|||
|
current_dist = distance( level.player.origin, org );
|
|||
|
current_dist += 50; // must continue making progress
|
|||
|
|
|||
|
if ( current_dist < dist || dist < 150 )
|
|||
|
{
|
|||
|
level.player set_player_attacker_accuracy( 0 );
|
|||
|
dist = current_dist;
|
|||
|
|
|||
|
wait 0.5;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
protected = gettime() < old_protection_time;
|
|||
|
nearby = distance( level.player.origin, start_org ) < protection_dist;
|
|||
|
|
|||
|
if ( protected && nearby )
|
|||
|
{
|
|||
|
level.player set_player_attacker_accuracy( 0.1 );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
level.player maps\_gameskill::resetSkill();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
wait 0.05;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
get_org_from_self( org )
|
|||
|
{
|
|||
|
if ( !isalive( self ) )
|
|||
|
return org;
|
|||
|
if ( !isdefined( self.goalpos ) )
|
|||
|
return self.origin;
|
|||
|
return self.goalpos;
|
|||
|
}
|