mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-04-26 20:11:47 +00:00
Merge branch 'message-drawer' into 'master'
Battle HUD message drawer See merge request KartKrew/Kart!1838
This commit is contained in:
commit
281d4e72bd
7 changed files with 196 additions and 0 deletions
|
|
@ -19,6 +19,7 @@
|
||||||
#include "k_powerup.h"
|
#include "k_powerup.h"
|
||||||
#include "k_hitlag.h"
|
#include "k_hitlag.h"
|
||||||
#include "m_random.h"
|
#include "m_random.h"
|
||||||
|
#include "k_hud.h" // K_AddMessage
|
||||||
|
|
||||||
angle_t K_GetCollideAngle(mobj_t *t1, mobj_t *t2)
|
angle_t K_GetCollideAngle(mobj_t *t1, mobj_t *t2)
|
||||||
{
|
{
|
||||||
|
|
@ -872,6 +873,9 @@ boolean K_InstaWhipCollide(mobj_t *shield, mobj_t *victim)
|
||||||
attackerPlayer->instaWhipCharge = 0;
|
attackerPlayer->instaWhipCharge = 0;
|
||||||
attackerPlayer->flashing = 0;
|
attackerPlayer->flashing = 0;
|
||||||
|
|
||||||
|
K_AddMessageForPlayer(victimPlayer, va("Whip Reflected!"), false);
|
||||||
|
K_AddMessageForPlayer(attackerPlayer, va("COUNTERED!!"), false);
|
||||||
|
|
||||||
// Localized broly for a local event.
|
// Localized broly for a local event.
|
||||||
if (mobj_t *broly = Obj_SpawnBrolyKi(victim, victimHitlag/2))
|
if (mobj_t *broly = Obj_SpawnBrolyKi(victim, victimHitlag/2))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
174
src/k_hud.cpp
174
src/k_hud.cpp
|
|
@ -12,6 +12,7 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <deque>
|
||||||
|
|
||||||
#include "v_draw.hpp"
|
#include "v_draw.hpp"
|
||||||
|
|
||||||
|
|
@ -5618,6 +5619,178 @@ static void K_DrawGPRankDebugger(void)
|
||||||
va(" ** FINAL GRADE: %c", gradeChar));
|
va(" ** FINAL GRADE: %c", gradeChar));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
MM_IN,
|
||||||
|
MM_HOLD,
|
||||||
|
MM_OUT,
|
||||||
|
} messagemode_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
std::string text;
|
||||||
|
sfxenum_t sound;
|
||||||
|
} message_t;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
void add(std::string msg)
|
||||||
|
{
|
||||||
|
messages.push_back(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
messages.clear();
|
||||||
|
switch_mode(MM_IN);
|
||||||
|
}
|
||||||
|
|
||||||
|
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_s3k47);
|
||||||
|
|
||||||
|
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)
|
||||||
|
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 (!player)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (player && !P_IsDisplayPlayer(player))
|
||||||
|
return;
|
||||||
|
|
||||||
|
messagestate_t *state = &messagestates[G_PartyPosition(player - players)];
|
||||||
|
|
||||||
|
if (interrupt)
|
||||||
|
state->clear();
|
||||||
|
|
||||||
|
state->add(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void K_TickMessages()
|
||||||
|
{
|
||||||
|
for (auto &state : messagestates)
|
||||||
|
{
|
||||||
|
state.tick();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void K_DrawMessageFeed(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i <= splitscreen; i++)
|
||||||
|
{
|
||||||
|
messagestate_t state = messagestates[i];
|
||||||
|
|
||||||
|
if (state.messages.size() == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
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 (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+shift).align(Draw::Align::kCenter).text(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void K_drawKartHUD(void)
|
void K_drawKartHUD(void)
|
||||||
{
|
{
|
||||||
boolean islonesome = false;
|
boolean islonesome = false;
|
||||||
|
|
@ -5911,6 +6084,7 @@ void K_drawKartHUD(void)
|
||||||
K_DrawBotDebugger();
|
K_DrawBotDebugger();
|
||||||
K_DrawDirectorDebugger();
|
K_DrawDirectorDebugger();
|
||||||
K_DrawGPRankDebugger();
|
K_DrawGPRankDebugger();
|
||||||
|
K_DrawMessageFeed();
|
||||||
}
|
}
|
||||||
|
|
||||||
void K_DrawSticker(INT32 x, INT32 y, INT32 width, INT32 flags, boolean isSmall)
|
void K_DrawSticker(INT32 x, INT32 y, INT32 width, INT32 flags, boolean isSmall)
|
||||||
|
|
|
||||||
|
|
@ -93,6 +93,10 @@ extern patch_t *kp_button_left[2];
|
||||||
extern patch_t *kp_eggnum[6];
|
extern patch_t *kp_eggnum[6];
|
||||||
extern patch_t *kp_facenum[MAXPLAYERS+1];
|
extern patch_t *kp_facenum[MAXPLAYERS+1];
|
||||||
|
|
||||||
|
void K_AddMessage(char *msg, boolean interrupt);
|
||||||
|
void K_AddMessageForPlayer(player_t *player, char *msg, boolean interrupt);
|
||||||
|
void K_TickMessages(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -3841,6 +3841,9 @@ void K_DoGuardBreak(mobj_t *t1, mobj_t *t2) {
|
||||||
S_StartSound(t1, sfx_gbrk);
|
S_StartSound(t1, sfx_gbrk);
|
||||||
K_AddHitLag(t1, 24, true);
|
K_AddHitLag(t1, 24, true);
|
||||||
|
|
||||||
|
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);
|
angle_t thrangle = R_PointToAngle2(t1->x, t1->y, t2->x, t2->y);
|
||||||
P_Thrust(t1, thrangle, 7*mapobjectscale);
|
P_Thrust(t1, thrangle, 7*mapobjectscale);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
#include "k_kart.h"
|
#include "k_kart.h"
|
||||||
#include "k_objects.h"
|
#include "k_objects.h"
|
||||||
#include "k_powerup.h"
|
#include "k_powerup.h"
|
||||||
|
#include "k_hud.h" // K_AddMessage
|
||||||
|
|
||||||
tic_t K_PowerUpRemaining(const player_t* player, kartitems_t powerup)
|
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)
|
switch (powerup)
|
||||||
{
|
{
|
||||||
case POWERUP_SMONITOR:
|
case POWERUP_SMONITOR:
|
||||||
|
K_AddMessageForPlayer(player, va("Got S MONITOR!"), true);
|
||||||
K_DoInvincibility(player, time);
|
K_DoInvincibility(player, time);
|
||||||
player->powerup.superTimer += time;
|
player->powerup.superTimer += time;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case POWERUP_BARRIER:
|
case POWERUP_BARRIER:
|
||||||
|
K_AddMessageForPlayer(player, va("Got MEGA BARRIER!"), true);
|
||||||
player->powerup.barrierTimer += time;
|
player->powerup.barrierTimer += time;
|
||||||
Obj_SpawnMegaBarrier(player);
|
Obj_SpawnMegaBarrier(player);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case POWERUP_BUMPER:
|
case POWERUP_BUMPER:
|
||||||
|
K_AddMessageForPlayer(player, va("Got BUMPER RESTOCK!"), true);
|
||||||
K_GiveBumpersToPlayer(player, nullptr, 5);
|
K_GiveBumpersToPlayer(player, nullptr, 5);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case POWERUP_BADGE:
|
case POWERUP_BADGE:
|
||||||
|
K_AddMessageForPlayer(player, va("Got RHYTHM BADGE!"), true);
|
||||||
player->powerup.rhythmBadgeTimer += time;
|
player->powerup.rhythmBadgeTimer += time;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case POWERUP_SUPERFLICKY:
|
case POWERUP_SUPERFLICKY:
|
||||||
|
K_AddMessageForPlayer(player, va("Got SUPER FLICKY!"), true);
|
||||||
if (K_PowerUpRemaining(player, POWERUP_SUPERFLICKY))
|
if (K_PowerUpRemaining(player, POWERUP_SUPERFLICKY))
|
||||||
{
|
{
|
||||||
Obj_ExtendSuperFlickySwarm(player->powerup.flickyController, time);
|
Obj_ExtendSuperFlickySwarm(player->powerup.flickyController, time);
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
#include "../k_battle.h"
|
#include "../k_battle.h"
|
||||||
#include "../k_objects.h"
|
#include "../k_objects.h"
|
||||||
#include "../k_kart.h"
|
#include "../k_kart.h"
|
||||||
|
#include "../k_hud.h" // K_AddMessage
|
||||||
|
|
||||||
using srb2::math::Fixed;
|
using srb2::math::Fixed;
|
||||||
using srb2::Mobj;
|
using srb2::Mobj;
|
||||||
|
|
@ -114,6 +115,8 @@ public:
|
||||||
|
|
||||||
Spawner* spawner = next(g_battleufo.previousId);
|
Spawner* spawner = next(g_battleufo.previousId);
|
||||||
UFO* ufo = static_cast<UFO*>(P_SpawnMobjFromMobj(spawner, 0, 0, 250*FRACUNIT - ofs, MT_BATTLEUFO));
|
UFO* ufo = static_cast<UFO*>(P_SpawnMobjFromMobj(spawner, 0, 0, 250*FRACUNIT - ofs, MT_BATTLEUFO));
|
||||||
|
K_AddMessage(va("Crack the Combat UFO!"), true);
|
||||||
|
S_StartSound(NULL, sfx_mbs54);
|
||||||
|
|
||||||
ufo->sprzoff(ofs * spawner->scale());
|
ufo->sprzoff(ofs * spawner->scale());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@
|
||||||
#include "music.h"
|
#include "music.h"
|
||||||
#include "k_dialogue.h"
|
#include "k_dialogue.h"
|
||||||
#include "m_easing.h"
|
#include "m_easing.h"
|
||||||
|
#include "k_hud.h" // messagetimer
|
||||||
|
|
||||||
#include "lua_profile.h"
|
#include "lua_profile.h"
|
||||||
|
|
||||||
|
|
@ -1203,6 +1204,7 @@ void P_Ticker(boolean run)
|
||||||
if (run && !levelloading && leveltime)
|
if (run && !levelloading && leveltime)
|
||||||
{
|
{
|
||||||
K_TickDialogue();
|
K_TickDialogue();
|
||||||
|
K_TickMessages();
|
||||||
}
|
}
|
||||||
|
|
||||||
LUA_HOOK(PostThinkFrame);
|
LUA_HOOK(PostThinkFrame);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue