// IW6 GSC SOURCE // Generated by https://github.com/xensik/gsc-tool main() { setupalienstate(); thread think(); thread watchownerdamage(); thread watchownerdeath(); thread watchownerteamchange(); thread waitforbadpath(); thread waitforpathset(); } setupalienstate() { self.blockgoalpos = 0; self.ownerradiussq = 20736; self.meleeradiussq = 8100; self.attackoffset = 25 + self.radius; self.attackradiussq = 202500; self.warningradiussq = 302500; self.warningzheight = 96.0; self.attackzheight = 54; self.attackzheightdown = -64; self.ownerdamagedradiussq = 2250000; self.dogdamagedradiussq = 42250000; self.keeppursuingtargetradiussq = 36000000; self.preferredoffsetfromowner = 76; self.minoffsetfromowner = 50; self.forceattack = 1; self.ignoreclosefoliage = 1; self.movemode = "run"; self.enableextendedkill = 1; self.attackstate = "idle"; self.movestate = "idle"; self.bhasbadpath = 0; self.timeoflastdamage = 0; self.alien_goalpos = get_closest( self.origin, self.pathnodearray ); self.allowcrouch = 1; self scragentsetgoalradius( 24 ); } init() { self.animcbs = spawnstruct(); self.animcbs.onenter = []; self.animcbs.onenter["idle"] = maps\mp\mp_dome_ns_alien_idle::main; self.animcbs.onenter["move"] = maps\mp\mp_dome_ns_alien_move::main; self.animcbs.onenter["traverse"] = maps\mp\mp_dome_ns_alien_traverse::main; self.animcbs.onexit = []; self.animcbs.onexit["idle"] = maps\mp\mp_dome_ns_alien_idle::end_script; self.animcbs.onexit["move"] = maps\mp\mp_dome_ns_alien_move::end_script; self.animcbs.onexit["traverse"] = maps\mp\mp_dome_ns_alien_traverse::end_script; self suicide(); self.watchattackstatefunc = ::watchattackstate; self.aistate = "idle"; self.movemode = "fastwalk"; self.radius = 15; self.height = 40; } onenteranimstate( var_0, var_1 ) { self notify( "killanimscript" ); if ( !isdefined( self.animcbs.onenter[var_1] ) ) return; if ( var_0 == var_1 && var_1 != "alien_traverse" ) return; if ( isdefined( self.animcbs.onexit[var_0] ) ) self [[ self.animcbs.onexit[var_0] ]](); exitaistate( self.aistate ); self.aistate = var_1; enteraistate( var_1 ); self [[ self.animcbs.onenter[var_1] ]](); } think() { self endon( "death" ); level endon( "game_ended" ); if ( isdefined( self.owner ) ) { self endon( "owner_disconnect" ); thread destroyonownerdisconnect( self.owner ); } self thread [[ self.watchattackstatefunc ]](); thread monitorflash(); for (;;) { if ( !self.statelocked && readytomeleetarget() ) { mp_dome_ns_alien_explode( self.curmeleetarget ); return; } switch ( self.aistate ) { case "idle": updateidle(); break; case "move": updatemove(); break; case "melee": updatemelee(); break; } wait 0.05; } } mp_dome_ns_alien_explode( var_0, var_1, var_2, var_3 ) { self emissiveblend( 0.2, 1.0 ); playfx( level._effect["vfx_alien_minion_explode_dome"], self.origin ); var_4 = 2; var_5 = 1; if ( !isdefined( var_1 ) ) var_1 = 400; if ( !isdefined( var_2 ) ) var_2 = 380; if ( isdefined( var_3 ) ) var_3 radiusdamage( self.origin, var_2, var_1, var_5, var_3, "MOD_EXPLOSIVE", "killstreak_level_event_mp" ); else if ( isdefined( self.owner ) ) self radiusdamage( self.origin, var_2, var_1, var_5, self.owner, "MOD_EXPLOSIVE", "killstreak_level_event_mp" ); else self radiusdamage( self.origin, var_2, var_1, var_5, undefined, "MOD_EXPLOSIVE", "killstreak_level_event_mp" ); self playsound( "alien_minion_explode" ); physicsexplosionsphere( self.origin, var_2, var_2 / 2, var_4 ); maps\mp\gametypes\_shellshock::barrel_earthquake(); self notify( "killanimscript" ); self setanimstate( "explode", 0, 1 ); wait( getanimlength( self getanimentry( "explode", 0 ) ) ); if ( isdefined( self ) ) self suicide(); } didpastpursuitfail( var_0 ) { if ( isdefined( self.curmeleetarget ) && var_0 != self.curmeleetarget ) return 0; if ( !isdefined( self.lastpursuitfailedpos ) || !isdefined( self.lastpursuitfailedmypos ) ) return 0; if ( distance2dsquared( var_0.origin, self.lastpursuitfailedpos ) > 4 ) return 0; if ( self.blastpursuitfailedposbad ) return 1; if ( distancesquared( self.origin, self.lastpursuitfailedmypos ) > 4096 && gettime() - self.lastpursuitfailedtime > 2000 ) return 0; return 1; } didpastmeleefail() { if ( isdefined( self.lastmeleefailedpos ) && isdefined( self.lastmeleefailedmypos ) && distance2dsquared( self.curmeleetarget.origin, self.lastmeleefailedpos ) < 4 && distancesquared( self.origin, self.lastmeleefailedmypos ) < 2500 ) return 1; if ( wanttoattacktargetbutcant( 0 ) ) return 1; return 0; } enteraistate( var_0 ) { exitaistate( self.aistate ); self.aistate = var_0; switch ( var_0 ) { case "idle": self.movestate = "idle"; self.bhasbadpath = 0; break; case "move": self.movestate = "follow"; break; case "melee": break; default: break; } } exitaistate( var_0 ) { switch ( var_0 ) { case "move": self.ownerprevpos = undefined; break; default: break; } } updateidle() { updatemovestate(); } updatemove() { updatemovestate(); } updatemelee() { self scragentsetgoalpos( self.origin ); } updatemovestate() { if ( self.blockgoalpos ) return; self.prevmovestate = self.movestate; var_0 = undefined; var_1 = 0; var_2 = 0; var_3 = 500; if ( self.bhasbadpath && gettime() - self.lastbadpathtime < var_3 ) { self.movestate = "follow"; var_1 = 1; } else self.movestate = getmovestate(); if ( self.movestate == "pursuit" ) { var_0 = getattackpoint( self.enemy ); var_4 = 0; if ( isdefined( self.lastbadpathtime ) && gettime() - self.lastbadpathtime < 3000 ) { if ( distance2dsquared( var_0, self.lastbadpathgoal ) < 16 ) var_4 = 1; else if ( isdefined( self.lastbadpathmovestate ) && self.lastbadpathmovestate == "pursuit" && distance2dsquared( self.lastbadpathultimategoal, self.enemy.origin ) < 16 ) var_4 = 1; } if ( var_4 ) { self.movestate = "follow"; var_2 = 1; } else if ( wanttoattacktargetbutcant( 1 ) ) { self.movestate = "follow"; var_2 = 1; } else if ( didpastpursuitfail( self.enemy ) ) { self.movestate = "follow"; var_2 = 1; } } setpastpursuitfailed( var_2 ); if ( self.movestate == "follow" ) { self.curmeleetarget = undefined; self.movemode = getfollowmovemode( self.movemode ); self.barrivalsenabled = 1; var_5 = self getpathgoalpos(); if ( !isdefined( var_5 ) ) var_5 = self.origin; if ( gettime() - self.timeoflastdamage < 5000 ) var_1 = 1; var_6 = distance2dsquared( self.origin, self.alien_goalpos.origin ); if ( var_6 < 800 ) picknewlocation(); self scragentsetgoalpos( self.alien_goalpos.origin ); if ( var_1 == 1 ) { self scragentsetgoalpos( self.origin ); return; } } else if ( self.movestate == "pursuit" ) { self.curmeleetarget = self.enemy; self.movemode = "sprint"; self.barrivalsenabled = 0; self scragentsetgoalpos( var_0 ); } } picknewlocation() { self.alien_goalpos = common_scripts\utility::getstruct( self.alien_goalpos.target, "targetname" ); } getmovestate( var_0 ) { if ( isdefined( self.enemy ) ) { if ( !maps\mp\_utility::isreallyalive( self.enemy ) ) return "follow"; if ( isdefined( self.favoriteenemy ) && self.enemy == self.favoriteenemy ) return "pursuit"; if ( abs( self.origin[2] - self.enemy.origin[2] ) < self.warningzheight && distance2dsquared( self.enemy.origin, self.origin ) < self.attackradiussq ) return "pursuit"; if ( isdefined( self.curmeleetarget ) && self.curmeleetarget == self.enemy ) { if ( distance2dsquared( self.curmeleetarget.origin, self.origin ) < self.keeppursuingtargetradiussq ) return "pursuit"; } } return "follow"; } setpastpursuitfailed( var_0 ) { if ( var_0 ) { if ( !isdefined( self.lastpursuitfailedpos ) ) { self.lastpursuitfailedpos = self.enemy.origin; self.lastpursuitfailedmypos = self.origin; var_1 = maps\mp\agents\_scriptedagents::droppostoground( self.enemy.origin ); self.blastpursuitfailedposbad = !isdefined( var_1 ); self.lastpursuitfailedtime = gettime(); } } else { self.lastpursuitfailedpos = undefined; self.lastpursuitfailedmypos = undefined; self.blastpursuitfailedposbad = undefined; self.lastpursuitfailedtime = undefined; } } waitforbadpath() { self endon( "death" ); level endon( "game_ended" ); for (;;) { self waittill( "bad_path", var_0 ); self.bhasbadpath = 1; self.lastbadpathtime = gettime(); self.lastbadpathgoal = var_0; self.lastbadpathmovestate = self.movestate; if ( self.movestate == "follow" && isdefined( self.owner ) ) { self.lastbadpathultimategoal = self.owner.origin; continue; } if ( self.movestate == "pursuit" && isdefined( self.enemy ) ) self.lastbadpathultimategoal = self.enemy.origin; } } waitforpathset() { self endon( "death" ); level endon( "game_ended" ); for (;;) { self waittill( "path_set" ); self.bhasbadpath = 0; } } getfollowmovemode( var_0 ) { var_1 = 122500; var_2 = 160000; var_3 = self getpathgoalpos(); if ( isdefined( var_3 ) ) { var_4 = distancesquared( var_3, self.origin ); if ( var_0 == "run" || var_0 == "sprint" ) { if ( var_4 < var_1 ) return "fastwalk"; else if ( var_0 == "sprint" ) return "run"; } else if ( var_0 == "fastwalk" ) { if ( var_4 > var_2 ) return "run"; } } return var_0; } iswithinattackheight( var_0 ) { var_1 = var_0[2] - self.origin[2]; return var_1 <= self.attackzheight && var_1 >= self.attackzheightdown; } wanttoattacktargetbutcant( var_0 ) { if ( !isdefined( self.curmeleetarget ) ) return 0; return !iswithinattackheight( self.curmeleetarget.origin ) && distance2dsquared( self.origin, self.curmeleetarget.origin ) < self.meleeradiussq * 0.75 * 0.75 && ( !var_0 || self agentcanseesentient( self.curmeleetarget ) ); } readytomeleetarget() { if ( !isdefined( self.curmeleetarget ) ) return 0; if ( !maps\mp\_utility::isreallyalive( self.curmeleetarget ) ) return 0; if ( self.aistate == "traverse" ) return 0; if ( distance2dsquared( self.origin, self.curmeleetarget.origin ) > self.meleeradiussq ) return 0; if ( !iswithinattackheight( self.curmeleetarget.origin ) ) return 0; return 1; } wantstogrowlattarget() { if ( !isdefined( self.enemy ) ) return 0; if ( abs( self.origin[2] - self.enemy.origin[2] ) <= self.warningzheight || self agentcanseesentient( self.enemy ) ) { var_0 = distance2dsquared( self.origin, self.enemy.origin ); if ( var_0 < self.warningradiussq ) return 1; } return 0; } getattackpoint( var_0 ) { var_1 = var_0.origin - self.origin; var_1 = vectornormalize( var_1 ); var_2 = self getpathgoalpos(); var_3 = self.attackoffset + 4; if ( isdefined( var_2 ) && distance2dsquared( var_2, var_0.origin ) < var_3 * var_3 && maps\mp\agents\_scriptedagents::canmovepointtopoint( var_0.origin, var_2 ) ) return var_2; var_4 = var_0.origin - var_1 * self.attackoffset; var_4 = maps\mp\agents\_scriptedagents::droppostoground( var_4 ); if ( !isdefined( var_4 ) ) return var_0.origin; if ( !maps\mp\agents\_scriptedagents::canmovepointtopoint( var_0.origin, var_4 ) ) { var_5 = anglestoforward( var_0.angles ); var_4 = var_0.origin + var_5 * self.attackoffset; if ( !maps\mp\agents\_scriptedagents::canmovepointtopoint( var_0.origin, var_4 ) ) return var_0.origin; } return var_4; } cross2d( var_0, var_1 ) { return var_0[0] * var_1[1] - var_1[0] * var_0[1]; } destroyonownerdisconnect( var_0 ) { self endon( "death" ); var_0 common_scripts\utility::waittill_any( "disconnect", "joined_team", "joined_spectators" ); self notify( "owner_disconnect" ); if ( maps\mp\gametypes\_hostmigration::waittillhostmigrationdone() ) wait 0.05; self notify( "killanimscript" ); if ( isdefined( self.animcbs.onexit[self.aistate] ) ) self [[ self.animcbs.onexit[self.aistate] ]](); mp_dome_ns_alien_explode( undefined, 1, 0 ); } watchattackstate() { self endon( "death" ); level endon( "game_ended" ); for (;;) { if ( self.aistate == "melee" ) { if ( self.attackstate != "melee" ) { self.attackstate = "melee"; setsoundstate( undefined ); } } else if ( self.movestate == "pursuit" ) { if ( self.attackstate != "attacking" ) { self.attackstate = "attacking"; setsoundstate( "bark", "attacking" ); } } else if ( self.attackstate != "warning" ) { if ( wantstogrowlattarget() ) { self.attackstate = "warning"; setsoundstate( "growl", "warning" ); } else { self.attackstate = self.aistate; setsoundstate( "pant" ); } } else if ( !wantstogrowlattarget() ) { self.attackstate = self.aistate; setsoundstate( "pant" ); } wait 0.05; } } setsoundstate( var_0, var_1 ) { if ( !isdefined( var_0 ) ) { self notify( "end_dog_sound" ); self.soundstate = undefined; return; } if ( !isdefined( self.soundstate ) || self.soundstate != var_0 ) { self notify( "end_dog_sound" ); self.soundstate = var_0; if ( var_0 == "bark" ) thread playbark( var_1 ); else if ( var_0 == "growl" ) thread playgrowl( var_1 ); else if ( var_0 == "pant" ) thread playpanting(); else { } } } playbark( var_0 ) { self endon( "death" ); level endon( "game_ended" ); self endon( "end_dog_sound" ); if ( !isdefined( self.barking_sound ) ) { self playsoundonmovingent( "alien_minion_attack" ); self.barking_sound = 1; thread watchbarking(); } } watchbarking() { self endon( "death" ); level endon( "game_ended" ); self endon( "end_dog_sound" ); wait( randomintrange( 5, 10 ) ); self.barking_sound = undefined; } playgrowl( var_0 ) { self endon( "death" ); level endon( "game_ended" ); self endon( "end_dog_sound" ); if ( isdefined( self.lastgrowlplayedtime ) && gettime() - self.lastgrowlplayedtime < 3000 ) wait 3; for (;;) { self.lastgrowlplayedtime = gettime(); self playsoundonmovingent( "alien_minion_attack" ); wait( randomintrange( 3, 6 ) ); } } playpanting( var_0 ) { self endon( "death" ); level endon( "game_ended" ); self endon( "end_dog_sound" ); if ( isdefined( self.lastpantplayedtime ) && gettime() - self.lastpantplayedtime < 3000 ) wait 3; self.lastpantplayedtime = gettime(); for (;;) { if ( self.aistate == "idle" ) { wait 3; continue; } self.lastpantplayedtime = gettime(); if ( self.movemode == "run" || self.movemode == "sprint" ) self playsoundonmovingent( "alien_minion_idle" ); else self playsoundonmovingent( "alien_minion_idle" ); wait( randomintrange( 6, 8 ) ); } } watchownerdamage() { self endon( "death" ); level endon( "game_ended" ); for (;;) { if ( !isdefined( self.owner ) ) return; self.owner waittill( "damage", var_0, var_1 ); if ( isplayer( var_1 ) && var_1 != self.owner ) { if ( self.attackstate == "attacking" ) continue; if ( distancesquared( self.owner.origin, self.origin ) > self.ownerdamagedradiussq ) continue; if ( distancesquared( self.owner.origin, var_1.origin ) > self.ownerdamagedradiussq ) continue; self.favoriteenemy = var_1; self.forceattack = 1; thread watchfavoriteenemydeath(); } } } watchownerdeath() { self endon( "death" ); level endon( "game_ended" ); for (;;) { if ( !isdefined( self.owner ) ) return; self.owner waittill( "death" ); switch ( level.gametype ) { case "sd": maps\mp\agents\_agent_utility::killdog(); break; case "sr": var_0 = level common_scripts\utility::waittill_any_return( "sr_player_eliminated", "sr_player_respawned" ); if ( isdefined( var_0 ) && var_0 == "sr_player_eliminated" ) maps\mp\agents\_agent_utility::killdog(); break; } } } watchownerteamchange() { self endon( "death" ); level endon( "game_ended" ); for (;;) { if ( !isdefined( self.owner ) ) return; var_0 = self.owner common_scripts\utility::waittill_any_return_no_endon_death( "joined_team", "joined_spectators" ); if ( isdefined( var_0 ) && ( var_0 == "joined_team" || var_0 == "joined_spectators" ) ) maps\mp\agents\_agent_utility::killdog(); } } watchfavoriteenemydeath() { self notify( "watchFavoriteEnemyDeath" ); self endon( "watchFavoriteEnemyDeath" ); self endon( "death" ); self.favoriteenemy common_scripts\utility::waittill_any_timeout( 5.0, "death", "disconnect" ); self.favoriteenemy = undefined; self.forceattack = 0; } ondamage( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9 ) { self.timeoflastdamage = gettime(); if ( isdefined( self.owner ) ) self.damagedownertome = vectornormalize( self.origin - self.owner.origin ); if ( shouldplayhitreaction( var_2, var_5, var_4 ) ) { switch ( self.aistate ) { case "idle": thread maps\mp\mp_dome_ns_alien_idle::ondamage( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9 ); break; case "move": thread maps\mp\mp_dome_ns_alien_move::ondamage( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9 ); break; } } } shouldplayhitreaction( var_0, var_1, var_2 ) { if ( isdefined( var_1 ) && weaponclass( var_1 ) == "sniper" ) return 1; if ( isdefined( var_2 ) && isexplosivedamagemod( var_2 ) && var_0 >= 10 ) return 1; if ( isdefined( var_2 ) && var_2 == "MOD_MELEE" ) return 1; if ( isdefined( var_1 ) && var_1 == "concussion_grenade_mp" ) return 1; return 0; } monitorflash() { self endon( "death" ); for (;;) { self waittill( "flashbang", var_0, var_1, var_2, var_3, var_4, var_5 ); if ( isdefined( var_3 ) && var_3 == self.owner ) continue; switch ( self.aistate ) { case "idle": maps\mp\mp_dome_ns_alien_idle::onflashbanged(); break; case "move": maps\mp\mp_dome_ns_alien_move::onflashbanged(); break; } } } get_closest( var_0, var_1, var_2 ) { var_3 = var_1[0]; var_4 = distance( var_0, var_3.origin ); for ( var_5 = 0; var_5 < var_1.size; var_5++ ) { var_6 = distance( var_0, var_1[var_5].origin ); if ( var_6 >= var_4 ) continue; var_4 = var_6; var_3 = var_1[var_5]; } if ( !isdefined( var_2 ) || var_4 <= var_2 ) return var_3; return undefined; }