IL-GSC/BO1/PC/ZM/maps/_banzai.gsc
2024-02-18 17:32:07 -05:00

452 lines
12 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include maps\_utility;
#include common_scripts\utility;
init()
{
self call_overloaded_func( "animscripts\banzai", "banzai_init_anims" );
PrecacheShellshock( "banzai_impact" );
PrecacheString( &"SCRIPT_PLATFORM_BANZAI_HINT" );
PrecacheString( &"SCRIPT_PLATFORM_BANZAI_DEATH_DO_NOTHING" );
PrecacheString( &"SCRIPT_PLATFORM_BANZAI_DEATH_TOO_SOON" );
PrecacheString( &"SCRIPT_PLATFORM_BANZAI_DEATH_TOO_LATE" );
level._effects[ "stab_wound" ] = loadfx( "impacts/fx_flesh_bayonet_neck" );
level thread check_interactive_hands();
}
check_interactive_hands()
{
}
spawned_banzai_immediate()
{
if ( spawn_failed( self ) )
return;
banzai_force();
}
spawned_banzai_dynamic()
{
banzai();
}
banzai()
{
self call_overloaded_func( "animscripts\banzai", "init" );
self endon( "death" );
self endon( "stop_banzai_thread" );
if( IsDefined( self.target ) && ( !IsDefined( self.banzai_no_wait ) || ( Isdefined( self.banzai_no_wait ) && !self.banzai_no_wait ) ) )
{
self waittill( "reached_path_end" );
}
wait_time = 3 + RandomFloat( 2 );
self thread banzai_print( "Banzai wait: " + wait_time );
wait( wait_time );
self thread banzai_print( "Getting nearby Banzai-ers" );
others = self get_nearby_banzai_guys();
self banzai_pump_up();
self thread staggered_banzai_charge();
for( i = 0; i < others.size; i++ )
{
if ( isalive(others[i]) && isdefined(others[i]) )
{
others[i] thread staggered_banzai_charge();
}
}
}
banzai_force()
{
self call_overloaded_func( "animscripts\banzai", "init" );
self endon( "death" );
self.banzai = true;
self.inmeleecharge = true;
if( IsDefined( self.target ) && ( !IsDefined( self.banzai_no_wait ) || ( Isdefined( self.banzai_no_wait ) && !self.banzai_no_wait ) ) )
{
self waittill( "reached_path_end" );
}
self banzai_charge( true );
}
may_banzai_attack( enemy, maxAttackers )
{
assert ( IsDefined( enemy ) );
if ( enemy call_overloaded_func( "animscripts\banzai", "in_banzai_melee" ) && DistanceSquared( self.origin, enemy.origin ) < 96 * 96 )
return false;
if ( IsDefined( enemy.num_banzai_chargers ) && enemy.num_banzai_chargers >= maxAttackers )
return false;
if ( IsDefined( enemy.no_banzai_attack ) && enemy.no_banzai_attack )
return false;
if ( IsDefined( enemy.magic_bullet_shield ) && enemy.magic_bullet_shield )
{
if ( enemy.a.pose != "stand" )
return false;
}
if ( IsPlayer( enemy ) )
{
if ( IsDefined( enemy.usingturret ) && enemy.usingturret )
return false;
if ( IsDefined( enemy.usingvehicle ) && enemy.usingvehicle )
return false;
if ( !check_player_can_see_me( enemy ) )
return false;
if ( enemy maps\_laststand::player_is_in_laststand() )
return false;
if( IsDefined(self.primaryweapon) && self.primaryweapon == "type100_smg")
return false;
}
return true;
}
should_switch_immediately( enemy )
{
if ( !IsDefined( enemy ) )
return true;
if ( !IsAlive( enemy ) )
return true;
if ( IsDefined( enemy.no_banzai_attack ) && enemy.no_banzai_attack )
return true;
if ( IsDefined( enemy.magic_bullet_shield ) && enemy.magic_bullet_shield )
{
if ( enemy.a.pose != "stand" )
return true;
}
if ( IsPlayer( enemy ) )
{
if ( IsDefined( enemy.usingTurret ) && enemy.usingTurret )
return true;
if ( IsDefined( enemy.usingVehicle ) && enemy.usingvehicle )
return true;
if ( enemy maps\_laststand::player_is_in_laststand() )
return true;
if ( distanceSquared(self.origin, enemy.origin) < 20736 )
{
if ( self.a.movement == "stop" && (self.origin[2] < (enemy.origin[2]-24)) )
return true;
}
}
return false;
}
find_enemy()
{
self endon("death");
if(!isDefined(self.team))
{
return undefined;
}
if( self.team == "axis" )
{
opposite_team = "allies";
}
else
{
opposite_team = "axis";
}
maxDistance = 4000;
if ( IsDefined( self.script_max_banzai_distance ) )
{
maxDistance = self.script_max_banzai_distance;
}
clear_blocked_enemy_cache();
if ( !IsDefined( self.script_player_chance ) )
{
ais = GetAiArray( opposite_team );
players = get_players();
enemies = array_combine( players, ais );
enemies = get_array_of_closest( self.origin, enemies, undefined, undefined, maxDistance );
for ( numAttackers = 1; numAttackers <= 2; numAttackers++)
{
for ( i = 0; i < enemies.size; i++ )
{
if ( may_banzai_attack( enemies[i], numAttackers ) )
return enemies[i];
}
}
players = get_array_of_closest( self.origin, players, undefined, undefined, maxDistance );
for ( i = 0; i < players.size; i++ )
{
if ( may_banzai_attack( players[i], numAttackers ) )
return players[i];
}
return undefined;
}
if ( self.script_player_chance > 0 )
{
enemies = get_players();
enemies = get_array_of_closest( self.origin, enemies, undefined, undefined, maxDistance );
for ( i = 0; i < enemies.size; i++ )
{
if ( may_banzai_attack( enemies[i], 3 ) )
{
dieRoll = RandomInt( 100 );
if ( dieRoll < self.script_player_chance )
{
return enemies[i];
}
}
}
}
enemies = GetAiArray( opposite_team );
enemies = get_array_of_closest( self.origin, enemies, undefined, undefined, maxDistance );
for ( i = 0; i < enemies.size; i++ )
{
if ( may_banzai_attack( enemies[i], 2 ) )
return enemies[i];
}
return undefined;
}
check_player_can_see_me( player )
{
if ( !IsDefined( self.script_banzai_within_fov ) || !self.script_banzai_within_fov )
return true;
return player_can_see_me( player );
}
player_can_see_me( player )
{
playerAngles = player getplayerangles();
playerForwardVec = AnglesToForward( playerAngles );
playerUnitForwardVec = VectorNormalize( playerForwardVec );
banzaiPos = self GetOrigin();
playerPos = player GetOrigin();
playerToBanzaiVec = banzaiPos - playerPos;
playerToBanzaiUnitVec = VectorNormalize( playerToBanzaiVec );
forwardDotBanzai = VectorDot( playerUnitForwardVec, playerToBanzaiUnitVec );
angleFromCenter = ACos( forwardDotBanzai );
playerFOV = GetDvarFloat( #"cg_fov" );
banzaiVsPlayerFOVBuffer = GetDvarFloat( #"g_banzai_player_fov_buffer" );
if ( banzaiVsPlayerFOVBuffer <= 0 )
{
banzaiVsPlayerFOVBuffer = 0.2;
}
playerCanSeeMe = ( angleFromCenter <= ( playerFOV * 0.5 * ( 1 - banzaiVsPlayerFOVBuffer ) ) );
return playerCanSeeMe;
}
get_nearby_banzai_guys()
{
guys = GetAiArray( self.team );
banzai_guys = [];
for( i = 0; i < guys.size; i++ )
{
if( guys[i] == self )
{
continue;
}
if( IsAlive( guys[i] ) && IsDefined( guys[i].script_banzai ) && guys[i].script_banzai )
{
if( DistanceSquared( self.origin, guys[i].origin ) < 512 * 512 )
{
guys[i] notify( "stop_banzai_thread" );
guys[i].script_banzai = 0;
banzai_guys[banzai_guys.size] = guys[i];
}
}
}
return banzai_guys;
}
staggered_banzai_charge()
{
wait( RandomFloat( 1.0 ) );
banzai_charge();
}
banzai_charge( spawned_charge )
{
self endon( "death" );
if( !IsDefined( spawned_charge ) )
{
spawned_charge = false;
}
if( !spawned_charge )
{
self.banzai = true;
self.inmeleecharge = true;
}
self.goalradius = 64;
self thread start_banzai_announce();
self.favoriteenemy = undefined;
thread find_new_enemy_immediately();
thread find_closer_enemy();
thread find_new_enemy_if_blocked();
wait ( 0.05 );
while ( 1 )
{
if ( IsDefined( self.favoriteenemy ) )
{
self SetGoalPos( self.favoriteenemy.origin );
}
wait( 0.1 );
}
}
distance_to_enemy_less_than( lessThanThis )
{
assert( IsDefined( self.favoriteenemy ) );
return DistanceSquared( self.origin, self.favoriteenemy.origin ) < lessThanThis * lessThanThis;
}
find_new_enemy_immediately()
{
self endon( "death" );
while ( 1 )
{
if ( !self call_overloaded_func( "animscripts\banzai", "in_banzai_attack" ) )
{
enemy = self.favoriteenemy;
if ( should_switch_immediately( enemy ) )
{
switch_enemies();
}
}
wait( 0.1 );
}
}
find_closer_enemy()
{
self endon( "death" );
lastPos = undefined;
while ( 1 )
{
if ( !self call_overloaded_func( "animscripts\banzai", "in_banzai_attack" ) )
{
enemy = self.favoriteenemy;
if ( IsDefined( enemy ) )
{
if ( !IsPlayer( enemy ) && !distance_to_enemy_less_than( 192 ) )
{
newEnemy = self find_enemy();
if ( IsDefined( newEnemy ) && newEnemy != enemy )
{
if ( self CanSee( newEnemy ) )
{
self notify( "banzai_new_enemy" );
self.favoriteenemy.num_banzai_chargers--;
banzai_set_enemy( newEnemy );
}
}
}
}
}
wait( 0.05 );
}
}
find_new_enemy_if_blocked()
{
self endon( "death" );
lastPos = undefined;
while ( 1 )
{
if ( !self call_overloaded_func( "animscripts\banzai", "in_banzai_attack" ) )
{
enemy = self.favoriteenemy;
if ( IsDefined( enemy ) )
{
currPos = self.origin;
if ( IsDefined( lastPos ) && DistanceSquared( currPos, lastPos ) < 64 )
{
if ( !findpath( currPos, enemy.origin ) )
{
switch_enemies();
}
else
{
lastPos = currPos;
}
}
else
{
lastPos = currPos;
}
}
}
wait( RandomFloatRange( 0.25, 0.35 ) );
}
}
switch_enemies()
{
if ( IsDefined( self.favoriteenemy ) )
{
self notify( "banzai_new_enemy" );
self.favoriteenemy.num_banzai_chargers--;
}
enemy = keep_trying_find_enemy();
banzai_set_enemy( enemy );
}
keep_trying_find_enemy()
{
while ( 1 )
{
enemy = self find_enemy();
if ( IsDefined( enemy ) && ( !IsDefined( self.favoriteenemy ) || enemy != self.favoriteenemy ) )
{
return enemy;
}
wait( 0.05 );
}
}
clear_blocked_enemy_cache()
{
self.blocked_enemies = [];
self.blocked_enemy_flags = [];
}
banzai_set_enemy( enemy )
{
level thread banzai_death_thread( self, enemy );
self.favoriteEnemy = enemy;
self SetGoalPos( enemy.origin );
if( !IsDefined( enemy.num_banzai_chargers ) )
{
enemy.num_banzai_chargers = 0;
}
enemy.num_banzai_chargers++;
}
draw_forward_line_until_notify( ent, r, g, b, notifyEnt, notifyString )
{
assert( isdefined( notifyEnt ) );
assert( isdefined( notifyString ) );
ent endon( "death" );
notifyEnt endon( "death" );
notifyEnt endon( notifyString );
while( 1 )
{
forwardVec = VectorNormalize( AnglesToForward( ent.angles ) );
pointForward = ent.origin + forwardVec * 64;
line( ent.origin, pointForward, ( r, g, b ), 0.05 );
wait .05;
}
}
banzai_death_thread( attacker, enemy )
{
attacker endon( "banzai_new_enemy" );
attacker waittill( "death" );
if( IsDefined( enemy ) )
{
enemy.num_banzai_chargers--;
}
}
start_banzai_announce()
{
self endon( "death" );
self.battlechatter = false;
if ( !IsDefined( self.banzai_announcing ) )
{
self.banzai_announcing = true;
self thread listen_for_end_of_banzai_announce();
self banzai_dialogue( "banzai_charge_announce", undefined, "banzai_announce_ended" );
}
}
listen_for_end_of_banzai_announce()
{
self endon( "death" );
self waittill( "banzai_announce_ended" );
self.banzai_announcing = false;
}
end_banzai_charge_yell()
{
self endon( "banzai_new_enemy" );
self waittill( "pain" );
self stopSounds();
}
banzai_pump_up()
{
facial_anim = undefined;
soundalias = "banzai_pump";
self banzai_dialogue( soundalias, facial_anim, "banzai_pump" );
self waittill( "banzai_pump" );
}
banzai_print( msg )
{
}
#using_animtree( "generic_human" );
banzai_dialogue( soundalias, facial_anim, notify_string )
{
self animscripts\face::SaySpecificDialogue( facial_anim, soundalias, 0.9, notify_string );
}