init
This commit is contained in:
303
raw/maps/mp/agents/dog/_dog_idle.gsc
Normal file
303
raw/maps/mp/agents/dog/_dog_idle.gsc
Normal file
@ -0,0 +1,303 @@
|
||||
#include maps\mp\agents\_scriptedAgents;
|
||||
|
||||
main()
|
||||
{
|
||||
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( "anml_dog_pants_mp_fast" );
|
||||
//else
|
||||
//self PlaySoundOnMovingEnt( "anml_dog_pants_mp_med" );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( GetTime() > self.timeOfNextSound )
|
||||
{
|
||||
//if ( RandomInt(10) < 4 )
|
||||
//self PlaySoundOnMovingEnt( "anml_doberman_bark" );
|
||||
//else
|
||||
//self PlaySoundOnMovingEnt( "anml_dog_pants_mp_med" );
|
||||
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 ) && DistanceSquared( self.owner.origin, self.origin ) > 24 * 24 )
|
||||
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 );
|
||||
}
|
350
raw/maps/mp/agents/dog/_dog_melee.gsc
Normal file
350
raw/maps/mp/agents/dog/_dog_melee.gsc
Normal file
@ -0,0 +1,350 @@
|
||||
#include maps\mp\agents\_scriptedAgents;
|
||||
#include maps\mp\_utility;
|
||||
|
||||
main()
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "killanimscript" );
|
||||
|
||||
assert( IsDefined( self.curMeleeTarget ) );
|
||||
|
||||
self.curMeleeTarget endon( "disconnect" );
|
||||
|
||||
// get desired end pos.
|
||||
meToTarget = self.curMeleeTarget.origin - self.origin;
|
||||
distMeToTarget = Length( meToTarget );
|
||||
|
||||
bTestCanMove = true;
|
||||
if ( distMeToTarget < self.attackOffset )
|
||||
{
|
||||
attackPos = self.origin;
|
||||
bTestCanMove = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
meToTarget = meToTarget / distMeToTarget;
|
||||
attackPos = self.curMeleeTarget.origin - meToTarget * self.attackOffset;
|
||||
}
|
||||
|
||||
bLerp = false;
|
||||
|
||||
startPos = self.origin + (0,0,30);
|
||||
endPos = self.curMeleeTarget.origin + (0,0,30);
|
||||
hitPos = PhysicsTrace( startPos, endPos );
|
||||
if ( DistanceSquared( hitPos, endPos ) > 1 )
|
||||
{
|
||||
self MeleeFailed();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( bTestCanMove )
|
||||
bCanMoveToAttackPos = self CanMovePointToPoint( self.origin, attackPos );
|
||||
else
|
||||
bCanMoveToAttackPos = true;
|
||||
|
||||
animEntry = undefined;
|
||||
if ( !bCanMoveToAttackPos )
|
||||
{
|
||||
bShouldDoExtendedKill = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
animEntry = self ShouldDoExtendedKill( self.curMeleeTarget );
|
||||
bShouldDoExtendedKill = IsDefined( animEntry );
|
||||
}
|
||||
|
||||
self.bLockGoalPos = true;
|
||||
|
||||
if ( bShouldDoExtendedKill )
|
||||
{
|
||||
assert( IsDefined( animEntry ) );
|
||||
self DoExtendedKill( animEntry );
|
||||
}
|
||||
else
|
||||
{
|
||||
self DoStandardKill( attackPos, bCanMoveToAttackPos );
|
||||
}
|
||||
}
|
||||
|
||||
end_script()
|
||||
{
|
||||
self ScrAgentSetAnimScale( 1, 1 );
|
||||
self.bLockGoalPos = false;
|
||||
}
|
||||
|
||||
GetMeleeAnimState()
|
||||
{
|
||||
return "attack_run_and_jump";
|
||||
}
|
||||
|
||||
// returns kill direction, if any.
|
||||
ShouldDoExtendedKill( victim )
|
||||
{
|
||||
if( !self.enableExtendedKill )
|
||||
return undefined;
|
||||
|
||||
cMaxHeightDiff = 4;
|
||||
|
||||
if ( !IsGameParticipant( victim ) ) // humans only.
|
||||
return undefined;
|
||||
if ( self IsProtectedByRiotshield( victim ) )
|
||||
return undefined;
|
||||
if ( victim IsJuggernaut() )
|
||||
return undefined;
|
||||
|
||||
victimToMe = self.origin - victim.origin;
|
||||
if ( abs( victimToMe[2] ) > cMaxHeightDiff )
|
||||
return undefined;
|
||||
|
||||
victimToMe2D = VectorNormalize( (victimToMe[0], victimToMe[1], 0) );
|
||||
victimFacing = AnglesToForward( victim.angles );
|
||||
angleToMe = VectorDot( victimFacing, victimToMe2D );
|
||||
|
||||
if ( angleToMe > 0.707 )
|
||||
{
|
||||
animEntry = 0; // front
|
||||
snappedVictimToMe = RotateVector( ( 1, 0, 0 ), victim.angles );
|
||||
}
|
||||
else if ( angleToMe < -0.707 )
|
||||
{
|
||||
animEntry = 1; // back
|
||||
snappedVictimToMe = RotateVector( (-1, 0, 0), victim.angles );
|
||||
}
|
||||
else
|
||||
{
|
||||
cross = maps\mp\agents\dog\_dog_think::cross2D( victimToMe, victimFacing );
|
||||
if ( cross > 0 )
|
||||
{
|
||||
animEntry = 3; // right
|
||||
snappedVictimToMe = RotateVector( (0, -1, 0), victim.angles );
|
||||
}
|
||||
else
|
||||
{
|
||||
animEntry = 2; // left
|
||||
snappedVictimToMe = RotateVector( (0, 1, 0), victim.angles );
|
||||
}
|
||||
}
|
||||
|
||||
if ( animEntry == 1 )
|
||||
cClearanceRequired = 128;
|
||||
else
|
||||
cClearanceRequired = 96;
|
||||
landPos = victim.origin - cClearanceRequired * snappedVictimToMe;
|
||||
|
||||
landPosDropped = self DropPosToGround( landPos );
|
||||
if ( !IsDefined( landPosDropped ) )
|
||||
return undefined;
|
||||
|
||||
if ( abs( landPosDropped[2] - landPos[2] ) > cMaxHeightDiff )
|
||||
return undefined;
|
||||
|
||||
if ( !self AIPhysicsTracePassed( victim.origin + (0,0,4), landPosDropped + (0,0,4), self.radius, self.height ) )
|
||||
return undefined;
|
||||
|
||||
return animEntry;
|
||||
}
|
||||
|
||||
DoExtendedKill( animEntry )
|
||||
{
|
||||
meleeAnimState = "attack_extended";
|
||||
|
||||
self DoMeleeDamage( self.curMeleeTarget, self.curMeleeTarget.health, "MOD_MELEE_DOG" );
|
||||
|
||||
attackAnim = self GetAnimEntry( meleeAnimState, animEntry );
|
||||
self thread ExtendedKill_StickToVictim( attackAnim, self.curMeleeTarget.origin, self.curMeleeTarget.angles );
|
||||
|
||||
// if ( animEntry == 1 ) // back
|
||||
// self PlaySoundOnMovingEnt( "mp_dog_attack_quick_back_npc" );
|
||||
// else
|
||||
// self PlaySoundOnMovingEnt( "mp_dog_attack_short_npc" );
|
||||
|
||||
self PlayAnimNUntilNotetrack( meleeAnimState, animEntry, "attack", "end" );
|
||||
|
||||
self notify( "kill_stick" );
|
||||
self.curMeleeTarget = undefined;
|
||||
|
||||
self ScrAgentSetAnimMode( "anim deltas" );
|
||||
self Unlink();
|
||||
}
|
||||
|
||||
ExtendedKill_StickToVictim( attackAnim, targetOrigin, targetAngles )
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "killanimscript" );
|
||||
self endon( "kill_stick" );
|
||||
|
||||
wait( 0.05 ); // must wait for anim to kick in before we can properly calculate our offsets.
|
||||
assert( IsDefined( self.curMeleeTarget ) );
|
||||
|
||||
if ( IsAlive( self.curMeleeTarget ) ) // godmode, etc.
|
||||
return;
|
||||
|
||||
corpse = self.curMeleeTarget GetCorpseEntity();
|
||||
assert( IsDefined( corpse ) );
|
||||
self LinkTo( corpse );
|
||||
|
||||
self ScrAgentDoAnimRelative( attackAnim, targetOrigin, targetAngles );
|
||||
}
|
||||
|
||||
DoStandardKill( attackPos, bCanMoveToAttackPos )
|
||||
{
|
||||
meleeAnimState = self GetMeleeAnimState();
|
||||
|
||||
bLerp = false;
|
||||
|
||||
if ( !bCanMoveToAttackPos )
|
||||
{
|
||||
if ( self AgentCanSeeSentient( self.curMeleeTarget ) )
|
||||
{
|
||||
groundPos = self DropPosToGround( self.curMeleeTarget.origin );
|
||||
if ( IsDefined( groundPos ) )
|
||||
{
|
||||
bLerp = true;
|
||||
attackPos = groundPos; // i'm going to clip the heck through him, but i need a guaranteed safe spot.
|
||||
}
|
||||
else
|
||||
{
|
||||
self MeleeFailed();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
self MeleeFailed();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
self.lastMeleeFailedMyPos = undefined;
|
||||
self.lastMeleeFailedPos = undefined;
|
||||
|
||||
attackAnim = self GetAnimEntry( meleeAnimState, 0 );
|
||||
animLength = GetAnimLength( attackAnim );
|
||||
meleeNotetracks = GetNotetrackTimes( attackAnim, "dog_melee" );
|
||||
if ( meleeNotetracks.size > 0 )
|
||||
lerpTime = meleeNotetracks[0] * animLength;
|
||||
else
|
||||
lerpTime = animLength;
|
||||
|
||||
self ScrAgentDoAnimLerp( self.origin, attackPos, lerpTime );
|
||||
|
||||
self thread UpdateLerpPos( self.curMeleeTarget, lerpTime, bCanMoveToAttackPos );
|
||||
|
||||
self PlayAnimNUntilNotetrack( meleeAnimState, 0, "attack", "dog_melee" );
|
||||
|
||||
self notify( "cancel_updatelerppos" );
|
||||
|
||||
damageDealt = 0;
|
||||
if( IsDefined( self.curMeleeTarget ) )
|
||||
damageDealt = self.curMeleeTarget.health;
|
||||
if( IsDefined( self.meleeDamage ) )
|
||||
damageDealt = self.meleeDamage;
|
||||
|
||||
if( IsDefined( self.curMeleeTarget ) )
|
||||
self DoMeleeDamage( self.curMeleeTarget, damageDealt, "MOD_IMPACT" );
|
||||
|
||||
self.curMeleeTarget = undefined; // dude's dead now, or soon will be.
|
||||
|
||||
if ( bLerp )
|
||||
self ScrAgentSetAnimScale( 0, 1 );
|
||||
else
|
||||
self ScrAgentSetAnimScale( 1, 1 );
|
||||
|
||||
self ScrAgentSetPhysicsMode( "gravity" );
|
||||
self ScrAgentSetAnimMode( "anim deltas" );
|
||||
|
||||
self WaitUntilNotetrack( "attack", "end" );
|
||||
}
|
||||
|
||||
UpdateLerpPos( enemy, lerpTime, bCanMoveToAttackPos )
|
||||
{
|
||||
self endon( "killanimscript" );
|
||||
self endon( "death" );
|
||||
self endon( "cancel_updatelerppos" );
|
||||
enemy endon( "disconnect" );
|
||||
enemy endon( "death" );
|
||||
|
||||
timeRemaining = lerpTime;
|
||||
interval = 0.05;
|
||||
while ( true )
|
||||
{
|
||||
wait( interval );
|
||||
timeRemaining -= interval;
|
||||
|
||||
if ( timeRemaining <= 0 )
|
||||
break;
|
||||
|
||||
attackPos = GetUpdatedAttackPos( enemy, bCanMoveToAttackPos );
|
||||
if ( !IsDefined( attackPos ) )
|
||||
break;
|
||||
|
||||
self ScrAgentDoAnimLerp( self.origin, attackPos, timeRemaining );
|
||||
}
|
||||
}
|
||||
|
||||
GetUpdatedAttackPos( enemy, bCanMove )
|
||||
{
|
||||
if ( !bCanMove )
|
||||
{
|
||||
droppedPos = self DropPosToGround( enemy.origin );
|
||||
return droppedPos;
|
||||
}
|
||||
else
|
||||
{
|
||||
meToTarget = enemy.origin - self.origin;
|
||||
distMeToTarget = Length( meToTarget );
|
||||
|
||||
if ( distMeToTarget < self.attackOffset )
|
||||
{
|
||||
return self.origin;
|
||||
}
|
||||
else
|
||||
{
|
||||
meToTarget = meToTarget / distMeToTarget;
|
||||
attackPos = enemy.origin - meToTarget * self.attackOffset;
|
||||
if ( self CanMovePointToPoint( self.origin, attackPos ) )
|
||||
return attackPos;
|
||||
else
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IsProtectedByRiotshield( enemy )
|
||||
{
|
||||
if ( enemy maps\mp\_riotshield::hasRiotShield() )
|
||||
{
|
||||
enemyToMe = self.origin - enemy.origin;
|
||||
meToEnemy = VectorNormalize( ( enemyToMe[0], enemyToMe[1], 0 ) );
|
||||
|
||||
enemyFacing = AnglesToForward( enemy.angles );
|
||||
angleToMe = VectorDot( enemyFacing, enemyToMe );
|
||||
|
||||
if ( enemy maps\mp\_riotshield::hasRiotShieldEquipped() )
|
||||
{
|
||||
if ( angleToMe > 0.766 )
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( angleToMe < -0.766 )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
DoMeleeDamage( enemy, damage, meansOfDeath )
|
||||
{
|
||||
if ( self IsProtectedByRiotshield( enemy ) )
|
||||
return;
|
||||
|
||||
enemy DoDamage( damage, self.origin, self, self, meansOfDeath );
|
||||
}
|
||||
|
||||
MeleeFailed()
|
||||
{
|
||||
self.lastMeleeFailedMyPos = self.origin;
|
||||
self.lastMeleeFailedPos = self.curMeleeTarget.origin;
|
||||
}
|
490
raw/maps/mp/agents/dog/_dog_move.gsc
Normal file
490
raw/maps/mp/agents/dog/_dog_move.gsc
Normal file
@ -0,0 +1,490 @@
|
||||
#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 );
|
||||
}
|
1198
raw/maps/mp/agents/dog/_dog_think.gsc
Normal file
1198
raw/maps/mp/agents/dog/_dog_think.gsc
Normal file
File diff suppressed because it is too large
Load Diff
242
raw/maps/mp/agents/dog/_dog_traverse.gsc
Normal file
242
raw/maps/mp/agents/dog/_dog_traverse.gsc
Normal file
@ -0,0 +1,242 @@
|
||||
#include maps\mp\agents\_scriptedAgents;
|
||||
CONST_BOT_WALK_FORWARD_UNITS_PER_SECOND = 256;
|
||||
|
||||
main()
|
||||
{
|
||||
self endon( "killanimscript" );
|
||||
|
||||
if ( !IsDefined( level.dogTraverseAnims ) )
|
||||
InitDogTraverseAnims();
|
||||
|
||||
startNode = self GetNegotiationStartNode();
|
||||
endNode = self GetNegotiationEndNode();
|
||||
assert( IsDefined( startNode ) && IsDefined( endNode ) );
|
||||
|
||||
if( startNode.animscript == "bot_walk_forward" )
|
||||
{
|
||||
startToEnd = endNode.origin - startNode.origin;
|
||||
lerpTime = Length(startToEnd) / CONST_BOT_WALK_FORWARD_UNITS_PER_SECOND;
|
||||
startToEnd2D = ( startToEnd[0], startToEnd[1], 0);
|
||||
anglestoEnd = VectorToAngles( startToEnd2D );
|
||||
self ScrAgentSetOrientMode( "face angle abs", anglestoEnd );
|
||||
self ScrAgentDoAnimLerp( startNode.origin, endNode.origin, lerpTime );
|
||||
self ScrAgentSetPhysicsMode( "noclip" );
|
||||
self PlayAnimForTime( "run", lerpTime );
|
||||
return;
|
||||
}
|
||||
|
||||
animState = undefined;
|
||||
animState = level.dogTraverseAnims[ startNode.animscript ];
|
||||
|
||||
if ( !IsDefined( animState ) )
|
||||
{
|
||||
assertmsg( "no animation for traverse " + startNode.animscript + "@ " + startNode.origin );
|
||||
return;
|
||||
}
|
||||
|
||||
self.bLockGoalPos = true;
|
||||
|
||||
startToEnd = endNode.origin - startNode.origin;
|
||||
startToEnd2D = ( startToEnd[0], startToEnd[1], 0 );
|
||||
anglesToEnd = VectorToAngles( startToEnd2D );
|
||||
|
||||
self ScrAgentSetOrientMode( "face angle abs", anglesToEnd );
|
||||
self ScrAgentSetAnimMode( "anim deltas" );
|
||||
|
||||
traverseAnim = self GetAnimEntry( animState, 0 );
|
||||
|
||||
codeMoveNotetracks = GetNotetrackTimes( traverseAnim, "code_move" );
|
||||
if ( codeMoveNotetracks.size > 0 )
|
||||
moveDelta = GetMoveDelta( traverseAnim, 0, codeMoveNotetracks[0] );
|
||||
else
|
||||
moveDelta = GetMoveDelta( traverseAnim, 0, 1 );
|
||||
|
||||
scaleFactors = GetAnimScaleFactors( startToEnd, moveDelta );
|
||||
|
||||
self ScrAgentSetPhysicsMode( "noclip" );
|
||||
|
||||
// the end node is higher than the start node.
|
||||
if ( startToEnd[2] > 0 )
|
||||
{
|
||||
if ( moveDelta[2] > 0 )
|
||||
{
|
||||
jumpStartNotetracks = GetNotetrackTimes( traverseAnim, "traverse_jump_start" );
|
||||
if ( jumpStartNotetracks.size > 0 )
|
||||
{
|
||||
xyScale = 1;
|
||||
zScale = 1;
|
||||
if ( Length2DSquared( startToEnd2D ) < 0.8 * 0.8 * Length2DSquared( moveDelta ) )
|
||||
xyScale = 0.4;
|
||||
if ( startToEnd[2] < 0.75 * moveDelta[2] )
|
||||
zScale = 0.5;
|
||||
|
||||
self ScrAgentSetAnimScale( xyScale, zScale );
|
||||
|
||||
self PlayAnimNUntilNotetrack( animState, 0, "traverse", "traverse_jump_start" );
|
||||
jumpEndNotetracks = GetNotetrackTimes( traverseAnim, "traverse_jump_end" );
|
||||
assert( jumpEndNotetracks.size > 0 );
|
||||
jumpStartMoveDelta = GetMoveDelta( traverseAnim, 0, jumpStartNotetracks[0] );
|
||||
jumpEndMoveDelta = GetMoveDelta( traverseAnim, 0, jumpEndNotetracks[0] );
|
||||
|
||||
xyScale = 1;
|
||||
zScale = 1;
|
||||
currentToEnd = endNode.origin - self.origin;
|
||||
animToEnd = moveDelta - jumpStartMoveDelta;
|
||||
if ( Length2DSquared( currentToEnd ) < 0.75 * 0.75 * Length2DSquared( animToEnd ) )
|
||||
xyScale = 0.75;
|
||||
if ( currentToEnd[2] < 0.75 * animToEnd[2] )
|
||||
zScale = 0.75;
|
||||
|
||||
animJumpEndToEnd = moveDelta - jumpEndMoveDelta;
|
||||
scaledAnimJumpEndToEnd = ( animJumpEndToEnd[0] * xyScale, animJumpEndToEnd[1] * xyScale, animJumpEndToEnd[2] * zScale );
|
||||
worldAnimJumpEndToEnd = RotateVector( scaledAnimJumpEndToEnd, anglesToEnd );
|
||||
nodeJumpEndPos = endNode.origin - worldAnimJumpEndToEnd;
|
||||
|
||||
animJumpStartToJumpEnd = jumpEndMoveDelta - jumpStartMoveDelta;
|
||||
worldAnimJumpStartToJumpEnd = RotateVector( animJumpStartToJumpEnd, anglesToEnd );
|
||||
currentToNodeJumpEnd = nodeJumpEndPos - self.origin;
|
||||
|
||||
scaleFactors = GetAnimScaleFactors( currentToNodeJumpEnd, worldAnimJumpStartToJumpEnd, true);
|
||||
self ScrAgentSetAnimScale( scaleFactors.xy, scaleFactors.z );
|
||||
self WaitUntilNotetrack( "traverse", "traverse_jump_end" );
|
||||
|
||||
self ScrAgentSetAnimScale( xyScale, zScale );
|
||||
self WaitUntilNotetrack( "traverse", "code_move" );
|
||||
}
|
||||
else
|
||||
{
|
||||
self ScrAgentSetAnimScale( scaleFactors.xy, scaleFactors.z );
|
||||
self PlayAnimNUntilNotetrack( animState, 0, "traverse" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // can't do negative scale. use lerp.
|
||||
gravityOnNotetracks = GetNotetrackTimes( traverseAnim, "gravity on" );
|
||||
if ( gravityOnNotetracks.size > 0 )
|
||||
{
|
||||
targetEntPos = startNode GetTargetEntPos();
|
||||
if ( IsDefined( targetEntPos ) )
|
||||
{
|
||||
startToTarget = targetEntPos - self.origin;
|
||||
targetToEnd = endNode.origin - targetEntPos;
|
||||
|
||||
startDelta = GetMoveDelta( traverseAnim, 0, gravityOnNotetracks[0] );
|
||||
scaleFactors = self GetAnimScaleFactors( startToTarget, startDelta );
|
||||
|
||||
self ScrAgentSetAnimScale( scaleFactors.xy, scaleFactors.z );
|
||||
self PlayAnimNUntilNotetrack( animState, 0, "traverse", "gravity on" );
|
||||
|
||||
endDelta = GetMoveDelta( traverseAnim, gravityOnNotetracks[0], 1 );
|
||||
scaleFactors = self GetAnimScaleFactors( targetToEnd, endDelta );
|
||||
|
||||
self ScrAgentSetAnimScale( scaleFactors.xy, scaleFactors.z );
|
||||
self WaitUntilNotetrack( "traverse", "code_move" );
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
animLength = GetAnimLength( traverseAnim );
|
||||
self ScrAgentDoAnimLerp( startNode.origin, endNode.origin, animLength );
|
||||
self PlayAnimNUntilNotetrack( animState, 0, "traverse" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gravityOnNotetracks = GetNotetrackTimes( traverseAnim, "gravity on" );
|
||||
if ( gravityOnNotetracks.size > 0 )
|
||||
{
|
||||
self ScrAgentSetAnimScale( scaleFactors.xy, 1 );
|
||||
self PlayAnimNUntilNotetrack( animState, 0, "traverse", "gravity on" );
|
||||
|
||||
gravityOnMoveDelta = GetMoveDelta( traverseAnim, 0, gravityOnNotetracks[0] );
|
||||
zAnimDelta = gravityOnMoveDelta[2] - moveDelta[2];
|
||||
|
||||
if ( abs( zAnimDelta ) > 0 )
|
||||
{
|
||||
zMeToEnd = self.origin[2] - endNode.origin[2];
|
||||
|
||||
zScale = zMeToEnd / zAnimDelta;
|
||||
assert( zScale > 0 );
|
||||
|
||||
self ScrAgentSetAnimScale( scaleFactors.xy, zScale );
|
||||
|
||||
animrate = Clamp( 2 / zScale, 0.5, 1 );
|
||||
|
||||
norestart = animState + "_norestart";
|
||||
self SetAnimState( norestart, 0, animrate );
|
||||
}
|
||||
|
||||
self WaitUntilNotetrack( "traverse", "code_move" );
|
||||
}
|
||||
else
|
||||
{
|
||||
self ScrAgentSetAnimScale( scaleFactors.xy, scaleFactors.z );
|
||||
|
||||
animrate = Clamp( 2 / scaleFactors.z, 0.5, 1 );
|
||||
|
||||
jumpEndNotetracks = GetNotetrackTimes( traverseAnim, "traverse_jump_end" );
|
||||
if ( jumpEndNotetracks.size > 0 )
|
||||
{
|
||||
self PlayAnimNAtRateUntilNotetrack( animState, 0, animrate, "traverse", "traverse_jump_end" );
|
||||
norestart = animState + "_norestart";
|
||||
self SetAnimState( norestart, 0, 1 );
|
||||
self WaitUntilNotetrack( "traverse", "code_move" );
|
||||
}
|
||||
else
|
||||
{
|
||||
self PlayAnimNUntilNotetrack( animState, 0, "traverse" );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
self ScrAgentSetAnimScale( 1, 1 );
|
||||
}
|
||||
}
|
||||
|
||||
end_script()
|
||||
{
|
||||
self ScrAgentSetAnimScale( 1, 1 );
|
||||
self.bLockGoalPos = false;
|
||||
}
|
||||
|
||||
GetTargetEntPos()
|
||||
{
|
||||
if ( IsDefined( self.targetEntPos ) )
|
||||
return self.targetEntPos;
|
||||
|
||||
targetEnt = GetEnt( self.target, "targetname" );
|
||||
if ( !IsDefined( targetEnt ) )
|
||||
return undefined;
|
||||
|
||||
self.targetEntPos = targetEnt.origin;
|
||||
targetEnt delete();
|
||||
return self.targetEntPos;
|
||||
}
|
||||
|
||||
InitDogTraverseAnims()
|
||||
{
|
||||
level.dogTraverseAnims = [];
|
||||
|
||||
level.dogTraverseAnims[ "hjk_tree_hop" ] = "traverse_jump_over_24";
|
||||
level.dogTraverseAnims[ "jump_across_72" ] = "traverse_jump_over_24";
|
||||
level.dogTraverseAnims[ "wall_hop" ] = "traverse_jump_over_36";
|
||||
level.dogTraverseAnims[ "window_2" ] = "traverse_jump_over_36";
|
||||
level.dogTraverseAnims[ "wall_over_40" ] = "traverse_jump_over_36";
|
||||
level.dogTraverseAnims[ "wall_over" ] = "traverse_jump_over_36";
|
||||
level.dogTraverseAnims[ "window_divethrough_36" ] = "traverse_jump_over_36";
|
||||
level.dogTraverseAnims[ "window_over_40" ] = "traverse_jump_over_36";
|
||||
level.dogTraverseAnims[ "window_over_quick" ] = "traverse_jump_over_36";
|
||||
level.dogTraverseAnims[ "jump_up_80" ] = "traverse_jump_up_70";
|
||||
level.dogTraverseAnims[ "jump_standing_80" ] = "traverse_jump_up_70";
|
||||
level.dogTraverseAnims[ "jump_down_80" ] = "traverse_jump_down_70";
|
||||
level.dogTraverseAnims[ "jumpdown_96" ] = "traverse_jump_down_70";
|
||||
level.dogTraverseAnims[ "jump_up_40" ] = "traverse_jump_up_40";
|
||||
level.dogTraverseAnims[ "jump_down_40" ] = "traverse_jump_down_40";
|
||||
level.dogTraverseAnims[ "step_up" ] = "traverse_jump_up_24";
|
||||
level.dogTraverseAnims[ "step_up_24" ] = "traverse_jump_up_24";
|
||||
level.dogTraverseAnims[ "step_down" ] = "traverse_jump_down_24";
|
||||
level.dogTraverseAnims[ "jump_down" ] = "traverse_jump_down_24";
|
||||
level.dogTraverseAnims[ "jump_across" ] = "traverse_jump_over_36";
|
||||
level.dogTraverseAnims[ "jump_across_100" ] = "traverse_jump_over_36";
|
||||
}
|
||||
|
1265
raw/maps/mp/agents/dog/_instinct_dog_think.gsc
Normal file
1265
raw/maps/mp/agents/dog/_instinct_dog_think.gsc
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user