490 lines
11 KiB
Plaintext
490 lines
11 KiB
Plaintext
#include common_scripts\utility;
|
|
#include maps\mp\agents\_scriptedAgents;
|
|
|
|
main()
|
|
{
|
|
self endon( "killanimscript" );
|
|
|
|
self.bLockGoalPos = false;
|
|
self ScrAgentSetPhysicsMode( "gravity" );
|
|
|
|
self StartMove();
|
|
self ContinueMovement();
|
|
}
|
|
|
|
end_script()
|
|
{
|
|
self.bLockGoalPos = false;
|
|
self CancelAllBut( undefined );
|
|
self ScrAgentSetAnimScale( 1, 1 );
|
|
}
|
|
|
|
SetupMovement()
|
|
{
|
|
self thread WaitForRunWalkChange();
|
|
self thread WaitForSharpTurn();
|
|
self thread WaitForStop();
|
|
//self thread WaitForStopEarly();
|
|
//self thread HandleMoveLoopFootsteps();
|
|
}
|
|
|
|
ContinueMovement()
|
|
{
|
|
self SetupMovement();
|
|
|
|
self ScrAgentSetAnimMode( "code_move" );
|
|
self ScrAgentSetOrientMode( "face motion" );
|
|
self ScrAgentSetAnimScale( 1, 1 );
|
|
self SetMoveAnim( self.moveMode );
|
|
}
|
|
|
|
SetMoveAnim( moveMode )
|
|
{
|
|
self SetAnimState( moveMode );
|
|
}
|
|
|
|
WaitForRunWalkChange()
|
|
{
|
|
self endon( "dogmove_endwait_runwalk" );
|
|
curMovement = self.moveMode;
|
|
while ( true )
|
|
{
|
|
if ( curMovement != self.moveMode )
|
|
{
|
|
self SetMoveAnim( self.moveMode );
|
|
curMovement = self.moveMode;
|
|
}
|
|
wait( 0.1 );
|
|
}
|
|
}
|
|
|
|
DoSharpTurn( newDir )
|
|
{
|
|
lookaheadAngles = VectorToAngles( newDir );
|
|
angleDiff = AngleClamp180( lookaheadAngles[1] - self.angles[1] );
|
|
angleIndex = GetAngleIndex( angleDiff );
|
|
|
|
if ( angleIndex == 4 ) // 4 means this turn wasn't sharp enough for me to care. (angle ~= 0)
|
|
{
|
|
ContinueMovement();
|
|
return;
|
|
}
|
|
|
|
animState = "sharp_turn";
|
|
|
|
turnAnim = self GetAnimEntry( animState, angleIndex );
|
|
animAngleDelta = GetAngleDelta( turnAnim );
|
|
|
|
self ScrAgentSetAnimMode( "anim deltas" );
|
|
self ScrAgentSetOrientMode( "face angle abs", ( 0, AngleClamp180( lookaheadAngles[1] - animAngleDelta ), 0 ) );
|
|
|
|
self PlayAnimNUntilNotetrack( animState, angleIndex, "sharp_turn" );
|
|
|
|
self ContinueMovement();
|
|
}
|
|
|
|
WaitForSharpTurn()
|
|
{
|
|
self endon( "dogmove_endwait_sharpturn" );
|
|
|
|
self waittill( "path_dir_change", newDir );
|
|
self CancelAllBut( "sharpturn" );
|
|
|
|
self DoSharpTurn( newDir );
|
|
}
|
|
|
|
WaitForStop()
|
|
{
|
|
self endon( "dogmove_endwait_stop" );
|
|
|
|
self waittill( "stop_soon" );
|
|
|
|
if ( IsDefined( self.bArrivalsEnabled ) && !self.bArrivalsEnabled )
|
|
{
|
|
self thread WaitForStop();
|
|
return;
|
|
}
|
|
|
|
stopState = self GetStopAnimState();
|
|
|
|
stopAnim = self GetAnimEntry( stopState.state, stopState.index );
|
|
stopDelta = GetMoveDelta( stopAnim );
|
|
stopAngleDelta = GetAngleDelta( stopAnim );
|
|
|
|
goalPos = self GetPathGoalPos();
|
|
assert( IsDefined( goalPos ) );
|
|
|
|
meToStop = goalPos - self.origin;
|
|
// not enough room left to play the animation. abort. (i'm willing to squish/scale the anim up to 12 units.)
|
|
if ( Length( meToStop ) + 12 < Length( stopDelta ) )
|
|
{
|
|
self thread WaitForStop();
|
|
return;
|
|
}
|
|
|
|
stopData = self GetStopData();
|
|
stopStartPos = self CalcAnimStartPos( stopData.pos, stopData.angles[1], stopDelta, stopAngleDelta );
|
|
stopStartPosDropped = DropPosToGround( stopStartPos );
|
|
|
|
if ( !IsDefined( stopStartPosDropped ) )
|
|
{
|
|
self thread WaitForStop();
|
|
return;
|
|
}
|
|
|
|
if ( !self CanMovePointToPoint( stopData.pos, stopStartPosDropped ) )
|
|
{
|
|
self thread WaitForStop();
|
|
return;
|
|
}
|
|
|
|
self CancelAllBut( "stop" );
|
|
|
|
self thread WaitForPathSetWhileStopping();
|
|
self thread WaitForSharpTurnWhileStopping();
|
|
if ( DistanceSquared( stopStartPos, self.origin ) > 4 )
|
|
{
|
|
self ScrAgentSetWaypoint( stopStartPos );
|
|
self thread WaitForBlockedWhileStopping();
|
|
self waittill( "waypoint_reached" );
|
|
self notify( "dogmove_endwait_blockedwhilestopping" );
|
|
}
|
|
|
|
facingDir = goalPos - self.origin;
|
|
facingAngles = VectorToAngles( facingDir );
|
|
facingYaw = ( 0, facingAngles[1] - stopAngleDelta, 0 );
|
|
|
|
// scale the anim if necessary, to make sure we end up where we wanted to end up.
|
|
scaleFactors = GetAnimScaleFactors( goalPos - self.origin, stopDelta );
|
|
|
|
self ScrAgentSetAnimMode( "anim deltas" );
|
|
self ScrAgentSetOrientMode( "face angle abs", facingYaw, ( 0, facingAngles[1], 0 ) );
|
|
self ScrAgentSetAnimScale( scaleFactors.xy, scaleFactors.z );
|
|
self PlayAnimNUntilNotetrack( stopState.state, stopState.index, "move_stop" );
|
|
|
|
self ScrAgentSetGoalPos( self.origin ); // whether i got where i was going, get where i got.
|
|
}
|
|
|
|
WaitForPathSetWhileStopping()
|
|
{
|
|
self endon( "killanimscript" );
|
|
self endon( "dogmove_endwait_pathsetwhilestopping" );
|
|
|
|
oldGoalPos = self ScrAgentGetGoalPos();
|
|
|
|
self waittill( "path_set" );
|
|
|
|
newGoalPos = self ScrAgentGetGoalPos();
|
|
|
|
if ( DistanceSquared( oldGoalPos, newGoalPos ) < 1 )
|
|
{
|
|
self thread WaitForPathSetWhileStopping();
|
|
return;
|
|
}
|
|
|
|
self notify( "dogmove_endwait_stop" );
|
|
self notify( "dogmove_endwait_sharpturnwhilestopping" );
|
|
|
|
self ContinueMovement();
|
|
}
|
|
|
|
WaitForSharpTurnWhileStopping()
|
|
{
|
|
self endon( "killanimscript" );
|
|
self endon( "dogmove_endwait_sharpturnwhilestopping" );
|
|
|
|
self waittill( "path_dir_change", newDir );
|
|
|
|
self notify( "dogmove_endwait_pathsetwhilestopping" );
|
|
self notify( "dogmove_endwait_stop" );
|
|
|
|
self DoSharpTurn( newDir );
|
|
}
|
|
|
|
WaitForBlockedWhileStopping()
|
|
{
|
|
self endon( "killanimscript" );
|
|
self endon( "dogmove_endwait_blockedwhilestopping" );
|
|
|
|
self waittill( "path_blocked" );
|
|
self notify( "dogmove_endwait_stop" );
|
|
self ScrAgentSetWaypoint( undefined );
|
|
}
|
|
|
|
WaitForStopEarly()
|
|
{
|
|
self endon( "killanimscript" );
|
|
self endon( "dogmove_endwait_stopearly" );
|
|
|
|
stopAnim = self GetAnimEntry( "move_stop_4", 0 );
|
|
stopAnimTranslation = GetMoveDelta( stopAnim );
|
|
stoppingDistance = Length( stopAnimTranslation );
|
|
offset = self.preferredOffsetFromOwner + stoppingDistance;
|
|
offsetSq = offset * offset;
|
|
|
|
if ( DistanceSquared( self.origin, self.owner.origin ) <= offsetSq )
|
|
return;
|
|
|
|
while ( true )
|
|
{
|
|
if ( !IsDefined( self.owner ) )
|
|
break;
|
|
|
|
if ( DistanceSquared( self.origin, self.owner.origin ) < offsetSq )
|
|
{
|
|
stopPos = self LocalToWorldCoords( stopAnimTranslation );
|
|
self ScrAgentSetGoalPos( stopPos );
|
|
break;
|
|
}
|
|
|
|
wait( 0.1 );
|
|
}
|
|
}
|
|
|
|
CancelAllBut( doNotCancel )
|
|
{
|
|
cleanups = [ "runwalk", "sharpturn", "stop", "pathsetwhilestopping", "blockedwhilestopping", "sharpturnwhilestopping", "stopearly" ];
|
|
|
|
bCheckDoNotCancel = IsDefined( doNotCancel );
|
|
|
|
foreach ( cleanup in cleanups )
|
|
{
|
|
if ( bCheckDoNotCancel && cleanup == doNotCancel )
|
|
continue;
|
|
self notify( "dogmove_endwait_" + cleanup );
|
|
}
|
|
}
|
|
|
|
StartMove()
|
|
{
|
|
negStartNode = self GetNegotiationStartNode();
|
|
if ( IsDefined( negStartNode ) )
|
|
goalPos = negStartNode.origin;
|
|
else
|
|
goalPos = self GetPathGoalPos();
|
|
|
|
// don't play start if i have no room for the start.
|
|
if ( DistanceSquared( goalPos, self.origin ) < 100 * 100 )
|
|
return;
|
|
|
|
lookaheadDir = self GetLookaheadDir();
|
|
lookaheadAngles = VectorToAngles( lookaheadDir );
|
|
|
|
myVelocity = self GetVelocity();
|
|
if ( Length2DSquared( myVelocity ) > 16 )
|
|
{
|
|
myVelocity = VectorNormalize( myVelocity );
|
|
if ( VectorDot( myVelocity, lookaheadDir ) > 0.707 )
|
|
return; // don't need a start if i'm already moving in the direction i want to move.
|
|
}
|
|
|
|
angleDiff = AngleClamp180( lookaheadAngles[1] - self.angles[1] );
|
|
angleIndex = GetAngleIndex( angleDiff );
|
|
|
|
startAnim = self GetAnimEntry( "move_start", angleIndex );
|
|
startAnimTranslation = GetMoveDelta( startAnim );
|
|
|
|
endPos = RotateVector( startAnimTranslation, self.angles ) + self.origin;
|
|
if ( !self CanMovePointToPoint( self.origin, endPos ) )
|
|
return;
|
|
|
|
startAnimAngles = GetAngleDelta3D( startAnim );
|
|
|
|
self ScrAgentSetAnimMode( "anim deltas" );
|
|
if ( 3 <= angleIndex && angleIndex <= 5 )
|
|
self ScrAgentSetOrientMode( "face angle abs", ( 0, AngleClamp180( lookaheadAngles[1] - startAnimAngles[1] ), 0 ) );
|
|
else
|
|
self ScrAgentSetOrientMode( "face angle abs", self.angles );
|
|
|
|
self.bLockGoalPos = true;
|
|
|
|
self PlayAnimNUntilNotetrack( "move_start", angleIndex, "move_start" );
|
|
|
|
self.bLockGoalPos = false;
|
|
}
|
|
|
|
GetStopData()
|
|
{
|
|
stopData = SpawnStruct();
|
|
|
|
if ( IsDefined( self.node ) )
|
|
{
|
|
stopData.pos = self.node.origin;
|
|
stopData.angles = self.node.angles;
|
|
}
|
|
else
|
|
{
|
|
pathGoalPos = self GetPathGoalPos();
|
|
assert( IsDefined( pathGoalPos ) );
|
|
stopData.pos = pathGoalPos;
|
|
//stopData.angles = self.angles;
|
|
stopData.angles = VectorToAngles( self GetLookaheadDir() );
|
|
}
|
|
|
|
return stopData;
|
|
}
|
|
|
|
GetStopAnimState( angle )
|
|
{
|
|
if ( IsDefined( self.node ) )
|
|
{
|
|
angleDiff = self.node.angles[1] - self.angles[1];
|
|
angleIndex = GetAngleIndex( angleDiff );
|
|
}
|
|
else
|
|
{
|
|
angleIndex = 4;
|
|
}
|
|
|
|
result = SpawnStruct();
|
|
result.state = "move_stop";
|
|
result.index = angleIndex;
|
|
|
|
return result;
|
|
}
|
|
|
|
CalcAnimStartPos( stopPos, stopAngle, animDelta, animAngleDelta )
|
|
{
|
|
dAngle = stopAngle - animAngleDelta;
|
|
angles = ( 0, dAngle, 0 );
|
|
vForward = AnglesToForward( angles );
|
|
vRight = AnglesToRight( angles );
|
|
|
|
forward = vForward * animDelta[0];
|
|
right = vRight * animDelta[1];
|
|
|
|
return stopPos - forward + right;
|
|
}
|
|
|
|
Dog_AddLean()
|
|
{
|
|
leanFrac = Clamp( self.leanAmount / 25.0, -1, 1 );
|
|
if ( leanFrac > 0 )
|
|
{
|
|
// set lean left( leanFrac );
|
|
// set lean right( 0 );
|
|
}
|
|
else
|
|
{
|
|
// set lean left( 0 );
|
|
// set lean right( 0 - leanFrac );
|
|
}
|
|
}
|
|
|
|
|
|
HandleFootstepNotetracks( note, animState, animIndex, animTime )
|
|
{
|
|
if ( true )
|
|
return false;
|
|
|
|
switch ( note )
|
|
{
|
|
case "footstep_front_left_small":
|
|
case "footstep_front_right_small":
|
|
case "footstep_back_left_small":
|
|
case "footstep_back_right_small":
|
|
case "footstep_front_left_large":
|
|
case "footstep_front_right_large":
|
|
case "footstep_back_left_large":
|
|
case "footstep_back_right_large":
|
|
{
|
|
surfaceType = undefined;
|
|
if ( IsDefined( self.surfaceType ) )
|
|
{
|
|
surfaceType = self.surfaceType;
|
|
self.lastSurfaceType = surfaceType;
|
|
}
|
|
else if ( IsDefined( self.lastSurfaceType ) )
|
|
{
|
|
surfaceType = self.lastSurfaceType;
|
|
}
|
|
else
|
|
{
|
|
surfaceType = "dirt";
|
|
}
|
|
|
|
if ( surfaceType != "dirt" && surfaceType != "concrete" && surfaceType != "wood" && surfaceType != "metal" )
|
|
surfaceType = "dirt";
|
|
|
|
if ( surfaceType == "concrete" ) // code == concrete, sound == cement.
|
|
surfaceType = "cement";
|
|
|
|
//moveType = self.sound_animMoveType;
|
|
//if ( !IsDefined( moveType ) )
|
|
// moveType = "run";
|
|
if ( self.aiState == "traverse" )
|
|
moveType = "land";
|
|
else if ( self.moveMode == "sprint" )
|
|
moveType = "sprint";
|
|
else if ( self.moveMode == "fastwalk" )
|
|
moveType = "walk";
|
|
else
|
|
moveType = "run";
|
|
|
|
self PlaySoundOnMovingEnt( "dogstep_" + moveType + "_" + surfaceType );
|
|
|
|
if ( IsSubStr( note, "front_left" ) )
|
|
{
|
|
soundAlias1 = "anml_dog_mvmt_accent";
|
|
soundAlias2 = "anml_dog_mvmt_vest";
|
|
|
|
if ( moveType == "walk" )
|
|
suffix = "_npc";
|
|
else
|
|
suffix = "_run_npc";
|
|
|
|
self PlaySoundOnMovingEnt( soundAlias1 + suffix );
|
|
self PlaySoundOnMovingEnt( soundAlias2 + suffix );
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
DoHitReaction( hitAngle )
|
|
{
|
|
self CancelAllBut( undefined );
|
|
|
|
self.bLockGoalPos = true;
|
|
self.stateLocked = 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 ScrAgentSetAnimMode( "anim deltas" );
|
|
self ScrAgentSetOrientMode( "face angle abs", self.angles );
|
|
|
|
self PlayAnimNUntilNotetrack( "run_pain", animIndex, "run_pain" );
|
|
|
|
self.bLockGoalPos = false;
|
|
self.stateLocked = false;
|
|
|
|
self ContinueMovement();
|
|
}
|
|
|
|
OnDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, timeOffset )
|
|
{
|
|
if ( self.stateLocked )
|
|
return;
|
|
|
|
hitDirToAngles = VectorToAngles( vDir );
|
|
hitAngle = hitDirToAngles[1] - 180;
|
|
|
|
self DoHitReaction( hitAngle );
|
|
}
|
|
|
|
OnFlashbanged( origin, percent_distance, percent_angle, attacker, teamName, extraDuration )
|
|
{
|
|
if ( self.stateLocked )
|
|
return;
|
|
|
|
DoHitReaction( self.angles[1] + 180 );
|
|
} |