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)
{
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;
INT32 i;
UINT8 secondgt = G_SometimesGetDifferentGametype();
INT16 votebuffer[4] = {-1,-1,-1,0};
INT16 votebuffer[VOTE_NUM_LEVELS] = {-1};
if ((cv_kartencore.value == 1) && (gametyperules & GTR_ENCORE))
WRITEUINT8(p, (gametype|VOTEMODIFIER_ENCORE));
else
WRITEUINT8(p, gametype);
WRITEUINT8(p, secondgt);
secondgt &= ~VOTEMODIFIER_ENCORE;
WRITEUINT8(p, ((cv_kartencore.value == 1) && (gametyperules & GTR_ENCORE)));
WRITEUINT8(p, G_SometimesGetDifferentEncore());
for (i = 0; i < 4; i++)
for (i = 0; i < VOTE_NUM_LEVELS; i++)
{
UINT16 m;
if (i == 2) // sometimes a different gametype
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;
UINT16 m = G_RandMap(G_TOLFlag(gametype), prevmap, 0, 0, true, votebuffer);
votebuffer[i] = m;
WRITEUINT16(p, m);
}
@ -2672,13 +2660,13 @@ void D_PickVote(void)
{
if (!playeringame[i] || players[i].spectator)
continue;
if (votes[i] != -1)
if (g_votes[i] != -1)
{
temppicks[numvotes] = i;
templevels[numvotes] = votes[i];
templevels[numvotes] = g_votes[i];
numvotes++;
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)
{
boolean baseEncore = false;
boolean optionalEncore = false;
INT16 tempVoteLevels[VOTE_NUM_LEVELS][2];
INT32 i;
UINT8 gt, secondgt;
INT16 tempvotelevels[4][2];
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]);
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.
tempvotelevels[2][1] = secondgt;
baseEncore = (boolean)READUINT8(*cp);
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);
Y_StartVote();
@ -5451,7 +5419,7 @@ static void Got_ModifyVotecmd(UINT8 **cp, INT32 playernum)
UINT8 p = READUINT8(*cp);
(void)playernum;
votes[p] = voted;
g_votes[p] = voted;
}
static void Got_PickVotecmd(UINT8 **cp, INT32 playernum)

View file

@ -488,8 +488,8 @@ extern mapheader_t** mapheaderinfo;
extern INT32 nummapheaders, mapallocsize;
// Gametypes
#define NUMGAMETYPEFREESLOTS (MAXGAMETYPES-GT_FIRSTFREESLOT)
#define MAXGAMETYPELENGTH 32
#define NUMGAMETYPEFREESLOTS (128)
#define MAXGAMETYPELENGTH (32)
enum GameType
{
@ -500,7 +500,7 @@ enum GameType
GT_TUTORIAL,
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
};
// If you alter this list, update defaultgametypes and *gametypes in g_game.c
@ -732,9 +732,9 @@ extern boolean legitimateexit;
extern boolean comebackshowninfo;
extern tic_t curlap, bestlap;
extern INT16 votelevels[4][2];
extern SINT8 votes[MAXPLAYERS];
extern SINT8 pickedvote;
extern INT16 g_voteLevels[4][2];
extern SINT8 g_votes[MAXPLAYERS];
extern SINT8 g_pickedVote;
// ===========================
// Internal parameters, fixed.

View file

@ -298,9 +298,9 @@ boolean prevencoremode;
boolean franticitems; // Frantic items currently enabled?
// Voting system
INT16 votelevels[4][2]; // Levels that were rolled by the host
SINT8 votes[MAXPLAYERS]; // Each player's vote
SINT8 pickedvote; // What vote the host rolls
INT16 g_voteLevels[4][2]; // Levels that were rolled by the host
SINT8 g_votes[MAXPLAYERS]; // Each player's vote
SINT8 g_pickedVote; // What vote the host rolls
// Server-sided, synched variables
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.
// 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)
&& (gametyperules & GTR_ENCORE));
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?
if (encorepossible && encorescramble != -1)
{
// FORCE to what was scrambled on intermission
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.
@ -3736,10 +3732,11 @@ INT16 G_RandMap(UINT32 tolflags, INT16 pprevmap, UINT8 ignorebuffer, UINT8 maphe
UINT32 numokmaps = 0;
INT16 ix, bufx;
UINT16 extbufsize = 0;
boolean usehellmaps; // Only consider Hell maps in this pick
if (randmaps.lastnummapheaders != nummapheaders)
{
G_ResetRandMapBuffer();
}
if (!okmaps)
{
@ -3750,33 +3747,39 @@ INT16 G_RandMap(UINT32 tolflags, INT16 pprevmap, UINT8 ignorebuffer, UINT8 maphe
if (extbuffer != NULL)
{
bufx = 0;
while (extbuffer[bufx])
{
extbufsize++; bufx++;
extbufsize++;
bufx++;
}
}
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.
for (ix = 0; ix < nummapheaders; ix++)
{
boolean isokmap = true;
if (!mapheaderinfo[ix] || mapheaderinfo[ix]->lumpnum == LUMPERROR)
{
continue;
}
if (!(mapheaderinfo[ix]->typeoflevel & tolflags)
|| ix == pprevmap
|| M_MapLocked(ix+1)
|| (usehellmaps != (mapheaderinfo[ix]->menuflags & LF2_HIDEINMENU))) // this is bad
|| (mapheaderinfo[ix]->menuflags & LF2_HIDEINMENU)) // this is bad
{
continue; //isokmap = false;
}
if (pprevmap == -2 // title demo hack
&& mapheaderinfo[ix]->ghostCount == 0)
{
continue;
}
if (!ignorebuffer)
{
@ -3785,7 +3788,10 @@ tryagain:
for (bufx = 0; bufx < extbufsize; bufx++)
{
if (extbuffer[bufx] == -1) // Rest of buffer SHOULD be empty
{
break;
}
if (ix == extbuffer[bufx])
{
isokmap = false;
@ -3794,13 +3800,18 @@ tryagain:
}
if (!isokmap)
{
continue;
}
}
for (bufx = 0; bufx < (maphell ? 3 : randmaps.lastnummapheaders); bufx++)
{
if (randmaps.mapbuffer[bufx] == -1) // Rest of buffer SHOULD be empty
{
break;
}
if (ix == randmaps.mapbuffer[bufx])
{
isokmap = false;
@ -3819,33 +3830,32 @@ tryagain:
{
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
//CONS_Printf("RANDMAP - ignoring buffer\n");
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;
//CONS_Printf("RANDMAP - emptying randmapbuffer\n");
goto tryagain;
}
}
if (maphell) // Any wiggle room to loosen our restrictions here?
{
//CONS_Printf("RANDMAP -maphell decrement\n");
maphell--;
//CONS_Printf("RANDMAP - emptying randmapbuffer\n");
goto tryagain;
}
//CONS_Printf("RANDMAP - defaulting to map01\n");
ix = 0; // Sorry, none match. You get MAP01.
if (ignorebuffer == 1)
{
//CONS_Printf("(emptying randmapbuffer entirely)\n");
for (bufx = 0; bufx < randmaps.lastnummapheaders; bufx++)
{
randmaps.mapbuffer[bufx] = -1; // if we're having trouble finding a map we should probably clear it
}
}
}
else
@ -3867,10 +3877,12 @@ tryagain:
void G_AddMapToBuffer(INT16 map)
{
INT16 bufx;
INT16 refreshnum = (TOLMaps(gametype))-3;
INT16 refreshnum = (TOLMaps(gametype)) - VOTE_NUM_LEVELS;
if (refreshnum < 0)
refreshnum = 3;
{
refreshnum = 0;
}
if (nummapheaders != randmaps.lastnummapheaders)
{
@ -3878,8 +3890,10 @@ void G_AddMapToBuffer(INT16 map)
}
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[0] = map;
@ -3887,9 +3901,11 @@ void G_AddMapToBuffer(INT16 map)
// We're getting pretty full, so lets flush this for future usage.
if (randmaps.mapbuffer[refreshnum] != -1)
{
// Clear all but the five most recent maps.
for (bufx = 5; bufx < randmaps.lastnummapheaders; bufx++)
// Clear all but the most recent maps.
for (bufx = VOTE_NUM_LEVELS; bufx < randmaps.lastnummapheaders; bufx++)
{
randmaps.mapbuffer[bufx] = -1;
}
//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_GametypeHasTeams(void);
boolean G_GametypeHasSpectators(void);
#define VOTEMODIFIER_ENCORE 0x80
INT16 G_SometimesGetDifferentGametype(void);
INT16 G_SometimesGetDifferentEncore(void);
void G_ExitLevel(void);
void G_NextLevel(void);
void G_Continue(void);

File diff suppressed because it is too large Load diff

View file

@ -19,6 +19,11 @@
extern "C" {
#endif
#define VOTE_NUM_LEVELS (4)
#define VOTE_NOT_PICKED (-1)
#define VOTE_MOD_ENCORE (0x01)
void Y_VoteDrawer(void);
void Y_VoteTicker(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++)
{
WRITEINT16(save->p, votelevels[i][0]);
WRITEINT16(save->p, votelevels[i][1]);
WRITEINT16(save->p, g_voteLevels[i][0]);
WRITEINT16(save->p, g_voteLevels[i][1]);
}
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);
{
@ -5171,14 +5171,16 @@ static inline boolean P_NetUnArchiveMisc(savebuffer_t *save, boolean reloading)
for (i = 0; i < 4; i++)
{
votelevels[i][0] = READINT16(save->p);
votelevels[i][1] = READINT16(save->p);
g_voteLevels[i][0] = READINT16(save->p);
g_voteLevels[i][1] = READINT16(save->p);
}
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);
{