Add follower ring animation

Add "RingState" and "RingTime" to followers. RingState is the state to use while they're giving you an auto-ring. The animation plays for RingTime tics per-ring, so it can extend to however long they need to use rings.
This commit is contained in:
Sally Coolatta 2024-04-29 10:22:24 -04:00 committed by James R
parent a557039ce3
commit b610353699
4 changed files with 41 additions and 2 deletions

View file

@ -4152,6 +4152,7 @@ void readfollower(MYFILE *f)
followers[numfollowers].bobspeed = TICRATE*2;
followers[numfollowers].bobamp = 4*FRACUNIT;
followers[numfollowers].hitconfirmtime = TICRATE;
followers[numfollowers].ringtime = 6;
followers[numfollowers].defaultcolor = FOLLOWERCOLOR_MATCH;
followers[numfollowers].category = UINT8_MAX;
followers[numfollowers].hornsound = sfx_horn00;
@ -4329,6 +4330,16 @@ void readfollower(MYFILE *f)
{
followers[numfollowers].hitconfirmtime = (tic_t)get_number(word2);
}
else if (fastcmp(word, "RINGSTATE"))
{
if (word2)
strupr(word2);
followers[numfollowers].ringstate = get_number(word2);
}
else if (fastcmp(word, "RINGTIME"))
{
followers[numfollowers].ringtime = (tic_t)get_number(word2);
}
else
{
deh_warning("Follower %d: unknown word '%s'", numfollowers, word);
@ -4386,6 +4397,7 @@ if ((signed)followers[numfollowers].field < threshold) \
FALLBACK(bobamp, "BOBAMP", 0, 0);
FALLBACK(bobspeed, "BOBSPEED", 0, 0);
FALLBACK(hitconfirmtime, "HITCONFIRMTIME", 1, 1);
FALLBACK(ringtime, "RINGTIME", 1, 1);
FALLBACK(scale, "SCALE", 1, 1); // No null/negative scale
FALLBACK(bubblescale, "BUBBLESCALE", 0, 0); // No negative scale
@ -4408,6 +4420,7 @@ if (!followers[numfollowers].field) \
NOSTATE(losestate, "LOSESTATE");
NOSTATE(winstate, "WINSTATE");
NOSTATE(hitconfirmstate, "HITCONFIRMSTATE");
NOSTATE(ringstate, "RINGSTATE");
#undef NOSTATE
if (!followers[numfollowers].hornsound)

View file

@ -537,6 +537,15 @@ void K_HandleFollower(player_t *player)
destAngle += ANGLE_180;
}
// Using auto-ring, face towards the player while throwing your rings.
if (player->follower->cvmem)
{
destAngle = R_PointToAngle2(
player->follower->x, player->follower->y,
player->mo->x, player->mo->y
);
}
// Sal: Smoothly rotate angle to the destination value.
angleDiff = AngleDeltaSigned(destAngle, player->follower->angle);
@ -628,8 +637,9 @@ void K_HandleFollower(player_t *player)
// hurt or dead
if (P_PlayerInPain(player) == true || player->mo->state == &states[S_KART_SPINOUT] || player->mo->health <= 0)
{
// cancel hit confirm.
// cancel hit confirm / rings
player->follower->movecount = 0;
player->follower->cvmem = 0;
// spin out
player->follower->angle = player->drawangle;
@ -661,6 +671,11 @@ void K_HandleFollower(player_t *player)
K_UpdateFollowerState(player->follower, fl->hitconfirmstate, FOLLOWERSTATE_HITCONFIRM);
player->follower->movecount--;
}
else if (player->follower->cvmem)
{
K_UpdateFollowerState(player->follower, fl->ringstate, FOLLOWERSTATE_RING);
player->follower->cvmem--;
}
else if (player->speed > 10*player->mo->scale) // animation for moving fast enough
{
K_UpdateFollowerState(player->follower, fl->followstate, FOLLOWERSTATE_FOLLOW);

View file

@ -49,6 +49,7 @@ typedef enum
FOLLOWERSTATE_WIN,
FOLLOWERSTATE_LOSE,
FOLLOWERSTATE_HITCONFIRM, // Uses movecount as a timer for how long to play this state.
FOLLOWERSTATE_RING, // Uses cvmem as a timer for how long to play this state.
FOLLOWERSTATE__MAX
} followerstate_t;
@ -93,6 +94,8 @@ struct follower_t
statenum_t losestate; // state when the player has lost
statenum_t hitconfirmstate; // state for hit confirm
tic_t hitconfirmtime; // time to keep the above playing for
statenum_t ringstate; // state for giving an auto-ring
tic_t ringtime; // time to keep the above playing for
sfxenum_t hornsound; // Press (B) to announce you are pressing (B)
};

View file

@ -12650,12 +12650,20 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
ring->shadowscale = 0;
P_SetTarget(&ring->target, player->mo); // user
if (player->follower && !P_MobjWasRemoved(player->follower))
if (player->follower != NULL
&& P_MobjWasRemoved(player->follower) == false
&& player->followerskin >= 0
&& player->followerskin < numfollowers)
{
// TODO: only do when using an auto-ring
const follower_t *fl = &followers[player->followerskin];
ring->cusval = player->follower->x - player->mo->x;
ring->cvmem = player->follower->y - player->mo->y;
ring->movefactor = P_GetMobjHead(player->follower) - P_GetMobjHead(player->mo);
// cvmem is used to play the ring animation for followers
player->follower->cvmem = fl->ringtime;
}
else
{