NSMonster: turning animation support, with new overridable methods AnimTurnLeft/AnimTurnRight

This commit is contained in:
Marco Cawthorne 2023-06-01 15:52:30 -07:00
parent 1bb1fe705d
commit d0838eab60
Signed by: eukara
GPG Key ID: CE2032F0A2882A22
4 changed files with 73 additions and 40 deletions

View File

@ -322,7 +322,7 @@ public:
/** Returns if the entity is visible from a given position and a field of view of 90 degrees. */
nonvirtual bool VisibleVec(vector);
/** Returns a normalized value of how far away the target is from the entity's view direction. 1 means dead-center. 0 means it's behind.*/
nonvirtual bool DistanceFromYaw(entity);
nonvirtual bool DistanceFromYaw(vector);
/** Returns if the entity has any spawnflags set. */
nonvirtual bool HasSpawnFlags(float);
/** Returns if the entity is aligned to the ground. */

View File

@ -99,7 +99,7 @@ bool NSEntity::VisibleVec( vector org ) {
bool NSEntity::Visible( entity ent ) {
/* is it in our field of view? */
if ( DistanceFromYaw(ent) > 0.3f ) {
if ( DistanceFromYaw(ent.origin) > 0.3f ) {
traceline( origin, ent.origin, MOVE_NORMAL, this );
if ( trace_fraction == 1.0f || trace_ent == ent ) {
print( sprintf( "%s can see %s\n", classname, ent.classname ) );
@ -110,12 +110,12 @@ bool NSEntity::Visible( entity ent ) {
return ( false );
}
bool NSEntity::DistanceFromYaw( entity ent ) {
bool NSEntity::DistanceFromYaw( vector targetPos ) {
vector flDelta;
float flFoV;
makevectors( angles );
flDelta = normalize( ent.origin - origin );
flDelta = normalize( targetPos - origin );
return flDelta * v_forward;
}

View File

@ -337,6 +337,10 @@ public:
virtual int AnimWalk(void);
/** Overridable: Called when we need to play a fresh running framegroup. */
virtual int AnimRun(void);
/** Overridable: Called when we need to play a left turning animation. */
virtual int AnimTurnLeft(void);
/** Overridable: Called when we need to play a right turning animation. */
virtual int AnimTurnRight(void);
/** Call to play a single animation onto it, which cannot be interrupted by movement. */
virtual void AnimPlay(float);
/** Internal use only. Run every frame to update animation parameters. */
@ -417,8 +421,10 @@ private:
/* caching variables, don't save these */
float m_actIdle;
bool m_bTurning;
nonvirtual void _LerpTurnToEnemy(void);
nonvirtual void _LerpTurnToYaw(vector);
virtual void _Alerted(void);
#endif
};

View File

@ -200,7 +200,20 @@ NSMonster::AnimWalk(void)
int
NSMonster::AnimRun(void)
{
return frameforaction(modelindex, ACT_RUN);
float runAnim = frameforaction(modelindex, ACT_RUN);
return (runAnim == -1) ? AnimWalk() : runAnim;
}
int
NSMonster::AnimTurnLeft(void)
{
return frameforaction(modelindex, ACT_TURN_LEFT);
}
int
NSMonster::AnimTurnRight(void)
{
return frameforaction(modelindex, ACT_TURN_RIGHT);
}
void
@ -453,20 +466,27 @@ NSMonster::GetYawSpeed(void)
}
void
NSMonster::_LerpTurnToEnemy(void)
NSMonster::_LerpTurnToYaw(vector turnYaw)
{
/* only continue if we're in one of the three states. */
if (GetState() != MONSTER_AIMING)
if (GetState() != MONSTER_CHASING)
if (GetState() != MONSTER_FOLLOWING)
return;
if (!m_eEnemy)
return;
float turnSpeed = GetYawSpeed();
vector vecWishAngle = vectoangles(m_eEnemy.origin - origin);
float yawDiff = anglesub(vecWishAngle[1], v_angle[1]);
vector vecWishAngle = turnYaw;
float yawDiff = anglesub(turnYaw[1], v_angle[1]);
if (fabs(yawDiff) > 90) {
velocity = g_vec_null;
input_movevalues = g_vec_null;
if (m_bTurning == false)
if (yawDiff < 0) {
SetFrame(AnimTurnRight());
} else {
SetFrame(AnimTurnLeft());
}
m_bTurning = true;
} else {
m_bTurning = false;
}
/* min/max out the diff */
if (yawDiff > 0) {
@ -487,6 +507,29 @@ NSMonster::_LerpTurnToEnemy(void)
angles[1] = input_angles[1] = v_angle[1] = vecWishAngle[1];
}
void
NSMonster::_LerpTurnToPos(vector turnPos)
{
vector vecWishAngle = vectoangles(turnPos - origin);
_LerpTurnToYaw(vecWishAngle);
}
void
NSMonster::_LerpTurnToEnemy(void)
{
/* only continue if we're in one of the three states. */
if (GetState() != MONSTER_AIMING)
if (GetState() != MONSTER_CHASING)
if (GetState() != MONSTER_FOLLOWING)
return;
if (!m_eEnemy)
return;
_LerpTurnToPos(m_eEnemy.origin);
}
void
NSMonster::AttackThink(void)
{
@ -645,6 +688,8 @@ NSMonster::RouteEnded(void)
void
NSMonster::WalkRoute(void)
{
vector wishAngles;
/* we're busy shooting at something, don't walk */
if (GetState() == MONSTER_AIMING && m_eEnemy) {
input_angles = vectoangles(m_eEnemy.origin - origin);
@ -662,29 +707,7 @@ NSMonster::WalkRoute(void)
return;
/* yaw interpolation */
{
float turnSpeed = GetYawSpeed();
vector vecWishAngle = input_angles;
float yawDiff = anglesub(vecWishAngle[1], v_angle[1]);
/* min/max out the diff */
if (yawDiff > 0) {
v_angle[1] += turnSpeed * frametime;
if (v_angle[1] > vecWishAngle[1])
v_angle[1] = vecWishAngle[1];
} else if (yawDiff < 0) {
v_angle[1] -= turnSpeed * frametime;
if (v_angle[1] < vecWishAngle[1])
v_angle[1] = vecWishAngle[1];
}
/* fix angles */
makevectors(v_angle);
vecWishAngle = vectoangles( v_forward );
angles[1] = input_angles[1] = v_angle[1] = vecWishAngle[1];
}
_LerpTurnToYaw(input_angles);
}
void
@ -699,6 +722,9 @@ NSMonster::AnimationUpdate(void)
if (GetState() == MONSTER_AIMING)
return;
if (m_bTurning)
return;
float spvel = vlen(velocity);
float midspeed = GetWalkSpeed() + ((GetRunSpeed() - GetWalkSpeed()) * 0.5f);
@ -813,6 +839,7 @@ NSMonster::Physics(void)
input_buttons = 0;
input_timelength = frametime;
input_angles = angles;
m_bTurning = false;
/* when stuck in a sequence, forget enemies, combat stance */
if (GetSequenceState() != SEQUENCESTATE_NONE) {