mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Per-viewport HUD messages
This commit is contained in:
parent
25149db4eb
commit
e9ee268965
3 changed files with 135 additions and 64 deletions
171
src/k_hud.cpp
171
src/k_hud.cpp
|
|
@ -5621,97 +5621,162 @@ typedef struct
|
|||
sfxenum_t sound;
|
||||
} message_t;
|
||||
|
||||
static std::deque<std::string> messages;
|
||||
static tic_t messagetimer = 0;
|
||||
static messagemode_t messagemode = MM_IN;
|
||||
typedef struct
|
||||
{
|
||||
std::deque<std::string> messages;
|
||||
tic_t timer = 0;
|
||||
messagemode_t mode = MM_IN;
|
||||
const tic_t speedyswitch = 2*TICRATE;
|
||||
const tic_t lazyswitch = 4*TICRATE;
|
||||
|
||||
static tic_t speedyswitch = 2*TICRATE;
|
||||
static tic_t lazyswitch = 4*TICRATE;
|
||||
void add(std::string msg)
|
||||
{
|
||||
messages.push_back(msg);
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
messages.clear();
|
||||
}
|
||||
|
||||
void switch_mode(messagemode_t nextmode)
|
||||
{
|
||||
mode = nextmode;
|
||||
timer = 0;
|
||||
}
|
||||
|
||||
void tick()
|
||||
{
|
||||
if (messages.size() == 0)
|
||||
return;
|
||||
|
||||
if (timer == 0 && mode == MM_IN)
|
||||
S_StartSound(NULL, sfx_cdfm15);
|
||||
|
||||
timer++;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case MM_IN:
|
||||
if (timer > messages[0].length())
|
||||
switch_mode(MM_HOLD);
|
||||
break;
|
||||
case MM_HOLD:
|
||||
if (messages.size() > 1 && timer > speedyswitch) // Waiting message, switch to it right away!
|
||||
next();
|
||||
else if (timer > lazyswitch) // If there's no pending message, we can chill for a bit.
|
||||
switch_mode(MM_OUT);
|
||||
break;
|
||||
case MM_OUT:
|
||||
if (timer > messages[0].length())
|
||||
next();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void next()
|
||||
{
|
||||
switch_mode(MM_IN);
|
||||
if (messages.size() > 0)
|
||||
messages.pop_front();
|
||||
}
|
||||
|
||||
} messagestate_t;
|
||||
|
||||
static std::vector<messagestate_t> messagestates{MAXSPLITSCREENPLAYERS};
|
||||
|
||||
void K_AddMessage(char *msg, boolean interrupt)
|
||||
{
|
||||
for (auto &state : messagestates)
|
||||
{
|
||||
if (interrupt)
|
||||
messages.clear();
|
||||
messages.push_back(msg);
|
||||
state.clear();
|
||||
state.add(msg);
|
||||
}
|
||||
}
|
||||
|
||||
// Return value can be used for "paired" splitscreen messages, true = was displayed
|
||||
void K_AddMessageForPlayer(player_t *player, char *msg, boolean interrupt)
|
||||
{
|
||||
if (!P_IsDisplayPlayer(player))
|
||||
if (!player)
|
||||
return;
|
||||
K_AddMessage(msg, interrupt);
|
||||
}
|
||||
|
||||
static void K_SwitchMessageMode(messagemode_t mode)
|
||||
{
|
||||
messagemode = mode;
|
||||
messagetimer = 0;
|
||||
}
|
||||
if (player && !P_IsDisplayPlayer(player))
|
||||
return;
|
||||
|
||||
static void K_NextMessage()
|
||||
{
|
||||
K_SwitchMessageMode(MM_IN);
|
||||
if (messages.size() > 0)
|
||||
messages.pop_front();
|
||||
messagestate_t *state = &messagestates[G_PartyPosition(player - players)];
|
||||
|
||||
if (interrupt)
|
||||
state->clear();
|
||||
|
||||
state->add(msg);
|
||||
}
|
||||
|
||||
void K_TickMessages()
|
||||
{
|
||||
if (messages.size() == 0)
|
||||
return;
|
||||
|
||||
if (messagetimer == 0 && messagemode == MM_IN)
|
||||
S_StartSound(NULL, sfx_cdfm15);
|
||||
|
||||
messagetimer++;
|
||||
|
||||
switch (messagemode)
|
||||
for (auto &state : messagestates)
|
||||
{
|
||||
case MM_IN:
|
||||
if (messagetimer > messages[0].length())
|
||||
K_SwitchMessageMode(MM_HOLD);
|
||||
break;
|
||||
case MM_HOLD:
|
||||
if (messages.size() > 1 && messagetimer > speedyswitch) // Waiting message, switch to it right away!
|
||||
K_NextMessage();
|
||||
else if (messagetimer > lazyswitch) // If there's no pending message, we can chill for a bit.
|
||||
K_SwitchMessageMode(MM_OUT);
|
||||
break;
|
||||
case MM_OUT:
|
||||
if (messagetimer > messages[0].length())
|
||||
K_NextMessage();
|
||||
break;
|
||||
state.tick();
|
||||
}
|
||||
}
|
||||
|
||||
static void K_DrawMessageFeed(void)
|
||||
{
|
||||
if (messages.size() == 0)
|
||||
return;
|
||||
int i;
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
{
|
||||
messagestate_t state = messagestates[i];
|
||||
|
||||
std::string msg = messages[0];
|
||||
if (state.messages.size() == 0)
|
||||
continue;
|
||||
|
||||
UINT8 sublen = messagetimer;
|
||||
if (messagemode == MM_IN)
|
||||
sublen = messagetimer;
|
||||
else if (messagemode == MM_HOLD)
|
||||
std::string msg = state.messages[0];
|
||||
|
||||
UINT8 sublen = state.timer;
|
||||
if (state.mode == MM_IN)
|
||||
sublen = state.timer;
|
||||
else if (state.mode == MM_HOLD)
|
||||
sublen = msg.length();
|
||||
else if (messagemode == MM_OUT)
|
||||
sublen = msg.length() - messagetimer;
|
||||
else if (state.mode == MM_OUT)
|
||||
sublen = msg.length() - state.timer;
|
||||
|
||||
std::string submsg = msg.substr(0, sublen);
|
||||
|
||||
using srb2::Draw;
|
||||
|
||||
Draw::TextElement text(submsg);
|
||||
|
||||
text.font(Draw::Font::kMenu);
|
||||
|
||||
UINT8 x = 160;
|
||||
UINT8 y = 10;
|
||||
SINT8 shift = 0;
|
||||
if (splitscreen > 2)
|
||||
{
|
||||
text.font(Draw::Font::kThin);
|
||||
shift = -2;
|
||||
|
||||
x = BASEVIDWIDTH/4;
|
||||
y = 5;
|
||||
|
||||
if (i % 2)
|
||||
x += BASEVIDWIDTH/2;
|
||||
|
||||
if (i >= 2)
|
||||
y += BASEVIDHEIGHT / 2;
|
||||
}
|
||||
else if (splitscreen > 1)
|
||||
{
|
||||
y = 5;
|
||||
|
||||
if (i >= 1)
|
||||
y += BASEVIDHEIGHT / 2;
|
||||
}
|
||||
UINT8 sw = text.width();
|
||||
|
||||
K_DrawSticker(x - sw/2, y, sw, 0, true);
|
||||
Draw(x, y).align(Draw::Align::kCenter).text(text);
|
||||
Draw(x, y+shift).align(Draw::Align::kCenter).text(text);
|
||||
}
|
||||
}
|
||||
|
||||
void K_drawKartHUD(void)
|
||||
|
|
|
|||
|
|
@ -3836,8 +3836,8 @@ void K_DoGuardBreak(mobj_t *t1, mobj_t *t2) {
|
|||
S_StartSound(t1, sfx_gbrk);
|
||||
K_AddHitLag(t1, 24, true);
|
||||
|
||||
K_AddMessageForPlayer(t1->player, va("Barrier Break..."), false);
|
||||
K_AddMessageForPlayer(t2->player, va("Smashed 'em!"), false);
|
||||
K_AddMessageForPlayer(t1->player, va("Barrier Break..."), false);
|
||||
|
||||
angle_t thrangle = R_PointToAngle2(t1->x, t1->y, t2->x, t2->y);
|
||||
P_Thrust(t1, thrangle, 7*mapobjectscale);
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include "k_kart.h"
|
||||
#include "k_objects.h"
|
||||
#include "k_powerup.h"
|
||||
#include "k_hud.h" // K_AddMessage
|
||||
|
||||
tic_t K_PowerUpRemaining(const player_t* player, kartitems_t powerup)
|
||||
{
|
||||
|
|
@ -52,24 +53,29 @@ void K_GivePowerUp(player_t* player, kartitems_t powerup, tic_t time)
|
|||
switch (powerup)
|
||||
{
|
||||
case POWERUP_SMONITOR:
|
||||
K_AddMessageForPlayer(player, va("Got S MONITOR!"), true);
|
||||
K_DoInvincibility(player, time);
|
||||
player->powerup.superTimer += time;
|
||||
break;
|
||||
|
||||
case POWERUP_BARRIER:
|
||||
K_AddMessageForPlayer(player, va("Got MEGA BARRIER!"), true);
|
||||
player->powerup.barrierTimer += time;
|
||||
Obj_SpawnMegaBarrier(player);
|
||||
break;
|
||||
|
||||
case POWERUP_BUMPER:
|
||||
K_AddMessageForPlayer(player, va("Got BUMPER RESTOCK!"), true);
|
||||
K_GiveBumpersToPlayer(player, nullptr, 5);
|
||||
break;
|
||||
|
||||
case POWERUP_BADGE:
|
||||
K_AddMessageForPlayer(player, va("Got RHYTHM BADGE!"), true);
|
||||
player->powerup.rhythmBadgeTimer += time;
|
||||
break;
|
||||
|
||||
case POWERUP_SUPERFLICKY:
|
||||
K_AddMessageForPlayer(player, va("Got SUPER FLICKY!"), true);
|
||||
if (K_PowerUpRemaining(player, POWERUP_SUPERFLICKY))
|
||||
{
|
||||
Obj_ExtendSuperFlickySwarm(player->powerup.flickyController, time);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue