iw6-scripts-dev/maps/mp/mp_dome_ns_alien_idle.gsc
2024-12-11 11:28:08 +01:00

305 lines
6.7 KiB
Plaintext

#include maps\mp\agents\_scriptedAgents;
main()
{
//IPrintLnBold ("Alien entering IDLE state");
self.animSubstate = "none";
self SetTimeOfNextSound();
self.timeOfNextSound += 2000;
self.bIdleHitReaction = false;
self ScrAgentSetGoalPos( self.origin );
self ScrAgentSetOrientMode( "face angle abs", self.angles );
self ScrAgentSetAnimMode( "anim deltas" );
self ScrAgentSetPhysicsMode( "gravity" );
self UpdateState();
}
end_script()
{
if ( IsDefined( self.prevTurnRate ) )
{
self ScrAgentSetMaxTurnSpeed( self.prevTurnRate );
self.prevTurnRate = undefined;
}
}
UpdateState()
{
self endon( "killanimscript" );
self endon( "cancelidleloop" );
while ( true )
{
prevState = self.animSubstate;
nextState = self DetermineState();
if ( nextState != self.animSubstate )
self EnterState( nextState );
self UpdateAngle();
switch ( self.animSubstate )
{
case "idle_combat":
wait( 0.2 );
break;
case "idle_noncombat":
if ( prevState == "none" )
{
if ( self.moveMode == "run" || self.moveMode == "sprint" )
self PlaySoundOnMovingEnt( "alien_minion_idle" );
else
self PlaySoundOnMovingEnt( "alien_minion_idle" );
}
else
{
if ( GetTime() > self.timeOfNextSound )
{
if ( RandomInt(10) < 4 )
self PlaySoundOnMovingEnt( "alien_minion_idle" );
else
self PlaySoundOnMovingEnt( "alien_minion_idle" );
self SetTimeOfNextSound();
}
}
wait ( 0.5 );
break;
default:
assertmsg( "unknown dog stop state " + self.animSubstate );
wait( 1 );
break;
}
}
}
DetermineState()
{
if ( ShouldAttackIdle() )
return "idle_combat";
else
return "idle_noncombat";
}
EnterState( state )
{
self ExitState( self.animSubstate );
self.animSubstate = state;
PlayIdleAnim();
}
ExitState( prevState )
{
if ( IsDefined( self.prevTurnRate ) )
{
self ScrAgentSetMaxTurnSpeed( self.prevTurnRate );
self.prevTurnRate = undefined;
}
}
PlayIdleAnim()
{
if ( self.animSubstate == "idle_combat" )
self SetAnimState( "attack_idle" );
else
self SetAnimState( "casual_idle" );
}
UpdateAngle()
{
faceTarget = undefined;
if ( IsDefined( self.enemy ) && DistanceSquared( self.enemy.origin, self.origin ) < 1024 * 1024 )
faceTarget = self.enemy;
else if ( IsDefined( self.owner ) )
faceTarget = self.owner;
if ( IsDefined( faceTarget ) )
{
meToTarget = faceTarget.origin - self.origin;
meToTargetAngles = VectorToAngles( meToTarget );
if ( abs( AngleClamp180( meToTargetAngles[1] - self.angles[1] ) ) > 1 )
self TurnToAngle( meToTargetAngles[1] );
}
}
ShouldAttackIdle()
{
return isdefined( self.enemy )
&& maps\mp\_utility::IsReallyAlive( self.enemy )
&& distanceSquared( self.origin, self.enemy.origin ) < 1000000;
//&& self SeeRecently( self.enemy, 5 );
}
GetTurnAnimState( angleDiff )
{
if ( self ShouldAttackIdle() )
{
if ( angleDiff < -135 || angleDiff > 135 )
return "attack_turn_180";
else if ( angleDiff < 0 )
return "attack_turn_right_90";
else
return "attack_turn_left_90";
}
else
{
if ( angleDiff < -135 || angleDiff > 135 )
return "casual_turn_180";
else if ( angleDiff < 0 )
return "casual_turn_right_90";
else
return "casual_turn_left_90";
}
}
TurnToAngle( desiredAngle )
{
currentAngle = self.angles[1];
angleDiff = AngleClamp180( desiredAngle - currentAngle );
if ( -0.5 < angleDiff && angleDiff < 0.5 )
return;
if ( -10 < angleDiff && angleDiff < 10 )
{
RotateToAngle( desiredAngle, 2 );
return;
}
animState = GetTurnAnimState( angleDiff );
turnAnim = self GetAnimEntry( animState, 0 );
animLength = GetAnimLength( turnAnim );
animAngleDelta = GetAngleDelta3D( turnAnim );
self ScrAgentSetAnimMode( "anim angle delta" );
if ( AnimHasNotetrack( turnAnim, "turn_begin" ) && AnimHasNotetrack( turnAnim, "turn_end" ) )
{
self PlayAnimNUntilNotetrack( animState, 0, "turn_in_place" );
beginTimes = GetNotetrackTimes( turnAnim, "turn_begin" );
endTimes = GetNotetrackTimes( turnAnim, "turn_end" );
turnTime = (endTimes[0] - beginTimes[0]) * animLength;
turnAdjust = AngleClamp180( angleDiff - animAngleDelta[1] );
turnSpeed = abs(turnAdjust) / turnTime / 20;
turnSpeed = turnSpeed * 3.14159 / 180; // radians per frame.
angles = ( 0, AngleClamp180( self.angles[1] + turnAdjust ), 0 );
self.prevTurnRate = self ScrAgentGetMaxTurnSpeed();
self ScrAgentSetMaxTurnSpeed( turnSpeed );
self ScrAgentSetOrientMode( "face angle abs", angles );
self WaitUntilNotetrack( "turn_in_place", "turn_end" );
self ScrAgentSetMaxTurnSpeed( self.prevTurnRate );
self.prevTurnRate = undefined;
self WaitUntilNotetrack( "turn_in_place", "end" );
}
else
{
self.prevTurnRate = self ScrAgentGetMaxTurnSpeed();
turnSpeed = abs( AngleClamp180(angleDiff-animAngleDelta[1]) ) / animLength / 20;
turnSpeed = turnSpeed * 3.14159 / 180;
self ScrAgentSetMaxTurnSpeed( turnSpeed ); // radians per frame.
angles = ( 0, AngleClamp180( desiredAngle - animAngleDelta[1] ), 0 );
self ScrAgentSetOrientMode( "face angle abs", angles );
self PlayAnimNUntilNotetrack( animState, 0, "turn_in_place" );
self ScrAgentSetMaxTurnSpeed( self.prevTurnRate );
self.prevTurnRate = undefined;
}
self ScrAgentSetAnimMode( "anim deltas" );
self PlayIdleAnim();
}
RotateToAngle( desiredAngle, tolerance )
{
if ( abs( AngleClamp180( desiredAngle - self.angles[1] ) ) <= tolerance )
return;
angles = ( 0, desiredAngle, 0 );
self ScrAgentSetOrientMode( "face angle abs", angles );
while ( AngleClamp180( desiredAngle - self.angles[1] ) > tolerance )
wait ( 0.1 );
}
SetTimeOfNextSound()
{
self.timeOfNextSound = GetTime() + 8000 + RandomInt( 5000 );
}
DoHitReaction( hitAngle )
{
self.bLockGoalPos = true;
self.stateLocked = true;
self.bIdleHitReaction = true;
// hitAngle is angle from me to damage
angleDiff = AngleClamp180( hitAngle - self.angles[1] );
if ( angleDiff > 0 )
animIndex = 1; // left
else
animIndex = 0; // right
self notify( "cancelidleloop" );
self ScrAgentSetAnimMode( "anim deltas" );
self ScrAgentSetOrientMode( "face angle abs", self.angles );
self PlayAnimNUntilNotetrack( "stand_pain", animIndex, "stand_pain" );
self.bLockGoalPos = false;
self.stateLocked = false;
self.bIdleHitReaction = false;
self ScrAgentSetOrientMode( "face angle abs", self.angles );
self.animSubstate = "none";
self thread UpdateState();
}
OnDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, timeOffset )
{
if ( self.bIdleHitReaction )
return;
hitDirToAngles = VectorToAngles( vDir );
hitAngle = hitDirToAngles[1] - 180;
self DoHitReaction( hitAngle );
}
OnFlashbanged( origin, percent_distance, percent_angle, attacker, teamName, extraDuration )
{
if ( self.bIdleHitReaction )
return;
DoHitReaction( self.angles[1] + 180 );
}