1606 lines
40 KiB
Plaintext
1606 lines
40 KiB
Plaintext
// IW6 GSC SOURCE
|
|
// Generated by https://github.com/xensik/gsc-tool
|
|
|
|
gettargetangleoffset( var_0 )
|
|
{
|
|
var_1 = self getshootatpos() + ( 0, 0, -3 );
|
|
var_2 = ( var_1[0] - var_0[0], var_1[1] - var_0[1], var_1[2] - var_0[2] );
|
|
var_2 = vectornormalize( var_2 );
|
|
var_3 = var_2[2] * -1;
|
|
return var_3;
|
|
}
|
|
|
|
getsniperburstdelaytime()
|
|
{
|
|
if ( isplayer( self.enemy ) )
|
|
return randomfloatrange( self.enemy.gs.min_sniper_burst_delay_time, self.enemy.gs.max_sniper_burst_delay_time );
|
|
else
|
|
return randomfloatrange( anim.min_sniper_burst_delay_time, anim.max_sniper_burst_delay_time );
|
|
}
|
|
|
|
getremainingburstdelaytime()
|
|
{
|
|
var_0 = ( gettime() - self.a.lastshoottime ) / 1000;
|
|
var_1 = getburstdelaytime();
|
|
|
|
if ( var_1 > var_0 )
|
|
return var_1 - var_0;
|
|
|
|
return 0;
|
|
}
|
|
|
|
getburstdelaytime()
|
|
{
|
|
if ( animscripts\utility::usingsidearm() )
|
|
return randomfloatrange( 0.15, 0.55 );
|
|
else if ( animscripts\utility::weapon_pump_action_shotgun() )
|
|
return randomfloatrange( 1.0, 1.7 );
|
|
else if ( issniper() )
|
|
return getsniperburstdelaytime();
|
|
else if ( self.fastburst )
|
|
return randomfloatrange( 0.1, 0.35 );
|
|
else
|
|
return randomfloatrange( 0.4, 0.9 );
|
|
}
|
|
|
|
burstdelay()
|
|
{
|
|
if ( self.bulletsinclip )
|
|
{
|
|
if ( self.shootstyle == "full" && !self.fastburst )
|
|
{
|
|
if ( self.a.lastshoottime == gettime() )
|
|
wait 0.05;
|
|
|
|
return;
|
|
}
|
|
|
|
var_0 = getremainingburstdelaytime();
|
|
|
|
if ( var_0 )
|
|
wait( var_0 );
|
|
}
|
|
}
|
|
|
|
cheatammoifnecessary()
|
|
{
|
|
if ( !isdefined( self.enemy ) )
|
|
return 0;
|
|
|
|
if ( self.team != "allies" )
|
|
{
|
|
if ( !isplayer( self.enemy ) )
|
|
return 0;
|
|
|
|
if ( self.enemy maps\_utility::ent_flag( "player_is_invulnerable" ) )
|
|
return 0;
|
|
}
|
|
|
|
if ( animscripts\utility::usingsidearm() || animscripts\utility::usingrocketlauncher() )
|
|
return 0;
|
|
|
|
if ( gettime() - self.ammocheattime < self.ammocheatinterval )
|
|
return 0;
|
|
|
|
if ( !self cansee( self.enemy ) && distancesquared( self.origin, self.enemy.origin ) > 65536 )
|
|
return 0;
|
|
|
|
self.bulletsinclip = int( weaponclipsize( self.weapon ) / 2 );
|
|
|
|
if ( self.bulletsinclip > weaponclipsize( self.weapon ) )
|
|
self.bulletsinclip = weaponclipsize( self.weapon );
|
|
|
|
self.ammocheattime = gettime();
|
|
return 1;
|
|
}
|
|
|
|
aimbutdontshoot()
|
|
{
|
|
for ( var_0 = int( 60.0 ); var_0 > 0; var_0-- )
|
|
{
|
|
if ( isdefined( self.dontevershoot ) || isdefined( self.enemy ) && isdefined( self.enemy.dontattackme ) )
|
|
{
|
|
wait 0.05;
|
|
continue;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
shootuntilshootbehaviorchange()
|
|
{
|
|
self endon( "shoot_behavior_change" );
|
|
self endon( "stopShooting" );
|
|
|
|
if ( islongrangeai() )
|
|
{
|
|
if ( isdefined( self.enemy ) && isai( self.enemy ) && distancesquared( level.player.origin, self.enemy.origin ) < 147456 )
|
|
self.enemy animscripts\battlechatter_ai::addthreatevent( "infantry", self, 1.0 );
|
|
|
|
if ( animscripts\utility::usingrocketlauncher() && issentient( self.enemy ) )
|
|
wait( randomfloat( 2.0 ) );
|
|
}
|
|
|
|
if ( isdefined( self.enemy ) && distancesquared( self.origin, self.enemy.origin ) > 160000 )
|
|
var_0 = randomintrange( 1, 5 );
|
|
else
|
|
var_0 = 10;
|
|
|
|
for (;;)
|
|
{
|
|
burstdelay();
|
|
|
|
if ( aimbutdontshoot() )
|
|
break;
|
|
|
|
if ( self.shootstyle == "full" )
|
|
fireuntiloutofammo( animscripts\utility::animarray( "fire" ), 1, animscripts\shared::decidenumshotsforfull() );
|
|
else if ( self.shootstyle == "burst" || self.shootstyle == "semi" )
|
|
{
|
|
var_1 = animscripts\shared::decidenumshotsforburst();
|
|
|
|
if ( var_1 == 1 )
|
|
fireuntiloutofammo( animscripts\utility::animarraypickrandom( "single" ), 1, var_1 );
|
|
else
|
|
fireuntiloutofammo( animscripts\utility::animarray( self.shootstyle + var_1 ), 1, var_1 );
|
|
}
|
|
else if ( self.shootstyle == "single" )
|
|
fireuntiloutofammo( animscripts\utility::animarraypickrandom( "single" ), 1, 1 );
|
|
else
|
|
self waittill( "hell freezes over" );
|
|
|
|
if ( !self.bulletsinclip )
|
|
break;
|
|
|
|
var_0--;
|
|
|
|
if ( var_0 < 0 )
|
|
{
|
|
self.shouldreturntocover = 1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
getuniqueflagnameindex()
|
|
{
|
|
anim.animflagnameindex++;
|
|
return anim.animflagnameindex;
|
|
}
|
|
|
|
#using_animtree("generic_human");
|
|
|
|
setupaim( var_0 )
|
|
{
|
|
self setanim( %exposed_aiming, 1, 0.2 );
|
|
self setanimknoblimited( animscripts\utility::animarray( "straight_level" ), 1, var_0 );
|
|
self setanimknoblimited( animscripts\utility::animarray( "add_aim_up" ), 1, var_0 );
|
|
self setanimknoblimited( animscripts\utility::animarray( "add_aim_down" ), 1, var_0 );
|
|
self setanimknoblimited( animscripts\utility::animarray( "add_aim_left" ), 1, var_0 );
|
|
self setanimknoblimited( animscripts\utility::animarray( "add_aim_right" ), 1, var_0 );
|
|
self.facialidx = animscripts\face::playfacialanim( undefined, "aim", self.facialidx );
|
|
}
|
|
|
|
startfireandaimidlethread()
|
|
{
|
|
if ( !isdefined( self.a.aimidlethread ) )
|
|
{
|
|
setupaim( 0.2 );
|
|
thread aimidlethread();
|
|
thread animscripts\track::trackshootentorpos();
|
|
}
|
|
}
|
|
|
|
endfireandanimidlethread()
|
|
{
|
|
endaimidlethread();
|
|
self clearanim( %add_fire, 0.1 );
|
|
self notify( "stop tracking" );
|
|
}
|
|
|
|
showfirehideaimidle()
|
|
{
|
|
if ( isdefined( self.a.aimidlethread ) )
|
|
self setanim( %add_idle, 0, 0.2 );
|
|
|
|
self setanim( %add_fire, 1, 0.1 );
|
|
}
|
|
|
|
hidefireshowaimidle()
|
|
{
|
|
if ( isdefined( self.a.aimidlethread ) )
|
|
self setanim( %add_idle, 1, 0.2 );
|
|
|
|
self setanim( %add_fire, 0, 0.1 );
|
|
}
|
|
|
|
aimidlethread( var_0 )
|
|
{
|
|
self endon( "killanimscript" );
|
|
self endon( "end_aim_idle_thread" );
|
|
|
|
if ( isdefined( self.a.aimidlethread ) )
|
|
return;
|
|
|
|
self.a.aimidlethread = 1;
|
|
wait 0.1;
|
|
self setanimlimited( %add_idle, 1, 0.2 );
|
|
var_1 = %add_idle;
|
|
var_2 = 0;
|
|
|
|
for (;;)
|
|
{
|
|
var_3 = "idle" + var_2;
|
|
|
|
if ( isdefined( self.a.leanaim ) )
|
|
var_4 = animscripts\utility::animarraypickrandom( "lean_idle" );
|
|
else if ( animscripts\utility::animarrayanyexist( "exposed_idle" ) )
|
|
var_4 = animscripts\utility::animarraypickrandom( "exposed_idle" );
|
|
else
|
|
{
|
|
wait 0.5;
|
|
// FIXME: Decompilation error __asm_jmp( loc_5D2 )
|
|
}
|
|
|
|
if ( var_4 == var_1 )
|
|
self setflaggedanimlimitedrestart( var_3, var_4, 1, 0.2 );
|
|
else
|
|
self setflaggedanimknoblimitedrestart( var_3, var_4, 1, 0.2 );
|
|
|
|
var_1 = var_4;
|
|
self waittillmatch( var_3, "end" );
|
|
var_2++;
|
|
}
|
|
|
|
self clearanim( %add_idle, 0.1 );
|
|
}
|
|
|
|
endaimidlethread()
|
|
{
|
|
self notify( "end_aim_idle_thread" );
|
|
self.a.aimidlethread = undefined;
|
|
self clearanim( %add_idle, 0.1 );
|
|
}
|
|
|
|
shotgunfirerate()
|
|
{
|
|
if ( animscripts\utility::weapon_pump_action_shotgun() )
|
|
return 1.0;
|
|
|
|
if ( animscripts\weaponlist::usingautomaticweapon() )
|
|
return animscripts\weaponlist::autoshootanimrate() * 0.7;
|
|
|
|
return 0.4;
|
|
}
|
|
|
|
fireuntiloutofammo( var_0, var_1, var_2 )
|
|
{
|
|
var_3 = "fireAnim_" + getuniqueflagnameindex();
|
|
maps\_gameskill::resetmisstime();
|
|
|
|
while ( !aimedatshootentorpos() )
|
|
wait 0.05;
|
|
|
|
showfirehideaimidle();
|
|
var_4 = 1.0;
|
|
|
|
if ( isdefined( self.shootrateoverride ) )
|
|
var_4 = self.shootrateoverride;
|
|
else if ( self.shootstyle == "full" )
|
|
var_4 = animscripts\weaponlist::autoshootanimrate() * randomfloatrange( 0.5, 1.0 );
|
|
else if ( self.shootstyle == "burst" )
|
|
var_4 = animscripts\weaponlist::burstshootanimrate();
|
|
else if ( animscripts\utility::usingsidearm() )
|
|
var_4 = 3.0;
|
|
else if ( animscripts\utility::usingshotgun() )
|
|
var_4 = shotgunfirerate();
|
|
|
|
self setflaggedanimknobrestart( var_3, var_0, 1, 0.2, var_4 );
|
|
self updateplayersightaccuracy();
|
|
fireuntiloutofammointernal( var_3, var_0, var_1, var_2 );
|
|
hidefireshowaimidle();
|
|
}
|
|
|
|
fireuntiloutofammo_waittillended()
|
|
{
|
|
self endon( "killanimscript" );
|
|
self endon( "fireAnimEnd" );
|
|
var_0 = thisthread;
|
|
|
|
for (;;)
|
|
{
|
|
waittillframeend;
|
|
|
|
if ( !isdefined( var_0 ) )
|
|
{
|
|
self shootstopsound();
|
|
return;
|
|
}
|
|
|
|
wait 0.05;
|
|
}
|
|
}
|
|
|
|
fireuntiloutofammointernal( var_0, var_1, var_2, var_3 )
|
|
{
|
|
self endon( "enemy" );
|
|
|
|
if ( isplayer( self.enemy ) && ( self.shootstyle == "full" || self.shootstyle == "semi" ) )
|
|
level endon( "player_becoming_invulnerable" );
|
|
|
|
if ( var_2 )
|
|
{
|
|
thread notifyonanimend( var_0, "fireAnimEnd" );
|
|
self endon( "fireAnimEnd" );
|
|
}
|
|
|
|
if ( !isdefined( var_3 ) )
|
|
var_3 = -1;
|
|
|
|
var_4 = 0;
|
|
var_5 = animhasnotetrack( var_1, "fire" );
|
|
var_6 = weaponclass( self.weapon ) == "rocketlauncher";
|
|
thread fireuntiloutofammo_waittillended();
|
|
|
|
while ( var_4 < var_3 && var_3 > 0 )
|
|
{
|
|
if ( var_5 )
|
|
self waittillmatch( var_0, "fire" );
|
|
|
|
if ( !self.bulletsinclip )
|
|
{
|
|
if ( !cheatammoifnecessary() )
|
|
break;
|
|
}
|
|
|
|
if ( !aimedatshootentorpos() )
|
|
break;
|
|
|
|
shootatshootentorpos();
|
|
|
|
if ( isplayer( self.enemy ) && self.enemy maps\_utility::ent_flag( "player_is_invulnerable" ) )
|
|
{
|
|
if ( randomint( 3 ) == 0 )
|
|
self.bulletsinclip--;
|
|
}
|
|
else
|
|
self.bulletsinclip--;
|
|
|
|
if ( var_6 )
|
|
{
|
|
self.a.rockets--;
|
|
|
|
if ( issubstr( tolower( self.weapon ), "rpg" ) || issubstr( tolower( self.weapon ), "panzerfaust" ) )
|
|
{
|
|
self hidepart( "tag_rocket" );
|
|
self.a.rocketvisible = 0;
|
|
}
|
|
}
|
|
|
|
var_4++;
|
|
thread shotgunpumpsound( var_0 );
|
|
|
|
if ( self.fastburst && var_4 == var_3 )
|
|
break;
|
|
|
|
if ( !var_5 || var_3 == 1 && self.shootstyle == "single" )
|
|
self waittillmatch( var_0, "end" );
|
|
}
|
|
|
|
self shootstopsound();
|
|
|
|
if ( var_2 )
|
|
self notify( "fireAnimEnd" );
|
|
}
|
|
|
|
aimedatshootentorpos()
|
|
{
|
|
if ( !isdefined( self.shootpos ) )
|
|
return 1;
|
|
|
|
var_0 = self getmuzzleangle();
|
|
var_1 = animscripts\shared::getshootfrompos();
|
|
var_2 = vectortoangles( self.shootpos - var_1 );
|
|
var_3 = animscripts\utility::absangleclamp180( var_0[1] - var_2[1] );
|
|
|
|
if ( var_3 > anim.aimyawdifffartolerance )
|
|
{
|
|
if ( distancesquared( self geteye(), self.shootpos ) > anim.aimyawdiffclosedistsq || var_3 > anim.aimyawdiffclosetolerance )
|
|
return 0;
|
|
}
|
|
|
|
return animscripts\utility::absangleclamp180( var_0[0] - var_2[0] ) <= anim.aimpitchdifftolerance;
|
|
}
|
|
|
|
notifyonanimend( var_0, var_1 )
|
|
{
|
|
self endon( "killanimscript" );
|
|
self endon( var_1 );
|
|
self waittillmatch( var_0, "end" );
|
|
self notify( var_1 );
|
|
}
|
|
|
|
issingleshot()
|
|
{
|
|
if ( weaponburstcount( self.weapon ) > 0 )
|
|
return 0;
|
|
else if ( weaponisauto( self.weapon ) )
|
|
return 0;
|
|
|
|
return 1;
|
|
}
|
|
|
|
shootatshootentorpos()
|
|
{
|
|
var_0 = issingleshot();
|
|
|
|
if ( isdefined( self.shootent ) )
|
|
{
|
|
if ( isdefined( self.enemy ) && self.shootent == self.enemy )
|
|
animscripts\utility::shootenemywrapper( var_0 );
|
|
}
|
|
else
|
|
self [[ anim.shootposwrapper_func ]]( self.shootpos, var_0 );
|
|
}
|
|
|
|
decrementbulletsinclip()
|
|
{
|
|
if ( self.bulletsinclip )
|
|
self.bulletsinclip--;
|
|
}
|
|
|
|
shotgunpumpsound( var_0 )
|
|
{
|
|
if ( !animscripts\utility::weapon_pump_action_shotgun() )
|
|
return;
|
|
|
|
self endon( "killanimscript" );
|
|
self notify( "shotgun_pump_sound_end" );
|
|
self endon( "shotgun_pump_sound_end" );
|
|
thread stopshotgunpumpaftertime( 2.0 );
|
|
self waittillmatch( var_0, "rechamber" );
|
|
self playsound( "ai_shotgun_pump" );
|
|
self notify( "shotgun_pump_sound_end" );
|
|
}
|
|
|
|
stopshotgunpumpaftertime( var_0 )
|
|
{
|
|
self endon( "killanimscript" );
|
|
self endon( "shotgun_pump_sound_end" );
|
|
wait( var_0 );
|
|
self notify( "shotgun_pump_sound_end" );
|
|
}
|
|
|
|
rechamber( var_0 )
|
|
{
|
|
|
|
}
|
|
|
|
needtoreload( var_0 )
|
|
{
|
|
if ( self.weapon == "none" )
|
|
return 0;
|
|
|
|
if ( isdefined( self.noreload ) )
|
|
{
|
|
if ( self.bulletsinclip < weaponclipsize( self.weapon ) * 0.5 )
|
|
self.bulletsinclip = int( weaponclipsize( self.weapon ) * 0.5 );
|
|
|
|
if ( self.bulletsinclip <= 0 )
|
|
self.bulletsinclip = 0;
|
|
|
|
return 0;
|
|
}
|
|
|
|
if ( self.bulletsinclip <= weaponclipsize( self.weapon ) * var_0 )
|
|
{
|
|
if ( var_0 == 0 )
|
|
{
|
|
if ( cheatammoifnecessary() )
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
putgunbackinhandonkillanimscript()
|
|
{
|
|
self endon( "weapon_switch_done" );
|
|
self endon( "death" );
|
|
self waittill( "killanimscript" );
|
|
animscripts\shared::placeweaponon( self.primaryweapon, "right" );
|
|
}
|
|
|
|
reload( var_0, var_1 )
|
|
{
|
|
self endon( "killanimscript" );
|
|
|
|
if ( !needtoreload( var_0 ) )
|
|
return 0;
|
|
|
|
animscripts\battlechatter_ai::evaluatereloadevent();
|
|
animscripts\battlechatter::playbattlechatter();
|
|
|
|
if ( isdefined( var_1 ) )
|
|
{
|
|
self setflaggedanimknoball( "reloadanim", var_1, %body, 1, 0.1, 1 );
|
|
animscripts\shared::donotetracks( "reloadanim" );
|
|
animscripts\weaponlist::refillclip();
|
|
self.a.needstorechamber = 0;
|
|
}
|
|
else
|
|
{
|
|
if ( self.a.pose == "prone" )
|
|
{
|
|
self setflaggedanimknoball( "reloadanim", %prone_reload, %body, 1, 0.1, 1 );
|
|
self updateprone( %prone_legs_up, %prone_legs_down, 1, 0.1, 1 );
|
|
}
|
|
else
|
|
{
|
|
wait 2;
|
|
return;
|
|
}
|
|
|
|
animscripts\shared::donotetracks( "reloadanim" );
|
|
animscripts\weaponlist::refillclip();
|
|
self.a.needstorechamber = 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
addgrenadethrowanimoffset( var_0, var_1 )
|
|
{
|
|
if ( !isdefined( anim.grenadethrowanims ) )
|
|
{
|
|
anim.grenadethrowanims = [];
|
|
anim.grenadethrowoffsets = [];
|
|
}
|
|
|
|
var_2 = anim.grenadethrowanims.size;
|
|
anim.grenadethrowanims[var_2] = var_0;
|
|
anim.grenadethrowoffsets[var_2] = var_1;
|
|
}
|
|
|
|
initgrenadethrowanims()
|
|
{
|
|
addgrenadethrowanimoffset( %exposed_grenadethrowb, ( 41.5391, 7.28883, 72.2128 ) );
|
|
addgrenadethrowanimoffset( %exposed_grenadethrowc, ( 34.8849, -4.77048, 74.0488 ) );
|
|
addgrenadethrowanimoffset( %corner_standl_grenade_a, ( 41.605, 6.80107, 81.4785 ) );
|
|
addgrenadethrowanimoffset( %corner_standl_grenade_b, ( 24.1585, -14.7221, 29.2992 ) );
|
|
addgrenadethrowanimoffset( %cornercrl_grenadea, ( 25.8988, -10.2811, 30.4813 ) );
|
|
addgrenadethrowanimoffset( %cornercrl_grenadeb, ( 24.688, 45.0702, 64.377 ) );
|
|
addgrenadethrowanimoffset( %corner_standr_grenade_a, ( 37.1254, -32.7053, 76.5745 ) );
|
|
addgrenadethrowanimoffset( %corner_standr_grenade_b, ( 19.356, 15.5341, 16.5036 ) );
|
|
addgrenadethrowanimoffset( %cornercrr_grenadea, ( 39.8857, 5.92472, 24.5878 ) );
|
|
addgrenadethrowanimoffset( %covercrouch_grenadea, ( -1.6363, -0.693674, 60.1009 ) );
|
|
addgrenadethrowanimoffset( %covercrouch_grenadeb, ( -1.6363, -0.693674, 60.1009 ) );
|
|
addgrenadethrowanimoffset( %coverstand_grenadea, ( 10.8573, 7.12614, 77.2356 ) );
|
|
addgrenadethrowanimoffset( %coverstand_grenadeb, ( 19.1804, 5.68214, 73.2278 ) );
|
|
addgrenadethrowanimoffset( %prone_grenade_a, ( 12.2859, -1.3019, 33.4307 ) );
|
|
addgrenadethrowanimoffset( %cqb_stand_grenade_throw, ( 35.7494, 26.6052, 37.7086 ) );
|
|
}
|
|
|
|
getgrenadethrowoffset( var_0 )
|
|
{
|
|
var_1 = ( 0, 0, 64 );
|
|
|
|
if ( isdefined( var_0 ) )
|
|
{
|
|
foreach ( var_4, var_3 in anim.grenadethrowanims )
|
|
{
|
|
if ( var_0 == var_3 )
|
|
{
|
|
var_1 = anim.grenadethrowoffsets[var_4];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( var_1[2] == 64 )
|
|
{
|
|
if ( isdefined( var_0 ) )
|
|
{
|
|
|
|
}
|
|
else
|
|
{
|
|
|
|
}
|
|
}
|
|
|
|
return var_1;
|
|
}
|
|
|
|
throwgrenadeatplayerasap_combat_utility()
|
|
{
|
|
for ( var_0 = 0; var_0 < level.players.size; var_0++ )
|
|
{
|
|
if ( level.players[var_0].numgrenadesinprogresstowardsplayer == 0 )
|
|
{
|
|
level.players[var_0].grenadetimers["fraggrenade"] = 0;
|
|
level.players[var_0].grenadetimers["flash_grenade"] = 0;
|
|
}
|
|
}
|
|
|
|
anim.throwgrenadeatplayerasap = 1;
|
|
}
|
|
|
|
setactivegrenadetimer( var_0 )
|
|
{
|
|
self.activegrenadetimer = spawnstruct();
|
|
|
|
if ( isplayer( var_0 ) )
|
|
{
|
|
self.activegrenadetimer.isplayertimer = 1;
|
|
self.activegrenadetimer.player = var_0;
|
|
self.activegrenadetimer.timername = self.grenadeweapon;
|
|
}
|
|
else
|
|
{
|
|
self.activegrenadetimer.isplayertimer = 0;
|
|
self.activegrenadetimer.timername = "AI_" + self.grenadeweapon;
|
|
}
|
|
}
|
|
|
|
usingplayergrenadetimer()
|
|
{
|
|
return self.activegrenadetimer.isplayertimer;
|
|
}
|
|
|
|
setgrenadetimer( var_0, var_1 )
|
|
{
|
|
if ( var_0.isplayertimer )
|
|
{
|
|
var_2 = var_0.player;
|
|
var_3 = var_2.grenadetimers[var_0.timername];
|
|
var_2.grenadetimers[var_0.timername] = max( var_1, var_3 );
|
|
}
|
|
else
|
|
{
|
|
var_3 = anim.grenadetimers[var_0.timername];
|
|
anim.grenadetimers[var_0.timername] = max( var_1, var_3 );
|
|
}
|
|
}
|
|
|
|
getdesiredgrenadetimervalue()
|
|
{
|
|
var_0 = undefined;
|
|
|
|
if ( usingplayergrenadetimer() )
|
|
{
|
|
var_1 = self.activegrenadetimer.player;
|
|
var_0 = gettime() + var_1.gs.playergrenadebasetime + randomint( var_1.gs.playergrenaderangetime );
|
|
}
|
|
else
|
|
var_0 = gettime() + 30000 + randomint( 30000 );
|
|
|
|
return var_0;
|
|
}
|
|
|
|
getgrenadetimertime( var_0 )
|
|
{
|
|
if ( var_0.isplayertimer )
|
|
return var_0.player.grenadetimers[var_0.timername];
|
|
else
|
|
return anim.grenadetimers[var_0.timername];
|
|
}
|
|
|
|
considerchangingtarget( var_0 )
|
|
{
|
|
if ( !isplayer( var_0 ) && self isbadguy() )
|
|
{
|
|
if ( gettime() < getgrenadetimertime( self.activegrenadetimer ) )
|
|
{
|
|
if ( level.player.ignoreme )
|
|
return var_0;
|
|
|
|
var_1 = self getthreatbiasgroup();
|
|
var_2 = level.player getthreatbiasgroup();
|
|
|
|
if ( var_1 != "" && var_2 != "" && getthreatbias( var_2, var_1 ) < -10000 )
|
|
return var_0;
|
|
|
|
if ( self cansee( level.player ) || isai( var_0 ) && var_0 cansee( level.player ) )
|
|
{
|
|
if ( isdefined( self.covernode ) )
|
|
{
|
|
var_3 = vectortoangles( level.player.origin - self.origin );
|
|
var_4 = angleclamp180( self.covernode.angles[1] - var_3[1] );
|
|
}
|
|
else
|
|
var_4 = animscripts\utility::getyawtospot( level.player.origin );
|
|
|
|
if ( abs( var_4 ) < 60 )
|
|
{
|
|
var_0 = level.player;
|
|
setactivegrenadetimer( var_0 );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return var_0;
|
|
}
|
|
|
|
maythrowdoublegrenade( var_0 )
|
|
{
|
|
if ( maps\_utility::player_died_recently() )
|
|
return 0;
|
|
|
|
if ( !var_0.gs.double_grenades_allowed )
|
|
return 0;
|
|
|
|
var_1 = gettime();
|
|
|
|
if ( var_1 < var_0.grenadetimers["double_grenade"] )
|
|
return 0;
|
|
|
|
if ( var_1 > var_0.lastfraggrenadetoplayerstart + 3000 )
|
|
return 0;
|
|
|
|
if ( var_1 < var_0.lastfraggrenadetoplayerstart + 500 )
|
|
return 0;
|
|
|
|
return var_0.numgrenadesinprogresstowardsplayer < 2;
|
|
}
|
|
|
|
mygrenadecooldownelapsed()
|
|
{
|
|
return gettime() >= self.a.nextgrenadetrytime;
|
|
}
|
|
|
|
grenadecooldownelapsed( var_0 )
|
|
{
|
|
if ( maps\_utility::player_died_recently() )
|
|
return 0;
|
|
|
|
if ( self.script_forcegrenade == 1 )
|
|
return 1;
|
|
|
|
if ( !mygrenadecooldownelapsed() )
|
|
return 0;
|
|
|
|
if ( gettime() >= getgrenadetimertime( self.activegrenadetimer ) )
|
|
return 1;
|
|
|
|
if ( self.activegrenadetimer.isplayertimer && self.activegrenadetimer.timername == "fraggrenade" )
|
|
return maythrowdoublegrenade( var_0 );
|
|
|
|
return 0;
|
|
}
|
|
|
|
trygrenadeposproc( var_0, var_1, var_2, var_3 )
|
|
{
|
|
if ( !self isgrenadepossafe( var_0, var_1 ) )
|
|
return 0;
|
|
else if ( distancesquared( self.origin, var_1 ) < 40000 )
|
|
return 0;
|
|
|
|
var_4 = physicstrace( var_1 + ( 0, 0, 1 ), var_1 + ( 0, 0, -500 ) );
|
|
|
|
if ( var_4 == var_1 + ( 0, 0, -500 ) )
|
|
return 0;
|
|
|
|
var_4 = var_4 + ( 0, 0, 0.1 );
|
|
return trygrenadethrow( var_0, var_4, var_2, var_3 );
|
|
}
|
|
|
|
trygrenade( var_0, var_1 )
|
|
{
|
|
if ( self.weapon == "mg42" || self.grenadeammo <= 0 )
|
|
return 0;
|
|
|
|
setactivegrenadetimer( var_0 );
|
|
var_0 = considerchangingtarget( var_0 );
|
|
|
|
if ( !grenadecooldownelapsed( var_0 ) )
|
|
return 0;
|
|
|
|
var_2 = getgrenadethrowoffset( var_1 );
|
|
|
|
if ( isdefined( self.enemy ) && var_0 == self.enemy )
|
|
{
|
|
if ( !checkgrenadethrowdist() )
|
|
return 0;
|
|
|
|
if ( isplayer( self.enemy ) && maps\_utility::is_player_down( self.enemy ) )
|
|
return 0;
|
|
|
|
if ( animscripts\utility::canseeenemyfromexposed() )
|
|
{
|
|
if ( !self isgrenadepossafe( var_0, var_0.origin ) )
|
|
return 0;
|
|
|
|
return trygrenadethrow( var_0, undefined, var_1, var_2 );
|
|
}
|
|
else if ( animscripts\utility::cansuppressenemyfromexposed() )
|
|
return trygrenadeposproc( var_0, animscripts\utility::getenemysightpos(), var_1, var_2 );
|
|
else
|
|
{
|
|
if ( !self isgrenadepossafe( var_0, var_0.origin ) )
|
|
return 0;
|
|
|
|
return trygrenadethrow( var_0, undefined, var_1, var_2 );
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
else
|
|
return trygrenadeposproc( var_0, var_0.origin, var_1, var_2 );
|
|
}
|
|
|
|
trygrenadethrow( var_0, var_1, var_2, var_3, var_4, var_5, var_6 )
|
|
{
|
|
if ( gettime() < 10000 && !isdefined( level.ignoregrenadesafetime ) )
|
|
return 0;
|
|
|
|
if ( !isdefined( var_5 ) )
|
|
var_5 = 1;
|
|
|
|
if ( isdefined( var_2 ) )
|
|
{
|
|
var_7 = var_2;
|
|
var_8 = self.a.gunhand;
|
|
}
|
|
else
|
|
{
|
|
switch ( self.a.special )
|
|
{
|
|
case "cover_crouch":
|
|
case "none":
|
|
if ( self.a.pose == "stand" )
|
|
{
|
|
var_3 = ( 0, 0, 80 );
|
|
var_7 = %stand_grenade_throw;
|
|
}
|
|
else
|
|
{
|
|
var_3 = ( 0, 0, 65 );
|
|
var_7 = %crouch_grenade_throw;
|
|
}
|
|
|
|
var_8 = "left";
|
|
break;
|
|
default:
|
|
var_7 = undefined;
|
|
var_8 = undefined;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( !isdefined( var_7 ) )
|
|
return 0;
|
|
|
|
if ( isdefined( var_1 ) )
|
|
{
|
|
if ( !isdefined( var_4 ) )
|
|
var_9 = self checkgrenadethrowpos( var_3, var_1, var_5, "min energy", "min time", "max time" );
|
|
else
|
|
var_9 = self checkgrenadethrowpos( var_3, var_1, var_5, "min time", "min energy" );
|
|
}
|
|
else
|
|
{
|
|
var_10 = self.randomgrenaderange;
|
|
var_11 = distance( var_0.origin, self.origin );
|
|
|
|
if ( var_11 < 800 )
|
|
{
|
|
if ( var_11 < 256 )
|
|
var_10 = 0;
|
|
else
|
|
var_10 = var_10 * ( ( var_11 - 256 ) / 544 );
|
|
}
|
|
|
|
if ( !isdefined( var_4 ) )
|
|
var_9 = self checkgrenadethrow( var_3, var_10, "min energy", "min time", "max time" );
|
|
else
|
|
var_9 = self checkgrenadethrow( var_3, var_10, "min time", "min energy" );
|
|
}
|
|
|
|
self.a.nextgrenadetrytime = gettime() + randomintrange( 1000, 2000 );
|
|
|
|
if ( isdefined( var_9 ) )
|
|
{
|
|
if ( !isdefined( self.oldgrenawareness ) )
|
|
self.oldgrenawareness = self.grenadeawareness;
|
|
|
|
self.grenadeawareness = 0;
|
|
var_12 = getdesiredgrenadetimervalue();
|
|
setgrenadetimer( self.activegrenadetimer, min( gettime() + 3000, var_12 ) );
|
|
var_13 = 0;
|
|
|
|
if ( usingplayergrenadetimer() )
|
|
{
|
|
var_0.numgrenadesinprogresstowardsplayer++;
|
|
thread reducegiptponkillanimscript( var_0 );
|
|
|
|
if ( var_0.numgrenadesinprogresstowardsplayer > 1 )
|
|
var_13 = 1;
|
|
|
|
if ( self.activegrenadetimer.timername == "fraggrenade" )
|
|
{
|
|
if ( var_0.numgrenadesinprogresstowardsplayer <= 1 )
|
|
var_0.lastfraggrenadetoplayerstart = gettime();
|
|
}
|
|
}
|
|
|
|
if ( isdefined( var_6 ) )
|
|
thread dogrenadethrow( var_7, var_9, var_12, var_13 );
|
|
else
|
|
dogrenadethrow( var_7, var_9, var_12, var_13 );
|
|
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
reducegiptponkillanimscript( var_0 )
|
|
{
|
|
self endon( "dont_reduce_giptp_on_killanimscript" );
|
|
self waittill( "killanimscript" );
|
|
var_0.numgrenadesinprogresstowardsplayer--;
|
|
}
|
|
|
|
dogrenadethrow( var_0, var_1, var_2, var_3 )
|
|
{
|
|
self endon( "killanimscript" );
|
|
|
|
if ( self.script == "combat" || self.script == "move" )
|
|
self orientmode( "face direction", var_1 );
|
|
|
|
animscripts\battlechatter_ai::evaluateattackevent( self.grenadeweapon );
|
|
self notify( "stop_aiming_at_enemy" );
|
|
self setflaggedanimknoballrestart( "throwanim", var_0, %body, fasteranimspeed(), 0.1, 1 );
|
|
thread animscripts\notetracks::donotetracksforever( "throwanim", "killanimscript" );
|
|
var_4 = animscripts\utility::getgrenademodel();
|
|
var_5 = "none";
|
|
|
|
for (;;)
|
|
{
|
|
self waittill( "throwanim", var_6 );
|
|
|
|
if ( var_6 == "grenade_left" || var_6 == "grenade_right" )
|
|
{
|
|
var_5 = attachgrenademodel( var_4, "TAG_INHAND" );
|
|
self.isholdinggrenade = 1;
|
|
}
|
|
|
|
if ( var_6 == "grenade_throw" || var_6 == "grenade throw" )
|
|
break;
|
|
|
|
if ( var_6 == "end" )
|
|
{
|
|
self.activegrenadetimer.player.numgrenadesinprogresstowardsplayer--;
|
|
self notify( "dont_reduce_giptp_on_killanimscript" );
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
self notify( "dont_reduce_giptp_on_killanimscript" );
|
|
|
|
if ( usingplayergrenadetimer() )
|
|
thread watchgrenadetowardsplayer( self.activegrenadetimer.player, var_2 );
|
|
|
|
self throwgrenade();
|
|
|
|
if ( !usingplayergrenadetimer() )
|
|
setgrenadetimer( self.activegrenadetimer, var_2 );
|
|
|
|
if ( var_3 )
|
|
{
|
|
var_13 = self.activegrenadetimer.player;
|
|
|
|
if ( var_13.numgrenadesinprogresstowardsplayer > 1 || gettime() - var_13.lastgrenadelandednearplayertime < 2000 )
|
|
var_13.grenadetimers["double_grenade"] = gettime() + min( 5000, var_13.gs.playerdoublegrenadetime );
|
|
}
|
|
|
|
self notify( "stop grenade check" );
|
|
|
|
if ( var_5 != "none" )
|
|
self detach( var_4, var_5 );
|
|
else
|
|
{
|
|
|
|
}
|
|
|
|
self.isholdinggrenade = undefined;
|
|
self.grenadeawareness = self.oldgrenawareness;
|
|
self.oldgrenawareness = undefined;
|
|
self waittillmatch( "throwanim", "end" );
|
|
self notify( "done_grenade_throw" );
|
|
self notify( "weapon_switch_done" );
|
|
self setanim( %exposed_modern, 1, 0.2 );
|
|
self setanim( %exposed_aiming, 1 );
|
|
self clearanim( var_0, 0.2 );
|
|
}
|
|
|
|
watchgrenadetowardsplayer( var_0, var_1 )
|
|
{
|
|
var_0 endon( "death" );
|
|
watchgrenadetowardsplayerinternal( var_1 );
|
|
var_0.numgrenadesinprogresstowardsplayer--;
|
|
}
|
|
|
|
watchgrenadetowardsplayerinternal( var_0 )
|
|
{
|
|
var_1 = self.activegrenadetimer;
|
|
var_2 = spawnstruct();
|
|
var_2 thread watchgrenadetowardsplayertimeout( 5 );
|
|
var_2 endon( "watchGrenadeTowardsPlayerTimeout" );
|
|
var_3 = self.grenadeweapon;
|
|
var_4 = getgrenadeithrew();
|
|
|
|
if ( !isdefined( var_4 ) )
|
|
return;
|
|
|
|
setgrenadetimer( var_1, min( gettime() + 5000, var_0 ) );
|
|
var_5 = 62500;
|
|
var_6 = 160000;
|
|
|
|
if ( var_3 == "flash_grenade" )
|
|
{
|
|
var_5 = 810000;
|
|
var_6 = 1690000;
|
|
}
|
|
|
|
var_7 = level.players;
|
|
var_8 = var_4.origin;
|
|
|
|
for (;;)
|
|
{
|
|
wait 0.1;
|
|
|
|
if ( !isdefined( var_4 ) )
|
|
break;
|
|
|
|
if ( distancesquared( var_4.origin, var_8 ) < 400 )
|
|
{
|
|
var_9 = [];
|
|
|
|
for ( var_10 = 0; var_10 < var_7.size; var_10++ )
|
|
{
|
|
var_11 = var_7[var_10];
|
|
var_12 = distancesquared( var_4.origin, var_11.origin );
|
|
|
|
if ( var_12 < var_5 )
|
|
{
|
|
var_11 grenadelandednearplayer( var_1, var_0 );
|
|
continue;
|
|
}
|
|
|
|
if ( var_12 < var_6 )
|
|
var_9[var_9.size] = var_11;
|
|
}
|
|
|
|
var_7 = var_9;
|
|
|
|
if ( var_7.size == 0 )
|
|
break;
|
|
}
|
|
|
|
var_8 = var_4.origin;
|
|
}
|
|
}
|
|
|
|
grenadelandednearplayer( var_0, var_1 )
|
|
{
|
|
var_2 = self;
|
|
anim.throwgrenadeatplayerasap = undefined;
|
|
|
|
if ( gettime() - var_2.lastgrenadelandednearplayertime < 3000 )
|
|
var_2.grenadetimers["double_grenade"] = gettime() + var_2.gs.playerdoublegrenadetime;
|
|
|
|
var_2.lastgrenadelandednearplayertime = gettime();
|
|
var_3 = var_2.grenadetimers[var_0.timername];
|
|
var_2.grenadetimers[var_0.timername] = max( var_1, var_3 );
|
|
}
|
|
|
|
getgrenadeithrew()
|
|
{
|
|
self endon( "killanimscript" );
|
|
self waittill( "grenade_fire", var_0 );
|
|
return var_0;
|
|
}
|
|
|
|
watchgrenadetowardsplayertimeout( var_0 )
|
|
{
|
|
wait( var_0 );
|
|
self notify( "watchGrenadeTowardsPlayerTimeout" );
|
|
}
|
|
|
|
attachgrenademodel( var_0, var_1 )
|
|
{
|
|
self attach( var_0, var_1 );
|
|
thread detachgrenadeonscriptchange( var_0, var_1 );
|
|
return var_1;
|
|
}
|
|
|
|
detachgrenadeonscriptchange( var_0, var_1 )
|
|
{
|
|
self endon( "stop grenade check" );
|
|
self waittill( "killanimscript" );
|
|
|
|
if ( !isdefined( self ) )
|
|
return;
|
|
|
|
if ( isdefined( self.oldgrenawareness ) )
|
|
{
|
|
self.grenadeawareness = self.oldgrenawareness;
|
|
self.oldgrenawareness = undefined;
|
|
}
|
|
|
|
self detach( var_0, var_1 );
|
|
}
|
|
|
|
offsettoorigin( var_0 )
|
|
{
|
|
var_1 = anglestoforward( self.angles );
|
|
var_2 = anglestoright( self.angles );
|
|
var_3 = anglestoup( self.angles );
|
|
var_1 = var_1 * var_0[0];
|
|
var_2 = var_2 * var_0[1];
|
|
var_3 = var_3 * var_0[2];
|
|
return var_1 + var_2 + var_3;
|
|
}
|
|
|
|
grenadeline( var_0, var_1 )
|
|
{
|
|
level notify( "armoffset" );
|
|
level endon( "armoffset" );
|
|
var_0 = self.origin + offsettoorigin( var_0 );
|
|
|
|
for (;;)
|
|
wait 0.05;
|
|
}
|
|
|
|
getgrenadedropvelocity()
|
|
{
|
|
var_0 = randomfloat( 360 );
|
|
var_1 = randomfloatrange( 30, 75 );
|
|
var_2 = sin( var_1 );
|
|
var_3 = cos( var_1 );
|
|
var_4 = cos( var_0 ) * var_3;
|
|
var_5 = sin( var_0 ) * var_3;
|
|
var_6 = randomfloatrange( 100, 200 );
|
|
var_7 = ( var_4, var_5, var_2 ) * var_6;
|
|
return var_7;
|
|
}
|
|
|
|
dropgrenade()
|
|
{
|
|
var_0 = self gettagorigin( "tag_inhand" );
|
|
var_1 = getgrenadedropvelocity();
|
|
self magicgrenademanual( var_0, var_1, 3 );
|
|
}
|
|
|
|
lookforbettercover()
|
|
{
|
|
if ( !isdefined( self.enemy ) )
|
|
return 0;
|
|
|
|
if ( self.fixednode || self.doingambush )
|
|
return 0;
|
|
|
|
var_0 = getbestcovernodeifavailable();
|
|
|
|
if ( isdefined( var_0 ) )
|
|
return usecovernodeifpossible( var_0 );
|
|
|
|
return 0;
|
|
}
|
|
|
|
getbestcovernodeifavailable()
|
|
{
|
|
var_0 = self findbestcovernode();
|
|
|
|
if ( !isdefined( var_0 ) )
|
|
return undefined;
|
|
|
|
var_1 = animscripts\utility::getclaimednode();
|
|
|
|
if ( isdefined( var_1 ) && var_0 == var_1 )
|
|
return undefined;
|
|
|
|
if ( isdefined( self.covernode ) && var_0 == self.covernode )
|
|
return undefined;
|
|
|
|
return var_0;
|
|
}
|
|
|
|
usecovernodeifpossible( var_0 )
|
|
{
|
|
var_1 = self.keepclaimednodeifvalid;
|
|
var_2 = self.keepclaimednode;
|
|
self.keepclaimednodeifvalid = 0;
|
|
self.keepclaimednode = 0;
|
|
|
|
if ( self usecovernode( var_0 ) )
|
|
return 1;
|
|
else
|
|
{
|
|
|
|
}
|
|
|
|
self.keepclaimednodeifvalid = var_1;
|
|
self.keepclaimednode = var_2;
|
|
return 0;
|
|
}
|
|
|
|
shouldhelpadvancingteammate()
|
|
{
|
|
if ( level.advancetoenemygroup[self.team] > 0 && level.advancetoenemygroup[self.team] < level.advancetoenemygroupmax )
|
|
{
|
|
if ( gettime() - level.lastadvancetoenemytime[self.team] > 4000 )
|
|
return 0;
|
|
|
|
var_0 = level.lastadvancetoenemyattacker[self.team];
|
|
|
|
if ( var_0 == self )
|
|
return 0;
|
|
|
|
var_1 = isdefined( var_0 ) && distancesquared( self.origin, var_0.origin ) < 65536;
|
|
|
|
if ( ( var_1 || distancesquared( self.origin, level.lastadvancetoenemysrc[self.team] ) < 65536 ) && ( !isdefined( self.enemy ) || distancesquared( self.enemy.origin, level.lastadvancetoenemydest[self.team] ) < 262144 ) )
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
checkadvanceonenemyconditions()
|
|
{
|
|
if ( !isdefined( level.lastadvancetoenemytime[self.team] ) )
|
|
return 0;
|
|
|
|
if ( shouldhelpadvancingteammate() )
|
|
return 1;
|
|
|
|
if ( gettime() - level.lastadvancetoenemytime[self.team] < level.advancetoenemyinterval )
|
|
return 0;
|
|
|
|
if ( !issentient( self.enemy ) )
|
|
return 0;
|
|
|
|
if ( level.advancetoenemygroup[self.team] )
|
|
level.advancetoenemygroup[self.team] = 0;
|
|
|
|
var_0 = isdefined( self.advance_regardless_of_numbers ) && self.advance_regardless_of_numbers;
|
|
|
|
if ( !var_0 && getaicount( self.team ) < getaicount( self.enemy.team ) )
|
|
return 0;
|
|
|
|
return 1;
|
|
}
|
|
|
|
tryrunningtoenemy( var_0 )
|
|
{
|
|
if ( !isdefined( self.enemy ) )
|
|
return 0;
|
|
|
|
if ( self.fixednode )
|
|
return 0;
|
|
|
|
if ( self.combatmode == "ambush" || self.combatmode == "ambush_nodes_only" )
|
|
return 0;
|
|
|
|
if ( !self isingoal( self.enemy.origin ) )
|
|
return 0;
|
|
|
|
if ( islongrangeai() )
|
|
return 0;
|
|
|
|
if ( !checkadvanceonenemyconditions() )
|
|
return 0;
|
|
|
|
self findreacquiredirectpath( var_0 );
|
|
|
|
if ( self reacquiremove() )
|
|
{
|
|
self.keepclaimednodeifvalid = 0;
|
|
self.keepclaimednode = 0;
|
|
self.a.magicreloadwhenreachenemy = 1;
|
|
|
|
if ( level.advancetoenemygroup[self.team] == 0 )
|
|
{
|
|
level.lastadvancetoenemytime[self.team] = gettime();
|
|
level.lastadvancetoenemyattacker[self.team] = self;
|
|
}
|
|
|
|
level.lastadvancetoenemysrc[self.team] = self.origin;
|
|
level.lastadvancetoenemydest[self.team] = self.enemy.origin;
|
|
level.advancetoenemygroup[self.team]++;
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
delayedbadplace( var_0 )
|
|
{
|
|
self endon( "death" );
|
|
wait 0.5;
|
|
var_1 = "" + anim.badplaceint;
|
|
badplace_cylinder( var_1, 5, var_0, 16, 64, self.team );
|
|
anim.badplaces[anim.badplaces.size] = var_1;
|
|
|
|
if ( anim.badplaces.size >= 10 )
|
|
{
|
|
var_2 = [];
|
|
|
|
for ( var_3 = 1; var_3 < anim.badplaces.size; var_3++ )
|
|
var_2[var_2.size] = anim.badplaces[var_3];
|
|
|
|
badplace_delete( anim.badplaces[0] );
|
|
anim.badplaces = var_2;
|
|
}
|
|
|
|
anim.badplaceint++;
|
|
|
|
if ( anim.badplaceint > 10 )
|
|
anim.badplaceint = anim.badplaceint - 20;
|
|
}
|
|
|
|
valueiswithin( var_0, var_1, var_2 )
|
|
{
|
|
if ( var_0 > var_1 && var_0 < var_2 )
|
|
return 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
getgunyawtoshootentorpos()
|
|
{
|
|
if ( !isdefined( self.shootpos ) )
|
|
return 0;
|
|
|
|
var_0 = self getmuzzleangle()[1] - animscripts\utility::getyaw( self.shootpos );
|
|
var_0 = angleclamp180( var_0 );
|
|
return var_0;
|
|
}
|
|
|
|
getgunpitchtoshootentorpos()
|
|
{
|
|
if ( !isdefined( self.shootpos ) )
|
|
return 0;
|
|
|
|
var_0 = self getmuzzleangle()[0] - vectortoangles( self.shootpos - self getmuzzlepos() )[0];
|
|
var_0 = angleclamp180( var_0 );
|
|
return var_0;
|
|
}
|
|
|
|
getpitchtoenemy()
|
|
{
|
|
if ( !isdefined( self.enemy ) )
|
|
return 0;
|
|
|
|
var_0 = self.enemy getshootatpos() - self getshootatpos();
|
|
var_0 = vectornormalize( var_0 );
|
|
var_1 = 360 - vectortoangles( var_0 )[0];
|
|
return angleclamp180( var_1 );
|
|
}
|
|
|
|
getpitchtospot( var_0 )
|
|
{
|
|
if ( !isdefined( var_0 ) )
|
|
return 0;
|
|
|
|
var_1 = var_0 - self getshootatpos();
|
|
var_1 = vectornormalize( var_1 );
|
|
var_2 = 360 - vectortoangles( var_1 )[0];
|
|
return angleclamp180( var_2 );
|
|
}
|
|
|
|
getpitchtoorgfromorg( var_0, var_1 )
|
|
{
|
|
if ( !isdefined( var_0 ) || !isdefined( var_1 ) )
|
|
return 0;
|
|
|
|
if ( isdefined( self ) && animscripts\utility::isspaceai() )
|
|
{
|
|
var_2 = anglestoforward( self.angles );
|
|
var_3 = rotatepointaroundvector( var_2, var_0 - self.origin, self.angles[2] * -1 );
|
|
var_0 = var_3 + self.origin;
|
|
}
|
|
|
|
var_4 = var_0 - var_1;
|
|
var_4 = vectornormalize( var_4 );
|
|
var_5 = 360 - vectortoangles( var_4 )[0];
|
|
return angleclamp180( var_5 );
|
|
}
|
|
|
|
watchreloading()
|
|
{
|
|
self.isreloading = 0;
|
|
self.lastreloadstarttime = -1;
|
|
|
|
for (;;)
|
|
{
|
|
self waittill( "reload_start" );
|
|
self.isreloading = 1;
|
|
self.lastreloadstarttime = gettime();
|
|
waittillreloadfinished();
|
|
self.isreloading = 0;
|
|
}
|
|
}
|
|
|
|
waittillreloadfinished()
|
|
{
|
|
thread timednotify( 4, "reloadtimeout" );
|
|
self endon( "reloadtimeout" );
|
|
self endon( "weapon_taken" );
|
|
|
|
for (;;)
|
|
{
|
|
self waittill( "reload" );
|
|
var_0 = self getcurrentweapon();
|
|
|
|
if ( var_0 == "none" )
|
|
break;
|
|
|
|
if ( self getcurrentweaponclipammo() >= weaponclipsize( var_0 ) )
|
|
break;
|
|
}
|
|
|
|
self notify( "reloadtimeout" );
|
|
}
|
|
|
|
timednotify( var_0, var_1 )
|
|
{
|
|
self endon( var_1 );
|
|
wait( var_0 );
|
|
self notify( var_1 );
|
|
}
|
|
|
|
checkgrenadethrowdist()
|
|
{
|
|
var_0 = self.enemy.origin - self.origin;
|
|
var_1 = lengthsquared( ( var_0[0], var_0[1], 0 ) );
|
|
|
|
if ( self.grenadeweapon == "flash_grenade" )
|
|
return var_1 < 589824;
|
|
|
|
return var_1 >= 40000 && var_1 <= 1562500;
|
|
}
|
|
|
|
monitorflash()
|
|
{
|
|
self endon( "death" );
|
|
|
|
if ( !isdefined( level.neverstopmonitoringflash ) )
|
|
self endon( "stop_monitoring_flash" );
|
|
|
|
for (;;)
|
|
{
|
|
var_0 = undefined;
|
|
var_1 = undefined;
|
|
var_2 = undefined;
|
|
var_3 = undefined;
|
|
var_4 = undefined;
|
|
self waittill( "flashbang", var_1, var_0, var_2, var_3, var_4 );
|
|
|
|
if ( isdefined( self.flashbangimmunity ) && self.flashbangimmunity )
|
|
continue;
|
|
|
|
if ( isdefined( self.script_immunetoflash ) && self.script_immunetoflash != 0 )
|
|
continue;
|
|
|
|
if ( isdefined( self.team ) && isdefined( var_4 ) && self.team == var_4 )
|
|
{
|
|
var_0 = 3 * ( var_0 - 0.75 );
|
|
|
|
if ( var_0 < 0 )
|
|
continue;
|
|
|
|
if ( isdefined( self.teamflashbangimmunity ) )
|
|
continue;
|
|
}
|
|
|
|
var_5 = 0.2;
|
|
|
|
if ( var_0 > 1 - var_5 )
|
|
var_0 = 1.0;
|
|
else
|
|
var_0 = var_0 / ( 1 - var_5 );
|
|
|
|
var_6 = 4.5 * var_0;
|
|
|
|
if ( var_6 < 0.25 )
|
|
continue;
|
|
|
|
self.flashingteam = var_4;
|
|
maps\_utility::flashbangstart( var_6 );
|
|
self notify( "doFlashBanged", var_1, var_3 );
|
|
}
|
|
}
|
|
|
|
isshotgunai()
|
|
{
|
|
return animscripts\utility::isshotgun( self.primaryweapon );
|
|
}
|
|
|
|
issniper()
|
|
{
|
|
return animscripts\utility::issniperrifle( self.primaryweapon );
|
|
}
|
|
|
|
islongrangeai()
|
|
{
|
|
return issniper() || animscripts\utility::usingrocketlauncher();
|
|
}
|
|
|
|
fasteranimspeed()
|
|
{
|
|
return 1.5;
|
|
}
|
|
|
|
randomfasteranimspeed()
|
|
{
|
|
return randomfloatrange( 1, 1.2 );
|
|
}
|
|
|
|
getrandomcovermode( var_0 )
|
|
{
|
|
if ( var_0.size == 0 )
|
|
return undefined;
|
|
|
|
if ( var_0.size == 1 )
|
|
return var_0[0];
|
|
|
|
if ( isdefined( self.a.prevattack ) && randomint( 100 ) > 20 )
|
|
{
|
|
foreach ( var_3, var_2 in var_0 )
|
|
{
|
|
if ( var_2 == self.a.prevattack )
|
|
{
|
|
if ( var_3 < var_0.size - 1 )
|
|
var_0[var_3] = var_0[var_0.size - 1];
|
|
|
|
var_0[var_0.size - 1] = undefined;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return var_0[randomint( var_0.size )];
|
|
}
|
|
|
|
player_sees_my_scope()
|
|
{
|
|
var_0 = self geteye();
|
|
|
|
foreach ( var_2 in level.players )
|
|
{
|
|
if ( !self cansee( var_2 ) )
|
|
continue;
|
|
|
|
var_3 = var_2 geteye();
|
|
var_4 = vectortoangles( var_0 - var_3 );
|
|
var_5 = anglestoforward( var_4 );
|
|
var_6 = var_2 getplayerangles();
|
|
var_7 = anglestoforward( var_6 );
|
|
var_8 = vectordot( var_5, var_7 );
|
|
|
|
if ( var_8 < 0.805 )
|
|
continue;
|
|
|
|
if ( common_scripts\utility::cointoss() && var_8 >= 0.996 )
|
|
continue;
|
|
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|