mirror of
https://github.com/JezuzLizard/Recompilable-gscs-for-BO2-zombies-and-multiplayer.git
synced 2025-06-10 10:47:58 -05:00
305 lines
6.3 KiB
Plaintext
305 lines
6.3 KiB
Plaintext
#include maps/mp/animscripts/zm_combat;
|
|
#include maps/mp/animscripts/zm_utility;
|
|
#include maps/mp/animscripts/utility;
|
|
#include maps/mp/animscripts/shared;
|
|
#include common_scripts/utility;
|
|
|
|
meleecombat()
|
|
{
|
|
self endon( "end_melee" );
|
|
self endon( "killanimscript" );
|
|
/#
|
|
assert( canmeleeanyrange() );
|
|
#/
|
|
self orientmode( "face enemy" );
|
|
if ( is_true( self.sliding_on_goo ) )
|
|
{
|
|
self animmode( "slide" );
|
|
}
|
|
else
|
|
{
|
|
self animmode( "zonly_physics" );
|
|
}
|
|
for ( ;; )
|
|
{
|
|
if ( isDefined( self.marked_for_death ) )
|
|
{
|
|
return;
|
|
}
|
|
if ( isDefined( self.enemy ) )
|
|
{
|
|
angles = vectorToAngle( self.enemy.origin - self.origin );
|
|
self orientmode( "face angle", angles[ 1 ] );
|
|
}
|
|
if ( isDefined( self.zmb_vocals_attack ) )
|
|
{
|
|
self playsound( self.zmb_vocals_attack );
|
|
}
|
|
if ( isDefined( self.nochangeduringmelee ) && self.nochangeduringmelee )
|
|
{
|
|
self.safetochangescript = 0;
|
|
}
|
|
if ( isDefined( self.is_inert ) && self.is_inert )
|
|
{
|
|
return;
|
|
}
|
|
set_zombie_melee_anim_state( self );
|
|
if ( isDefined( self.melee_anim_func ) )
|
|
{
|
|
self thread [[ self.melee_anim_func ]]();
|
|
}
|
|
while ( 1 )
|
|
{
|
|
self waittill( "melee_anim", note );
|
|
if ( note == "end" )
|
|
{
|
|
break;
|
|
}
|
|
else if ( note == "fire" )
|
|
{
|
|
if ( !isDefined( self.enemy ) )
|
|
{
|
|
break;
|
|
}
|
|
else if ( isDefined( self.dont_die_on_me ) && self.dont_die_on_me )
|
|
{
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
self.enemy notify( "melee_swipe" );
|
|
oldhealth = self.enemy.health;
|
|
self melee();
|
|
if ( !isDefined( self.enemy ) )
|
|
{
|
|
break;
|
|
}
|
|
else if ( self.enemy.health >= oldhealth )
|
|
{
|
|
if ( isDefined( self.melee_miss_func ) )
|
|
{
|
|
self [[ self.melee_miss_func ]]();
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
if ( isDefined( level.melee_miss_func ) )
|
|
{
|
|
self [[ level.melee_miss_func ]]();
|
|
}
|
|
}
|
|
}
|
|
/#
|
|
if ( getDvarInt( #"7F11F572" ) )
|
|
{
|
|
if ( self.enemy.health < oldhealth )
|
|
{
|
|
zombie_eye = self geteye();
|
|
player_eye = self.enemy geteye();
|
|
trace = bullettrace( zombie_eye, player_eye, 1, self );
|
|
hitpos = trace[ "position" ];
|
|
dist = distance( zombie_eye, hitpos );
|
|
iprintln( "melee HIT " + dist );
|
|
#/
|
|
}
|
|
}
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
if ( note == "stop" )
|
|
{
|
|
if ( !cancontinuetomelee() )
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
}
|
|
}
|
|
}
|
|
if ( is_true( self.sliding_on_goo ) )
|
|
{
|
|
self orientmode( "face enemy" );
|
|
}
|
|
else self orientmode( "face default" );
|
|
if ( isDefined( self.nochangeduringmelee ) || self.nochangeduringmelee && is_true( self.sliding_on_goo ) )
|
|
{
|
|
if ( isDefined( self.enemy ) )
|
|
{
|
|
dist_sq = distancesquared( self.origin, self.enemy.origin );
|
|
if ( dist_sq > ( self.meleeattackdist * self.meleeattackdist ) )
|
|
{
|
|
self.safetochangescript = 1;
|
|
wait 0,1;
|
|
break;
|
|
}
|
|
else }
|
|
else self.safetochangescript = 1;
|
|
wait 0,1;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
}
|
|
}
|
|
if ( is_true( self.sliding_on_goo ) )
|
|
{
|
|
self animmode( "slide" );
|
|
}
|
|
else self animmode( "none" );
|
|
self thread maps/mp/animscripts/zm_combat::main();
|
|
}
|
|
|
|
cancontinuetomelee()
|
|
{
|
|
return canmeleeinternal( "already started" );
|
|
}
|
|
|
|
canmeleeanyrange()
|
|
{
|
|
return canmeleeinternal( "any range" );
|
|
}
|
|
|
|
canmeleedesperate()
|
|
{
|
|
return canmeleeinternal( "long range" );
|
|
}
|
|
|
|
canmelee()
|
|
{
|
|
return canmeleeinternal( "normal" );
|
|
}
|
|
|
|
canmeleeinternal( state )
|
|
{
|
|
if ( !issentient( self.enemy ) )
|
|
{
|
|
return 0;
|
|
}
|
|
if ( !isalive( self.enemy ) )
|
|
{
|
|
return 0;
|
|
}
|
|
if ( isDefined( self.disablemelee ) )
|
|
{
|
|
/#
|
|
assert( self.disablemelee );
|
|
#/
|
|
return 0;
|
|
}
|
|
yaw = abs( getyawtoenemy() );
|
|
if ( yaw > 60 || state != "already started" && yaw > 110 )
|
|
{
|
|
return 0;
|
|
}
|
|
enemypoint = self.enemy getorigin();
|
|
vectoenemy = enemypoint - self.origin;
|
|
self.enemydistancesq = lengthsquared( vectoenemy );
|
|
if ( self.enemydistancesq <= anim.meleerangesq )
|
|
{
|
|
if ( !ismeleepathclear( vectoenemy, enemypoint ) )
|
|
{
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
if ( state != "any range" )
|
|
{
|
|
chargerangesq = anim.chargerangesq;
|
|
if ( state == "long range" )
|
|
{
|
|
chargerangesq = anim.chargelongrangesq;
|
|
}
|
|
if ( self.enemydistancesq > chargerangesq )
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
if ( state == "already started" )
|
|
{
|
|
return 0;
|
|
}
|
|
if ( isDefined( self.check_melee_path ) && self.check_melee_path )
|
|
{
|
|
if ( !ismeleepathclear( vectoenemy, enemypoint ) )
|
|
{
|
|
self notify( "melee_path_blocked" );
|
|
return 0;
|
|
}
|
|
}
|
|
if ( isDefined( level.can_melee ) )
|
|
{
|
|
if ( !( self [[ level.can_melee ]]() ) )
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
ismeleepathclear( vectoenemy, enemypoint )
|
|
{
|
|
dirtoenemy = vectornormalize( ( vectoenemy[ 0 ], vectoenemy[ 1 ], 0 ) );
|
|
meleepoint = enemypoint - ( dirtoenemy[ 0 ] * 28, dirtoenemy[ 1 ] * 28, 0 );
|
|
if ( !self isingoal( meleepoint ) )
|
|
{
|
|
return 0;
|
|
}
|
|
if ( self maymovetopoint( meleepoint ) )
|
|
{
|
|
return 1;
|
|
}
|
|
trace1 = bullettrace( self.origin + vectorScale( ( 0, 0, 1 ), 20 ), meleepoint + vectorScale( ( 0, 0, 1 ), 20 ), 1, self );
|
|
trace2 = bullettrace( self.origin + vectorScale( ( 0, 0, 1 ), 72 ), meleepoint + vectorScale( ( 0, 0, 1 ), 72 ), 1, self );
|
|
if ( isDefined( trace1[ "fraction" ] ) && trace1[ "fraction" ] == 1 && isDefined( trace2[ "fraction" ] ) && trace2[ "fraction" ] == 1 )
|
|
{
|
|
return 1;
|
|
}
|
|
if ( isDefined( trace1[ "entity" ] ) && trace1[ "entity" ] == self.enemy && isDefined( trace2[ "entity" ] ) && trace2[ "entity" ] == self.enemy )
|
|
{
|
|
return 1;
|
|
}
|
|
if ( isDefined( level.zombie_melee_in_water ) && level.zombie_melee_in_water )
|
|
{
|
|
if ( isDefined( trace1[ "surfacetype" ] ) && trace1[ "surfacetype" ] == "water" && isDefined( trace2[ "fraction" ] ) && trace2[ "fraction" ] == 1 )
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
set_zombie_melee_anim_state( zombie )
|
|
{
|
|
if ( isDefined( level.melee_anim_state ) )
|
|
{
|
|
melee_anim_state = self [[ level.melee_anim_state ]]();
|
|
}
|
|
if ( !isDefined( melee_anim_state ) )
|
|
{
|
|
if ( !zombie.has_legs && zombie.a.gib_ref == "no_legs" )
|
|
{
|
|
melee_anim_state = "zm_stumpy_melee";
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
switch( zombie.zombie_move_speed )
|
|
{
|
|
case "walk":
|
|
melee_anim_state = append_missing_legs_suffix( "zm_walk_melee" );
|
|
break;
|
|
case "run":
|
|
case "sprint":
|
|
default:
|
|
melee_anim_state = append_missing_legs_suffix( "zm_run_melee" );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
zombie setanimstatefromasd( melee_anim_state );
|
|
}
|