Fix map anger race condition

Was making angry maps never actually get picked. Dang.
This commit is contained in:
Sally Coolatta 2024-09-02 04:20:04 -04:00
parent 398f1cdc9b
commit 9b63fb4078
4 changed files with 33 additions and 20 deletions

View file

@ -2376,13 +2376,12 @@ void D_ModifyClientVote(UINT8 player, SINT8 voted)
SendNetXCmdForPlayer(sendPlayer, XD_MODIFYVOTE, buf, p - buf); SendNetXCmdForPlayer(sendPlayer, XD_MODIFYVOTE, buf, p - buf);
} }
void D_PickVote(void) void D_PickVote(SINT8 angry_map)
{ {
char buf[2]; char buf[3];
char* p = buf; char* p = buf;
SINT8 temppicks[VOTE_TOTAL]; SINT8 temppicks[VOTE_TOTAL];
SINT8 templevels[VOTE_TOTAL]; SINT8 templevels[VOTE_TOTAL];
SINT8 votecompare = VOTE_NOT_PICKED;
UINT8 numvotes = 0, key = 0; UINT8 numvotes = 0, key = 0;
INT32 i; INT32 i;
@ -2393,16 +2392,23 @@ void D_PickVote(void)
continue; continue;
} }
if (i == VOTE_SPECIAL && angry_map != VOTE_NOT_PICKED)
{
// Anger map is going to change because of
// the vote ending. We need to account for this
// here because a net command would not be ready
// in time for this code.
temppicks[numvotes] = i;
templevels[numvotes] = angry_map;
numvotes++;
continue;
}
if (g_votes[i] != VOTE_NOT_PICKED) if (g_votes[i] != VOTE_NOT_PICKED)
{ {
temppicks[numvotes] = i; temppicks[numvotes] = i;
templevels[numvotes] = g_votes[i]; templevels[numvotes] = g_votes[i];
numvotes++; numvotes++;
if (votecompare == VOTE_NOT_PICKED)
{
votecompare = g_votes[i];
}
} }
} }
@ -2411,14 +2417,16 @@ void D_PickVote(void)
key = M_RandomKey(numvotes); key = M_RandomKey(numvotes);
WRITESINT8(p, temppicks[key]); WRITESINT8(p, temppicks[key]);
WRITESINT8(p, templevels[key]); WRITESINT8(p, templevels[key]);
WRITESINT8(p, angry_map);
} }
else else
{ {
WRITESINT8(p, VOTE_NOT_PICKED); WRITESINT8(p, VOTE_NOT_PICKED);
WRITESINT8(p, 0); WRITESINT8(p, 0);
WRITESINT8(p, VOTE_NOT_PICKED);
} }
SendNetXCmd(XD_PICKVOTE, &buf, 2); SendNetXCmd(XD_PICKVOTE, &buf, 3);
} }
static char * static char *
@ -5859,6 +5867,7 @@ static void Got_PickVotecmd(const UINT8 **cp, INT32 playernum)
{ {
SINT8 pick = READSINT8(*cp); SINT8 pick = READSINT8(*cp);
SINT8 level = READSINT8(*cp); SINT8 level = READSINT8(*cp);
SINT8 anger = READSINT8(*cp);
if (playernum != serverplayer && !IsPlayerAdmin(playernum)) if (playernum != serverplayer && !IsPlayerAdmin(playernum))
{ {
@ -5868,7 +5877,7 @@ static void Got_PickVotecmd(const UINT8 **cp, INT32 playernum)
return; return;
} }
Y_SetupVoteFinish(pick, level); Y_SetupVoteFinish(pick, level, anger);
} }
static void Got_ScheduleTaskcmd(const UINT8 **cp, INT32 playernum) static void Got_ScheduleTaskcmd(const UINT8 **cp, INT32 playernum)

View file

@ -249,7 +249,7 @@ void D_GameTypeChanged(INT32 lastgametype); // not a real _OnChange function any
void D_MapChange(UINT16 pmapnum, INT32 pgametype, boolean pencoremode, boolean presetplayers, INT32 pdelay, boolean pskipprecutscene, boolean pforcespecialstage); void D_MapChange(UINT16 pmapnum, INT32 pgametype, boolean pencoremode, boolean presetplayers, INT32 pdelay, boolean pskipprecutscene, boolean pforcespecialstage);
void D_SetupVote(INT16 newgametype); void D_SetupVote(INT16 newgametype);
void D_ModifyClientVote(UINT8 player, SINT8 voted); void D_ModifyClientVote(UINT8 player, SINT8 voted);
void D_PickVote(void); void D_PickVote(SINT8 angry_map);
void ObjectPlace_OnChange(void); void ObjectPlace_OnChange(void);
void P_SetPlayerSpectator(INT32 playernum); void P_SetPlayerSpectator(INT32 playernum);
boolean IsPlayerAdmin(INT32 playernum); boolean IsPlayerAdmin(INT32 playernum);

View file

@ -1352,7 +1352,7 @@ static void Y_TickVoteRoulette(void)
} }
} }
static void Y_TryMapAngerVote(void) static SINT8 Y_TryMapAngerVote(void)
{ {
SINT8 angryMaps[VOTE_NUM_LEVELS] = { -1 }; SINT8 angryMaps[VOTE_NUM_LEVELS] = { -1 };
size_t angryMapsCount = 0; size_t angryMapsCount = 0;
@ -1381,7 +1381,7 @@ static void Y_TryMapAngerVote(void)
if (numPlayers < 3) if (numPlayers < 3)
{ {
// Don't handle map anger if there's not enough players. // Don't handle map anger if there's not enough players.
return; return VOTE_NOT_PICKED;
} }
for (i = 0; i < VOTE_NUM_LEVELS; i++) for (i = 0; i < VOTE_NUM_LEVELS; i++)
@ -1409,12 +1409,12 @@ static void Y_TryMapAngerVote(void)
if (angryMapsCount == 0) if (angryMapsCount == 0)
{ {
return; return VOTE_NOT_PICKED;
} }
// Set the special vote to a random angry map. // Set the special vote to a random angry map.
pick = M_RandomKey(angryMapsCount); pick = M_RandomKey(angryMapsCount);
D_ModifyClientVote(UINT8_MAX, angryMaps[pick]); return angryMaps[pick];
} }
static void Y_TickVoteSelection(void) static void Y_TickVoteSelection(void)
@ -1542,8 +1542,7 @@ static void Y_TickVoteSelection(void)
if (server) if (server)
{ {
Y_TryMapAngerVote(); D_PickVote( Y_TryMapAngerVote() );
D_PickVote();
} }
} }
} }
@ -1593,7 +1592,7 @@ void Y_VoteTicker(void)
if (server && g_pickedVote != VOTE_NOT_PICKED && g_votes[g_pickedVote] == VOTE_NOT_PICKED) // Uh oh! The person who got picked left! Recalculate, quick! if (server && g_pickedVote != VOTE_NOT_PICKED && g_votes[g_pickedVote] == VOTE_NOT_PICKED) // Uh oh! The person who got picked left! Recalculate, quick!
{ {
D_PickVote(); D_PickVote( VOTE_NOT_PICKED );
} }
if (vote.tic == 0) if (vote.tic == 0)
@ -1849,13 +1848,18 @@ enum
VOTE_END_NORMAL, VOTE_END_NORMAL,
}; };
void Y_SetupVoteFinish(SINT8 pick, SINT8 level) void Y_SetupVoteFinish(SINT8 pick, SINT8 level, SINT8 anger)
{ {
if (vote.loaded == false) if (vote.loaded == false)
{ {
return; return;
} }
if (anger != VOTE_NOT_PICKED)
{
Y_SetPlayersVote(VOTE_SPECIAL, anger);
}
if (pick == VOTE_NOT_PICKED || level == VOTE_NOT_PICKED) // No other votes? We gotta get out of here, then! if (pick == VOTE_NOT_PICKED || level == VOTE_NOT_PICKED) // No other votes? We gotta get out of here, then!
{ {
Y_EndVote(); Y_EndVote();

View file

@ -31,7 +31,7 @@ void Y_VoteDrawer(void);
void Y_VoteTicker(void); void Y_VoteTicker(void);
void Y_StartVote(void); void Y_StartVote(void);
void Y_EndVote(void); void Y_EndVote(void);
void Y_SetupVoteFinish(SINT8 pick, SINT8 level); void Y_SetupVoteFinish(SINT8 pick, SINT8 level, SINT8 anger);
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"