Merge branch 'mania-time-trial' into 'master'

Mania-style time trials (resolves #747 mostly by accident)

Closes #747

See merge request KartKrew/Kart!1592
This commit is contained in:
Oni 2023-11-03 03:12:03 +00:00
commit 4e5e0835b5
10 changed files with 56 additions and 29 deletions

View file

@ -821,6 +821,7 @@ extern boolean thwompsactive;
extern UINT8 lastLowestLap;
extern SINT8 spbplace;
extern boolean rainbowstartavailable;
extern tic_t linecrossed;
extern boolean inDuel;
extern tic_t bombflashtimer; // Used to avoid causing seizures if multiple mines explode close to you :)

View file

@ -1171,9 +1171,18 @@ void G_GhostTicker(void)
demoghost *g,*p;
for(g = ghosts, p = NULL; g; g = g->next)
{
UINT16 ziptic;
UINT8 xziptic;
// Pause jhosts that cross until we cross ourself.
if (g->linecrossed && !linecrossed)
continue;
readghosttic:
// Skip normal demo data.
UINT16 ziptic = READUINT8(g->p);
UINT8 xziptic = 0;
ziptic = READUINT8(g->p);
xziptic = 0;
while (ziptic != DW_END) // Get rid of extradata stuff
{
@ -1198,6 +1207,8 @@ void G_GhostTicker(void)
g->p += 32; // ok (32 because there's both the skin and the colour)
if (ziptic & DXD_WEAPONPREF)
g->p++; // ditto
if (ziptic & DXD_START)
g->linecrossed = true;
}
else if (ziptic == DW_RNG)
{
@ -1463,6 +1474,9 @@ skippedghosttic:
continue;
}
if (linecrossed && !g->linecrossed)
goto readghosttic;
p = g;
#undef follow
}

View file

@ -126,6 +126,7 @@ extern UINT8 demo_writerng;
#define DXD_NAME 0x08 // name changed
#define DXD_COLOR 0x10 // color changed
#define DXD_FOLLOWER 0x20 // follower was changed
#define DXD_START 0x40 // Crossed the line in TA
#define DXD_ADDPLAYER (DXD_JOINDATA|DXD_PLAYSTATE|DXD_COLOR|DXD_NAME|DXD_SKIN|DXD_FOLLOWER)
@ -168,6 +169,7 @@ struct demoghost {
UINT8 fadein;
UINT16 version;
UINT8 numskins;
boolean linecrossed;
democharlist_t *skinlist;
mobj_t oldmo, *mo;
struct demoghost *next;

View file

@ -310,6 +310,7 @@ boolean thwompsactive; // Thwomps activate on lap 2
UINT8 lastLowestLap; // Last lowest lap, for activating race lap executors
SINT8 spbplace; // SPB exists, give the person behind better items
boolean rainbowstartavailable; // Boolean, keeps track of if the rainbow start was gotten
tic_t linecrossed; // For Time Attack
boolean inDuel; // Boolean, keeps track of if it is a 1v1
// Client-sided, unsynched variables (NEVER use in anything that needs to be synced with other players)
@ -328,6 +329,11 @@ UINT16 prevmap, nextmap;
char player_names[MAXPLAYERS][MAXPLAYERNAME+1];
INT32 player_name_changes[MAXPLAYERS];
boolean G_TimeAttackStart(void)
{
return (modeattacking && (gametyperules & (GTR_CIRCUIT|GTR_CATCHER)) == GTR_CIRCUIT);
}
// MAKE SURE YOU SAVE DATA BEFORE CALLING THIS
void G_ClearRecords(void)
{

View file

@ -263,6 +263,8 @@ void G_LoadGameSettings(void);
void G_SetGameModified(boolean silent, boolean major);
void G_SetUsedCheats(void);
boolean G_TimeAttackStart(void);
// Gamedata record shit
void G_ClearRecords(void);

View file

@ -118,6 +118,7 @@ void K_TimerReset(void)
darkness = darktimer = 0;
numbulbs = 1;
inDuel = rainbowstartavailable = false;
linecrossed = 0;
timelimitintics = extratimeintics = secretextratime = 0;
g_pointlimit = 0;
}
@ -262,6 +263,12 @@ void K_TimerInit(void)
introtime = 0;
}
if (G_TimeAttackStart())
{
starttime = 15*TICRATE; // Longest permitted start. No half-laps in reverse.
// (Changed on finish line cross later, don't worry.)
}
K_SpawnItemCapsules();
K_BattleInit(domodeattack);
@ -8332,7 +8339,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
// If the button stays held, delay charge a bit.
if (player->instaWhipChargeLockout)
player->instaWhipChargeLockout--;
if (player->rings > 0 || player->itemamount || player->ringdelay || player->rocketsneakertimer)
if (player->rings > 0 || player->itemamount || player->ringdelay || player->rocketsneakertimer || player->ringboxdelay)
player->instaWhipChargeLockout = INSTAWHIP_HOLD_DELAY;
else if (!(player->cmd.buttons & BT_ATTACK)) // Deliberate Item button release, no need to protect you from lockout
player->instaWhipChargeLockout = 0;
@ -8357,7 +8364,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
S_StopSoundByID(player->mo, sfx_wchrg2);
}
if (player->itemamount || player->respawn.state != RESPAWNST_NONE || player->pflags & (PF_ITEMOUT|PF_EGGMANOUT) || player->rocketsneakertimer)
if (player->itemamount || player->respawn.state != RESPAWNST_NONE || player->pflags & (PF_ITEMOUT|PF_EGGMANOUT) || player->rocketsneakertimer || player->ringboxdelay)
player->instaWhipCharge = 0;
if (player->tiregrease)

View file

@ -319,6 +319,13 @@ boolean M_Responder(event_t *ev)
}
#endif
// Attack modes quick-restart
if (CON_Ready() == false && modeattacking && G_PlayerInputDown(0, gc_y, splitscreen + 1) == true)
{
M_TryAgain(0);
return true;
}
if (CON_Ready() == false && G_PlayerInputDown(0, gc_start, splitscreen + 1) == true)
{
if (!chat_on)

View file

@ -283,7 +283,7 @@ static void K_DrawFinishLineBeamForLine(fixed_t offset, angle_t aiming, line_t *
y = liney + FixedMul(FixedMul(FINISHLINEBEAM_SPACING, FINESINE(lineangle >> ANGLETOFINESHIFT)), FINECOSINE(aiming >> ANGLETOFINESHIFT));
z = FINISHLINEBEAM_SPACING + FixedMul(FINISHLINEBEAM_SPACING, FINESINE(aiming >> ANGLETOFINESHIFT));
if (leveltime >= starttime)
if (leveltime >= starttime || G_TimeAttackStart())
{
spriteframe = 4; // Weakest sprite when passable
}

View file

@ -49,6 +49,7 @@
#include "k_objects.h"
#include "acs/interface.h"
#include "m_easing.h"
#include "music.h"
// Not sure if this is necessary, but it was in w_wad.c, so I'm putting it here too -Shadow Hog
#include <errno.h>
@ -1909,7 +1910,7 @@ static void K_HandleLapIncrement(player_t *player)
{
if (player)
{
if (leveltime < starttime && !(gametyperules & GTR_ROLLINGSTART))
if (!G_TimeAttackStart() && leveltime < starttime && !(gametyperules & GTR_ROLLINGSTART))
{
// freeze 'em until fault penalty is over
player->mo->hitlag = starttime - leveltime + TICRATE*3;
@ -1964,6 +1965,15 @@ static void K_HandleLapIncrement(player_t *player)
player->karthud[khud_lapanimation] = 80;
}
if (G_TimeAttackStart() && !linecrossed)
{
linecrossed = leveltime;
if (starttime > leveltime) // Overlong starts shouldn't reset time on cross
starttime = leveltime;
demo_extradata[player-players] |= DXD_START;
Music_Stop("position");
}
if (rainbowstartavailable == true && player->mo->hitlag == 0)
{
S_StartSound(player->mo, sfx_s23c);

View file

@ -1330,7 +1330,7 @@ void P_DoPlayerExit(player_t *player, pflags_t flags)
if (demo.playback == false)
{
if (modeattacking == true)
if (modeattacking)
{
G_UpdateRecords();
}
@ -2834,28 +2834,6 @@ static void P_DeathThink(player_t *player)
K_ToggleDirector(G_PartyPosition(player - players), true);
}
// Keep time rolling
if (!(player->exiting || mapreset) && !(player->pflags & PF_NOCONTEST) && !stoppedclock)
{
if (leveltime >= starttime)
{
player->realtime = leveltime - starttime;
if (player == &players[consoleplayer])
{
if (player->spectator)
curlap = 0;
else if (curlap != UINT32_MAX)
curlap++; // This is too complicated to sync to realtime, just sorta hope for the best :V
}
}
else
{
player->realtime = 0;
if (player == &players[consoleplayer])
curlap = 0;
}
}
if (!player->mo)
return;