1303 lines
34 KiB
Plaintext
1303 lines
34 KiB
Plaintext
|
#include common_scripts\utility;
|
||
|
#include maps\_utility;
|
||
|
#include maps\_vehicle;
|
||
|
#include maps\_anim;
|
||
|
#include maps\_specialops;
|
||
|
#include maps\_hud_util;
|
||
|
|
||
|
// ---------------------------------------------------------------------------------
|
||
|
|
||
|
fire_off_exploder( current )
|
||
|
{
|
||
|
while( 1 )
|
||
|
{
|
||
|
exploder( current.script_prefab_exploder );
|
||
|
if( !isdefined( current.target ) )
|
||
|
break;
|
||
|
next = getent( current.target, "targetname" );
|
||
|
if( !isdefined( next ) )
|
||
|
break;
|
||
|
current = next;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// ---------------------------------------------------------------------------------
|
||
|
|
||
|
create_smoke_wave( smoke_tag, flag_start, dialog_wait )
|
||
|
{
|
||
|
if ( isdefined( flag_start ) )
|
||
|
{
|
||
|
flag_init( flag_start );
|
||
|
flag_wait( flag_start );
|
||
|
}
|
||
|
|
||
|
// Prevent smoke from happening too frequently
|
||
|
if ( isdefined( level.smoke_throttle ) )
|
||
|
{
|
||
|
if ( !isdefined( level.smoke_wave_time ) )
|
||
|
level.smoke_wave_time = gettime() - level.smoke_throttle - 1;
|
||
|
|
||
|
time_since = gettime() - level.smoke_wave_time;
|
||
|
if ( time_since <= level.smoke_throttle )
|
||
|
return;
|
||
|
|
||
|
level.smoke_wave_time = gettime();
|
||
|
}
|
||
|
|
||
|
magic_smoke_grenades = getentarray( smoke_tag, "targetname" );
|
||
|
array_thread( magic_smoke_grenades, ::smoke_wave_play );
|
||
|
|
||
|
// Undefined dialog_wait assumes we don't want any. Use 0 for no wait.
|
||
|
if ( isdefined( dialog_wait ) )
|
||
|
thread dialog_smoke_wave_alert( dialog_wait );
|
||
|
}
|
||
|
|
||
|
smoke_wave_play()
|
||
|
{
|
||
|
playfx( getfx( "smokescreen" ), self.origin );
|
||
|
self thread play_sound_in_space( "smokegrenade_explode_default" );
|
||
|
}
|
||
|
|
||
|
dialog_smoke_wave_alert( dialog_wait )
|
||
|
{
|
||
|
level endon( "special_op_terminated" );
|
||
|
|
||
|
wait dialog_wait;
|
||
|
|
||
|
//Hunter Two-One, Overlord. Advise switching to thermal optics, over.
|
||
|
radio_dialogue( "so_def_inv_thermaloptics" );
|
||
|
}
|
||
|
|
||
|
// ---------------------------------------------------------------------------------
|
||
|
|
||
|
btr80_level_init()
|
||
|
{
|
||
|
if ( isdefined( level.btr_init ) )
|
||
|
return;
|
||
|
|
||
|
level.btr_init = true;
|
||
|
level.btr80_count = 0;
|
||
|
|
||
|
if ( !isdefined( level.btr_min_fighting_range ) )
|
||
|
level.btr_min_fighting_range = 400;
|
||
|
|
||
|
if ( !isdefined( level.btr_max_fighting_range ) )
|
||
|
level.btr_max_fighting_range = 2400;
|
||
|
|
||
|
if ( !isdefined( level.btr_target_fov ) )
|
||
|
level.btr_target_fov = cos( 50 );
|
||
|
|
||
|
level.btr80_building_checks = getentarray( "trigger_multiple_flag_set_touching", "classname" );
|
||
|
|
||
|
for ( i = level.btr80_building_checks.size - 1; i >= 0; i-- )
|
||
|
{
|
||
|
building = level.btr80_building_checks[ i ];
|
||
|
if ( !isdefined( building.script_flag ) )
|
||
|
{
|
||
|
level.btr80_building_checks[ i ] = undefined;
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
switch( building.script_flag )
|
||
|
{
|
||
|
case "player_inside_nates" :
|
||
|
case "player_in_burgertown" :
|
||
|
case "player_in_diner" :
|
||
|
// Do nothing, keep in the list.
|
||
|
break;
|
||
|
default:
|
||
|
level.btr80_building_checks[ i ] = undefined;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
create_btr80( btr80_tag, flag_start )
|
||
|
{
|
||
|
if ( isdefined( flag_start ) )
|
||
|
{
|
||
|
flag_init( flag_start );
|
||
|
flag_wait( flag_start );
|
||
|
}
|
||
|
|
||
|
btr80_level_init();
|
||
|
|
||
|
btr80 = spawn_vehicle_from_targetname_and_drive( btr80_tag );
|
||
|
array_thread( getvehiclenodearray( "new_target", "script_noteworthy" ), ::btr80_new_target_think );
|
||
|
|
||
|
btr80 thread btr80_watch_for_player();
|
||
|
btr80 thread btr80_register_death();
|
||
|
btr80 thread ent_flag_init( "spotted_player" );
|
||
|
btr80 thread btr80_turret_spotlight();
|
||
|
btr80 thread maps\_vehicle::damage_hints();
|
||
|
btr80 thread dialog_btr80_spotted_you();
|
||
|
}
|
||
|
|
||
|
btr80_watch_for_player()
|
||
|
{
|
||
|
level endon( "special_op_terminated" );
|
||
|
self endon( "death" );
|
||
|
self.turret_busy = false;
|
||
|
|
||
|
while( 1 )
|
||
|
{
|
||
|
wait .05;
|
||
|
|
||
|
if ( self ent_flag( "spotted_player" ) )
|
||
|
continue;
|
||
|
|
||
|
player = btr80_find_available_player();
|
||
|
if ( !isdefined( player ) )
|
||
|
continue;
|
||
|
|
||
|
tag_flash_angles = self getTagAngles( "tag_flash" );
|
||
|
if( !within_fov( self.origin, tag_flash_angles, player.origin, level.btr_target_fov ) )
|
||
|
continue;
|
||
|
|
||
|
if( !btr80_can_see_player( player ) )
|
||
|
continue;
|
||
|
|
||
|
self notify( "new_target" ); // Clears ambient target shooting
|
||
|
self.turret_busy = true;
|
||
|
self ent_flag_set( "spotted_player" );
|
||
|
player.btr80_attacker_id = self.unique_id; // Claim this player for myself.
|
||
|
self Vehicle_SetSpeed( 0, 10 );
|
||
|
|
||
|
//saw player, now miss for 2 bursts
|
||
|
btr80_miss_player( player );
|
||
|
wait( randomfloatrange( 0.8, 2.4 ) );
|
||
|
btr80_miss_player( player );
|
||
|
wait( randomfloatrange( 0.8, 2.4 ) );
|
||
|
|
||
|
//if player is still exposed then hit him
|
||
|
while ( btr80_can_see_player( player ) )
|
||
|
{
|
||
|
btr80_fire_at_player( player );
|
||
|
wait( randomfloatrange( 0.5, 1.5 ) );
|
||
|
}
|
||
|
|
||
|
self clearturrettarget();
|
||
|
self.turret_busy = false;
|
||
|
self ent_flag_clear( "spotted_player" );
|
||
|
player.btr80_attacker_id = undefined;
|
||
|
self Vehicle_SetSpeed( 10, 1 );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
btr80_turret_spotlight()
|
||
|
{
|
||
|
vehicle_lights_on( "spotlight spotlight_turret" );
|
||
|
}
|
||
|
|
||
|
btr80_fire_at_player( player )
|
||
|
{
|
||
|
self endon( "death" );
|
||
|
burstsize = randomintrange( 3, 5 );
|
||
|
fireTime = .2;
|
||
|
for ( i = 0; i < burstsize; i++ )
|
||
|
{
|
||
|
self setturrettargetent( player, randomvector( 20 ) + ( 0, 0, 32 ) );//randomvec was 50
|
||
|
self fireweapon();
|
||
|
wait fireTime;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
btr80_miss_player( player )
|
||
|
{
|
||
|
self endon( "death" );
|
||
|
|
||
|
//point in front of player
|
||
|
forward = AnglesToForward( player.angles );
|
||
|
forwardfar = vector_multiply( forward, 100 );
|
||
|
miss_vec = forwardfar + randomvector( 50 );
|
||
|
|
||
|
burstsize = randomintrange( 4, 6 );
|
||
|
fireTime = .2;
|
||
|
for ( i = 0; i < burstsize; i++ )
|
||
|
{
|
||
|
offset = randomvector( 15 ) + miss_vec + (0,0,64);
|
||
|
self setturrettargetent( player, offset );
|
||
|
self fireweapon();
|
||
|
wait fireTime;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
btr80_find_available_player()
|
||
|
{
|
||
|
p1_ok = btr80_check_player_available( level.player ) && btr80_check_player_in_range( level.player );
|
||
|
p2_ok = btr80_check_player_available( level.player2 ) && btr80_check_player_in_range( level.player2 );
|
||
|
|
||
|
if ( p1_ok && p2_ok )
|
||
|
return getclosest( self.origin, level.players );
|
||
|
|
||
|
if ( p1_ok )
|
||
|
return level.player;
|
||
|
|
||
|
if ( p2_ok )
|
||
|
return level.player2;
|
||
|
|
||
|
return undefined;
|
||
|
}
|
||
|
|
||
|
btr80_check_player_available( player )
|
||
|
{
|
||
|
if ( !isdefined( player ) )
|
||
|
return false;
|
||
|
|
||
|
if ( isdefined( player.btr80_attacker_id ) )
|
||
|
return false;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
btr80_check_player_in_range( player )
|
||
|
{
|
||
|
if ( !isdefined( player ) )
|
||
|
return false;
|
||
|
|
||
|
if ( distance( self.origin, player.origin ) > level.btr_max_fighting_range )
|
||
|
return false;
|
||
|
|
||
|
if( distance( self.origin, player.origin ) < level.btr_min_fighting_range )
|
||
|
return false;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
btr80_check_player_in_building( player )
|
||
|
{
|
||
|
if ( !isdefined( player ) )
|
||
|
return;
|
||
|
|
||
|
foreach ( building in level.btr80_building_checks )
|
||
|
{
|
||
|
if ( player istouching( building ) )
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
btr80_can_see_player( player )
|
||
|
{
|
||
|
if ( btr80_check_player_in_building( player ) )
|
||
|
return false;
|
||
|
|
||
|
if ( !btr80_check_player_in_range( player ) )
|
||
|
return false;
|
||
|
|
||
|
tag_flash_loc = self getTagOrigin( "tag_flash" );
|
||
|
player_eye = player geteye();
|
||
|
if ( SightTracePassed( tag_flash_loc, player_eye, false, self ) )
|
||
|
{
|
||
|
if( isdefined( level.debug ) )
|
||
|
line( tag_flash_loc, player_eye, ( 0.2, 0.5, 0.8 ), 0.5, false, 60 );
|
||
|
return true;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
btr80_new_target_think()
|
||
|
{
|
||
|
level endon( "special_op_terminated" );
|
||
|
level endon( "btr80s_all_down" );
|
||
|
|
||
|
targets = getentarray( self.script_linkto, "script_linkname" );
|
||
|
while( 1 )
|
||
|
{
|
||
|
self waittill( "trigger", vehicle );
|
||
|
|
||
|
if( !isalive( vehicle ) )
|
||
|
return;
|
||
|
if( vehicle.turret_busy )
|
||
|
continue;
|
||
|
|
||
|
vehicle notify( "new_target" );
|
||
|
|
||
|
vehicle setturrettargetent( targets[0] );
|
||
|
|
||
|
thread btr80_fire_at_targets( vehicle );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
btr80_fire_at_targets( vehicle )
|
||
|
{
|
||
|
level endon( "special_op_terminated" );
|
||
|
|
||
|
vehicle endon( "new_target" );
|
||
|
vehicle endon( "death" );
|
||
|
|
||
|
vehicle waittill( "turret_on_target" );
|
||
|
|
||
|
while( 1 )
|
||
|
{
|
||
|
s = randomintrange( 4, 6 );
|
||
|
for ( j = 0; j < s; j++ )
|
||
|
{
|
||
|
vehicle fireWeapon();
|
||
|
wait .2;
|
||
|
}
|
||
|
wait( randomfloatrange( 1, 2 ) );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
btr80_register_death()
|
||
|
{
|
||
|
level endon( "special_op_terminated" );
|
||
|
|
||
|
level.btr80_count++;
|
||
|
|
||
|
my_id = self.unique_id;
|
||
|
thread btr80_challenge_complete_behavior();
|
||
|
|
||
|
self waittill( "death", attacker );
|
||
|
|
||
|
if ( attacker_is_p1( attacker ) )
|
||
|
thread pulse_kill_counter_hud( level.btr_kill_value, 0 );
|
||
|
else
|
||
|
if ( attacker_is_p2( attacker ) )
|
||
|
thread pulse_kill_counter_hud( 0, level.btr_kill_value );
|
||
|
|
||
|
if( self ent_flag( "spotted_player" ) )
|
||
|
{
|
||
|
foreach ( player in level.players )
|
||
|
{
|
||
|
if ( isdefined( player.btr80_attacker_id ) && ( my_id == player.btr80_attacker_id ) )
|
||
|
player.btr80_attacker_id = undefined;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
level.btr80_count--;
|
||
|
/#
|
||
|
assertex( ( level.btr80_count >= 0 ), "Somehow the BTR80 population counter dropped below 0. This should never happen." );
|
||
|
#/
|
||
|
if ( level.btr80_count <= 0 )
|
||
|
level notify( "btr80s_all_down" );
|
||
|
}
|
||
|
|
||
|
btr80_challenge_complete_behavior()
|
||
|
{
|
||
|
self endon( "death" );
|
||
|
|
||
|
level waittill( "special_op_terminated" );
|
||
|
|
||
|
self Vehicle_SetSpeed( 0, 10 );
|
||
|
}
|
||
|
|
||
|
dialog_btr80_spotted_you()
|
||
|
{
|
||
|
level endon( "special_op_terminated" );
|
||
|
self endon( "death" );
|
||
|
|
||
|
while( 1 )
|
||
|
{
|
||
|
ent_flag_wait( "spotted_player" );
|
||
|
dialog_btr80_spotted_you_action();
|
||
|
wait 20;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
dialog_btr80_spotted_you_action()
|
||
|
{
|
||
|
spotted_player = undefined;
|
||
|
foreach ( player in level.players )
|
||
|
{
|
||
|
if ( isdefined( player.btr80_attacker_id ) && ( player.btr80_attacker_id == self.unique_id ) )
|
||
|
{
|
||
|
spotted_player = player;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( !btr80_can_see_player( spotted_player ) )
|
||
|
return;
|
||
|
|
||
|
// Prevent btr80 dialog from happening too frequently
|
||
|
if ( isdefined( level.btr80_alert_throttle ) )
|
||
|
{
|
||
|
if ( !isdefined( level.btr80_alert_time ) )
|
||
|
level.btr80_alert_time = gettime() - level.btr80_alert_throttle - 1;
|
||
|
|
||
|
time_since = gettime() - level.btr80_alert_time;
|
||
|
if ( time_since <= level.btr80_alert_throttle )
|
||
|
return;
|
||
|
|
||
|
level.btr80_alert_time = gettime();
|
||
|
}
|
||
|
|
||
|
//Enemy BTR has a visual on you, Hunter Two-One, advise seeking cover, over.
|
||
|
//Hunter Two-One, be advised enemy BTR is targetting you, over.
|
||
|
radio_dialogue( "so_def_inv_bmpspottedyou" );
|
||
|
}
|
||
|
|
||
|
// ---------------------------------------------------------------------------------
|
||
|
|
||
|
hunter_enemies_level_init()
|
||
|
{
|
||
|
if ( isdefined( level.hunters_init ) )
|
||
|
return;
|
||
|
|
||
|
level.hunters_init = true;
|
||
|
|
||
|
level.hunters_active = 0;
|
||
|
level.hunter_enemies = [];
|
||
|
level.hunter_damage_p1 = [];
|
||
|
level.hunter_damage_p2 = [];
|
||
|
dialog_hunter_enemies_setup();
|
||
|
|
||
|
set_group_advance_to_enemy_parameters( 60000, 1 );
|
||
|
|
||
|
level.difficultySettings[ "accuracyDistScale" ][ "easy" ] = 0.65;
|
||
|
level.difficultySettings[ "accuracyDistScale" ][ "normal" ] = 0.65;
|
||
|
level.difficultySettings[ "accuracyDistScale" ][ "hardened" ] = 0.5;
|
||
|
level.difficultySettings[ "accuracyDistScale" ][ "veteran" ] = 0.4;
|
||
|
maps\_gameskill::updateAllDifficulty();
|
||
|
}
|
||
|
|
||
|
create_hunter_enemy_group( enemy_tag, flag_start, enemy_count )
|
||
|
{
|
||
|
if ( isdefined( flag_start ) )
|
||
|
{
|
||
|
flag_init( flag_start );
|
||
|
flag_wait( flag_start );
|
||
|
}
|
||
|
|
||
|
hunter_enemies_level_init();
|
||
|
|
||
|
if ( !isdefined( level.hunter_group_initialized ) )
|
||
|
{
|
||
|
level.hunter_group_initialized = true;
|
||
|
level.hunter_goals = getentarray( "closest_goal_radius", "targetname" );
|
||
|
}
|
||
|
|
||
|
current_enemies = getentarray( enemy_tag, "targetname" );
|
||
|
array_thread( current_enemies, ::add_spawn_function, ::create_hunter_enemy );
|
||
|
|
||
|
if ( !isdefined( enemy_count ) || ( enemy_count > current_enemies.size ) )
|
||
|
enemy_count = current_enemies.size;
|
||
|
|
||
|
thread dialog_hunter_enemies( enemy_tag, 2.5 );
|
||
|
|
||
|
current_enemies = array_randomize( current_enemies );
|
||
|
for ( i = 0 ; i < enemy_count ; i++ )
|
||
|
{
|
||
|
current_enemies[ i ].count = 1;
|
||
|
guy = current_enemies[ i ] spawn_ai();
|
||
|
wait randomfloat( 1 );
|
||
|
}
|
||
|
|
||
|
level notify( "hunter_group_spawn_complete" );
|
||
|
}
|
||
|
|
||
|
create_hunter_truck_enemies( truck_tag, flag_start )
|
||
|
{
|
||
|
if ( isdefined( flag_start ) )
|
||
|
{
|
||
|
flag_init( flag_start );
|
||
|
flag_wait( flag_start );
|
||
|
}
|
||
|
|
||
|
hunter_enemies_level_init();
|
||
|
|
||
|
if ( !isdefined( level.truck_group_initialized ) )
|
||
|
{
|
||
|
level.truck_group_initialized = true;
|
||
|
truck_group_enemies = getentarray( "truck_group_enemies", "script_noteworthy" );
|
||
|
array_thread( truck_group_enemies, ::add_spawn_function, ::create_hunter_enemy, true );
|
||
|
}
|
||
|
|
||
|
truck = thread spawn_vehicle_from_targetname_and_drive( truck_tag );
|
||
|
truck.veh_pathtype = "constrained";
|
||
|
}
|
||
|
|
||
|
create_hunter_enemy( wait_for_unload )
|
||
|
{
|
||
|
self endon( "death" );
|
||
|
level endon( "special_op_terminated" );
|
||
|
|
||
|
thread hunter_register_damage();
|
||
|
thread hunter_register_death();
|
||
|
|
||
|
level.hunter_enemies[ self.unique_id ] = self;
|
||
|
|
||
|
if ( isdefined( wait_for_unload ) && wait_for_unload )
|
||
|
self waittill( "jumpedout" );
|
||
|
|
||
|
thread hunter_enemy_maintain_closest_goal();
|
||
|
}
|
||
|
|
||
|
hunter_enemy_maintain_closest_goal()
|
||
|
{
|
||
|
self endon( "death" );
|
||
|
level endon( "special_op_terminated" );
|
||
|
|
||
|
self enable_danger_react( 5 );
|
||
|
self.goalradius = 3096;
|
||
|
self.goalheight = 768;
|
||
|
|
||
|
while ( true )
|
||
|
{
|
||
|
closest_player = getclosest( self.origin, level.players );
|
||
|
closest_goal = getclosest( closest_player.origin, level.hunter_goals );
|
||
|
if ( !isdefined( self.current_goal ) || ( self.current_goal != closest_goal ) )
|
||
|
{
|
||
|
waittillframeend;
|
||
|
//waittillframeend because you may be in the part of the frame that is before
|
||
|
//the script has received the "death" notify but after the AI has died.
|
||
|
|
||
|
self.current_goal = closest_goal;
|
||
|
self setgoalpos( self.current_goal.origin );
|
||
|
}
|
||
|
|
||
|
wait 1.0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// This should be updated to be more like the one in so_defense_invasion
|
||
|
hunter_enemies_refill( refill_at, min_fill, max_fill )
|
||
|
{
|
||
|
level endon( "special_op_terminated" );
|
||
|
|
||
|
if ( !isdefined( refill_at ) || ( refill_at < 0 ) )
|
||
|
refill_at = 0;
|
||
|
if ( !isdefined( min_fill ) || ( min_fill < 1 ) )
|
||
|
min_fill = 1;
|
||
|
if ( !isdefined( max_fill ) || ( max_fill <= min_fill ) )
|
||
|
max_fill = min_fill + 1;
|
||
|
|
||
|
used_smoke = false;
|
||
|
last_spawn = "gas"; // Level starts off with them coming from the gas station.
|
||
|
while ( true )
|
||
|
{
|
||
|
if ( !isdefined( level.hunters_active ) || ( level.hunters_active <= refill_at ) )
|
||
|
{
|
||
|
spawn_options = [];
|
||
|
if ( !flag( "so_player_near_bank" ) )
|
||
|
spawn_options[ spawn_options.size ] = "bank";
|
||
|
if ( !flag( "so_player_near_gas_station" ) )
|
||
|
spawn_options[ spawn_options.size ] = "gas";
|
||
|
if ( !flag( "so_player_near_taco" ) )
|
||
|
spawn_options[ spawn_options.size ] = "taco";
|
||
|
|
||
|
// No "good" options, so just pick a random one.
|
||
|
if ( spawn_options.size <= 0 )
|
||
|
{
|
||
|
spawn_options[ spawn_options.size ] = "bank";
|
||
|
spawn_options[ spawn_options.size ] = "gas";
|
||
|
spawn_options[ spawn_options.size ] = "taco";
|
||
|
}
|
||
|
|
||
|
// Only try for a new option of we have more than one.
|
||
|
i = 0;
|
||
|
if ( spawn_options.size > 1 )
|
||
|
{
|
||
|
i = randomint( spawn_options.size );
|
||
|
if ( spawn_options[ i ] == last_spawn )
|
||
|
{
|
||
|
i--;
|
||
|
if ( i < 0 )
|
||
|
i = spawn_options.size - 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
respawn_amount = randomintrange( min_fill, max_fill );
|
||
|
last_spawn = spawn_options[ i ];
|
||
|
switch ( spawn_options[ i ] )
|
||
|
{
|
||
|
case "bank":
|
||
|
thread maps\so_killspree_invasion::enable_hunter_enemy_group_bank( respawn_amount );
|
||
|
if ( !used_smoke || randomfloat( 1.0 ) < level.smoke_chance )
|
||
|
{
|
||
|
used_smoke = true;
|
||
|
thread maps\so_killspree_invasion::enable_smoke_wave_north( 4 );
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case "gas":
|
||
|
thread maps\so_killspree_invasion::enable_hunter_enemy_group_gas_station( respawn_amount );
|
||
|
break;
|
||
|
|
||
|
case "taco":
|
||
|
thread maps\so_killspree_invasion::enable_hunter_enemy_group_taco( respawn_amount );
|
||
|
if ( !used_smoke || randomfloat( 1.0 ) < level.smoke_chance )
|
||
|
{
|
||
|
used_smoke = true;
|
||
|
thread maps\so_killspree_invasion::enable_smoke_wave_south( 4 );
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
level waittill( "hunter_group_spawn_complete" );
|
||
|
}
|
||
|
|
||
|
// Give it a moment before checking again.
|
||
|
wait 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
hunter_register_damage()
|
||
|
{
|
||
|
level.hunter_damage_p1[ self.unique_id ] = 0;
|
||
|
level.hunter_damage_p2[ self.unique_id ] = 0;
|
||
|
|
||
|
self endon( "death" );
|
||
|
|
||
|
for ( ;; )
|
||
|
{
|
||
|
self waittill( "damage", amount, attacker );
|
||
|
|
||
|
if ( !isdefined( attacker ) )
|
||
|
continue;
|
||
|
|
||
|
if ( attacker == level.player )
|
||
|
{
|
||
|
level.hunter_damage_p1[ self.unique_id ] += amount;
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if ( is_coop() )
|
||
|
{
|
||
|
if ( attacker == level.player2 )
|
||
|
{
|
||
|
level.hunter_damage_p2[ self.unique_id ] += amount;
|
||
|
continue;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
hunter_register_death()
|
||
|
{
|
||
|
level endon( "special_op_terminated" );
|
||
|
self endon( "pain_death" );
|
||
|
|
||
|
level.hunters_active++;
|
||
|
|
||
|
my_maxhealth = self.maxhealth;
|
||
|
my_id = self.unique_id;
|
||
|
my_noteworthy = self.script_noteworthy;
|
||
|
my_birthtime = gettime();
|
||
|
|
||
|
thread hunter_register_long_death( my_id );
|
||
|
|
||
|
self waittill( "death", attacker, cause, weapon_name );
|
||
|
|
||
|
hunter_register_death_score( my_id, attacker, level.hunter_kill_value, my_noteworthy, my_birthtime );
|
||
|
hunter_register_death_cleanup( my_id );
|
||
|
}
|
||
|
|
||
|
hunter_register_long_death( my_id )
|
||
|
{
|
||
|
level endon( "special_op_terminated" );
|
||
|
self endon( "death" );
|
||
|
|
||
|
self waittill( "pain_death", attacker );
|
||
|
|
||
|
thread hunter_register_long_death_finish( my_id );
|
||
|
}
|
||
|
|
||
|
hunter_register_long_death_finish( my_id )
|
||
|
{
|
||
|
level endon( "special_op_terminated" );
|
||
|
|
||
|
level.hunter_damage_p1[ my_id ] = 0;
|
||
|
level.hunter_damage_p2[ my_id ] = 0;
|
||
|
|
||
|
self waittill( "death", attacker, cause );
|
||
|
|
||
|
if ( !isdefined( attacker ) )
|
||
|
return;
|
||
|
|
||
|
if ( !isplayer( attacker ) )
|
||
|
return;
|
||
|
|
||
|
if ( cause == "MOD_UNKNOWN" )
|
||
|
return;
|
||
|
|
||
|
melee_kill = false;
|
||
|
if ( isdefined( cause ) && ( cause == "MOD_MELEE" ) )
|
||
|
melee_kill = true;
|
||
|
|
||
|
if ( melee_kill )
|
||
|
hunter_register_death_score( my_id, attacker, level.hunter_brutal_value );
|
||
|
else
|
||
|
hunter_register_death_score( my_id, attacker, level.hunter_finish_value );
|
||
|
|
||
|
hunter_register_death_cleanup( my_id );
|
||
|
}
|
||
|
|
||
|
hunter_register_death_cleanup( my_id )
|
||
|
{
|
||
|
level.hunters_active--;
|
||
|
level.hunter_enemies[ my_id ] = undefined;
|
||
|
level.hunter_damage_p1[ my_id ] = undefined;
|
||
|
level.hunter_damage_p2[ my_id ] = undefined;
|
||
|
}
|
||
|
|
||
|
hunter_register_death_score( my_id, attacker, point_value, my_noteworthy, my_birthtime )
|
||
|
{
|
||
|
if ( attacker_is_p1( attacker ) )
|
||
|
{
|
||
|
thread pulse_kill_counter_hud( point_value, 0 );
|
||
|
}
|
||
|
else
|
||
|
if ( attacker_is_p2( attacker ) )
|
||
|
{
|
||
|
thread pulse_kill_counter_hud( 0, point_value );
|
||
|
}
|
||
|
else
|
||
|
if ( isdefined( self.vehicle_attacker ) && attacker_is_p1( self.vehicle_attacker ) )
|
||
|
{
|
||
|
thread pulse_kill_counter_hud( point_value, 0 );
|
||
|
}
|
||
|
else
|
||
|
if ( isdefined( self.vehicle_attacker ) && attacker_is_p2( self.vehicle_attacker ) )
|
||
|
{
|
||
|
thread pulse_kill_counter_hud( 0, point_value );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Only needed for enemies spawning from the trucks. They aren't getting their killer
|
||
|
// passed on correctly and haven't been able to track down where they are getting killed from.
|
||
|
if ( !isdefined( my_noteworthy ) || ( my_noteworthy != "truck_group_enemies" ) )
|
||
|
return;
|
||
|
|
||
|
// Only fudge for 25 seconds after spawning.
|
||
|
if ( !isdefined( my_birthtime ) || ( my_birthtime + 25000 <= gettime() ) )
|
||
|
return;
|
||
|
|
||
|
// Grant it to whoever did at least 40 damage and got the most out of the two players.
|
||
|
if ( ( level.hunter_damage_p1[ my_id ] > 40 ) || ( level.hunter_damage_p2[ my_id ] > 40 ) )
|
||
|
{
|
||
|
if ( level.hunter_damage_p1[ my_id ] > level.hunter_damage_p2[ my_id ] )
|
||
|
thread pulse_kill_counter_hud( point_value, 0 );
|
||
|
else
|
||
|
thread pulse_kill_counter_hud( 0, point_value );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
dialog_hunter_enemies( enemy_tag, wait_time )
|
||
|
{
|
||
|
// Prevent hunter spawn dialogs from happening too frequently
|
||
|
if ( isdefined( level.hunter_dialog_throttle ) )
|
||
|
{
|
||
|
if ( !isdefined( level.hunter_dialog_time ) )
|
||
|
level.hunter_dialog_time = gettime() - level.hunter_dialog_throttle - 1;
|
||
|
|
||
|
time_since = gettime() - level.hunter_dialog_time;
|
||
|
if ( time_since <= level.hunter_dialog_throttle )
|
||
|
return;
|
||
|
|
||
|
level.hunter_dialog_time = gettime();
|
||
|
}
|
||
|
|
||
|
if ( isdefined( wait_time ) )
|
||
|
wait wait_time;
|
||
|
|
||
|
assertex( isdefined( level.dialog ), "dialog_hunter_enemies requires level.dialog to be defined before it can play anything." );
|
||
|
|
||
|
sound_selection = randomint( level.dialog[ enemy_tag ].size );
|
||
|
thread radio_dialogue( level.dialog[ enemy_tag ][ sound_selection ] );
|
||
|
}
|
||
|
|
||
|
dialog_hunter_enemies_setup( enemy_tag, wait_time )
|
||
|
{
|
||
|
if ( !isdefined( level.dialog ) )
|
||
|
level.dialog = [];
|
||
|
|
||
|
//Hunter Two-One this is Overlord Actual, we're seeing enemy reinforcements to your north, over.
|
||
|
level.dialog[ "bank_enemies" ][ 0 ] = "inv_hqr_enemynorth";
|
||
|
//Be advised Hunter Two-One, you got enemy infantry by that bank to the north, over.
|
||
|
level.dialog[ "bank_enemies" ][ 1 ] = "inv_hqr_banktonorth";
|
||
|
//Hunter Two-One, be advised, enemy foot-mobiles approaching north of your location, over.
|
||
|
level.dialog[ "bank_enemies" ][ 2 ] = "inv_hqr_footmobiles";
|
||
|
|
||
|
//Hunter Two-One, Hunter Four has a visual on hostiles near the Nova gas station, over.
|
||
|
level.dialog[ "gas_station_enemies" ][ 0 ] = "inv_hqr_novagasstation";
|
||
|
//Hunter Two-One, relay from Goliath Two, enemy reinforcements approaching from the west, over.
|
||
|
level.dialog[ "gas_station_enemies" ][ 1 ] = "inv_hqr_enemywest";
|
||
|
//Hunter Two-One, tangos approaching near the diner to the west, over.
|
||
|
level.dialog[ "gas_station_enemies" ][ 2 ] = "inv_hqr_dinerwest";
|
||
|
|
||
|
//Hunter Two-One, Overlord. Enemy foot-mobiles approaching you from the southeast, over.
|
||
|
level.dialog[ "taco_enemies" ][ 0 ] = "inv_hqr_southeast";
|
||
|
//Hunter Two-One, Goliath One has a visual on hostiles coming from the southeast, over.
|
||
|
level.dialog[ "taco_enemies" ][ 1 ] = "inv_hqr_visualse";
|
||
|
//Hunter Two-One, be advised, enemy foot-mobiles have been sighted near the taco joint, over.
|
||
|
level.dialog[ "taco_enemies" ][ 2 ] = "inv_hqr_tacojoint";
|
||
|
}
|
||
|
|
||
|
// ---------------------------------------------------------------------------------
|
||
|
|
||
|
hud_create_kill_counter()
|
||
|
{
|
||
|
level endon( "special_op_failed" );
|
||
|
|
||
|
yline = 2;
|
||
|
if ( is_coop() )
|
||
|
{
|
||
|
yline = 3;
|
||
|
thread hud_create_p1_counter();
|
||
|
thread hud_create_p2_counter();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
thread hud_create_p1_counter_nodraw();
|
||
|
}
|
||
|
|
||
|
hudelem = so_create_hud_item( yline, so_hud_ypos(), &"SO_KILLSPREE_INVASION_HUD_REMAINING", self );
|
||
|
hudelem_score = so_create_hud_item( yline, so_hud_ypos(), undefined, self );
|
||
|
hudelem_score.alignx = "left";
|
||
|
|
||
|
self.kill_counter_hud = hudelem_score;
|
||
|
|
||
|
old_score = level.points_counter_display;
|
||
|
while ( 1 )
|
||
|
{
|
||
|
hudelem_score SetValue( level.points_counter_display );
|
||
|
|
||
|
if ( level.points_counter_display <= 0 )
|
||
|
{
|
||
|
hudelem thread so_hud_pulse_success();
|
||
|
hudelem_score thread so_hud_pulse_success();
|
||
|
}
|
||
|
else if ( level.points_counter_display < old_score )
|
||
|
{
|
||
|
if ( level.points_counter_display <= 5000 )
|
||
|
{
|
||
|
hudelem thread so_hud_pulse_close();
|
||
|
hudelem_score thread so_hud_pulse_close();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hudelem thread so_hud_pulse_default();
|
||
|
hudelem_score thread so_hud_pulse_default();
|
||
|
}
|
||
|
old_score = level.points_counter_display;
|
||
|
}
|
||
|
|
||
|
if ( flag( "challenge_success" ) )
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
level waittill( "score_updated" );
|
||
|
}
|
||
|
|
||
|
hudelem_score SetValue( 0 );
|
||
|
|
||
|
hudelem thread so_remove_hud_item();
|
||
|
hudelem_score thread so_remove_hud_item();
|
||
|
}
|
||
|
|
||
|
hud_create_p1_counter()
|
||
|
{
|
||
|
level endon( "special_op_failed" );
|
||
|
|
||
|
hudelem = so_create_hud_item( 4, so_hud_ypos(), &"SO_KILLSPREE_INVASION_PLAYER_LINE", self );
|
||
|
hudelem_score = so_create_hud_item( 4, so_hud_ypos(), undefined, self );
|
||
|
hudelem_score.alignx = "left";
|
||
|
hudelem SetPlayerNameString( level.player );
|
||
|
|
||
|
self.kill_msg_hud_p1 = hudelem;
|
||
|
self.kill_counter_hud_p1 = hudelem_score;
|
||
|
|
||
|
thread info_hud_handle_fade( hudelem );
|
||
|
thread info_hud_handle_fade( hudelem_score );
|
||
|
|
||
|
while ( 1 )
|
||
|
{
|
||
|
level.player.total_score = level.points_p1_display;
|
||
|
hudelem_score SetValue( level.points_p1_display );
|
||
|
if ( flag( "challenge_success" ) )
|
||
|
break;
|
||
|
|
||
|
level waittill( "score_updated" );
|
||
|
}
|
||
|
|
||
|
hudelem_score SetValue( level.points_p1_display );
|
||
|
level.player.total_score = level.points_p1_display;
|
||
|
|
||
|
hudelem thread so_remove_hud_item();
|
||
|
hudelem_score thread so_remove_hud_item();
|
||
|
}
|
||
|
|
||
|
hud_create_p1_counter_nodraw()
|
||
|
{
|
||
|
level endon( "special_op_failed" );
|
||
|
|
||
|
while ( 1 )
|
||
|
{
|
||
|
level.player.total_score = level.points_p1_display;
|
||
|
if ( flag( "challenge_success" ) )
|
||
|
break;
|
||
|
|
||
|
level waittill( "score_updated" );
|
||
|
}
|
||
|
|
||
|
level.player.total_score = level.points_p1_display;
|
||
|
}
|
||
|
|
||
|
hud_create_p2_counter()
|
||
|
{
|
||
|
level endon( "special_op_failed" );
|
||
|
|
||
|
hudelem = so_create_hud_item( 5, so_hud_ypos(), &"SO_KILLSPREE_INVASION_PLAYER_LINE", self );
|
||
|
hudelem_score = so_create_hud_item( 5, so_hud_ypos(), undefined, self );
|
||
|
hudelem_score.alignx = "left";
|
||
|
hudelem SetPlayerNameString( level.player2 );
|
||
|
|
||
|
self.kill_msg_hud_p2 = hudelem;
|
||
|
self.kill_counter_hud_p2 = hudelem_score;
|
||
|
|
||
|
thread info_hud_handle_fade( hudelem );
|
||
|
thread info_hud_handle_fade( hudelem_score );
|
||
|
|
||
|
while ( 1 )
|
||
|
{
|
||
|
level.player2.total_score = level.points_p2_display;
|
||
|
hudelem_score SetValue( level.points_p2_display );
|
||
|
if ( flag( "challenge_success" ) )
|
||
|
break;
|
||
|
|
||
|
level waittill( "score_updated" );
|
||
|
}
|
||
|
|
||
|
level.player2.total_score = level.points_p2_display;
|
||
|
hudelem_score SetValue( level.points_p2_display );
|
||
|
|
||
|
hudelem thread so_remove_hud_item();
|
||
|
hudelem_score thread so_remove_hud_item();
|
||
|
}
|
||
|
|
||
|
// CTW - Egads this is terrible.
|
||
|
pulse_kill_counter_hud( points_p1, points_p2 )
|
||
|
{
|
||
|
level endon( "special_op_terminated" );
|
||
|
|
||
|
if ( !isdefined( points_p1 ) )
|
||
|
points_p1 = 0;
|
||
|
if ( !isdefined( points_p2 ) )
|
||
|
points_p2 = 0;
|
||
|
|
||
|
if ( points_p1 > 0 )
|
||
|
level.player thread hud_create_kill_splash( points_p1 );
|
||
|
if ( points_p2 > 0 )
|
||
|
level.player2 thread hud_create_kill_splash( points_p2 );
|
||
|
|
||
|
points = points_p1 + points_p2;
|
||
|
|
||
|
level.points_counter -= points;
|
||
|
level.points_p1 += points_p1;
|
||
|
level.points_p2 += points_p2;
|
||
|
|
||
|
// Allow pulse requests to queue up, but if we've already got one active, then just add and get out.
|
||
|
level.pulse_requests[ level.pulse_requests.size ] = points;
|
||
|
level.pulse_requests_p1[ level.pulse_requests_p1.size ] = points_p1;
|
||
|
level.pulse_requests_p2[ level.pulse_requests_p2.size ] = points_p2;
|
||
|
if ( level.pulse_requests.size > 1 )
|
||
|
return;
|
||
|
|
||
|
while ( ( level.pulse_requests.size > 0 ) && !flag( "challenge_success" ) )
|
||
|
{
|
||
|
level.player PlaySound( "arcademode_2x" );
|
||
|
level.points_counter_display -= level.pulse_requests[ 0 ];
|
||
|
|
||
|
// Don't do the VO except on the big updates.
|
||
|
if ( level.points_counter_display > 5999 )
|
||
|
thread so_dialog_counter_update( level.points_counter_display, level.points_max, level.hunter_kill_value );
|
||
|
|
||
|
level.points_p1_display += level.pulse_requests_p1[ 0 ];
|
||
|
if ( level.player.points_combo_unused > 0 )
|
||
|
{
|
||
|
level.points_counter_display -= level.player.points_combo_unused;
|
||
|
level.points_counter -= level.player.points_combo_unused;
|
||
|
level.points_p1_display += level.player.points_combo_unused;
|
||
|
level.player.points_combo_unused = 0;
|
||
|
}
|
||
|
|
||
|
if ( is_coop() )
|
||
|
{
|
||
|
level.points_p2_display += level.pulse_requests_p2[ 0 ];
|
||
|
if ( level.player2.points_combo_unused > 0 )
|
||
|
{
|
||
|
level.points_counter_display -= level.player2.points_combo_unused;
|
||
|
level.points_counter -= level.player2.points_combo_unused;
|
||
|
level.points_p2_display += level.player2.points_combo_unused;
|
||
|
level.player2.points_combo_unused = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( level.points_counter_display <= 0 )
|
||
|
{
|
||
|
level.points_counter = 0;
|
||
|
level.points_counter_display = 0;
|
||
|
flag_set( "challenge_success" );
|
||
|
level notify( "score_updated" );
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
level notify( "score_updated" );
|
||
|
foreach ( player in level.players )
|
||
|
{
|
||
|
if ( is_coop() )
|
||
|
{
|
||
|
if ( level.pulse_requests_p1[ 0 ] > 0 )
|
||
|
{
|
||
|
player.kill_msg_hud_p1 thread so_hud_pulse_default();
|
||
|
player.kill_counter_hud_p1 thread so_hud_pulse_default();
|
||
|
}
|
||
|
if ( level.pulse_requests_p2[ 0 ] > 0 )
|
||
|
{
|
||
|
player.kill_msg_hud_p2 thread so_hud_pulse_default();
|
||
|
player.kill_counter_hud_p2 thread so_hud_pulse_default();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
wait 0.5;
|
||
|
pulse_purge_request();
|
||
|
}
|
||
|
|
||
|
level notify ( "pulse_queue_processed" );
|
||
|
}
|
||
|
|
||
|
pulse_purge_request()
|
||
|
{
|
||
|
for ( i = level.pulse_requests.size - 1; i > 0; i-- )
|
||
|
{
|
||
|
level.pulse_requests[ i - 1 ] = level.pulse_requests[ i ];
|
||
|
level.pulse_requests_p1[ i - 1 ] = level.pulse_requests_p1[ i ];
|
||
|
level.pulse_requests_p2[ i - 1 ] = level.pulse_requests_p2[ i ];
|
||
|
}
|
||
|
|
||
|
level.pulse_requests[ level.pulse_requests.size - 1 ] = undefined;
|
||
|
level.pulse_requests_p1[ level.pulse_requests_p1.size - 1 ] = undefined;
|
||
|
level.pulse_requests_p2[ level.pulse_requests_p2.size - 1 ] = undefined;
|
||
|
}
|
||
|
|
||
|
// This is not a good way to do this at all, but is good enough for a quick review.
|
||
|
hud_create_kill_splash( points )
|
||
|
{
|
||
|
level endon( "special_op_terminated" );
|
||
|
|
||
|
self notify( "hud_create_kill_splash" );
|
||
|
self endon( "hud_create_kill_splash" );
|
||
|
|
||
|
if ( !isdefined( self.hud_kill_splash_total ) )
|
||
|
{
|
||
|
self.hud_kill_splash_total = points;
|
||
|
self.hud_kill_splash_max = points;
|
||
|
|
||
|
self.hud_kill_splash_points = hud_create_kill_splash_default( self );
|
||
|
|
||
|
self.hud_kill_splash_msg = hud_create_kill_splash_default( self );
|
||
|
self.hud_kill_splash_msg.y = self.hud_kill_splash_points.y - 10;
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
self.hud_kill_splash_total += points;
|
||
|
if ( points > self.hud_kill_splash_max )
|
||
|
self.hud_kill_splash_max = points;
|
||
|
|
||
|
if ( !isdefined( self.hud_kill_combo_total ) )
|
||
|
{
|
||
|
self.hud_kill_combo_total = 2;
|
||
|
self.hud_kill_combo = hud_create_kill_splash_default( self, &"SO_KILLSPREE_INVASION_SPLASH_COMBO" );
|
||
|
self.hud_kill_combo.y = self.hud_kill_splash_points.y - 30;
|
||
|
|
||
|
self.hud_kill_combo_points = hud_create_kill_splash_default( self, &"SO_KILLSPREE_INVASION_SPLASH_BONUS" );
|
||
|
self.hud_kill_combo_points.y = self.hud_kill_splash_points.y + 15;
|
||
|
self.hud_combo_bonus = 0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
self.hud_kill_combo_total++;
|
||
|
}
|
||
|
|
||
|
combo_bonus = level.points_combo_base * self.hud_kill_combo_total;
|
||
|
self.hud_combo_bonus += combo_bonus;
|
||
|
self.points_combo_unused += combo_bonus;
|
||
|
}
|
||
|
|
||
|
// self.hud_kill_splash_points.label = hud_convert_to_points( self.hud_kill_splash_total );
|
||
|
self.hud_kill_splash_points SetValue( self.hud_kill_splash_total );
|
||
|
self.hud_kill_splash_points.alpha = 1;
|
||
|
|
||
|
self.hud_kill_splash_msg.label = hud_splash_kill_style( points );
|
||
|
self.hud_kill_splash_msg.alpha = 1;
|
||
|
|
||
|
if ( isdefined( self.hud_kill_combo_total ) )
|
||
|
{
|
||
|
// self.hud_kill_combo.label = "Combo x" + self.hud_kill_combo_total + "!"; // &SO_KILLSPREE_INVASION_SPLASH_COMBO
|
||
|
self.hud_kill_combo SetValue( self.hud_kill_combo_total );
|
||
|
self.hud_kill_combo.alpha = 1;
|
||
|
self.hud_kill_combo.fontScale = 1.0 + ( 0.1 * self.hud_kill_combo_total );
|
||
|
if ( self.highest_combo < self.hud_kill_combo_total )
|
||
|
self.highest_combo = self.hud_kill_combo_total;
|
||
|
|
||
|
// self.hud_kill_combo_points.label = "Bonus: " + hud_convert_to_points( self.hud_combo_bonus ); // &SO_KILLSPREE_INVASION_SPLASH_BONUS
|
||
|
self.hud_kill_combo_points SetValue( self.hud_combo_bonus ); // &SO_KILLSPREE_INVASION_SPLASH_BONUS
|
||
|
self.hud_kill_combo_points.alpha = 1;
|
||
|
}
|
||
|
|
||
|
// level waittill( "pulse_queue_processed" );
|
||
|
|
||
|
// wait level.combo_time_window - 0.25;
|
||
|
// When reloading, give the player a little bit of extra time.
|
||
|
timer = level.combo_time_window - 0.25;
|
||
|
while ( timer > 0 )
|
||
|
{
|
||
|
wait 0.05;
|
||
|
if ( self isreloading() )
|
||
|
timer -= 0.025;
|
||
|
else
|
||
|
timer -= 0.05;
|
||
|
}
|
||
|
|
||
|
self.hud_kill_splash_points FadeOverTime( 0.25 );
|
||
|
self.hud_kill_splash_points.alpha = 0;
|
||
|
|
||
|
self.hud_kill_splash_msg FadeOverTime( 0.25 );
|
||
|
self.hud_kill_splash_msg.alpha = 0;
|
||
|
|
||
|
if ( isdefined( self.hud_kill_combo_total ) )
|
||
|
{
|
||
|
self.hud_kill_combo FadeOverTime( 0.25 );
|
||
|
self.hud_kill_combo.alpha = 0;
|
||
|
|
||
|
self.hud_kill_combo_points FadeOverTime( 0.25 );
|
||
|
self.hud_kill_combo_points.alpha = 0;
|
||
|
}
|
||
|
|
||
|
wait 0.25;
|
||
|
|
||
|
if ( isdefined( self.hud_kill_splash_points ) )
|
||
|
self.hud_kill_splash_points Destroy();
|
||
|
if ( isdefined( self.hud_kill_splash_msg ) )
|
||
|
self.hud_kill_splash_msg Destroy();
|
||
|
self.hud_kill_splash_total = undefined;
|
||
|
|
||
|
if ( isdefined( self.hud_kill_combo ) )
|
||
|
self.hud_kill_combo Destroy();
|
||
|
if ( isdefined( self.hud_kill_combo_points ) )
|
||
|
self.hud_kill_combo_points Destroy();
|
||
|
self.hud_kill_combo_total = undefined;
|
||
|
}
|
||
|
|
||
|
hud_splash_destroy()
|
||
|
{
|
||
|
level waittill( "special_op_terminated" );
|
||
|
|
||
|
if ( isdefined( self.hud_kill_splash_points ) )
|
||
|
self.hud_kill_splash_points Destroy();
|
||
|
if ( isdefined( self.hud_kill_splash_msg ) )
|
||
|
self.hud_kill_splash_msg Destroy();
|
||
|
if ( isdefined( self.hud_kill_combo ) )
|
||
|
self.hud_kill_combo Destroy();
|
||
|
if ( isdefined( self.hud_kill_combo_points ) )
|
||
|
self.hud_kill_combo_points Destroy();
|
||
|
}
|
||
|
|
||
|
hud_splash_kill_style( points, current_msg )
|
||
|
{
|
||
|
if ( points == level.hunter_finish_value )
|
||
|
{
|
||
|
self.solid_kills++;
|
||
|
return &"SO_KILLSPREE_INVASION_SCORE_FINISHED";
|
||
|
}
|
||
|
|
||
|
if ( points == level.hunter_kill_value )
|
||
|
{
|
||
|
self.solid_kills++;
|
||
|
return &"SO_KILLSPREE_INVASION_SCORE_KILL";
|
||
|
}
|
||
|
|
||
|
if ( points == level.hunter_brutal_value )
|
||
|
{
|
||
|
self.heartless_kills++;
|
||
|
return &"SO_KILLSPREE_INVASION_SCORE_BRUTAL";
|
||
|
}
|
||
|
|
||
|
if ( points == level.btr_kill_value )
|
||
|
{
|
||
|
return &"SO_KILLSPREE_INVASION_SCORE_BTR80";
|
||
|
}
|
||
|
}
|
||
|
|
||
|
hud_convert_to_points( value )
|
||
|
{
|
||
|
return value;
|
||
|
/* thousands = 0;
|
||
|
if ( value >= 1000 )
|
||
|
thousands = int( value / 1000 );
|
||
|
hundreds = value - ( thousands * 1000 );
|
||
|
|
||
|
label = "";
|
||
|
if ( thousands > 0 )
|
||
|
{
|
||
|
label += thousands + ",";
|
||
|
if ( hundreds < 100 )
|
||
|
label += "0";
|
||
|
if ( hundreds < 10 )
|
||
|
label += "0";
|
||
|
}
|
||
|
label += hundreds;
|
||
|
|
||
|
return label;*/
|
||
|
}
|
||
|
|
||
|
hud_create_kill_splash_default( player, message )
|
||
|
{
|
||
|
hudelem = newClientHudElem( player );
|
||
|
hudelem.alignX = "center";
|
||
|
hudelem.alignY = "middle";
|
||
|
hudelem.horzAlign = "center";
|
||
|
hudelem.vertAlign = "middle";
|
||
|
hudelem.x = 0;
|
||
|
hudelem.y = -70;
|
||
|
hudelem.fontScale = 1.0;
|
||
|
hudelem.font = "hudsmall";
|
||
|
hudelem.foreground = 1;
|
||
|
hudelem.hidewheninmenu = true;
|
||
|
hudelem.hidewhendead = true;
|
||
|
hudelem.sort = 2;
|
||
|
hudelem set_hud_yellow();
|
||
|
if ( isdefined( message ) )
|
||
|
hudelem.label = message;
|
||
|
|
||
|
return hudelem;
|
||
|
}
|
||
|
|
||
|
// ---------------------------------------------------------------------------------
|
||
|
|
||
|
door_diner_open()
|
||
|
{
|
||
|
diner_back_door = getent( "diner_back_door", "targetname" );
|
||
|
diner_back_door rotateyaw( 85, .3 );//counter clockwise
|
||
|
diner_back_door playsound( "diner_backdoor_slams_open" );
|
||
|
diner_back_door connectpaths();
|
||
|
}
|
||
|
|
||
|
door_nates_locker_open()
|
||
|
{
|
||
|
nates_meat_locker_door = getent( "nates_meat_locker_door", "targetname" );
|
||
|
nates_meat_locker_door_model = getent( nates_meat_locker_door.target, "targetname" );
|
||
|
nates_meat_locker_door_model LinkTo( nates_meat_locker_door );
|
||
|
nates_meat_locker_door rotateyaw( -82, .1, 0, 0 );
|
||
|
nates_meat_locker_door connectpaths();
|
||
|
}
|
||
|
|
||
|
door_bt_locker_open()
|
||
|
{
|
||
|
BT_locker_door = getent( "BT_locker_door", "targetname" );
|
||
|
BT_locker_door rotateyaw( -172, .1, 0, 0 );
|
||
|
BT_locker_door connectpaths();
|
||
|
}
|
||
|
|
||
|
// ---------------------------------------------------------------------------------
|