IW4-Dump-Files/animscripts/reactions.gsc

408 lines
10 KiB
Plaintext

#include animscripts\SetPoseMovement;
#include animscripts\Utility;
#include common_scripts\Utility;
#using_animtree( "generic_human" );
main()
{
self endon( "killanimscript" );
animscripts\utility::initialize( "reactions" );
self newEnemySurprisedReaction();
}
initReactionAnims()
{
anim.runningReactToBullets = [];
anim.runningReactToBullets[ anim.runningReactToBullets.size ] = %run_react_duck;
anim.runningReactToBullets[ anim.runningReactToBullets.size ] = %run_react_flinch;
anim.runningReactToBullets[ anim.runningReactToBullets.size ] = %run_react_stumble;
anim.lastRunningReactAnim = 0;
anim.coverReactions = [];
anim.coverReactions[ "cover_stand" ] = array( %stand_cover_reaction_A, %stand_cover_reaction_B );
anim.coverReactions[ "cover_crouch" ] = array( %crouch_cover_reaction_A, %crouch_cover_reaction_B );
anim.coverReactions[ "cover_left" ] = array( %CornerStndL_react_A );
anim.coverReactions[ "cover_right" ] = array( %CornerStndR_react_A );
}
///////////////////////////////////////////////////////////////////////////
//
///////////////////////////////////////////////////////////////////////////
reactionsCheckLoop()
{
self thread bulletWhizbyCheckLoop();
}
///////////////////////////////////////////////////////////////////////////
// death reactions
///////////////////////////////////////////////////////////////////////////
/* disabled for now since the animations aren't in common csv
MoveDeathReaction()
{
// Decide what pose to use
desiredPose = self animscripts\utility::choosePose();
if ( desiredPose == "stand" )
{
deathAnim = getDeathReactionAnim();
DoDeathReactionAnim( deathAnim );
}
}
ExposedCombatDeathReaction()
{
// Decide what pose to use
desiredPose = self animscripts\utility::choosePose();
if ( desiredPose == "stand" )
{
deathAnim = getDeathReactionAnim();
DoDeathReactionAnim( deathAnim );
}
}
DoDeathReactionAnim( deathAnim )
{
self endon( "movemode" );
rate = self.moveplaybackrate;
self setFlaggedAnimKnobAll( "deathanim", deathAnim, %body, 1, 1, rate, true );
// self animscripts\run::SetMoveNonForwardAnims( %walk_backward, %walk_left, %walk_right );
// self thread animscripts\run::SetCombatStandMoveAnimWeights( "walk" );
self animscripts\shared::DoNoteTracks( "deathanim" );
self.deathTeamate = false;
}
getDeathReactionAnim()
{
if ( self.deathTeamateReaction == "back" )
return %run_reaction_180;
else if ( self.deathTeamateReaction == "left" )
return %run_reaction_L_quick;
else if ( self.deathTeamateReaction == "right" )
return %run_reaction_R_quick;
}
deathCheck()
{
self endon( "killanimscript" );
self.deathTeamateReaction = "none";
self.deathTeamate = false;
minDeathDistance = 100;
maxDeathDistance = 500;
minGoalDistance = 200;
maxTurnAngle = 135;
minTurnAngle = 10;
self AddAIEventListener( "death" );
for ( ;; )
{
self waittill( "ai_event", event, originator, position );
if ( event != "death" )
continue;
deathDirection = position - self.origin;
deathDistance = Length( deathDirection );
if ( deathDistance >= minDeathDistance && deathDistance <= maxDeathDistance )
{
goalDirection = self.goalpos - self.origin;
goalDistance = Length( goalDirection );
if ( goalDistance >= minGoalDistance )
{
goalAngles = VectorToAngles( goalDirection );
deltaAngles = Abs( self.angles[1] - goalAngles[1] );
if ( deltaAngles > minTurnAngle )
{
if ( deltaAngles > maxTurnAngle )
self.deathTeamateReaction = "back";
else if ( self.angles[1] > goalAngles[1] )
self.deathTeamateReaction = "left";
else
self.deathTeamateReaction = "right";
self.deathTeamate = true;
}
}
}
}
}
*/
canReactAgain()
{
return ( !isdefined( self.lastReactTime ) || gettime() - self.lastReactTime > 2000 );
}
///////////////////////////////////////////////////////////////////////////
// bullet whizby reaction
///////////////////////////////////////////////////////////////////////////
bulletWhizbyReaction()
{
self endon( "killanimscript" );
self.lastReactTime = gettime();
self.a.movement = "stop";
enemyNear = ( isDefined( self.whizbyEnemy ) && distanceSquared( self.origin, self.whizbyEnemy.origin ) < 400 * 400 );
self animmode( "gravity" );
self orientmode( "face current" );
// react and go to prone
if ( enemyNear || cointoss() )
{
self clearanim( %root, 0.1 );
reactAnim = [];
reactAnim[ 0 ] = %exposed_idle_reactA;
reactAnim[ 1 ] = %exposed_idle_reactB;
reactAnim[ 2 ] = %exposed_idle_twitch;
reactAnim[ 3 ] = %exposed_idle_twitch_v4;
reaction = reactAnim[ randomint( reactAnim.size ) ];
if ( enemyNear )
waitTime = 1 + randomfloat( 0.5 );
else
waitTime = 0.2 + randomfloat( 0.5 );
self setFlaggedAnimKnobRestart( "reactanim", reaction, 1, 0.1, 1 );
self animscripts\shared::DoNoteTracksForTime( waitTime, "reactanim" );
self clearanim( %root, 0.1 );
if ( !enemyNear && self.stairsState == "none" )
{
rate = 1 + randomfloat( 0.2 );
diveAnim = randomAnimOfTwo( %exposed_dive_grenade_B, %exposed_dive_grenade_F );
self setFlaggedAnimKnobRestart( "dive", diveAnim, 1, 0.1, rate );
self animscripts\shared::DoNoteTracks( "dive" );
}
}
else // crouch then handsignal or turn
{
wait randomfloat( 0.2 );
rate = 1.2 + randomfloat( 0.3 );
if ( self.a.pose == "stand" )
{
self clearanim( %root, 0.1 );
self setFlaggedAnimKnobRestart( "crouch", %exposed_stand_2_crouch, 1, 0.1, rate );
self animscripts\shared::DoNoteTracks( "crouch" );
}
forward = anglesToForward( self.angles );
if ( isDefined( self.whizbyEnemy ) )
dirToEnemy = vectorNormalize( self.whizbyEnemy.origin - self.origin );
else
dirToEnemy = forward;
if ( vectordot( dirToEnemy, forward ) > 0 )
{
twitchAnim = randomAnimOfTwo( %exposed_crouch_idle_twitch_v2, %exposed_crouch_idle_twitch_v3 );
self clearanim( %root, 0.1 );
self setFlaggedAnimKnobRestart( "twitch", twitchAnim, 1, 0.1, 1 );
self animscripts\shared::DoNoteTracks( "twitch" );
//if ( cointoss() )
// self handsignal( "go" );
}
else
{
turnAnim = randomAnimOfTwo( %exposed_crouch_turn_180_left, %exposed_crouch_turn_180_right );
self clearanim( %root, 0.1 );
self setFlaggedAnimKnobRestart( "turn", turnAnim, 1, 0.1, 1 );
self animscripts\shared::DoNoteTracks( "turn" );
}
}
self clearanim( %root, 0.1 );
self.whizbyEnemy = undefined;
self animmode( "normal" );
self orientmode( "face default" );
}
bulletWhizbyCheckLoop()
{
self endon( "killanimscript" );
if ( isdefined( self.disableBulletWhizbyReaction ) )
return;
while ( 1 )
{
self waittill( "bulletwhizby", shooter );
if ( !isdefined( shooter.team ) || self.team == shooter.team )
continue;
if ( isdefined( self.coverNode ) || isdefined( self.ambushNode ) )
continue;
if ( self.a.pose != "stand" )
continue;
if ( !canReactAgain() )
continue;
self.whizbyEnemy = shooter;
self animcustom( ::bulletWhizbyReaction );
}
}
///////////////////////////////////////////////////////////////////////////
// surprised by new enemy reaction
///////////////////////////////////////////////////////////////////////////
clearLookAtThread()
{
self endon( "killanimscript" );
wait 0.3;
self setLookAtEntity();
}
getNewEnemyReactionAnim()
{
reactAnim = undefined;
if ( self nearClaimNodeAndAngle() && isdefined( anim.coverReactions[ self.prevScript ] ) )
{
nodeForward = anglesToForward( self.node.angles );
dirToReactionTarget = vectorNormalize( self.reactionTargetPos - self.origin );
if ( vectorDot( nodeForward, dirToReactionTarget ) < -0.5 )
{
self orientmode( "face current" );
index = randomint( anim.coverReactions[ self.prevScript ].size );
reactAnim = anim.coverReactions[ self.prevScript ][ index ];
}
}
if ( !isdefined( reactAnim ) )
{
reactAnimArray = [];
reactAnimArray[ 0 ] = %exposed_backpedal;
reactAnimArray[ 1 ] = %exposed_idle_reactB;
if ( isdefined( self.enemy ) && distanceSquared( self.enemy.origin, self.reactionTargetPos ) < 256 * 256 )
self orientmode( "face enemy" );
else
self orientmode( "face point", self.reactionTargetPos );
if ( self.a.pose == "crouch" )
{
dirToReactionTarget = vectorNormalize( self.reactionTargetPos - self.origin );
forward = anglesToForward( self.angles );
if ( vectorDot( forward, dirToReactionTarget ) < -0.5 )
{
self orientmode( "face current" );
reactAnimArray[ 0 ] = %crouch_cover_reaction_A;
reactAnimArray[ 1 ] = %crouch_cover_reaction_B;
}
}
reactAnim = reactAnimArray[ randomint( reactAnimArray.size ) ];
}
return reactAnim;
}
stealthNewEnemyReactAnim()
{
self clearanim( %root, 0.2 );
if ( randomint( 4 ) < 3 )
{
self orientmode( "face enemy" );
self setFlaggedAnimKnobRestart( "reactanim", %exposed_idle_reactB, 1, 0.2, 1 );
time = getAnimLength( %exposed_idle_reactB );
self animscripts\shared::DoNoteTracksForTime( time * 0.8, "reactanim" );
self orientmode( "face current" );
}
else
{
self orientmode( "face enemy" );
self setFlaggedAnimKnobRestart( "reactanim", %exposed_backpedal, 1, 0.2, 1 );
time = getAnimLength( %exposed_backpedal );
self animscripts\shared::DoNoteTracksForTime( time * 0.8, "reactanim" );
self orientmode( "face current" );
self clearanim( %root, 0.2 );
self setFlaggedAnimKnobRestart( "reactanim", %exposed_backpedal_v2, 1, 0.2, 1 );
self animscripts\shared::DoNoteTracks( "reactanim" );
}
}
newEnemyReactionAnim()
{
self endon( "death" );
self endon( "endNewEnemyReactionAnim" );
self.lastReactTime = gettime();
self.a.movement = "stop";
if ( isdefined( self._stealth ) && self.alertLevel != "combat" )
{
stealthNewEnemyReactAnim();
}
else
{
reactAnim = self getNewEnemyReactionAnim();
self clearanim( %root, 0.2 );
self setFlaggedAnimKnobRestart( "reactanim", reactAnim, 1, 0.2, 1 );
self animscripts\shared::DoNoteTracks( "reactanim" );
}
self notify( "newEnemyReactionDone" );
}
newEnemySurprisedReaction()
{
self endon( "death" );
if ( isdefined( self.disableReactionAnims ) )
return;
if ( !canReactAgain() )
return;
if ( self.a.pose == "prone" || isdefined( self.a.onback ) )
return;
self animmode( "gravity" );
if ( isdefined( self.enemy ) )
newEnemyReactionAnim();
}