mirror of
https://github.com/InfinityLoader/IL-GSC.git
synced 2025-06-07 17:17:50 -05:00
452 lines
12 KiB
Plaintext
452 lines
12 KiB
Plaintext
#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 );
|
||
}
|
||
|
||
|