mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Add persistent objective messages via K_AddMessage, expose to ACS
This commit is contained in:
parent
14d6477aad
commit
9b224356fe
8 changed files with 118 additions and 18 deletions
|
|
@ -47,6 +47,7 @@
|
|||
#include "../music.h"
|
||||
#include "../r_draw.h"
|
||||
#include "../k_dialogue.hpp"
|
||||
#include "../k_hud.h"
|
||||
|
||||
#include "call-funcs.hpp"
|
||||
|
||||
|
|
@ -3997,3 +3998,49 @@ bool CallFunc_GetThingUserProperty(ACSVM::Thread *thread, const ACSVM::Word *arg
|
|||
thread->dataStk.push(ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CallFunc_AddMessage(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
|
||||
{
|
||||
ACSVM::MapScope *map = thread->scopeMap;
|
||||
|
||||
K_AddMessage(map->getString(argV[0])->str, argV[1], argV[2]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CallFunc_AddMessageForPlayer(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
|
||||
{
|
||||
ACSVM::MapScope *map = thread->scopeMap;
|
||||
|
||||
auto info = &static_cast<Thread *>(thread)->info;
|
||||
|
||||
if ((info != NULL)
|
||||
&& (info->mo != NULL && P_MobjWasRemoved(info->mo) == false)
|
||||
&& (info->mo->player != NULL))
|
||||
{
|
||||
K_AddMessageForPlayer(info->mo->player, map->getString(argV[0])->str, argV[1], argV[2]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CallFunc_ClearPersistentMessages(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
|
||||
{
|
||||
K_ClearPersistentMessages();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CallFunc_ClearPersistentMessageForPlayer(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
|
||||
{
|
||||
auto info = &static_cast<Thread *>(thread)->info;
|
||||
|
||||
if ((info != NULL)
|
||||
&& (info->mo != NULL && P_MobjWasRemoved(info->mo) == false)
|
||||
&& (info->mo->player != NULL))
|
||||
{
|
||||
K_ClearPersistentMessageForPlayer(info->mo->player);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -123,4 +123,9 @@ bool CallFunc_GetSideUserProperty(ACSVM::Thread *thread, const ACSVM::Word *argV
|
|||
bool CallFunc_GetSectorUserProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
bool CallFunc_GetThingUserProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
|
||||
bool CallFunc_AddMessage(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
bool CallFunc_AddMessageForPlayer(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
bool CallFunc_ClearPersistentMessages(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
bool CallFunc_ClearPersistentMessageForPlayer(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
|
||||
#endif // __SRB2_ACS_CALL_FUNCS_HPP__
|
||||
|
|
|
|||
|
|
@ -873,8 +873,8 @@ boolean K_InstaWhipCollide(mobj_t *shield, mobj_t *victim)
|
|||
attackerPlayer->instaWhipCharge = 0;
|
||||
attackerPlayer->flashing = 0;
|
||||
|
||||
K_AddMessageForPlayer(victimPlayer, va("Whip Reflected!"), false);
|
||||
K_AddMessageForPlayer(attackerPlayer, va("COUNTERED!!"), false);
|
||||
K_AddMessageForPlayer(victimPlayer, "Whip Reflected!", false, false);
|
||||
K_AddMessageForPlayer(attackerPlayer, "COUNTERED!!", false, false);
|
||||
|
||||
// Localized broly for a local event.
|
||||
if (mobj_t *broly = Obj_SpawnBrolyKi(victim, victimHitlag/2))
|
||||
|
|
|
|||
|
|
@ -5635,7 +5635,9 @@ typedef struct
|
|||
typedef struct
|
||||
{
|
||||
std::deque<std::string> messages;
|
||||
std::string objective = "";
|
||||
tic_t timer = 0;
|
||||
boolean persist = false;
|
||||
messagemode_t mode = MM_IN;
|
||||
const tic_t speedyswitch = 2*TICRATE;
|
||||
const tic_t lazyswitch = 4*TICRATE;
|
||||
|
|
@ -5660,7 +5662,13 @@ typedef struct
|
|||
void tick()
|
||||
{
|
||||
if (messages.size() == 0)
|
||||
return;
|
||||
{
|
||||
if (!objective.empty())
|
||||
restore();
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (timer == 0 && mode == MM_IN)
|
||||
S_StartSound(NULL, sfx_s3k47);
|
||||
|
|
@ -5676,7 +5684,7 @@ typedef struct
|
|||
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.
|
||||
else if (timer > lazyswitch && !persist) // If there's no pending message, we can chill for a bit.
|
||||
switch_mode(MM_OUT);
|
||||
break;
|
||||
case MM_OUT:
|
||||
|
|
@ -5686,9 +5694,18 @@ typedef struct
|
|||
}
|
||||
}
|
||||
|
||||
void restore()
|
||||
{
|
||||
switch_mode(MM_IN);
|
||||
persist = true;
|
||||
messages.clear();
|
||||
messages.push_front(objective);
|
||||
}
|
||||
|
||||
void next()
|
||||
{
|
||||
switch_mode(MM_IN);
|
||||
persist = false;
|
||||
if (messages.size() > 0)
|
||||
messages.pop_front();
|
||||
}
|
||||
|
|
@ -5697,18 +5714,31 @@ typedef struct
|
|||
|
||||
static std::vector<messagestate_t> messagestates{MAXSPLITSCREENPLAYERS};
|
||||
|
||||
void K_AddMessage(char *msg, boolean interrupt)
|
||||
void K_AddMessage(const char *msg, boolean interrupt, boolean persist)
|
||||
{
|
||||
for (auto &state : messagestates)
|
||||
{
|
||||
if (interrupt)
|
||||
state.clear();
|
||||
state.add(msg);
|
||||
|
||||
if (persist)
|
||||
state.objective = msg;
|
||||
else
|
||||
state.add(msg);
|
||||
}
|
||||
}
|
||||
|
||||
void K_ClearPersistentMessages()
|
||||
{
|
||||
for (auto &state : messagestates)
|
||||
{
|
||||
state.objective = "";
|
||||
state.clear();
|
||||
}
|
||||
}
|
||||
|
||||
// Return value can be used for "paired" splitscreen messages, true = was displayed
|
||||
void K_AddMessageForPlayer(player_t *player, char *msg, boolean interrupt)
|
||||
void K_AddMessageForPlayer(player_t *player, const char *msg, boolean interrupt, boolean persist)
|
||||
{
|
||||
if (!player)
|
||||
return;
|
||||
|
|
@ -5721,7 +5751,22 @@ void K_AddMessageForPlayer(player_t *player, char *msg, boolean interrupt)
|
|||
if (interrupt)
|
||||
state->clear();
|
||||
|
||||
state->add(msg);
|
||||
if (persist)
|
||||
state->objective = msg;
|
||||
else
|
||||
state->add(msg);
|
||||
}
|
||||
|
||||
void K_ClearPersistentMessageForPlayer(player_t *player)
|
||||
{
|
||||
if (!player)
|
||||
return;
|
||||
|
||||
if (player && !P_IsDisplayPlayer(player))
|
||||
return;
|
||||
|
||||
messagestate_t *state = &messagestates[G_PartyPosition(player - players)];
|
||||
state->objective = "";
|
||||
}
|
||||
|
||||
void K_TickMessages()
|
||||
|
|
|
|||
|
|
@ -93,8 +93,10 @@ extern patch_t *kp_button_left[2];
|
|||
extern patch_t *kp_eggnum[6];
|
||||
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_AddMessage(const char *msg, boolean interrupt, boolean persist);
|
||||
void K_AddMessageForPlayer(player_t *player, const char *msg, boolean interrupt, boolean persist);
|
||||
void K_ClearPersistentMessages(void);
|
||||
void K_ClearPersistentMessageForPlayer(player_t *player);
|
||||
void K_TickMessages(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
|
|
@ -3841,8 +3841,8 @@ void K_DoGuardBreak(mobj_t *t1, mobj_t *t2) {
|
|||
S_StartSound(t1, sfx_gbrk);
|
||||
K_AddHitLag(t1, 24, true);
|
||||
|
||||
K_AddMessageForPlayer(t2->player, va("Smashed 'em!"), false);
|
||||
K_AddMessageForPlayer(t1->player, va("BARRIER BREAK!!"), false);
|
||||
K_AddMessageForPlayer(t2->player, "Smashed 'em!", false, false);
|
||||
K_AddMessageForPlayer(t1->player, "BARRIER BREAK!!", false, false);
|
||||
|
||||
angle_t thrangle = R_PointToAngle2(t1->x, t1->y, t2->x, t2->y);
|
||||
P_Thrust(t1, thrangle, 7*mapobjectscale);
|
||||
|
|
|
|||
|
|
@ -53,29 +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_AddMessageForPlayer(player, "Got S MONITOR!", true, false);
|
||||
K_DoInvincibility(player, time);
|
||||
player->powerup.superTimer += time;
|
||||
break;
|
||||
|
||||
case POWERUP_BARRIER:
|
||||
K_AddMessageForPlayer(player, va("Got MEGA BARRIER!"), true);
|
||||
K_AddMessageForPlayer(player, "Got MEGA BARRIER!", true, false);
|
||||
player->powerup.barrierTimer += time;
|
||||
Obj_SpawnMegaBarrier(player);
|
||||
break;
|
||||
|
||||
case POWERUP_BUMPER:
|
||||
K_AddMessageForPlayer(player, va("Got BUMPER RESTOCK!"), true);
|
||||
K_AddMessageForPlayer(player, "Got BUMPER RESTOCK!", true, false);
|
||||
K_GiveBumpersToPlayer(player, nullptr, 5);
|
||||
break;
|
||||
|
||||
case POWERUP_BADGE:
|
||||
K_AddMessageForPlayer(player, va("Got RHYTHM BADGE!"), true);
|
||||
K_AddMessageForPlayer(player, "Got RHYTHM BADGE!", true, false);
|
||||
player->powerup.rhythmBadgeTimer += time;
|
||||
break;
|
||||
|
||||
case POWERUP_SUPERFLICKY:
|
||||
K_AddMessageForPlayer(player, va("Got SUPER FLICKY!"), true);
|
||||
K_AddMessageForPlayer(player, "Got SUPER FLICKY!", true, false);
|
||||
if (K_PowerUpRemaining(player, POWERUP_SUPERFLICKY))
|
||||
{
|
||||
Obj_ExtendSuperFlickySwarm(player->powerup.flickyController, time);
|
||||
|
|
|
|||
|
|
@ -115,7 +115,8 @@ public:
|
|||
|
||||
Spawner* spawner = next(g_battleufo.previousId);
|
||||
UFO* ufo = static_cast<UFO*>(P_SpawnMobjFromMobj(spawner, 0, 0, 250*FRACUNIT - ofs, MT_BATTLEUFO));
|
||||
K_AddMessage(va("Crack the Combat UFO!"), true);
|
||||
|
||||
K_AddMessage("Crack the Combat UFO!", true, false);
|
||||
S_StartSound(NULL, sfx_mbs54);
|
||||
|
||||
ufo->sprzoff(ofs * spawner->scale());
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue