// 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; __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; }