Tally screen

This commit is contained in:
Sal 2023-09-09 05:27:55 +00:00 committed by Oni
parent c8eff3a957
commit 0675a4e527
27 changed files with 1877 additions and 411 deletions

View file

@ -151,6 +151,7 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32
k_powerup.cpp
k_hitlag.c
k_dialogue.cpp
k_tally.cpp
music.cpp
music_manager.cpp
)

View file

@ -32,6 +32,9 @@
// the player struct stores a waypoint for racing
#include "k_waypoint.h"
// struct to store tally screen data on
#include "k_tally.h"
#ifdef __cplusplus
extern "C" {
#endif
@ -287,7 +290,6 @@ typedef enum
khud_taunthorns, // Used to specifically stop taunt horn spam
// Battle
khud_cardanimation, // Used to determine the position of some full-screen Battle Mode graphics
khud_yougotem, // "You Got Em" gfx when hitting someone as a karma player via a method that gets you back in the game instantly
// Tricks
@ -827,6 +829,8 @@ struct player_t
sonicloopvars_t loop;
roundconditions_t roundconditions;
powerupvars_t powerup;
level_tally_t tally;
};
// WARNING FOR ANYONE ABOUT TO ADD SOMETHING TO THE PLAYER STRUCT, G_PlayerReborn WANTS YOU TO SUFFER

View file

@ -6281,7 +6281,6 @@ const char *const KARTHUD_LIST[] = {
"VOICES",
"TAUNTVOICES",
"CARDANIMATION",
"YOUGOTEM",
};

View file

@ -743,9 +743,6 @@ extern tic_t starttime;
extern const tic_t bulbtime;
extern UINT8 numbulbs;
extern tic_t raceexittime;
#define MUSICCOUNTDOWNMAX (raceexittime - (TICRATE/2))
extern INT32 hyudorotime;
extern INT32 stealtime;
extern INT32 sneakertime;

View file

@ -250,8 +250,6 @@ tic_t starttime = 3;
const tic_t bulbtime = TICRATE/2;
UINT8 numbulbs = 1;
tic_t raceexittime = 7*TICRATE + (TICRATE/2);
INT32 hyudorotime = 7*TICRATE;
INT32 stealtime = TICRATE/2;
INT32 sneakertime = TICRATE + (TICRATE/3);
@ -1933,7 +1931,7 @@ void G_Ticker(boolean run)
{
Music_Play("intermission");
}
else if (musiccountdown == (MUSICCOUNTDOWNMAX - (3*TICRATE)/2))
else if (musiccountdown == MUSIC_COUNTDOWN_MAX - TALLY_TIME)
{
P_EndingMusic();
}
@ -1968,6 +1966,9 @@ static inline void G_PlayerFinishLevel(INT32 player)
memset(&p->respawn, 0, sizeof (p->respawn));
p->spectatorReentry = 0; // Clean up any pending re-entry forbiddings
// Init player tally if we didn't get one set up in advance.
K_InitPlayerTally(p);
}
//
@ -2000,7 +2001,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
INT32 cheatchecknum;
INT32 exiting;
INT32 khudfinish;
INT32 khudcardanimation;
INT16 totalring;
UINT8 laps;
UINT8 latestlap;
@ -2049,6 +2049,9 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
roundconditions_t roundconditions;
boolean saveroundconditions;
level_tally_t tally;
boolean tallyactive;
// This needs to be first, to permit it to wipe extra information
jointime = players[player].jointime;
if (jointime <= 1)
@ -2148,10 +2151,10 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
roundscore = 0;
exiting = 0;
khudfinish = 0;
khudcardanimation = 0;
cheatchecknum = 0;
saveroundconditions = false;
tallyactive = false;
}
else
{
@ -2186,16 +2189,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
roundscore = players[player].roundscore;
exiting = players[player].exiting;
if (exiting > 0)
{
khudfinish = players[player].karthud[khud_finish];
khudcardanimation = players[player].karthud[khud_cardanimation];
}
else
{
khudfinish = 0;
khudcardanimation = 0;
}
khudfinish = (exiting > 0) ? players[player].karthud[khud_finish] : 0;
cheatchecknum = players[player].cheatchecknum;
@ -2203,6 +2197,12 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
memcpy(&roundconditions, &players[player].roundconditions, sizeof (roundconditions));
saveroundconditions = true;
tallyactive = players[player].tally.active;
if (tallyactive)
{
tally = players[player].tally;
}
}
spectatorReentry = (betweenmaps ? 0 : players[player].spectatorReentry);
@ -2281,7 +2281,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
p->cheatchecknum = cheatchecknum;
p->exiting = exiting;
p->karthud[khud_finish] = khudfinish;
p->karthud[khud_cardanimation] = khudcardanimation;
p->laps = laps;
p->latestlap = latestlap;
@ -2324,6 +2323,11 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
if (saveroundconditions)
memcpy(&p->roundconditions, &roundconditions, sizeof (p->roundconditions));
if (tallyactive == true)
{
p->tally = tally;
}
// See above comment about refcount consistency.
p->ringShooter = ringShooter;
p->hoverhyudoro = hoverhyudoro;
@ -2863,24 +2867,11 @@ void G_BeginLevelExit(void)
g_exit.losing = true;
g_exit.retry = false;
if (grandprixinfo.gp == true)
{
UINT8 i;
for (i = 0; i < MAXPLAYERS; i++)
{
if (playeringame[i] && !players[i].spectator)
{
K_PlayerFinishGrandPrix(&players[i]);
}
}
}
if (!G_GametypeUsesLives() || skipstats != 0)
{
g_exit.losing = false; // never force a retry
}
else if (specialstageinfo.valid == true || (gametyperules & GTR_BOSS))
else
{
UINT8 i;
@ -2896,10 +2887,6 @@ void G_BeginLevelExit(void)
}
}
}
else if (grandprixinfo.gp == true && grandprixinfo.eventmode == GPEVENT_NONE)
{
g_exit.losing = (grandprixinfo.wonround != true);
}
if (g_exit.losing)
{
@ -2920,13 +2907,11 @@ void G_BeginLevelExit(void)
}
}
if (g_exit.losing && specialstageinfo.valid)
exitcountdown = TICRATE;
if (grandprixinfo.gp == true)
{
exitcountdown = TICRATE;
}
else
{
exitcountdown = raceexittime+1;
grandprixinfo.wonround = !g_exit.losing;
}
if (g_exit.losing)
@ -2958,7 +2943,7 @@ void G_FinishExitLevel(void)
{
// We were in a Special Stage.
// We can still progress to the podium when we game over here.
const boolean special = grandprixinfo.gp == true && grandprixinfo.eventmode == GPEVENT_SPECIAL;
const boolean special = grandprixinfo.gp == true && grandprixinfo.cup != NULL && grandprixinfo.eventmode == GPEVENT_SPECIAL;
if (!netgame && !special)
{
@ -4006,7 +3991,7 @@ void G_GetNextMap(void)
//
static void G_DoCompleted(void)
{
INT32 i, j = 0;
INT32 i;
if (modeattacking && pausedelay)
pausedelay = 0;
@ -4053,30 +4038,62 @@ static void G_DoCompleted(void)
for (i = 0; i < MAXPLAYERS; i++)
{
if (playeringame[i])
if (playeringame[i] == false)
{
// Exitlevel shouldn't get you the points
if (!players[i].exiting && !(players[i].pflags & PF_NOCONTEST))
{
clientPowerAdd[i] = 0;
if (players[i].bot)
{
K_FakeBotResults(&players[i]);
}
else
{
players[i].pflags |= PF_NOCONTEST;
if (P_IsLocalPlayer(&players[i]))
{
j++;
}
}
}
G_PlayerFinishLevel(i); // take away cards and stuff
continue;
}
player_t *const player = &players[i];
// Exitlevel shouldn't get you the points
if (player->exiting == false && (player->pflags & PF_NOCONTEST) == 0)
{
clientPowerAdd[i] = 0;
if (player->bot == true)
{
K_FakeBotResults(player);
}
else
{
player->pflags |= PF_NOCONTEST;
}
}
if (grandprixinfo.gp == true && grandprixinfo.wonround == true && player->exiting == true)
{
if (player->bot == true)
{
// Bots are going to get harder... :)
K_IncreaseBotDifficulty(player);
}
else if (K_IsPlayerLosing(player) == false)
{
// Increase your total rings
INT32 ringtotal = player->hudrings;
if (ringtotal > 0)
{
if (ringtotal > 20)
ringtotal = 20;
player->totalring += ringtotal;
grandprixinfo.rank.rings += ringtotal;
}
if (grandprixinfo.eventmode == GPEVENT_NONE)
{
grandprixinfo.rank.winPoints += K_CalculateGPRankPoints(player->position, grandprixinfo.rank.totalPlayers);
grandprixinfo.rank.laps += player->lapPoints;
}
else if (grandprixinfo.eventmode == GPEVENT_SPECIAL)
{
grandprixinfo.rank.specialWon = true;
}
P_GivePlayerLives(player, player->xtralife);
}
}
G_PlayerFinishLevel(i); // take away cards and stuff
}
if (automapactive)

View file

@ -789,17 +789,6 @@ void K_PlayerLoseLife(player_t *player)
player->lives--;
player->pflags |= PF_LOSTLIFE;
#if 0
if (player->lives <= 0)
{
if (P_IsLocalPlayer(player))
{
S_StopMusic();
S_ChangeMusicInternal("gmover", false);
}
}
#endif
}
/*--------------------------------------------------
@ -842,63 +831,6 @@ boolean K_CanChangeRules(boolean allowdemos)
return true;
}
/*--------------------------------------------------
void K_PlayerFinishGrandPrix(player_t *player);
See header file for description.
--------------------------------------------------*/
void K_PlayerFinishGrandPrix(player_t *player)
{
if (grandprixinfo.wonround == true)
{
// This was already completed.
return;
}
if (player->exiting == false)
{
// You did not finish
return;
}
if (player->bot)
{
// Bots are going to get harder... :)
K_IncreaseBotDifficulty(player);
return;
}
if (K_IsPlayerLosing(player))
{
return;
}
// YOU WIN
grandprixinfo.wonround = true;
// Increase your total rings
INT32 ringtotal = player->hudrings;
if (ringtotal > 0)
{
if (ringtotal > 20)
ringtotal = 20;
player->totalring += ringtotal;
grandprixinfo.rank.rings += ringtotal;
}
if (grandprixinfo.eventmode == GPEVENT_NONE)
{
grandprixinfo.rank.winPoints += K_CalculateGPRankPoints(player->position, grandprixinfo.rank.totalPlayers);
grandprixinfo.rank.laps += player->lapPoints;
}
else if (grandprixinfo.eventmode == GPEVENT_SPECIAL)
{
grandprixinfo.rank.specialWon = true;
}
P_GivePlayerLives(player, player->xtralife);
}
/*--------------------------------------------------
boolean K_BotDefaultSpectator(player_t *player);

View file

@ -191,21 +191,6 @@ void K_PlayerLoseLife(player_t *player);
boolean K_CanChangeRules(boolean allowdemos);
/*--------------------------------------------------
void K_PlayerFinishGrandPrix(player_t *player);
Increases rank and bot difficulties, wins the round.
Input Arguments:-
player - Player to do this for.
Return:-
None
--------------------------------------------------*/
void K_PlayerFinishGrandPrix(player_t *player);
/*--------------------------------------------------
boolean K_BotDefaultSpectator(void)

View file

@ -2023,6 +2023,11 @@ static void K_DrawKartPositionNum(INT32 num)
INT32 fflags = 0;
UINT8 *color = NULL;
if (stplyr->lives <= 0 && stplyr->playerstate == PST_DEAD)
{
return;
}
if (leveltime < (starttime + NUMTRANSMAPS))
{
trans = (starttime + NUMTRANSMAPS) - leveltime;
@ -2033,7 +2038,7 @@ static void K_DrawKartPositionNum(INT32 num)
return;
}
if (stplyr->positiondelay || stplyr->exiting)
if (stplyr->positiondelay > 0 || K_PlayerTallyActive(stplyr) == true)
{
const UINT8 delay = (stplyr->exiting) ? POS_DELAY_TIME : stplyr->positiondelay;
const fixed_t add = (scale * 3) >> ((r_splitscreen == 1) ? 1 : 2);
@ -2128,7 +2133,7 @@ static void K_DrawKartPositionNum(INT32 num)
{
K_DrawKartPositionNumPatch(
0, color,
fx, fy, scale, V_SLIDEIN|V_SPLITSCREEN|fflags
fx, fy, scale, V_SPLITSCREEN|fflags
);
return;
@ -2143,7 +2148,7 @@ static void K_DrawKartPositionNum(INT32 num)
fx = K_DrawKartPositionNumPatch(
(num % 10), color,
fx, fy, scale, V_SLIDEIN|V_SPLITSCREEN|fflags
fx, fy, scale, V_SPLITSCREEN|fflags
);
num /= 10;
}
@ -4606,6 +4611,11 @@ static void K_drawKartStartCountdown(void)
{
INT32 pnum = 0;
if (stplyr->lives <= 0 && stplyr->playerstate == PST_DEAD)
{
return;
}
if (stplyr->karthud[khud_fault] != 0)
{
K_drawKartFinish(false);
@ -4654,115 +4664,6 @@ static void K_drawKartStartCountdown(void)
}
}
static void K_drawBattleFullscreen(void)
{
INT32 x = BASEVIDWIDTH/2;
INT32 y = -64+(stplyr->karthud[khud_cardanimation]); // card animation goes from 0 to 164, 164 is the middle of the screen
INT32 splitflags = V_SNAPTOTOP; // I don't feel like properly supporting non-green resolutions, so you can have a misuse of SNAPTO instead
fixed_t scale = FRACUNIT;
boolean drawcomebacktimer = true; // lazy hack because it's cleaner in the long run.
if (!LUA_HudEnabled(hud_battlecomebacktimer))
drawcomebacktimer = false;
if (r_splitscreen)
{
if ((r_splitscreen == 1 && stplyr == &players[displayplayers[1]])
|| (r_splitscreen > 1 && (stplyr == &players[displayplayers[2]]
|| (stplyr == &players[displayplayers[3]] && r_splitscreen > 2))))
{
y = 232-(stplyr->karthud[khud_cardanimation]/2);
splitflags = V_SNAPTOBOTTOM;
}
else
y = -32+(stplyr->karthud[khud_cardanimation]/2);
if (r_splitscreen > 1)
{
scale /= 2;
if (stplyr == &players[displayplayers[1]]
|| (stplyr == &players[displayplayers[3]] && r_splitscreen > 2))
x = 3*BASEVIDWIDTH/4;
else
x = BASEVIDWIDTH/4;
}
else
{
if (stplyr->exiting)
{
if (stplyr == &players[displayplayers[1]])
x = BASEVIDWIDTH-96;
else
x = 96;
}
else
scale /= 2;
}
}
if (stplyr->exiting)
{
if (stplyr == &players[displayplayers[0]])
V_DrawFadeScreen(0xFF00, 16);
if (exitcountdown <= (11*TICRATE)/2 && !stplyr->spectator)
{
patch_t *p = kp_battlecool;
if (K_IsPlayerLosing(stplyr))
p = kp_battlelose;
else if (stplyr->position == 1 && (!battleprisons || numtargets >= maptargets))
p = kp_battlewin;
V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, scale, splitflags, p, NULL);
}
K_drawKartFinish(true);
}
else if (stplyr->karmadelay && !stplyr->spectator && drawcomebacktimer)
{
UINT16 t = stplyr->karmadelay/(10*TICRATE);
INT32 txoff, adjust = (r_splitscreen > 1) ? 4 : 6; // normal string is 8, kart string is 12, half of that for ease
INT32 ty = (BASEVIDHEIGHT/2)+66;
txoff = adjust;
while (t)
{
txoff += adjust;
t /= 10;
}
if (r_splitscreen)
{
if (r_splitscreen > 1)
ty = (BASEVIDHEIGHT/4)+33;
if ((r_splitscreen == 1 && stplyr == &players[displayplayers[1]])
|| (stplyr == &players[displayplayers[2]] && r_splitscreen > 1)
|| (stplyr == &players[displayplayers[3]] && r_splitscreen > 2))
ty += (BASEVIDHEIGHT/2);
}
else
V_DrawFadeScreen(0xFF00, 16);
if (!comebackshowninfo)
V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, scale, splitflags, kp_battleinfo, NULL);
else
V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, scale, splitflags, kp_battlewait, NULL);
if (r_splitscreen > 1)
V_DrawString(x-txoff, ty, 0, va("%d", stplyr->karmadelay/TICRATE));
else
{
V_DrawFixedPatch(x<<FRACBITS, ty<<FRACBITS, scale, 0, kp_timeoutsticker, NULL);
V_DrawTimerString(x-txoff, ty, 0, va("%d", stplyr->karmadelay/TICRATE));
}
}
// FREE PLAY?
K_drawKartFreePlay();
}
static void K_drawKartFirstPerson(void)
{
static INT32 pnum[4], turn[4], drift[4];
@ -5520,7 +5421,6 @@ static void K_DrawGPRankDebugger(void)
void K_drawKartHUD(void)
{
boolean islonesome = false;
boolean battlefullscreen = false;
boolean freecam = demo.freecam; //disable some hud elements w/ freecam
UINT8 viewnum = R_GetViewNumber();
@ -5539,13 +5439,7 @@ void K_drawKartHUD(void)
return;
}
battlefullscreen = (!(gametyperules & GTR_CIRCUIT)
&& (stplyr->exiting
|| (((gametyperules & GTR_KARMA) && (stplyr->karmadelay > 0))
&& !(stplyr->pflags & PF_ELIMINATED)
&& stplyr->playerstate == PST_LIVE)));
if (!demo.title && (!battlefullscreen || r_splitscreen))
if (!demo.title)
{
// Draw the CHECK indicator before the other items, so it's overlapped by everything else
if (LUA_HudEnabled(hud_check)) // delete lua when?
@ -5569,13 +5463,6 @@ void K_drawKartHUD(void)
K_drawKartMinimap();
}
if (battlefullscreen && !freecam)
{
if (LUA_HudEnabled(hud_battlefullscreen))
K_drawBattleFullscreen();
return;
}
// Draw the item window
if (LUA_HudEnabled(hud_item) && !freecam)
{
@ -5638,6 +5525,11 @@ void K_drawKartHUD(void)
{
boolean gametypeinfoshown = false;
if (K_PlayerTallyActive(stplyr) == true)
{
K_DrawPlayerTally();
}
if (LUA_HudEnabled(hud_position))
{
if (bossinfo.valid)

View file

@ -47,6 +47,7 @@
#include "k_podium.h"
#include "k_powerup.h"
#include "k_hitlag.h"
#include "k_tally.h"
#include "music.h"
// SOME IMPORTANT VARIABLES DEFINED IN DOOMDEF.H:
@ -7277,7 +7278,7 @@ static void K_UpdateEngineSounds(player_t *player)
INT32 targetsnd = 0;
INT32 i;
if (leveltime < 8 || player->spectator || gamestate != GS_LEVEL)
if (leveltime < 8 || player->spectator || gamestate != GS_LEVEL || player->exiting)
{
// Silence the engines, and reset sound number while we're at it.
player->karthud[khud_enginesnd] = 0;
@ -7419,6 +7420,11 @@ static void K_UpdateInvincibilitySounds(player_t *player)
// It's just a convenient name for things that don't stop during hitlag.
void K_KartPlayerHUDUpdate(player_t *player)
{
if (K_PlayerTallyActive(player) == true)
{
K_TickPlayerTally(player);
}
if (player->karthud[khud_lapanimation])
player->karthud[khud_lapanimation]--;
@ -7536,29 +7542,6 @@ void K_KartPlayerHUDUpdate(player_t *player)
}
else
player->karthud[khud_finish] = 0;
if ((gametyperules & GTR_BUMPERS) && (player->exiting || player->karmadelay))
{
if (player->exiting)
{
if (exitcountdown < (11*TICRATE)/2)
player->karthud[khud_cardanimation] += ((164-player->karthud[khud_cardanimation])/8)+1;
}
else
{
if (player->karmadelay < 6*TICRATE)
player->karthud[khud_cardanimation] -= ((164-player->karthud[khud_cardanimation])/8)+1;
else if (player->karmadelay < 9*TICRATE)
player->karthud[khud_cardanimation] += ((164-player->karthud[khud_cardanimation])/8)+1;
}
if (player->karthud[khud_cardanimation] > 164)
player->karthud[khud_cardanimation] = 164;
if (player->karthud[khud_cardanimation] < 0)
player->karthud[khud_cardanimation] = 0;
}
else
player->karthud[khud_cardanimation] = 0;
}
#undef RINGANIM_DELAYMAX
@ -12245,7 +12228,7 @@ UINT32 K_PointLimitForGametype(void)
return 0;
}
if ((gametyperules & battleRules) == battleRules)
if ((gametyperules & battleRules) == battleRules) // why isn't this just another GTR_??
{
INT32 i;

1374
src/k_tally.cpp Normal file

File diff suppressed because it is too large Load diff

126
src/k_tally.h Normal file
View file

@ -0,0 +1,126 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) by Kart Krew
// Copyright (C) by Sally "TehRealSalt" Cochenour
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file k_tally.h
/// \brief End of level tally screen animations
#ifndef __K_TALLY_H__
#define __K_TALLY_H__
#include "typedef.h"
#include "doomtype.h"
#include "doomdef.h"
#include "sounds.h"
#define TALLY_WINDOW_SIZE (2)
#define TALLY_TIME (3*TICRATE)
#define MUSIC_COUNTDOWN_MAX (TALLY_TIME + 8*TICRATE)
typedef enum
{
TALLY_STAT_NA,
TALLY_STAT_TIME,
TALLY_STAT_TOTALRINGS,
} tally_stat_e;
typedef enum
{
TALLY_BONUS_NA,
TALLY_BONUS_RING,
TALLY_BONUS_LAP,
TALLY_BONUS_PRISON,
TALLY_BONUS_SCORE,
TALLY_BONUS_POWERSTONES,
} tally_bonus_e;
typedef enum
{
TALLY_ST_IGNORE,
TALLY_ST_GOTTHRU_SLIDEIN,
TALLY_ST_GOTTHRU_SLIDEUP,
TALLY_ST_BOXES_SLIDEIN,
TALLY_ST_TEXT_APPEAR,
TALLY_ST_TEXT_PAUSE,
TALLY_ST_GRADE_APPEAR,
TALLY_ST_GRADE_VOICE,
TALLY_ST_DONE,
TALLY_ST_GAMEOVER_SLIDEIN,
TALLY_ST_GAMEOVER_LIVES,
TALLY_ST_GAMEOVER_DONE,
} tally_state_e;
struct level_tally_t
{
boolean active;
player_t *owner;
UINT16 gt;
boolean gotThru;
char header[64];
UINT8 roundNum;
sfxenum_t gradeVoice;
// Stats
INT32 time;
UINT16 ringPool;
tally_stat_e stats[TALLY_WINDOW_SIZE];
// Possible grade metrics
UINT8 position, numPlayers;
UINT8 rings;
UINT16 laps, totalLaps;
UINT16 prisons, totalPrisons;
INT32 points, pointLimit;
UINT8 powerStones;
tally_bonus_e bonuses[TALLY_WINDOW_SIZE];
INT32 rank; // FIXME: should be gp_rank_e, weird circular dependency happened
// Animations
tally_state_e state;
INT32 hudSlide;
INT32 delay;
INT32 transition, transitionTime;
UINT8 lines, lineCount;
INT32 displayStat[TALLY_WINDOW_SIZE];
INT32 displayBonus[TALLY_WINDOW_SIZE];
UINT8 tickSound;
UINT8 xtraBlink;
boolean showGrade;
boolean done;
#ifdef __cplusplus
boolean UseBonuses(void);
void DetermineBonuses(void);
void DetermineStatistics(void);
INT32 CalculateGrade(void);
void Init(player_t *player);
void NewLine(void);
boolean IncrementLine(void);
void Tick(void);
void Draw(void);
#endif
};
#ifdef __cplusplus
extern "C" {
#endif
void K_InitPlayerTally(player_t *player);
void K_TickPlayerTally(player_t *player);
void K_DrawPlayerTally(void);
boolean K_PlayerTallyActive(player_t *player);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // __K_TALLY_H__

View file

@ -34,8 +34,6 @@ enum hud {
hud_check, // "CHECK" f-zero indicator
hud_minirankings, // Rankings to the left
hud_battlebumpers, // mini rankings battle bumpers.
hud_battlefullscreen, // battle huge text (WAIT, WIN, LOSE ...) + karma comeback time
hud_battlecomebacktimer, // comeback timer in battlefullscreen. separated for ease of use.
hud_wanted,
hud_speedometer,
hud_freeplay,

View file

@ -52,8 +52,6 @@ static const char *const hud_disable_options[] = {
"check", // "CHECK" f-zero indicator
"minirankings", // Gametype rankings to the left
"battlerankingsbumpers", // bumper drawer for battle. Useful if you want to make a custom battle gamemode without bumpers being involved.
"battlefullscreen", // battlefullscreen func (WAIT, ATTACK OR PROTECT ...)
"battlecomebacktimer", // come back timer in battlefullscreen
"wanted",
"speedometer",
"freeplay",

View file

@ -1567,6 +1567,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
if (!target->player->exiting)
{
target->player->pflags |= PF_NOCONTEST;
K_InitPlayerTally(target->player);
}
}
break;

View file

@ -647,6 +647,52 @@ static void P_NetArchivePlayers(savebuffer_t *save)
WRITEUINT16(save->p, players[i].powerup.superTimer);
WRITEUINT16(save->p, players[i].powerup.barrierTimer);
WRITEUINT16(save->p, players[i].powerup.rhythmBadgeTimer);
// level_tally_t
WRITEUINT8(save->p, players[i].tally.active);
if (players[i].tally.active)
{
WRITEUINT16(save->p, players[i].tally.gt);
WRITEUINT8(save->p, players[i].tally.gotThru);
WRITESTRINGN(save->p, players[i].tally.header, 63);
WRITEUINT8(save->p, players[i].tally.roundNum);
WRITEINT32(save->p, players[i].tally.gradeVoice);
WRITEINT32(save->p, players[i].tally.time);
WRITEUINT16(save->p, players[i].tally.ringPool);
for (q = 0; q < TALLY_WINDOW_SIZE; q++)
WRITEINT32(save->p, players[i].tally.stats[q]);
WRITEUINT8(save->p, players[i].tally.position);
WRITEUINT8(save->p, players[i].tally.numPlayers);
WRITEUINT8(save->p, players[i].tally.rings);
WRITEUINT16(save->p, players[i].tally.laps);
WRITEUINT16(save->p, players[i].tally.totalLaps);
WRITEUINT16(save->p, players[i].tally.prisons);
WRITEUINT16(save->p, players[i].tally.totalPrisons);
WRITEINT32(save->p, players[i].tally.points);
WRITEINT32(save->p, players[i].tally.pointLimit);
WRITEUINT8(save->p, players[i].tally.powerStones);
for (q = 0; q < TALLY_WINDOW_SIZE; q++)
WRITEINT32(save->p, players[i].tally.bonuses[q]);
WRITEINT32(save->p, players[i].tally.rank);
WRITEINT32(save->p, players[i].tally.state);
WRITEINT32(save->p, players[i].tally.hudSlide);
WRITEINT32(save->p, players[i].tally.delay);
WRITEINT32(save->p, players[i].tally.transition);
WRITEINT32(save->p, players[i].tally.transitionTime);
WRITEUINT8(save->p, players[i].tally.lines);
WRITEUINT8(save->p, players[i].tally.lineCount);
for (q = 0; q < TALLY_WINDOW_SIZE; q++)
WRITEINT32(save->p, players[i].tally.displayStat[q]);
for (q = 0; q < TALLY_WINDOW_SIZE; q++)
WRITEINT32(save->p, players[i].tally.displayBonus[q]);
WRITEUINT8(save->p, players[i].tally.tickSound);
WRITEUINT8(save->p, players[i].tally.xtraBlink);
WRITEUINT8(save->p, players[i].tally.showGrade);
WRITEUINT8(save->p, players[i].tally.done);
}
}
}
@ -1085,6 +1131,56 @@ static void P_NetUnArchivePlayers(savebuffer_t *save)
players[i].powerup.barrierTimer = READUINT16(save->p);
players[i].powerup.rhythmBadgeTimer = READUINT16(save->p);
// level_tally_t
players[i].tally.active = READUINT8(save->p);
if (players[i].tally.active)
{
players[i].tally.owner = &players[i];
players[i].tally.gt = READUINT16(save->p);
players[i].tally.gotThru = (boolean)READUINT8(save->p);
READSTRINGN(save->p, players[i].tally.header, 63);
players[i].tally.header[63] = '\0';
players[i].tally.roundNum = READUINT8(save->p);
players[i].tally.gradeVoice = READINT32(save->p);
players[i].tally.time = READINT32(save->p);
players[i].tally.ringPool = READUINT16(save->p);
for (q = 0; q < TALLY_WINDOW_SIZE; q++)
players[i].tally.stats[q] = READINT32(save->p);
players[i].tally.position = READUINT8(save->p);
players[i].tally.numPlayers = READUINT8(save->p);
players[i].tally.rings = READUINT8(save->p);
players[i].tally.laps = READUINT16(save->p);
players[i].tally.totalLaps = READUINT16(save->p);
players[i].tally.prisons = READUINT16(save->p);
players[i].tally.totalPrisons = READUINT16(save->p);
players[i].tally.points = READINT32(save->p);
players[i].tally.pointLimit = READINT32(save->p);
players[i].tally.powerStones = READUINT8(save->p);
for (q = 0; q < TALLY_WINDOW_SIZE; q++)
players[i].tally.bonuses[q] = READINT32(save->p);
players[i].tally.rank = READINT32(save->p);
players[i].tally.state = READINT32(save->p);
players[i].tally.hudSlide = READINT32(save->p);
players[i].tally.delay = READINT32(save->p);
players[i].tally.transition = READINT32(save->p);
players[i].tally.transitionTime = READINT32(save->p);
players[i].tally.lines = READUINT8(save->p);
players[i].tally.lineCount = READUINT8(save->p);
for (q = 0; q < TALLY_WINDOW_SIZE; q++)
players[i].tally.displayStat[q] = READINT32(save->p);
for (q = 0; q < TALLY_WINDOW_SIZE; q++)
players[i].tally.displayBonus[q] = READINT32(save->p);
players[i].tally.tickSound = READUINT8(save->p);
players[i].tally.xtraBlink = READUINT8(save->p);
players[i].tally.showGrade = (boolean)READUINT8(save->p);
players[i].tally.done = (boolean)READUINT8(save->p);
}
//players[i].viewheight = P_GetPlayerViewHeight(players[i]); // scale cannot be factored in at this point
}
}

View file

@ -2037,7 +2037,7 @@ static void K_HandleLapIncrement(player_t *player)
if (nump > 1 && K_IsPlayerLosing(player) == false)
{
if (nump > 2 && player->position == 1) // 1st place in 1v1 uses thumbs up
if (inDuel == false && player->position == 1) // 1st place in 1v1 uses thumbs up
{
player->lapPoints += 2;
}
@ -4482,7 +4482,7 @@ static void P_SetupSignObject(mobj_t *sign, mobj_t *pmo, boolean error)
P_SetMobjState(sign, S_SIGN_POLE);
sign->movefactor = sign->z;
sign->z += (768*sign->scale) * P_MobjFlip(sign);
sign->z += (576*sign->scale) * P_MobjFlip(sign);
sign->movecount = 1;
sign->extravalue1 = AngleFixed(sign->angle) >> FRACBITS;

View file

@ -942,7 +942,6 @@ void P_Ticker(boolean run)
if (racecountdown > 1)
racecountdown--;
const fixed_t darkdelta = FRACUNIT/50;
const fixed_t maxdark = FRACUNIT/7;
if (darktimer) // dark or darkening
@ -960,12 +959,35 @@ void P_Ticker(boolean run)
darkness = 0;
}
if (exitcountdown > 1)
if (exitcountdown >= 1)
{
exitcountdown--;
if (server && exitcountdown == 1)
boolean run_exit_countdown = true;
for (i = 0; i < MAXPLAYERS; i++)
{
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
if (playeringame[i] == false)
{
continue;
}
player_t *player = &players[i];
if (K_PlayerTallyActive(player) == true && player->tally.done == false)
{
run_exit_countdown = false;
break;
}
}
if (run_exit_countdown == true)
{
if (exitcountdown > 1)
{
exitcountdown--;
}
if (server && exitcountdown == 1)
{
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
}
}
}

View file

@ -65,6 +65,7 @@
#include "g_party.h"
#include "k_profiles.h"
#include "music.h"
#include "k_tally.h"
#ifdef HW3SOUND
#include "hardware/hw3sound.h"
@ -1278,10 +1279,10 @@ void P_DoPlayerExit(player_t *player, pflags_t flags)
K_PlayerLoseLife(player);
}
if (P_IsLocalPlayer(player) && !specialout)
if (P_IsLocalPlayer(player) && !specialout && musiccountdown == 0)
{
Music_StopAll();
musiccountdown = MUSICCOUNTDOWNMAX;
musiccountdown = MUSIC_COUNTDOWN_MAX;
}
player->exiting = 1;
@ -1307,7 +1308,6 @@ void P_DoPlayerExit(player_t *player, pflags_t flags)
if (extra > oldExtra)
{
S_StartSound(NULL, sfx_cdfm73);
player->xtralife = (extra - oldExtra);
}
}
@ -1317,26 +1317,6 @@ void P_DoPlayerExit(player_t *player, pflags_t flags)
{
K_UpdateAllPlayerPositions();
if (cv_kartvoices.value && !(gametyperules & GTR_SPECIALSTART))
{
if (P_IsDisplayPlayer(player))
{
sfxenum_t sfx_id;
if (losing)
sfx_id = ((skin_t *)player->mo->skin)->soundsid[S_sfx[sfx_klose].skinsound];
else
sfx_id = ((skin_t *)player->mo->skin)->soundsid[S_sfx[sfx_kwin].skinsound];
S_StartSound(NULL, sfx_id);
}
else
{
if (losing)
S_StartSound(player->mo, sfx_klose);
else
S_StartSound(player->mo, sfx_kwin);
}
}
if (P_CheckRacers() && !exitcountdown)
{
G_BeginLevelExit();
@ -1348,6 +1328,8 @@ void P_DoPlayerExit(player_t *player, pflags_t flags)
}
}
K_InitPlayerTally(player);
if (demo.playback == false)
{
if (modeattacking == true)
@ -1373,8 +1355,6 @@ void P_DoPlayerExit(player_t *player, pflags_t flags)
if (player == &players[consoleplayer])
demo.savebutton = leveltime;
}
player->karthud[khud_cardanimation] = 0; // srb2kart: reset battle animation
}
//
@ -1384,7 +1364,6 @@ void P_DoPlayerExit(player_t *player, pflags_t flags)
void P_DoAllPlayersExit(pflags_t flags, boolean trygivelife)
{
UINT8 i;
boolean givenlife = false;
const boolean dofinishsound = (musiccountdown == 0);
for (i = 0; i < MAXPLAYERS; i++)
@ -1406,7 +1385,6 @@ void P_DoAllPlayersExit(pflags_t flags, boolean trygivelife)
}
P_GivePlayerLives(&players[i], 1);
givenlife = true;
}
if (!dofinishsound)
@ -1429,12 +1407,6 @@ void P_DoAllPlayersExit(pflags_t flags, boolean trygivelife)
// Everyone finish sound
S_StartSound(NULL, sfx_s3k6a);
}
if (givenlife)
{
// Life sound
S_StartSound(NULL, sfx_cdfm73);
}
}
//
@ -3744,16 +3716,18 @@ void P_DoTimeOver(player_t *player)
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_TIMEOVER);
}
if (P_IsLocalPlayer(player))
if (P_IsLocalPlayer(player) && musiccountdown == 0)
{
Music_StopAll();
musiccountdown = MUSICCOUNTDOWNMAX;
musiccountdown = MUSIC_COUNTDOWN_MAX;
}
if (!exitcountdown)
{
G_BeginLevelExit();
}
K_InitPlayerTally(player);
}
// SRB2Kart: These are useful functions, but we aren't using them yet.
@ -3984,6 +3958,27 @@ void P_PlayerThink(player_t *player)
player->playerstate = PST_DEAD;
}
if (G_GametypeUsesLives() == true && player->lives <= 0 && player->playerstate != PST_DEAD)
{
player->mo->flags &= ~(MF_SOLID|MF_SHOOTABLE); // does not block
P_UnsetThingPosition(player->mo);
player->mo->flags |= MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY;
P_SetThingPosition(player->mo);
player->mo->standingslope = NULL;
player->mo->terrain = NULL;
player->mo->pmomz = 0;
player->playerstate = PST_DEAD;
// respawn from where you died
player->respawn.pointx = player->mo->x;
player->respawn.pointy = player->mo->y;
player->respawn.pointz = player->mo->z;
player->pflags |= PF_LOSTLIFE|PF_ELIMINATED|PF_NOCONTEST;
K_InitPlayerTally(player);
}
// Erasing invalid player pointers
{
#define PlayerPointerErase(field) \

View file

@ -1208,6 +1208,8 @@ sfxinfo_t S_sfx[NUMSFX] =
{"dashr", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Regular Dash Ring
{"rainbr", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Rainbow Dash Ring
{"rank", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Rank slam
// SRB2Kart - Engine sounds
// Engine class A
{"krta00", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR, ""},

View file

@ -1277,6 +1277,8 @@ typedef enum
sfx_dashr,
sfx_rainbr,
sfx_rank,
// Next up: UNIQUE ENGINE SOUNDS! Hoooooo boy...
// Engine class A - Low Speed, Low Weight
sfx_krta00,

View file

@ -221,6 +221,9 @@ TYPEDEF (waypoint_t);
// k_rank.h
TYPEDEF (gpRank_t);
// k_tally.h
TYPEDEF (level_tally_t);
// k_zvote.h
TYPEDEF (midVote_t);
TYPEDEF (midVoteGUI_t);

View file

@ -91,7 +91,7 @@ Chain::Clipper::Clipper(const Chain& chain)
FloatToFixed(chain.clipy1_),
FloatToFixed(chain.clipx2_ - chain.clipx1_),
FloatToFixed(chain.clipy2_ - chain.clipy1_),
0
chain.flags_
);
}
@ -121,6 +121,9 @@ int Draw::font_to_fontno(Font font)
case Font::kPing:
return PINGF_FONT;
case Font::kTimer:
return TIMER_FONT;
}
return TINY_FONT;

View file

@ -36,6 +36,7 @@ public:
kFreeplay,
kZVote,
kPing,
kTimer,
};
enum class Align
@ -99,6 +100,7 @@ public:
public:
float x() const { return x_; }
float y() const { return y_; }
INT32 flags() const { return flags_; }
// Methods add relative to the current state
Chain& x(float x);
@ -188,6 +190,7 @@ public:
float x() const { return chain_.x(); }
float y() const { return chain_.y(); }
INT32 flags() const { return chain_.flags(); }
#define METHOD(Name) \
template <typename... Args>\

View file

@ -575,6 +575,7 @@ void V_AdjustXYWithSnap(INT32 *x, INT32 *y, UINT32 options, INT32 dupx, INT32 du
{
const tic_t length = TICRATE/4;
tic_t timer = lt_exitticker;
if (K_CheckBossIntro() == true || G_IsTitleCardAvailable() == false)
{
if (leveltime <= 16)
@ -583,6 +584,11 @@ void V_AdjustXYWithSnap(INT32 *x, INT32 *y, UINT32 options, INT32 dupx, INT32 du
timer = leveltime-16;
}
if (stplyr->tally.hudSlide != 0)
{
timer = length - stplyr->tally.hudSlide;
}
if (timer < length)
{
if ((options & (V_SNAPTORIGHT|V_SNAPTOLEFT|V_SPLITSCREEN)) != 0)
@ -1988,10 +1994,10 @@ INT32 V_CenteredTitleCardStringOffset(const char *str, boolean p4)
return Internal_TitleCardStringOffset<true>(str, p4);
}
// V_DrawTitleCardScreen.
// V_DrawTitleCardStringFixed.
// see v_video.h's prototype for more information.
//
void V_DrawTitleCardString(INT32 x, INT32 y, const char *str, INT32 flags, boolean bossmode, INT32 timer, INT32 threshold, boolean p4)
void V_DrawTitleCardStringFixed(fixed_t x, fixed_t y, fixed_t scale, const char *str, INT32 flags, boolean bossmode, INT32 timer, INT32 threshold, boolean p4)
{
int bg_font = GTOL_FONT;
int fg_font = GTFN_FONT;
@ -2018,11 +2024,12 @@ void V_DrawTitleCardString(INT32 x, INT32 y, const char *str, INT32 flags, boole
patch_t *pp;
patch_t *ol;
x -= 2; // Account for patch width...
x -= 2 * scale; // Account for patch width...
if (flags & V_SNAPTORIGHT)
x -= V_TitleCardStringWidth(str, p4);
{
x -= V_TitleCardStringWidth(str, p4) * scale;
}
for (;;ch++, i++)
{
@ -2038,7 +2045,7 @@ void V_DrawTitleCardString(INT32 x, INT32 y, const char *str, INT32 flags, boole
if (*ch == '\n')
{
xoffs = x;
yoffs += p4 ? 18 : 32;
yoffs += (p4 ? 18 : 32) * scale;
continue;
}
@ -2051,7 +2058,7 @@ void V_DrawTitleCardString(INT32 x, INT32 y, const char *str, INT32 flags, boole
// check if character exists, if not, it's a space.
if (c < 0 || c >= LT_FONTSIZE || !fontv[fg_font].font[(INT32)c])
{
xoffs += p4 ? 5 : 10;
xoffs += (p4 ? 5 : 10) * scale;
continue;
}
@ -2105,11 +2112,11 @@ void V_DrawTitleCardString(INT32 x, INT32 y, const char *str, INT32 flags, boole
if (scalex && ol && pp)
{
//CONS_Printf("%d\n", (INT32)c);
V_DrawStretchyFixedPatch((x + xoffs)*FRACUNIT + offs, (y+yoffs)*FRACUNIT, abs(scalex), FRACUNIT, flags|flipflag, ol, NULL);
V_DrawStretchyFixedPatch((x + xoffs)*FRACUNIT + offs, (y+yoffs)*FRACUNIT, abs(scalex), FRACUNIT, flags|flipflag, pp, NULL);
V_DrawStretchyFixedPatch((x + xoffs) + offs, (y+yoffs), FixedMul(abs(scalex), scale), scale, flags|flipflag, ol, NULL);
V_DrawStretchyFixedPatch((x + xoffs) + offs, (y+yoffs), FixedMul(abs(scalex), scale), scale, flags|flipflag, pp, NULL);
}
xoffs += pp->width - (p4 ? 3 : 5);
xoffs += (pp->width - (p4 ? 3 : 5)) * scale;
}
}

View file

@ -347,7 +347,9 @@ void V_DrawRightAlignedThinStringAtFixed(fixed_t x, fixed_t y, INT32 option, con
// threshold: when the letters start disappearing (leave to 0 to disable) (both are INT32 in case you supply negative values...)
// NOTE: This function ignores most conventional string flags (V_RETURN8, V_FORCEUPPERCASE ...)
// NOTE: This font only works with uppercase letters.
void V_DrawTitleCardString(INT32 x, INT32 y, const char *str, INT32 flags, boolean bossmode, INT32 timer, INT32 threshold, boolean p4);
void V_DrawTitleCardStringFixed(fixed_t x, fixed_t y, fixed_t scale, const char *str, INT32 flags, boolean bossmode, INT32 timer, INT32 threshold, boolean p4);
#define V_DrawTitleCardString( x,y,str,flags,bossmode,timer,threshold,p4 ) \
V_DrawTitleCardStringFixed ((x)<<FRACBITS,(y)<<FRACBITS,FRACUNIT,str,flags,bossmode,timer,threshold,p4)
// returns thr width of a string drawn using the above function.
INT32 V_TitleCardStringWidth(const char *str, boolean p4);

View file

@ -1410,6 +1410,76 @@ void Y_DrawIntermissionButton(INT32 startslide, INT32 through)
}
}
void Y_DrawIntermissionHeader(fixed_t x, fixed_t y, boolean gotthrough, const char *headerstring, UINT8 roundnum, boolean small)
{
const INT32 v_width = (small ? BASEVIDWIDTH/2 : BASEVIDWIDTH);
const fixed_t frac = (small ? FRACUNIT/2 : FRACUNIT);
const INT32 small_flag = (small ? V_SPLITSCREEN : 0);
if (small && r_splitscreen > 1)
{
V_SetClipRect(
0,
0,
v_width << FRACBITS,
BASEVIDHEIGHT << FRACBITS,
V_SPLITSCREEN
);
}
// Header bar
patch_t *rtpbr = W_CachePatchName((small ? "R_RTPB4" : "R_RTPBR"), PU_PATCH);
V_DrawFixedPatch((20 * frac) + x, (24 * frac) + y, FRACUNIT, small_flag, rtpbr, NULL);
fixed_t headerx, headery, headerwidth = 0;
if (gotthrough)
{
headerx = (51 * frac);
headery = (7 * frac);
}
else
{
headerwidth = V_TitleCardStringWidth(headerstring, small);
headerx = (v_width - headerwidth) * (FRACUNIT / 2);
headery = 17 * frac;
}
// Draw round numbers
if (roundnum > 0 && roundnum <= 10)
{
patch_t *roundpatch =
W_CachePatchName(
va("TT_RN%s%d", (small ? "S" : "D"), roundnum),
PU_PATCH
);
fixed_t roundx = (v_width * 3 * FRACUNIT) / 4;
if (headerwidth != 0)
{
const fixed_t roundoffset = (8 * frac) + (roundpatch->width * FRACUNIT);
roundx = headerx + roundoffset;
headerx -= roundoffset/2;
}
V_DrawFixedPatch(x + roundx, (39 * frac) + y, FRACUNIT, small_flag, roundpatch, NULL);
}
V_DrawTitleCardStringFixed(x + headerx, y + headery, FRACUNIT, headerstring, small_flag, false, 0, 0, small);
if (gotthrough)
{
// GOT THROUGH ROUND
patch_t *gthro = W_CachePatchName((small ? "R_GTHR4" : "R_GTHRO"), PU_PATCH);
V_DrawFixedPatch((50 * frac) + x, (42 * frac) + y, FRACUNIT, small_flag, gthro, NULL);
}
V_ClearClipRect();
}
//
// Y_IntermissionDrawer
//
@ -1488,54 +1558,7 @@ void Y_IntermissionDrawer(void)
}
// Draw the header bar
{
// Header bar
patch_t *rtpbr = W_CachePatchName("R_RTPBR", PU_PATCH);
V_DrawMappedPatch(20 + x, 24, 0, rtpbr, NULL);
INT32 headerx, headery, headerwidth = 0;
if (data.gotthrough)
{
// GOT THROUGH ROUND
patch_t *gthro = W_CachePatchName("R_GTHRO", PU_PATCH);
V_DrawMappedPatch(50 + x, 42, 0, gthro, NULL);
headerx = 51;
headery = 7;
}
else
{
headerwidth = V_TitleCardStringWidth(data.headerstring, false);
headerx = (BASEVIDWIDTH - headerwidth)/2;
headery = 17;
}
// Draw round numbers
if (data.roundnum > 0 && data.roundnum <= 10)
{
patch_t *roundpatch =
W_CachePatchName(
va("TT_RND%d", data.roundnum),
PU_PATCH
);
INT32 roundx = 240;
if (headerwidth != 0)
{
const INT32 roundoffset = 8 + SHORT(roundpatch->width);
roundx = headerx + roundoffset;
headerx -= roundoffset/2;
}
V_DrawMappedPatch(x + roundx, 39, 0, roundpatch, NULL);
}
V_DrawTitleCardString(x + headerx, headery, data.headerstring, 0, false, 0, 0, false);
}
Y_DrawIntermissionHeader(x << FRACBITS, 0, data.gotthrough, data.headerstring, data.roundnum, false);
// Returns early if there's no players to draw
Y_PlayerStandingsDrawer(&data, x);

View file

@ -45,6 +45,7 @@ typedef struct
INT32 linemeter; // For GP only
} y_data_t;
void Y_DrawIntermissionHeader(INT32 x, INT32 y, boolean gotthrough, const char *headerstring, UINT8 roundnum, boolean small);
void Y_IntermissionDrawer(void);
void Y_Ticker(void);