Follower mood system

* Followers get happy when you hit others, and angry when others hit you
* The mood doesn't do much beyond change the horn's symbol
This commit is contained in:
yamamama 2026-01-31 21:56:15 -05:00
parent 5efbc22a01
commit 598f974fdc
3 changed files with 68 additions and 3 deletions

View file

@ -3626,3 +3626,5 @@ _(RECSPIN_SKID)
// Horncode
_(HORNCODE)
_(HORNCODE_ANGRY)
_(HORNCODE_HAPPY)

View file

@ -245,6 +245,32 @@ static void K_UpdateFollowerState(mobj_t *f, statenum_t state, followerstate_t t
}
}
/*--------------------------------------------------
static void K_UpdateFollowerMood(mobj_t *f, followermood_t mood, tic_t time)
Sets a follower object's mood and time before returning to a normal mood.
Input Arguments:-
f - The follower's mobj_t.
mood - The mood to set.
time - The mood's duration.
Return:-
None
--------------------------------------------------*/
static void K_UpdateFollowerMood(mobj_t *f, followermood_t mood, tic_t time)
{
if (f == NULL || P_MobjWasRemoved(f) == true)
{
// safety net
return;
}
f->extravalue3 = mood;
f->cvmem = (INT32)(time);
}
/*--------------------------------------------------
void K_HandleFollower(player_t *player)
@ -567,6 +593,20 @@ void K_HandleFollower(player_t *player)
// However with how the code is factored, this is just a special case of S_INVISBLE to avoid having to add other player variables.
// Mood system
// For now, all this does is change the VFX generated when you honk your horn.
if (player->follower->cvmem && (player->follower->extravalue3 != FOLLOWERMOOD_NORMAL))
{
// Tick down the mood timer
player->follower->cvmem--;
// Return to our normal mood
if (player->follower->cvmem == 0)
{
player->follower->extravalue3 = FOLLOWERMOOD_NORMAL;
}
}
// handle follower animations. Could probably be better...
// hurt or dead
if (P_PlayerInPain(player) == true || player->mo->state == &states[S_KART_SPINOUT] || player->mo->health <= 0)
@ -585,6 +625,11 @@ void K_HandleFollower(player_t *player)
// if dead, follow the player's z momentum exactly so they both look like they die at the same speed.
player->follower->momz = player->mo->momz;
}
else
{
// Not dead; get mad on the player's behalf.
K_UpdateFollowerMood(player->follower, FOLLOWERMOOD_ANGRY, (3 * TICRATE / 2));
}
}
else if (player->exiting)
{
@ -603,6 +648,7 @@ void K_HandleFollower(player_t *player)
else if (player->follower->movecount)
{
K_UpdateFollowerState(player->follower, fl.hitconfirmstate, FOLLOWERSTATE_HITCONFIRM);
K_UpdateFollowerMood(player->follower, FOLLOWERMOOD_HAPPY, (3 * TICRATE / 2));
player->follower->movecount--;
}
else if (player->follower->reactiontime)
@ -702,12 +748,21 @@ void K_FollowerHornTaunt(player_t *taunter, player_t *victim)
MT_FOLLOWERHORN
);
// TODO (yama): Honk icons based on a follower's "emotion"
// (♪ for hitconfirm honks, 💢 for mid-damage honks)
if (P_MobjWasRemoved(honk) == true)
return; // Permit lua override of horn production
// Set the horn icon based on the follower's mood.
switch (taunter->follower->extravalue3)
{
case FOLLOWERMOOD_ANGRY:
P_SetMobjState(honk, S_HORNCODE_ANGRY);
break;
case FOLLOWERMOOD_HAPPY:
P_SetMobjState(honk, S_HORNCODE_HAPPY);
default:
break;
}
P_SetTarget(&taunter->follower->hprev, honk);
P_SetTarget(&honk->target, taunter->follower);

View file

@ -49,6 +49,14 @@ typedef enum
FOLLOWERSTATE__MAX
} followerstate_t;
typedef enum
{
FOLLOWERMOOD_NORMAL, // Default mood, produces a ++ symbol when you honk.
FOLLOWERMOOD_HAPPY, // Happy mood (recent hitconfirm, won race), produces a ♪ symbol when you honk.
FOLLOWERMOOD_ANGRY, // Angry/upset mood (taking damage, recently took damage), produces a 💢 symbol when you honk.
FOLLOWERMOOD__MAX
} followermood_t;
//
// We'll define these here because they're really just a mobj that'll follow some rules behind a player
//