iw6-scripts/maps/mp/mp_dome_ns_alien_think.gsc
2024-02-13 13:20:49 +01:00

840 lines
21 KiB
Plaintext

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