Big vote screen cleanup

- 4th map is now a regular option instead of dice.
- Add function to draw a maintained Combi Catcher object on screen.
- Put all vote static variables into either a "vote" struct or a "vote_draw" struct, if it's logic or drawing code.
- Prefix netcode vote globals with _g.
- Add enums/defines for vote magic numbers.
This commit is contained in:
Sally Coolatta 2023-04-04 01:49:12 -04:00
parent f1ec39764f
commit 8432d7e552
7 changed files with 620 additions and 611 deletions

View file

@ -2615,30 +2615,18 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pencoremode, boolean r
void D_SetupVote(void) void D_SetupVote(void)
{ {
UINT8 buf[5*2]; // four UINT16 maps (at twice the width of a UINT8), and two gametypes UINT8 buf[(VOTE_NUM_LEVELS * 2) + 2]; // four UINT16 maps (at twice the width of a UINT8), and two gametypes
UINT8 *p = buf; UINT8 *p = buf;
INT32 i; INT32 i;
UINT8 secondgt = G_SometimesGetDifferentGametype(); INT16 votebuffer[VOTE_NUM_LEVELS] = {-1};
INT16 votebuffer[4] = {-1,-1,-1,0};
if ((cv_kartencore.value == 1) && (gametyperules & GTR_ENCORE)) WRITEUINT8(p, ((cv_kartencore.value == 1) && (gametyperules & GTR_ENCORE)));
WRITEUINT8(p, (gametype|VOTEMODIFIER_ENCORE)); WRITEUINT8(p, G_SometimesGetDifferentEncore());
else
WRITEUINT8(p, gametype);
WRITEUINT8(p, secondgt);
secondgt &= ~VOTEMODIFIER_ENCORE;
for (i = 0; i < 4; i++) for (i = 0; i < VOTE_NUM_LEVELS; i++)
{ {
UINT16 m; UINT16 m = G_RandMap(G_TOLFlag(gametype), prevmap, 0, 0, true, votebuffer);
if (i == 2) // sometimes a different gametype votebuffer[i] = m;
m = G_RandMap(G_TOLFlag(secondgt), prevmap, ((secondgt != gametype) ? 2 : 0), 0, true, votebuffer);
else if (i >= 3) // Don't Care. Pick any of the available choices.
m = votebuffer[M_RandomRange(0, 2)];
else
m = G_RandMap(G_TOLFlag(gametype), prevmap, 0, 0, true, votebuffer);
if (i < 3)
votebuffer[i] = m;
WRITEUINT16(p, m); WRITEUINT16(p, m);
} }
@ -2672,13 +2660,13 @@ void D_PickVote(void)
{ {
if (!playeringame[i] || players[i].spectator) if (!playeringame[i] || players[i].spectator)
continue; continue;
if (votes[i] != -1) if (g_votes[i] != -1)
{ {
temppicks[numvotes] = i; temppicks[numvotes] = i;
templevels[numvotes] = votes[i]; templevels[numvotes] = g_votes[i];
numvotes++; numvotes++;
if (votecompare == -1) if (votecompare == -1)
votecompare = votes[i]; votecompare = g_votes[i];
} }
} }
@ -5371,75 +5359,55 @@ static void Got_ExitLevelcmd(UINT8 **cp, INT32 playernum)
static void Got_SetupVotecmd(UINT8 **cp, INT32 playernum) static void Got_SetupVotecmd(UINT8 **cp, INT32 playernum)
{ {
boolean baseEncore = false;
boolean optionalEncore = false;
INT16 tempVoteLevels[VOTE_NUM_LEVELS][2];
INT32 i; INT32 i;
UINT8 gt, secondgt;
INT16 tempvotelevels[4][2];
if (playernum != serverplayer) // admin shouldn't be able to set up vote... if (playernum != serverplayer) // admin shouldn't be able to set up vote...
{ {
CONS_Alert(CONS_WARNING, M_GetText("Illegal vote setup received from %s\n"), player_names[playernum]); CONS_Alert(CONS_WARNING, M_GetText("Illegal vote setup received from %s\n"), player_names[playernum]);
if (server) if (server)
SendKick(playernum, KICK_MSG_CON_FAIL);
return;
}
gt = (UINT8)READUINT8(*cp);
secondgt = (UINT8)READUINT8(*cp);
// Strip illegal Encore flag.
if ((gt & VOTEMODIFIER_ENCORE)
&& !(gametypes[(gt & ~VOTEMODIFIER_ENCORE)]->rules & GTR_ENCORE))
{
gt &= ~VOTEMODIFIER_ENCORE;
}
if ((gt & ~VOTEMODIFIER_ENCORE) >= numgametypes)
{
gt &= ~VOTEMODIFIER_ENCORE;
if (server)
I_Error("Got_SetupVotecmd: Internal gametype ID %d not found (numgametypes = %d)", gt, numgametypes);
CONS_Alert(CONS_WARNING, M_GetText("Vote setup with bad gametype ID %d received from %s\n"), gt, player_names[playernum]);
return;
}
if ((secondgt & ~VOTEMODIFIER_ENCORE) >= numgametypes)
{
secondgt &= ~VOTEMODIFIER_ENCORE;
if (server)
I_Error("Got_SetupVotecmd: Internal second gametype ID %d not found (numgametypes = %d)", secondgt, numgametypes);
CONS_Alert(CONS_WARNING, M_GetText("Vote setup with bad second gametype ID %d received from %s\n"), secondgt, player_names[playernum]);
return;
}
for (i = 0; i < 4; i++)
{
tempvotelevels[i][0] = (UINT16)READUINT16(*cp);
tempvotelevels[i][1] = gt;
if (tempvotelevels[i][0] < nummapheaders && mapheaderinfo[tempvotelevels[i][0]])
continue;
if (server)
I_Error("Got_SetupVotecmd: Internal map ID %d not found (nummapheaders = %d)", tempvotelevels[i][0], nummapheaders);
CONS_Alert(CONS_WARNING, M_GetText("Vote setup with bad map ID %d received from %s\n"), tempvotelevels[i][0], player_names[playernum]);
return;
}
// If third entry has an illelegal Encore flag... (illelegal!?)
if ((secondgt & VOTEMODIFIER_ENCORE)
&& !(gametypes[(secondgt & ~VOTEMODIFIER_ENCORE)]->rules & GTR_ENCORE))
{
secondgt &= ~VOTEMODIFIER_ENCORE;
// Apply it to the second entry instead, gametype permitting!
if (gametypes[gt]->rules & GTR_ENCORE)
{ {
tempvotelevels[1][1] |= VOTEMODIFIER_ENCORE; SendKick(playernum, KICK_MSG_CON_FAIL);
} }
return;
} }
// Finally, set third entry's gametype/Encore status. baseEncore = (boolean)READUINT8(*cp);
tempvotelevels[2][1] = secondgt; optionalEncore = (boolean)READUINT8(*cp);
memcpy(votelevels, tempvotelevels, sizeof(votelevels)); if (!(gametyperules & GTR_ENCORE))
{
// Strip illegal Encore flags.
baseEncore = optionalEncore = false;
}
for (i = 0; i < VOTE_NUM_LEVELS; i++)
{
tempVoteLevels[i][0] = (UINT16)READUINT16(*cp);
tempVoteLevels[i][1] = (baseEncore == true) ? VOTE_MOD_ENCORE : 0;
if (tempVoteLevels[i][0] < nummapheaders && mapheaderinfo[tempVoteLevels[i][0]])
{
continue;
}
if (server)
{
I_Error("Got_SetupVotecmd: Internal map ID %d not found (nummapheaders = %d)", tempVoteLevels[i][0], nummapheaders);
}
CONS_Alert(CONS_WARNING, M_GetText("Vote setup with bad map ID %d received from %s\n"), tempVoteLevels[i][0], player_names[playernum]);
return;
}
if (optionalEncore == true)
{
tempVoteLevels[VOTE_NUM_LEVELS - 1][1] ^= VOTE_MOD_ENCORE;
}
memcpy(g_voteLevels, tempVoteLevels, sizeof(g_voteLevels));
G_SetGamestate(GS_VOTING); G_SetGamestate(GS_VOTING);
Y_StartVote(); Y_StartVote();
@ -5451,7 +5419,7 @@ static void Got_ModifyVotecmd(UINT8 **cp, INT32 playernum)
UINT8 p = READUINT8(*cp); UINT8 p = READUINT8(*cp);
(void)playernum; (void)playernum;
votes[p] = voted; g_votes[p] = voted;
} }
static void Got_PickVotecmd(UINT8 **cp, INT32 playernum) static void Got_PickVotecmd(UINT8 **cp, INT32 playernum)

View file

@ -488,8 +488,8 @@ extern mapheader_t** mapheaderinfo;
extern INT32 nummapheaders, mapallocsize; extern INT32 nummapheaders, mapallocsize;
// Gametypes // Gametypes
#define NUMGAMETYPEFREESLOTS (MAXGAMETYPES-GT_FIRSTFREESLOT) #define NUMGAMETYPEFREESLOTS (128)
#define MAXGAMETYPELENGTH 32 #define MAXGAMETYPELENGTH (32)
enum GameType enum GameType
{ {
@ -500,7 +500,7 @@ enum GameType
GT_TUTORIAL, GT_TUTORIAL,
GT_FIRSTFREESLOT, GT_FIRSTFREESLOT,
GT_LASTFREESLOT = 127, // Previously (GT_FIRSTFREESLOT + NUMGAMETYPEFREESLOTS - 1) - it would be necessary to rewrite VOTEMODIFIER_ENCORE to go higher than this. GT_LASTFREESLOT = GT_FIRSTFREESLOT + NUMGAMETYPEFREESLOTS - 1,
MAXGAMETYPES MAXGAMETYPES
}; };
// If you alter this list, update defaultgametypes and *gametypes in g_game.c // If you alter this list, update defaultgametypes and *gametypes in g_game.c
@ -732,9 +732,9 @@ extern boolean legitimateexit;
extern boolean comebackshowninfo; extern boolean comebackshowninfo;
extern tic_t curlap, bestlap; extern tic_t curlap, bestlap;
extern INT16 votelevels[4][2]; extern INT16 g_voteLevels[4][2];
extern SINT8 votes[MAXPLAYERS]; extern SINT8 g_votes[MAXPLAYERS];
extern SINT8 pickedvote; extern SINT8 g_pickedVote;
// =========================== // ===========================
// Internal parameters, fixed. // Internal parameters, fixed.

View file

@ -298,9 +298,9 @@ boolean prevencoremode;
boolean franticitems; // Frantic items currently enabled? boolean franticitems; // Frantic items currently enabled?
// Voting system // Voting system
INT16 votelevels[4][2]; // Levels that were rolled by the host INT16 g_voteLevels[4][2]; // Levels that were rolled by the host
SINT8 votes[MAXPLAYERS]; // Each player's vote SINT8 g_votes[MAXPLAYERS]; // Each player's vote
SINT8 pickedvote; // What vote the host rolls SINT8 g_pickedVote; // What vote the host rolls
// Server-sided, synched variables // Server-sided, synched variables
tic_t wantedcalcdelay; // Time before it recalculates WANTED tic_t wantedcalcdelay; // Time before it recalculates WANTED
@ -3627,32 +3627,28 @@ boolean G_GametypeHasSpectators(void)
} }
// //
// G_SometimesGetDifferentGametype // G_SometimesGetDifferentEncore
// //
// Because gametypes are no longer on the vote screen, all this does is sometimes flip encore mode. // Because gametypes are no longer on the vote screen, all this does is sometimes flip encore mode.
// However, it remains a seperate function for long-term possibility. // However, it remains a seperate function for long-term possibility.
// //
INT16 G_SometimesGetDifferentGametype(void) INT16 G_SometimesGetDifferentEncore(void)
{ {
boolean encorepossible = ((M_SecretUnlocked(SECRET_ENCORE, false) || encorescramble == 1) boolean encorepossible = ((M_SecretUnlocked(SECRET_ENCORE, false) || encorescramble == 1)
&& (gametyperules & GTR_ENCORE)); && (gametyperules & GTR_ENCORE));
UINT8 encoremodifier = 0; UINT8 encoremodifier = 0;
// -- the below is only necessary if you want to use randmaps.mapbuffer here
//if (randmaps.lastnummapheaders != nummapheaders)
//G_ResetRandMapBuffer();
// FORCE to what was scrambled on intermission? // FORCE to what was scrambled on intermission?
if (encorepossible && encorescramble != -1) if (encorepossible && encorescramble != -1)
{ {
// FORCE to what was scrambled on intermission // FORCE to what was scrambled on intermission
if ((encorescramble != 0) != (cv_kartencore.value == 1)) if ((encorescramble != 0) != (cv_kartencore.value == 1))
{ {
encoremodifier = VOTEMODIFIER_ENCORE; encoremodifier = VOTE_MOD_ENCORE;
} }
} }
return (gametype|encoremodifier); return encoremodifier;
} }
/** Get the typeoflevel flag needed to indicate support of a gametype. /** Get the typeoflevel flag needed to indicate support of a gametype.
@ -3736,10 +3732,11 @@ INT16 G_RandMap(UINT32 tolflags, INT16 pprevmap, UINT8 ignorebuffer, UINT8 maphe
UINT32 numokmaps = 0; UINT32 numokmaps = 0;
INT16 ix, bufx; INT16 ix, bufx;
UINT16 extbufsize = 0; UINT16 extbufsize = 0;
boolean usehellmaps; // Only consider Hell maps in this pick
if (randmaps.lastnummapheaders != nummapheaders) if (randmaps.lastnummapheaders != nummapheaders)
{
G_ResetRandMapBuffer(); G_ResetRandMapBuffer();
}
if (!okmaps) if (!okmaps)
{ {
@ -3750,33 +3747,39 @@ INT16 G_RandMap(UINT32 tolflags, INT16 pprevmap, UINT8 ignorebuffer, UINT8 maphe
if (extbuffer != NULL) if (extbuffer != NULL)
{ {
bufx = 0; bufx = 0;
while (extbuffer[bufx]) while (extbuffer[bufx])
{ {
extbufsize++; bufx++; extbufsize++;
bufx++;
} }
} }
tryagain: tryagain:
usehellmaps = (maphell == 0 ? false : (maphell == 2 || M_RandomChance(FRACUNIT/100))); // 1% chance of Hell
// Find all the maps that are ok and and put them in an array. // Find all the maps that are ok and and put them in an array.
for (ix = 0; ix < nummapheaders; ix++) for (ix = 0; ix < nummapheaders; ix++)
{ {
boolean isokmap = true; boolean isokmap = true;
if (!mapheaderinfo[ix] || mapheaderinfo[ix]->lumpnum == LUMPERROR) if (!mapheaderinfo[ix] || mapheaderinfo[ix]->lumpnum == LUMPERROR)
{
continue; continue;
}
if (!(mapheaderinfo[ix]->typeoflevel & tolflags) if (!(mapheaderinfo[ix]->typeoflevel & tolflags)
|| ix == pprevmap || ix == pprevmap
|| M_MapLocked(ix+1) || M_MapLocked(ix+1)
|| (usehellmaps != (mapheaderinfo[ix]->menuflags & LF2_HIDEINMENU))) // this is bad || (mapheaderinfo[ix]->menuflags & LF2_HIDEINMENU)) // this is bad
{
continue; //isokmap = false; continue; //isokmap = false;
}
if (pprevmap == -2 // title demo hack if (pprevmap == -2 // title demo hack
&& mapheaderinfo[ix]->ghostCount == 0) && mapheaderinfo[ix]->ghostCount == 0)
{
continue; continue;
}
if (!ignorebuffer) if (!ignorebuffer)
{ {
@ -3785,7 +3788,10 @@ tryagain:
for (bufx = 0; bufx < extbufsize; bufx++) for (bufx = 0; bufx < extbufsize; bufx++)
{ {
if (extbuffer[bufx] == -1) // Rest of buffer SHOULD be empty if (extbuffer[bufx] == -1) // Rest of buffer SHOULD be empty
{
break; break;
}
if (ix == extbuffer[bufx]) if (ix == extbuffer[bufx])
{ {
isokmap = false; isokmap = false;
@ -3794,13 +3800,18 @@ tryagain:
} }
if (!isokmap) if (!isokmap)
{
continue; continue;
}
} }
for (bufx = 0; bufx < (maphell ? 3 : randmaps.lastnummapheaders); bufx++) for (bufx = 0; bufx < (maphell ? 3 : randmaps.lastnummapheaders); bufx++)
{ {
if (randmaps.mapbuffer[bufx] == -1) // Rest of buffer SHOULD be empty if (randmaps.mapbuffer[bufx] == -1) // Rest of buffer SHOULD be empty
{
break; break;
}
if (ix == randmaps.mapbuffer[bufx]) if (ix == randmaps.mapbuffer[bufx])
{ {
isokmap = false; isokmap = false;
@ -3819,33 +3830,32 @@ tryagain:
{ {
if (!ignorebuffer) if (!ignorebuffer)
{ {
if (randmaps.mapbuffer[3] == -1) // Is the buffer basically empty? if (randmaps.mapbuffer[VOTE_NUM_LEVELS] == -1) // Is the buffer basically empty?
{ {
ignorebuffer = 1; // This will probably only help in situations where there's very few maps, but it's folly not to at least try it ignorebuffer = 1; // This will probably only help in situations where there's very few maps, but it's folly not to at least try it
//CONS_Printf("RANDMAP - ignoring buffer\n"); //CONS_Printf("RANDMAP - ignoring buffer\n");
goto tryagain; goto tryagain;
} }
for (bufx = 3; bufx < randmaps.lastnummapheaders; bufx++) // Let's clear all but the three most recent maps... for (bufx = VOTE_NUM_LEVELS; bufx < randmaps.lastnummapheaders; bufx++) // Let's clear all but the three most recent maps...
{
randmaps.mapbuffer[bufx] = -1; randmaps.mapbuffer[bufx] = -1;
//CONS_Printf("RANDMAP - emptying randmapbuffer\n"); }
goto tryagain;
}
if (maphell) // Any wiggle room to loosen our restrictions here? //CONS_Printf("RANDMAP - emptying randmapbuffer\n");
{
//CONS_Printf("RANDMAP -maphell decrement\n");
maphell--;
goto tryagain; goto tryagain;
} }
//CONS_Printf("RANDMAP - defaulting to map01\n"); //CONS_Printf("RANDMAP - defaulting to map01\n");
ix = 0; // Sorry, none match. You get MAP01. ix = 0; // Sorry, none match. You get MAP01.
if (ignorebuffer == 1) if (ignorebuffer == 1)
{ {
//CONS_Printf("(emptying randmapbuffer entirely)\n"); //CONS_Printf("(emptying randmapbuffer entirely)\n");
for (bufx = 0; bufx < randmaps.lastnummapheaders; bufx++) for (bufx = 0; bufx < randmaps.lastnummapheaders; bufx++)
{
randmaps.mapbuffer[bufx] = -1; // if we're having trouble finding a map we should probably clear it randmaps.mapbuffer[bufx] = -1; // if we're having trouble finding a map we should probably clear it
}
} }
} }
else else
@ -3867,10 +3877,12 @@ tryagain:
void G_AddMapToBuffer(INT16 map) void G_AddMapToBuffer(INT16 map)
{ {
INT16 bufx; INT16 bufx;
INT16 refreshnum = (TOLMaps(gametype))-3; INT16 refreshnum = (TOLMaps(gametype)) - VOTE_NUM_LEVELS;
if (refreshnum < 0) if (refreshnum < 0)
refreshnum = 3; {
refreshnum = 0;
}
if (nummapheaders != randmaps.lastnummapheaders) if (nummapheaders != randmaps.lastnummapheaders)
{ {
@ -3878,8 +3890,10 @@ void G_AddMapToBuffer(INT16 map)
} }
else else
{ {
for (bufx = randmaps.lastnummapheaders-1; bufx > 0; bufx--) for (bufx = randmaps.lastnummapheaders - 1; bufx > 0; bufx--)
{
randmaps.mapbuffer[bufx] = randmaps.mapbuffer[bufx-1]; randmaps.mapbuffer[bufx] = randmaps.mapbuffer[bufx-1];
}
} }
randmaps.mapbuffer[0] = map; randmaps.mapbuffer[0] = map;
@ -3887,9 +3901,11 @@ void G_AddMapToBuffer(INT16 map)
// We're getting pretty full, so lets flush this for future usage. // We're getting pretty full, so lets flush this for future usage.
if (randmaps.mapbuffer[refreshnum] != -1) if (randmaps.mapbuffer[refreshnum] != -1)
{ {
// Clear all but the five most recent maps. // Clear all but the most recent maps.
for (bufx = 5; bufx < randmaps.lastnummapheaders; bufx++) for (bufx = VOTE_NUM_LEVELS; bufx < randmaps.lastnummapheaders; bufx++)
{
randmaps.mapbuffer[bufx] = -1; randmaps.mapbuffer[bufx] = -1;
}
//CONS_Printf("Random map buffer has been flushed.\n"); //CONS_Printf("Random map buffer has been flushed.\n");
} }
} }

View file

@ -182,8 +182,7 @@ INT32 G_GuessGametypeByTOL(UINT32 tol);
boolean G_GametypeUsesLives(void); boolean G_GametypeUsesLives(void);
boolean G_GametypeHasTeams(void); boolean G_GametypeHasTeams(void);
boolean G_GametypeHasSpectators(void); boolean G_GametypeHasSpectators(void);
#define VOTEMODIFIER_ENCORE 0x80 INT16 G_SometimesGetDifferentEncore(void);
INT16 G_SometimesGetDifferentGametype(void);
void G_ExitLevel(void); void G_ExitLevel(void);
void G_NextLevel(void); void G_NextLevel(void);
void G_Continue(void); void G_Continue(void);

File diff suppressed because it is too large Load diff

View file

@ -19,6 +19,11 @@
extern "C" { extern "C" {
#endif #endif
#define VOTE_NUM_LEVELS (4)
#define VOTE_NOT_PICKED (-1)
#define VOTE_MOD_ENCORE (0x01)
void Y_VoteDrawer(void); void Y_VoteDrawer(void);
void Y_VoteTicker(void); void Y_VoteTicker(void);
void Y_StartVote(void); void Y_StartVote(void);

View file

@ -4999,14 +4999,14 @@ static void P_NetArchiveMisc(savebuffer_t *save, boolean resending)
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
{ {
WRITEINT16(save->p, votelevels[i][0]); WRITEINT16(save->p, g_voteLevels[i][0]);
WRITEINT16(save->p, votelevels[i][1]); WRITEINT16(save->p, g_voteLevels[i][1]);
} }
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
WRITESINT8(save->p, votes[i]); WRITESINT8(save->p, g_votes[i]);
WRITESINT8(save->p, pickedvote); WRITESINT8(save->p, g_pickedVote);
WRITEUINT16(save->p, emeralds); WRITEUINT16(save->p, emeralds);
{ {
@ -5171,14 +5171,16 @@ static inline boolean P_NetUnArchiveMisc(savebuffer_t *save, boolean reloading)
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
{ {
votelevels[i][0] = READINT16(save->p); g_voteLevels[i][0] = READINT16(save->p);
votelevels[i][1] = READINT16(save->p); g_voteLevels[i][1] = READINT16(save->p);
} }
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
votes[i] = READSINT8(save->p); {
g_votes[i] = READSINT8(save->p);
}
pickedvote = READSINT8(save->p); g_pickedVote = READSINT8(save->p);
emeralds = READUINT16(save->p); emeralds = READUINT16(save->p);
{ {