// IW6 GSC SOURCE // Generated by https://github.com/xensik/gsc-tool #using_animtree("generic_human"); init_animset_combat() { var_0 = []; var_0["surprise_stop"] = %surprise_stop_v1; var_0["trans_to_combat"] = %casual_stand_idle_trans_out; var_0["drop_rpg_stand"] = %rpg_stand_throw; var_0["drop_rpg_crouch"] = %rpg_crouch_throw; var_0["pistol_to_primary"] = %pistol_stand_switch; var_0["primary_to_pistol"] = %pistol_stand_pullout; var_0["rpg_death"] = %rpg_stand_death; var_0["rpg_death_stagger"] = %rpg_stand_death_stagger; anim.archetypes["soldier"]["combat"] = var_0; } main() { if ( isdefined( self.no_ai ) ) return; if ( isdefined( self.custom_animscript ) ) { if ( isdefined( self.custom_animscript["combat"] ) ) { [[ self.custom_animscript["combat"] ]](); return; } } self endon( "killanimscript" ); [[ self.exception["exposed"] ]](); animscripts\utility::initialize( "combat" ); self.a.arrivaltype = undefined; if ( isdefined( self.node ) && self.node.type == "Ambush" && self nearnode( self.node ) ) self.ambushnode = self.node; transitiontocombat(); dofriendlyfirereaction(); if ( isdefined( self.specialidleanim ) ) animscripts\stop::specialidleloop(); setup(); exposedcombatmainloop(); self notify( "stop_deciding_how_to_shoot" ); } end_script() { self.ambushnode = undefined; combat_clearfacialanim(); } dofriendlyfirereaction() { if ( self.team != "allies" ) return; if ( self ismovesuppressed() && self.prevscript == "move" && self.a.pose == "stand" && !isdefined( self.disablefriendlyfirereaction ) ) { if ( isdefined( self.enemy ) && distancesquared( self.origin, self.enemy.origin ) < squared( 128 ) ) return; if ( !isdefined( self.a.array ) ) return; if ( isdefined( self.a.array["surprise_stop"] ) ) var_0 = animscripts\utility::animarray( "surprise_stop" ); else if ( self.swimmer ) { var_0 = animscripts\swim::getswimanim( "surprise_stop" ); if ( !isdefined( var_0 ) ) return; } else var_0 = animscripts\utility::lookupanim( "combat", "surprise_stop" ); resetanimmode(); self setflaggedanimknoballrestart( "react", var_0, %root, 1, 0.2, self.animplaybackrate ); combat_playfacialanim( var_0, "run" ); animscripts\shared::donotetracks( "react" ); } } transitiontocombat() { if ( isdefined( self.specialidleanim ) || isdefined( self.customidleanimset ) ) return; if ( isdefined( self.enemy ) && distancesquared( self.origin, self.enemy.origin ) < 262144 ) return; if ( self.prevscript == "stop" && !animscripts\utility::iscqbwalking() && self.a.pose == "stand" ) { resetanimmode(); var_0 = animscripts\utility::lookupanim( "combat", "trans_to_combat" ); self setflaggedanimknoballrestart( "transition", var_0, %root, 1, 0.2, 1.2 * self.animplaybackrate ); combat_playfacialanim( var_0, "run" ); animscripts\shared::donotetracks( "transition" ); } } setup_anim_array() { if ( self.a.pose == "stand" ) animscripts\animset::set_animarray_standing(); else if ( self.a.pose == "crouch" ) animscripts\animset::set_animarray_crouching(); else if ( self.a.pose == "prone" ) animscripts\animset::set_animarray_prone(); else { } } setup() { if ( animscripts\utility::usingsidearm() && self isstanceallowed( "stand" ) ) transitionto( "stand" ); setup_anim_array(); set_aim_and_turn_limits(); thread stopshortly(); self.previouspitchdelta = 0.0; self clearanim( %root, 0.2 ); animscripts\combat_utility::setupaim( 0.2 ); thread animscripts\combat_utility::aimidlethread(); self.a.meleestate = "aim"; delaystandardmelee(); } stopshortly() { self endon( "killanimscript" ); wait 0.2; self.a.movement = "stop"; } set_default_swimmer_aim_limits() { if ( self.swimmer ) { if ( animscripts\utility::isspaceai() ) { self.upaimlimit = 90; self.downaimlimit = -90; self.rightaimlimit = 45; self.leftaimlimit = -45; } else { self.upaimlimit = 90; self.downaimlimit = -120; } } } set_default_aim_limits( var_0 ) { if ( isdefined( var_0 ) ) self setdefaultaimlimits( var_0 ); else self setdefaultaimlimits(); set_default_swimmer_aim_limits(); } set_aim_and_turn_limits() { set_default_aim_limits(); if ( self.a.pose == "stand" && !self.swimmer ) { self.upaimlimit = 60; self.downaimlimit = -60; } self.turnthreshold = self.defaultturnthreshold; } setupexposedcombatloop() { thread animscripts\track::trackshootentorpos(); thread reacquirewhennecessary(); thread animscripts\shoot_behavior::decidewhatandhowtoshoot( "normal" ); thread watchshootentvelocity(); resetgiveuponenemytime(); if ( isdefined( self.a.magicreloadwhenreachenemy ) ) { animscripts\weaponlist::refillclip(); self.a.magicreloadwhenreachenemy = undefined; } self.a.dontcrouchtime = gettime() + randomintrange( 500, 1500 ); } exposedcombatstopusingrpgcheck( var_0 ) { if ( animscripts\utility::usingrocketlauncher() && animscripts\utility::shoulddroprocketlauncher( var_0 ) ) { if ( self.a.pose != "stand" && self.a.pose != "crouch" ) transitionto( "crouch" ); if ( self.a.pose == "stand" ) animscripts\shared::throwdownweapon( animscripts\utility::lookupanim( "combat", "drop_rpg_stand" ) ); else animscripts\shared::throwdownweapon( animscripts\utility::lookupanim( "combat", "drop_rpg_crouch" ) ); self clearanim( %root, 0.2 ); animscripts\combat_utility::endfireandanimidlethread(); setup_anim_array(); animscripts\combat_utility::startfireandaimidlethread(); return 1; } return 0; } exposedcombatcheckstance( var_0 ) { if ( self.a.pose != "stand" && self isstanceallowed( "stand" ) ) { if ( var_0 < 81225 ) { transitionto( "stand" ); return 1; } if ( standifmakesenemyvisible() ) return 1; } if ( var_0 > 262144 && self.a.pose != "crouch" && self isstanceallowed( "crouch" ) && !self.swimmer && !animscripts\utility::usingsidearm() && !isdefined( self.heat ) && gettime() >= self.a.dontcrouchtime && lengthsquared( self.shootentvelocity ) < 10000 ) { if ( !isdefined( self.shootpos ) || sighttracepassed( self.origin + ( 0, 0, 36 ), self.shootpos, 0, undefined ) ) { transitionto( "crouch" ); return 1; } } return 0; } exposedcombatcheckreloadorusepistol( var_0 ) { if ( !animscripts\utility::usingsidearm() ) { if ( isdefined( self.forcesidearm ) && self.a.pose == "stand" ) { if ( tryusingsidearm() ) return 1; } if ( animscripts\combat_utility::issniper() && var_0 < 167772.0 ) { if ( tryusingsidearm() ) return 1; } } if ( animscripts\combat_utility::needtoreload( 0 ) ) { if ( !animscripts\utility::usingsidearm() && common_scripts\utility::cointoss() && !animscripts\utility::usingrocketlauncher() && animscripts\utility::usingprimary() && var_0 < 167772.0 && self isstanceallowed( "stand" ) ) { if ( self.a.pose != "stand" ) { transitionto( "stand" ); return 1; } if ( tryusingsidearm() ) return 1; } if ( exposedreload( 0 ) ) return 1; } return 0; } exposedcombatcheckputawaypistol( var_0 ) { if ( animscripts\utility::usingsidearm() && self.a.pose == "stand" && !isdefined( self.forcesidearm ) ) { if ( var_0 > 262144 || self.combatmode == "ambush_nodes_only" && ( !isdefined( self.enemy ) || !self cansee( self.enemy ) ) ) switchtolastweapon( animscripts\utility::lookupanim( "combat", "pistol_to_primary" ) ); } } exposedcombatpositionadjust() { if ( isdefined( self.heat ) && self nearclaimnodeandangle() ) self safeteleport( self.nodeoffsetpos, self.node.angles ); } exposedcombatneedtoturn() { if ( needtoturn() ) { var_0 = 0.25; if ( isdefined( self.shootent ) && !issentient( self.shootent ) ) var_0 = 1.5; var_1 = animscripts\shared::getpredictedaimyawtoshootentorpos( var_0 ); if ( turntofacerelativeyaw( var_1 ) ) return 1; } return 0; } exposedcombatmainloop() { self endon( "killanimscript" ); setupexposedcombatloop(); resetanimmode( 0 ); if ( animscripts\utility::isspaceai() ) { var_0 = ( 0, self.angles[1], 0 ); self orientmode( "face angle 3d", var_0 ); } else self orientmode( "face angle", self.angles[1] ); for (;;) { if ( animscripts\utility::usingrocketlauncher() ) self.deathfunction = undefined; animscripts\utility::updateisincombattimer(); if ( waitforstancechange() ) continue; trymelee(); exposedcombatpositionadjust(); if ( !isdefined( self.shootpos ) ) { cantseeenemybehavior(); continue; } resetgiveuponenemytime(); var_1 = lengthsquared( self.origin - self.shootpos ); if ( exposedcombatstopusingrpgcheck( var_1 ) ) continue; if ( exposedcombatneedtoturn() ) continue; if ( considerthrowgrenade() ) continue; if ( exposedcombatcheckreloadorusepistol( var_1 ) ) continue; if ( animscripts\utility::usingrocketlauncher() && self.a.pose != "crouch" && randomfloat( 1 ) > 0.65 ) self.deathfunction = ::rpgdeath; exposedcombatcheckputawaypistol( var_1 ); if ( exposedcombatcheckstance( var_1 ) ) continue; if ( animscripts\combat_utility::aimedatshootentorpos() ) { shootuntilneedtoturn(); animscripts\combat_utility::hidefireshowaimidle(); continue; } exposedwait(); } } exposedwait() { if ( !isdefined( self.enemy ) || !self cansee( self.enemy ) ) { self endon( "enemy" ); self endon( "shoot_behavior_change" ); wait( 0.2 + randomfloat( 0.1 ) ); self waittill( "do_slow_things" ); } else wait 0.05; } standifmakesenemyvisible() { if ( isdefined( self.enemy ) && ( !self cansee( self.enemy ) || !self canshootenemy() ) && sighttracepassed( self.origin + ( 0, 0, 64 ), self.enemy getshootatpos(), 0, undefined ) ) { self.a.dontcrouchtime = gettime() + 3000; transitionto( "stand" ); return 1; } return 0; } needtoturn() { var_0 = self.shootpos; if ( !isdefined( var_0 ) ) return 0; var_1 = self.angles[1] - vectortoyaw( var_0 - self.origin ); var_2 = distancesquared( self.origin, var_0 ); if ( var_2 < 65536 ) { var_3 = sqrt( var_2 ); if ( var_3 > 3 ) var_1 = var_1 + asin( -3 / var_3 ); } return animscripts\utility::absangleclamp180( var_1 ) > self.turnthreshold; } waitforstancechange() { var_0 = self.a.pose; if ( isdefined( self.a.onback ) ) { wait 0.1; return 1; } if ( var_0 == "stand" && isdefined( self.heat ) ) return 0; if ( !self isstanceallowed( var_0 ) ) { var_1 = "crouch"; if ( var_0 == "crouch" ) var_1 = "stand"; var_2 = "prone"; if ( var_0 == "prone" ) { var_1 = "stand"; var_2 = "crouch"; } if ( self isstanceallowed( var_1 ) ) { if ( var_0 == "stand" && animscripts\utility::usingsidearm() ) return 0; transitionto( var_1 ); return 1; } else if ( self isstanceallowed( var_2 ) ) { if ( var_0 == "stand" && animscripts\utility::usingsidearm() ) return 0; transitionto( var_2 ); return 1; } else { } } return 0; } cantseeenemybehavior() { if ( self.a.pose != "stand" && self isstanceallowed( "stand" ) && standifmakesenemyvisible() ) return 1; var_0 = gettime(); self.a.dontcrouchtime = var_0 + 1500; if ( isdefined( self.group ) && isdefined( self.group.forward ) ) { var_1 = angleclamp180( self.angles[1] - vectortoyaw( self.group.forward ) ); if ( turntofacerelativeyaw( var_1 ) ) return 1; } if ( isdefined( self.node ) && isdefined( anim.iscombatscriptnode[self.node.type] ) ) { var_1 = angleclamp180( self.angles[1] - self.node.angles[1] ); if ( turntofacerelativeyaw( var_1 ) ) return 1; } else if ( isdefined( self.enemy ) && self seerecently( self.enemy, 2 ) || var_0 > self.a.scriptstarttime + 1200 ) { var_1 = undefined; var_2 = self getanglestolikelyenemypath(); if ( isdefined( var_2 ) ) var_1 = angleclamp180( self.angles[1] - var_2[1] ); else if ( isdefined( self.node ) ) var_1 = angleclamp180( self.angles[1] - self.node.angles[1] ); else if ( isdefined( self.enemy ) ) { var_2 = vectortoangles( self lastknownpos( self.enemy ) - self.origin ); var_1 = angleclamp180( self.angles[1] - var_2[1] ); } if ( isdefined( var_1 ) && turntofacerelativeyaw( var_1 ) ) return 1; } else if ( isdefined( self.heat ) && self nearclaimnode() ) { var_1 = angleclamp180( self.angles[1] - self.node.angles[1] ); if ( turntofacerelativeyaw( var_1 ) ) return 1; } if ( considerthrowgrenade() ) return 1; var_3 = self.a.nextgiveuponenemytime < var_0; var_4 = 0; if ( var_3 ) var_4 = 0.99999; if ( exposedreload( var_4 ) ) return 1; if ( var_3 && animscripts\utility::usingsidearm() ) { if ( switchtolastweapon( animscripts\utility::lookupanim( "combat", "pistol_to_primary" ) ) ) return 1; } cantseeenemywait(); return 1; } cantseeenemywait() { self endon( "shoot_behavior_change" ); wait( 0.4 + randomfloat( 0.4 ) ); self waittill( "do_slow_things" ); } resetgiveuponenemytime() { self.a.nextgiveuponenemytime = gettime() + randomintrange( 2000, 4000 ); } turntofacerelativeyaw( var_0 ) { if ( var_0 < 0 - self.turnthreshold ) { if ( self.a.pose == "prone" ) { animscripts\cover_prone::proneto( "crouch" ); animscripts\animset::set_animarray_crouching(); } doturn( "left", 0 - var_0 ); maps\_gameskill::didsomethingotherthanshooting(); return 1; } if ( var_0 > self.turnthreshold ) { if ( self.a.pose == "prone" ) { animscripts\cover_prone::proneto( "crouch" ); animscripts\animset::set_animarray_crouching(); } doturn( "right", var_0 ); maps\_gameskill::didsomethingotherthanshooting(); return 1; } return 0; } watchshootentvelocity() { self endon( "killanimscript" ); self.shootentvelocity = ( 0, 0, 0 ); var_0 = undefined; var_1 = self.origin; var_2 = 0.15; for (;;) { if ( isdefined( self.shootent ) && isdefined( var_0 ) && self.shootent == var_0 ) { var_3 = self.shootent.origin; self.shootentvelocity = ( var_3 - var_1 ) * ( 1 / var_2 ); var_1 = var_3; } else { if ( isdefined( self.shootent ) ) var_1 = self.shootent.origin; else var_1 = self.origin; var_0 = self.shootent; self.shootentvelocity = ( 0, 0, 0 ); } wait( var_2 ); } } shouldswapshotgun() { return 0; } donotetrackswithendon( var_0 ) { self endon( "killanimscript" ); animscripts\shared::donotetracks( var_0 ); } faceenemyimmediately() { self endon( "killanimscript" ); self notify( "facing_enemy_immediately" ); self endon( "facing_enemy_immediately" ); var_0 = 5; for (;;) { var_1 = 0 - animscripts\utility::getyawtoenemy(); if ( abs( var_1 ) < 2 ) break; if ( abs( var_1 ) > var_0 ) var_1 = var_0 * common_scripts\utility::sign( var_1 ); self orientmode( "face angle", self.angles[1] + var_1 ); wait 0.05; } self orientmode( "face current" ); self notify( "can_stop_turning" ); } isdeltaallowed( var_0 ) { var_1 = getmovedelta( var_0, 0, 1 ); var_2 = self localtoworldcoords( var_1 ); return self isingoal( var_2 ) && self maymovetopoint( var_2 ); } isanimdeltaingoal( var_0 ) { var_1 = getmovedelta( var_0, 0, 1 ); var_2 = self localtoworldcoords( var_1 ); return self isingoal( var_2 ); } doturn( var_0, var_1 ) { var_2 = isdefined( self.shootpos ); var_3 = 1; var_4 = 0.2; var_5 = isdefined( self.enemy ) && !isdefined( self.turntomatchnode ) && self seerecently( self.enemy, 2 ) && distancesquared( self.enemy.origin, self.origin ) < 262144; if ( self.a.scriptstarttime + 500 > gettime() ) { var_4 = 0.25; if ( var_5 ) thread faceenemyimmediately(); } else if ( var_5 ) { var_6 = 1.0 - distance( self.enemy.origin, self.origin ) / 512; var_3 = 1 + var_6 * 1; if ( var_3 > 2 ) var_4 = 0.05; else if ( var_3 > 1.3 ) var_4 = 0.1; else var_4 = 0.15; } var_7 = 0; if ( var_1 > 157.5 ) var_7 = 180; else if ( var_1 > 112.5 ) var_7 = 135; else if ( var_1 > 67.5 ) var_7 = 90; else var_7 = 45; var_8 = "turn_" + var_0 + "_" + var_7; var_9 = animscripts\utility::animarray( var_8 ); if ( isdefined( self.turntomatchnode ) ) self animmode( "angle deltas", 0 ); else if ( isdefined( self.node ) && isdefined( anim.iscombatpathnode[self.node.type] ) && distancesquared( self.origin, self.node.origin ) < 256 ) self animmode( "angle deltas", 0 ); else if ( isanimdeltaingoal( var_9 ) ) resetanimmode(); else self animmode( "angle deltas", 0 ); self setanimknoball( %exposed_aiming, %body, 1, var_4 ); if ( !isdefined( self.turntomatchnode ) ) turningaimingon( var_4 ); self setanimlimited( %turn, 1, var_4 ); if ( isdefined( self.heat ) ) var_3 = min( 1.0, var_3 ); else if ( isdefined( self.turntomatchnode ) ) var_3 = max( 1.5, var_3 ); self setflaggedanimknoblimitedrestart( "turn", var_9, 1, var_4, var_3 ); combat_playfacialanim( var_9, "aim" ); self notify( "turning" ); if ( var_2 && !isdefined( self.turntomatchnode ) && !isdefined( self.heat ) ) thread shootwhileturning(); doturnnotetracks(); self setanimlimited( %turn, 0, 0.2 ); if ( !isdefined( self.turntomatchnode ) ) turningaimingoff( 0.2 ); if ( !isdefined( self.turntomatchnode ) ) { self clearanim( %turn, 0.2 ); self setanimknob( %exposed_aiming, 1, 0.2, 1 ); } else self clearanim( %exposed_modern, 0.3 ); if ( isdefined( self.turnlastresort ) ) { self.turnlastresort = undefined; thread faceenemyimmediately(); } resetanimmode( 0 ); self notify( "done turning" ); } doturnnotetracks() { self endon( "can_stop_turning" ); animscripts\shared::donotetracks( "turn" ); } makesureturnworks() { self endon( "killanimscript" ); self endon( "done turning" ); var_0 = self.angles[1]; wait 0.3; if ( self.angles[1] == var_0 ) { self notify( "turning_isnt_working" ); self.turnlastresort = 1; } } turningaimingon( var_0 ) { self setanimlimited( animscripts\utility::animarray( "straight_level" ), 0, var_0 ); self setanim( %add_idle, 0, var_0 ); if ( !animscripts\utility::weapon_pump_action_shotgun() ) self clearanim( %add_fire, 0.2 ); } turningaimingoff( var_0 ) { self setanimlimited( animscripts\utility::animarray( "straight_level" ), 1, var_0 ); self setanim( %add_idle, 1, var_0 ); } shootwhileturning() { self endon( "killanimscript" ); self endon( "done turning" ); if ( animscripts\utility::usingrocketlauncher() ) return; animscripts\combat_utility::shootuntilshootbehaviorchange(); self clearanim( %add_fire, 0.2 ); } shootuntilneedtoturn() { thread watchforneedtoturnortimeout(); self endon( "need_to_turn" ); thread keeptryingtomelee(); animscripts\combat_utility::shootuntilshootbehaviorchange(); self notify( "stop_watching_for_need_to_turn" ); self notify( "stop_trying_to_melee" ); } watchforneedtoturnortimeout() { self endon( "killanimscript" ); self endon( "stop_watching_for_need_to_turn" ); var_0 = gettime() + 4000 + randomint( 2000 ); for (;;) { if ( gettime() > var_0 || needtoturn() ) { self notify( "need_to_turn" ); break; } wait 0.1; } } considerthrowgrenade() { if ( !animscripts\combat_utility::mygrenadecooldownelapsed() ) return 0; if ( isdefined( anim.throwgrenadeatplayerasap ) && isalive( level.player ) ) { if ( tryexposedthrowgrenade( level.player, 200 ) ) return 1; } if ( isdefined( self.enemy ) && tryexposedthrowgrenade( self.enemy, self.minexposedgrenadedist ) ) return 1; self.a.nextgrenadetrytime = gettime() + 500; return 0; } tryexposedthrowgrenade( var_0, var_1 ) { var_2 = 0; if ( isdefined( self.dontevershoot ) || isdefined( var_0.dontattackme ) ) return 0; if ( !isdefined( self.a.array["exposed_grenade"] ) ) return 0; var_3 = var_0.origin; if ( !self cansee( var_0 ) ) { if ( isdefined( self.enemy ) && var_0 == self.enemy && isdefined( self.shootpos ) ) var_3 = self.shootpos; } if ( !self cansee( var_0 ) ) var_1 = 100; if ( distancesquared( self.origin, var_3 ) > var_1 * var_1 && self.a.pose == self.a.grenadethrowpose ) { animscripts\combat_utility::setactivegrenadetimer( var_0 ); if ( !animscripts\combat_utility::grenadecooldownelapsed( var_0 ) ) return 0; var_4 = animscripts\utility::getyawtospot( var_3 ); if ( abs( var_4 ) < 60 ) { var_5 = []; foreach ( var_7 in self.a.array["exposed_grenade"] ) { if ( isdeltaallowed( var_7 ) ) var_5[var_5.size] = var_7; } if ( var_5.size > 0 ) { self setanim( %exposed_aiming, 0, 0.1 ); combat_clearfacialanim(); self animmode( "zonly_physics" ); animscripts\track::setanimaimweight( 0, 0 ); var_2 = animscripts\combat_utility::trygrenade( var_0, var_5[randomint( var_5.size )] ); self setanim( %exposed_aiming, 1, 0.1 ); combat_playfacialanim( undefined, "aim" ); if ( var_2 ) animscripts\track::setanimaimweight( 1, 0.5 ); else animscripts\track::setanimaimweight( 1, 0 ); } } } if ( var_2 ) maps\_gameskill::didsomethingotherthanshooting(); return var_2; } transitionto( var_0 ) { if ( var_0 == self.a.pose ) return; var_1 = self.a.pose + "_2_" + var_0; if ( !isdefined( self.a.array ) ) return; var_2 = self.a.array[var_1]; if ( !isdefined( var_2 ) ) return; self clearanim( %root, 0.3 ); animscripts\combat_utility::endfireandanimidlethread(); if ( var_0 == "stand" ) var_3 = 2; else var_3 = 1.5; if ( !animhasnotetrack( var_2, "anim_pose = \"" + var_0 + "\"" ) ) { } self setflaggedanimknoballrestart( "trans", var_2, %body, 1, 0.2, var_3 ); combat_playfacialanim( var_2, "run" ); var_4 = getanimlength( var_2 ) / var_3; var_5 = var_4 - 0.3; if ( var_5 < 0.2 ) var_5 = 0.2; animscripts\notetracks::donotetracksfortime( var_5, "trans" ); self.a.pose = var_0; setup_anim_array(); animscripts\combat_utility::startfireandaimidlethread(); maps\_gameskill::didsomethingotherthanshooting(); } keeptryingtomelee() { self endon( "killanimscript" ); self endon( "stop_trying_to_melee" ); self endon( "done turning" ); self endon( "need_to_turn" ); self endon( "shoot_behavior_change" ); for (;;) { wait( 0.2 + randomfloat( 0.3 ) ); if ( isdefined( self.enemy ) ) { if ( isplayer( self.enemy ) ) var_0 = 40000; else var_0 = 10000; if ( distancesquared( self.enemy.origin, self.origin ) < var_0 ) trymelee(); } } } trymelee() { animscripts\melee::melee_tryexecuting(); } delaystandardmelee() { if ( isdefined( self.nomeleechargedelay ) ) return; if ( isplayer( self.enemy ) ) return; animscripts\melee::melee_standard_delaystandardcharge( self.enemy ); } exposedreload( var_0 ) { if ( animscripts\combat_utility::needtoreload( var_0 ) ) { self.a.exposedreloading = 1; animscripts\combat_utility::endfireandanimidlethread(); var_1 = undefined; if ( isdefined( self.specialreloadanimfunc ) ) { var_1 = self [[ self.specialreloadanimfunc ]](); self.keepclaimednode = 1; } else { var_1 = animscripts\utility::animarraypickrandom( "reload" ); if ( self.a.pose == "stand" && animscripts\utility::animarrayanyexist( "reload_crouchhide" ) && common_scripts\utility::cointoss() ) var_1 = animscripts\utility::animarraypickrandom( "reload_crouchhide" ); } thread keeptryingtomelee(); self.finishedreload = 0; if ( weaponclass( self.weapon ) == "pistol" ) self orientmode( "face default" ); doreloadanim( var_1, var_0 > 0.05 ); self notify( "abort_reload" ); self orientmode( "face current" ); if ( self.finishedreload ) animscripts\weaponlist::refillclip(); self clearanim( %reload, 0.2 ); self.keepclaimednode = 0; self notify( "stop_trying_to_melee" ); self.a.exposedreloading = 0; self.finishedreload = undefined; maps\_gameskill::didsomethingotherthanshooting(); animscripts\combat_utility::startfireandaimidlethread(); return 1; } return 0; } doreloadanim( var_0, var_1 ) { self endon( "abort_reload" ); if ( var_1 ) thread abortreloadwhencanshoot(); var_2 = 1; if ( !animscripts\utility::usingsidearm() && !animscripts\utility::isshotgun( self.weapon ) && isdefined( self.enemy ) && self cansee( self.enemy ) && distancesquared( self.enemy.origin, self.origin ) < 1048576 ) var_2 = 1.2; var_3 = "reload_" + animscripts\combat_utility::getuniqueflagnameindex(); self clearanim( %root, 0.2 ); self setflaggedanimrestart( var_3, var_0, 1, 0.2, var_2 ); combat_playfacialanim( var_0, "run" ); thread notifyonstartaim( "abort_reload", var_3 ); self endon( "start_aim" ); animscripts\shared::donotetracks( var_3 ); self.finishedreload = 1; } abortreloadwhencanshoot() { self endon( "abort_reload" ); self endon( "killanimscript" ); for (;;) { if ( isdefined( self.shootent ) && self cansee( self.shootent ) ) break; wait 0.05; } self notify( "abort_reload" ); } notifyonstartaim( var_0, var_1 ) { self endon( var_0 ); self waittillmatch( var_1, "start_aim" ); self.finishedreload = 1; self notify( "start_aim" ); } finishnotetracks( var_0 ) { self endon( "killanimscript" ); animscripts\shared::donotetracks( var_0 ); } drop_turret() { maps\_mgturret::dropturret(); animscripts\weaponlist::refillclip(); self.a.needstorechamber = 0; self notify( "dropped_gun" ); maps\_mgturret::restoredefaults(); } exception_exposed_mg42_portable() { drop_turret(); } tryusingsidearm() { if ( isdefined( self.secondaryweapon ) && animscripts\utility::isshotgun( self.secondaryweapon ) ) return 0; if ( isdefined( self.no_pistol_switch ) ) return 0; self.a.pose = "stand"; switchtosidearm( animscripts\utility::lookupanim( "combat", "primary_to_pistol" ) ); return 1; } switchtosidearm( var_0 ) { self endon( "killanimscript" ); thread animscripts\combat_utility::putgunbackinhandonkillanimscript(); animscripts\combat_utility::endfireandanimidlethread(); self.swapanim = var_0; self setflaggedanimknoballrestart( "weapon swap", var_0, %body, 1, 0.2, animscripts\combat_utility::fasteranimspeed() ); combat_playfacialanim( var_0, "run" ); donotetrackspostcallbackwithendon( "weapon swap", ::handlepickup, "end_weapon_swap" ); self clearanim( self.swapanim, 0.2 ); self notify( "facing_enemy_immediately" ); self notify( "switched_to_sidearm" ); maps\_gameskill::didsomethingotherthanshooting(); } donotetrackspostcallbackwithendon( var_0, var_1, var_2 ) { self endon( var_2 ); animscripts\notetracks::donotetrackspostcallback( var_0, var_1 ); } faceenemydelay( var_0 ) { self endon( "killanimscript" ); wait( var_0 ); faceenemyimmediately(); } handlepickup( var_0 ) { if ( var_0 == "pistol_pickup" ) { self clearanim( animscripts\utility::animarray( "straight_level" ), 0 ); animscripts\animset::set_animarray_standing(); thread faceenemydelay( 0.25 ); } else if ( var_0 == "start_aim" ) { animscripts\combat_utility::startfireandaimidlethread(); if ( needtoturn() ) self notify( "end_weapon_swap" ); } } switchtolastweapon( var_0, var_1 ) { self endon( "killanimscript" ); if ( animscripts\utility::isshotgun( self.primaryweapon ) && ( isdefined( self.wantshotgun ) && !self.wantshotgun ) && self.lastweapon == animscripts\utility::getaiprimaryweapon() ) return 0; animscripts\combat_utility::endfireandanimidlethread(); self.swapanim = var_0; self setflaggedanimknoballrestart( "weapon swap", var_0, %body, 1, 0.1, 1 ); combat_playfacialanim( var_0, "run" ); if ( isdefined( var_1 ) ) donotetrackspostcallbackwithendon( "weapon swap", ::handlecleanupputaway, "end_weapon_swap" ); else donotetrackspostcallbackwithendon( "weapon swap", ::handleputaway, "end_weapon_swap" ); self clearanim( self.swapanim, 0.2 ); self notify( "switched_to_lastweapon" ); maps\_gameskill::didsomethingotherthanshooting(); return 1; } handleputaway( var_0 ) { if ( var_0 == "pistol_putaway" ) { self clearanim( animscripts\utility::animarray( "straight_level" ), 0 ); animscripts\animset::set_animarray_standing(); thread animscripts\combat_utility::putgunbackinhandonkillanimscript(); } else if ( var_0 == "start_aim" ) { animscripts\combat_utility::startfireandaimidlethread(); if ( needtoturn() ) self notify( "end_weapon_swap" ); } } handlecleanupputaway( var_0 ) { if ( var_0 == "pistol_putaway" ) thread animscripts\combat_utility::putgunbackinhandonkillanimscript(); else if ( issubstr( var_0, "anim_gunhand" ) ) self notify( "end_weapon_swap" ); } rpgdeath() { if ( !animscripts\utility::usingrocketlauncher() || self.bulletsinclip == 0 ) return 0; if ( randomfloat( 1 ) > 0.5 ) var_0 = animscripts\utility::lookupanim( "combat", "rpg_death" ); else var_0 = animscripts\utility::lookupanim( "combat", "rpg_death_stagger" ); self setflaggedanimknoball( "deathanim", var_0, %root, 1, 0.05, 1 ); combat_playfacialanim( var_0, "death" ); animscripts\shared::donotetracks( "deathanim" ); animscripts\shared::dropallaiweapons(); return; } reacquirewhennecessary() { self endon( "killanimscript" ); self.a.exposedreloading = 0; for (;;) { wait 0.2; if ( isdefined( self.enemy ) && !self seerecently( self.enemy, 2 ) ) { if ( self.combatmode == "ambush" || self.combatmode == "ambush_nodes_only" ) continue; } tryexposedreacquire(); } } tryexposedreacquire() { if ( self.fixednode ) return; if ( !isdefined( self.enemy ) ) { self.reacquire_state = 0; return; } if ( gettime() < self.teammovewaittime ) { self.reacquire_state = 0; return; } if ( isdefined( self.prevenemy ) && self.prevenemy != self.enemy ) { self.reacquire_state = 0; self.prevenemy = undefined; return; } self.prevenemy = self.enemy; if ( self cansee( self.enemy ) && self canshootenemy() ) { self.reacquire_state = 0; return; } if ( isdefined( self.finishedreload ) && !self.finishedreload ) { self.reacquire_state = 0; return; } if ( !isdefined( self.reacquire_without_facing ) || !self.reacquire_without_facing ) { var_0 = vectornormalize( self.enemy.origin - self.origin ); var_1 = anglestoforward( self.angles ); if ( vectordot( var_0, var_1 ) < 0.5 ) { self.reacquire_state = 0; return; } } if ( self.a.exposedreloading && animscripts\combat_utility::needtoreload( 0.25 ) && self.enemy.health > self.enemy.maxhealth * 0.5 ) { self.reacquire_state = 0; return; } if ( animscripts\combat_utility::shouldhelpadvancingteammate() && self.reacquire_state < 3 ) self.reacquire_state = 3; switch ( self.reacquire_state ) { case 0: if ( self reacquirestep( 32 ) ) return; break; case 1: if ( self reacquirestep( 64 ) ) { self.reacquire_state = 0; return; } break; case 2: if ( self reacquirestep( 96 ) ) { self.reacquire_state = 0; return; } break; case 3: if ( animscripts\combat_utility::tryrunningtoenemy( 0 ) ) { self.reacquire_state = 0; return; } break; case 4: if ( !self cansee( self.enemy ) || !self canshootenemy() ) self flagenemyunattackable(); break; default: if ( self.reacquire_state > 15 ) { self.reacquire_state = 0; return; } break; } self.reacquire_state++; } resetanimmode( var_0 ) { var_1 = var_0; if ( !isdefined( var_1 ) ) var_1 = 1; if ( self.swimmer ) self animmode( "nogravity", var_1 ); else self animmode( "zonly_physics", var_1 ); } combat_playfacialanim( var_0, var_1 ) { self.facialidx = animscripts\face::playfacialanim( var_0, var_1, self.facialidx ); } combat_clearfacialanim() { self.facialidx = undefined; self clearanim( %head, 0.2 ); }