Map anger

- Maps build anger every time a map isn't selected by anyone.
- If a map is ignored for 4 votes in a row, then on the 5th vote it shows up it will be angry enough to vote for itself when everyone else finishes voting.
- Once it gives its funny vote, or it gets played, it will calm down again.
- 13P+ vote icons are implemented; it's just a basic circle though cuz lazy.
- Made the roulette finish even faster.
- Bots can vote again but now behind a debug cvar.
This commit is contained in:
Sally Coolatta 2023-04-10 02:08:48 -04:00
parent 95540888ce
commit 9c4ace6fbc
8 changed files with 255 additions and 64 deletions

View file

@ -468,6 +468,8 @@ consvar_t cv_reducevfx = CVAR_INIT ("reducevfx", "No", CV_SAVE, CV_YesNo, NULL);
static CV_PossibleValue_t votetime_cons_t[] = {{10, "MIN"}, {3600, "MAX"}, {0, NULL}}; static CV_PossibleValue_t votetime_cons_t[] = {{10, "MIN"}, {3600, "MAX"}, {0, NULL}};
consvar_t cv_votetime = CVAR_INIT ("votetime", "20", CV_NETVAR, votetime_cons_t, NULL); consvar_t cv_votetime = CVAR_INIT ("votetime", "20", CV_NETVAR, votetime_cons_t, NULL);
consvar_t cv_botscanvote = CVAR_INIT ("botscanvote", "No", CV_CHEAT, CV_YesNo, NULL);
consvar_t cv_gravity = CVAR_INIT ("gravity", "0.8", CV_CHEAT|CV_FLOAT|CV_CALL, NULL, Gravity_OnChange); // change DEFAULT_GRAVITY if you change this consvar_t cv_gravity = CVAR_INIT ("gravity", "0.8", CV_CHEAT|CV_FLOAT|CV_CALL, NULL, Gravity_OnChange); // change DEFAULT_GRAVITY if you change this
consvar_t cv_soundtest = CVAR_INIT ("soundtest", "0", CV_CALL, NULL, SoundTest_OnChange); consvar_t cv_soundtest = CVAR_INIT ("soundtest", "0", CV_CALL, NULL, SoundTest_OnChange);
@ -2645,29 +2647,52 @@ void D_ModifyClientVote(UINT8 player, SINT8 voted)
{ {
char buf[2]; char buf[2];
char *p = buf; char *p = buf;
UINT8 sendPlayer = consoleplayer;
if (player >= MAXSPLITSCREENPLAYERS) if (player == UINT8_MAX)
{ {
return; // Special game vote (map anger, duel)
if (!server)
{
return;
}
}
if (player == UINT8_MAX)
{
// special vote
WRITEUINT8(p, UINT8_MAX);
}
else
{
INT32 i = 0;
WRITEUINT8(p, player);
for (i = 0; i <= splitscreen; i++)
{
if (g_localplayers[i] == player)
{
sendPlayer = i;
}
}
} }
WRITEUINT8(p, g_localplayers[player]);
WRITESINT8(p, voted); WRITESINT8(p, voted);
SendNetXCmdForPlayer(player, XD_MODIFYVOTE, buf, p - buf); SendNetXCmdForPlayer(sendPlayer, XD_MODIFYVOTE, buf, p - buf);
} }
void D_PickVote(void) void D_PickVote(void)
{ {
char buf[2]; char buf[2];
char* p = buf; char* p = buf;
SINT8 temppicks[MAXPLAYERS]; SINT8 temppicks[VOTE_TOTAL];
SINT8 templevels[MAXPLAYERS]; SINT8 templevels[VOTE_TOTAL];
SINT8 votecompare = VOTE_NOT_PICKED; SINT8 votecompare = VOTE_NOT_PICKED;
UINT8 numvotes = 0, key = 0; UINT8 numvotes = 0, key = 0;
INT32 i; INT32 i;
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < VOTE_TOTAL; i++)
{ {
if (Y_PlayerIDCanVote(i) == false) if (Y_PlayerIDCanVote(i) == false)
{ {
@ -5434,23 +5459,45 @@ static void Got_ModifyVotecmd(UINT8 **cp, INT32 playernum)
UINT8 targetID = READUINT8(*cp); UINT8 targetID = READUINT8(*cp);
SINT8 vote = READSINT8(*cp); SINT8 vote = READSINT8(*cp);
if (targetID >= MAXPLAYERS if (targetID == UINT8_MAX)
|| playernode[targetID] != playernode[playernum])
{ {
CONS_Alert(CONS_WARNING, if (playernum != serverplayer) // server-only special vote
M_GetText ("Illegal modify vote command received from %s\n"),
player_names[playernum]
);
if (server)
{ {
SendKick(playernum, KICK_MSG_CON_FAIL); goto fail;
} }
return; targetID = VOTE_SPECIAL;
}
else if (playeringame[targetID] == true && players[targetID].bot == true)
{
if (targetID >= MAXPLAYERS
|| playernum != serverplayer)
{
goto fail;
}
}
else
{
if (targetID >= MAXPLAYERS
|| playernode[targetID] != playernode[playernum])
{
goto fail;
}
} }
Y_SetPlayersVote(targetID, vote); Y_SetPlayersVote(targetID, vote);
return;
fail:
CONS_Alert(CONS_WARNING,
M_GetText ("Illegal modify vote command received from %s\n"),
player_names[playernum]
);
if (server)
{
SendKick(playernum, KICK_MSG_CON_FAIL);
}
} }
static void Got_PickVotecmd(UINT8 **cp, INT32 playernum) static void Got_PickVotecmd(UINT8 **cp, INT32 playernum)

View file

@ -90,6 +90,7 @@ extern consvar_t cv_karteliminatelast;
extern consvar_t cv_kartusepwrlv; extern consvar_t cv_kartusepwrlv;
extern consvar_t cv_votetime; extern consvar_t cv_votetime;
extern consvar_t cv_botscanvote;
extern consvar_t cv_kartdebugitem, cv_kartdebugamount, cv_kartdebugdistribution, cv_kartdebughuddrop; extern consvar_t cv_kartdebugitem, cv_kartdebugamount, cv_kartdebugdistribution, cv_kartdebughuddrop;
extern consvar_t cv_kartdebugnodes, cv_kartdebugcolorize, cv_kartdebugdirector; extern consvar_t cv_kartdebugnodes, cv_kartdebugcolorize, cv_kartdebugdirector;

View file

@ -411,6 +411,7 @@ struct mapheader_t
cupheader_t *cup; ///< Cached cup cupheader_t *cup; ///< Cached cup
size_t justPlayed; ///< Prevent this map from showing up in votes if it was recently picked. size_t justPlayed; ///< Prevent this map from showing up in votes if it was recently picked.
size_t anger; ///< No one picked this map... it's mad now.
// Titlecard information // Titlecard information
char lvlttl[22]; ///< Level name without "Zone". (21 character limit instead of 32, 21 characters can display on screen max anyway) char lvlttl[22]; ///< Level name without "Zone". (21 character limit instead of 32, 21 characters can display on screen max anyway)
@ -734,8 +735,10 @@ extern boolean legitimateexit;
extern boolean comebackshowninfo; extern boolean comebackshowninfo;
extern tic_t curlap, bestlap; extern tic_t curlap, bestlap;
#define VOTE_SPECIAL (MAXPLAYERS)
#define VOTE_TOTAL (MAXPLAYERS+1)
extern INT16 g_voteLevels[4][2]; extern INT16 g_voteLevels[4][2];
extern SINT8 g_votes[MAXPLAYERS]; extern SINT8 g_votes[VOTE_TOTAL];
extern SINT8 g_pickedVote; extern SINT8 g_pickedVote;
// =========================== // ===========================

View file

@ -299,7 +299,7 @@ boolean franticitems; // Frantic items currently enabled?
// Voting system // Voting system
INT16 g_voteLevels[4][2]; // Levels that were rolled by the host INT16 g_voteLevels[4][2]; // Levels that were rolled by the host
SINT8 g_votes[MAXPLAYERS]; // Each player's vote SINT8 g_votes[VOTE_TOTAL]; // Each player's vote
SINT8 g_pickedVote; // What vote the host rolls SINT8 g_pickedVote; // What vote the host rolls
// Server-sided, synched variables // Server-sided, synched variables
@ -3687,14 +3687,33 @@ static INT32 TOLMaps(UINT8 pgametype)
// Find all the maps that are ok // Find all the maps that are ok
for (i = 0; i < nummapheaders; i++) for (i = 0; i < nummapheaders; i++)
{ {
if (!mapheaderinfo[i]) if (mapheaderinfo[i] == NULL)
{
continue; continue;
}
if (mapheaderinfo[i]->lumpnum == LUMPERROR) if (mapheaderinfo[i]->lumpnum == LUMPERROR)
{
continue; continue;
if (!(mapheaderinfo[i]->typeoflevel & tolflag)) }
if ((mapheaderinfo[i]->typeoflevel & tolflag) == 0)
{
continue; continue;
if (mapheaderinfo[i]->menuflags & LF2_HIDEINMENU) // Don't include Map Hell }
if (mapheaderinfo[i]->menuflags & LF2_HIDEINMENU)
{
// Don't include hidden
continue; continue;
}
if (M_MapLocked(i + 1))
{
// Don't include locked
continue;
}
num++; num++;
} }

View file

@ -342,6 +342,7 @@ void K_RegisterKartStuff(void)
CV_RegisterVar(&cv_karteliminatelast); CV_RegisterVar(&cv_karteliminatelast);
CV_RegisterVar(&cv_kartusepwrlv); CV_RegisterVar(&cv_kartusepwrlv);
CV_RegisterVar(&cv_votetime); CV_RegisterVar(&cv_votetime);
CV_RegisterVar(&cv_botscanvote);
CV_RegisterVar(&cv_kartdebugitem); CV_RegisterVar(&cv_kartdebugitem);
CV_RegisterVar(&cv_kartdebugamount); CV_RegisterVar(&cv_kartdebugamount);

View file

@ -96,11 +96,14 @@
#define PILE_SPACING_W (PILE_WIDTH + PILE_SPACE) #define PILE_SPACING_W (PILE_WIDTH + PILE_SPACE)
#define PILE_SPACING_H (PILE_HEIGHT + PILE_SPACE) #define PILE_SPACING_H (PILE_HEIGHT + PILE_SPACE)
#define LOTS_OF_VOTES_X (120*FRACUNIT)
#define LOTS_OF_VOTES_Y (80*FRACUNIT)
// Give time for the animations to finish before finalizing the vote stages. // Give time for the animations to finish before finalizing the vote stages.
#define SELECT_DELAY_TIME (TICRATE*4) #define SELECT_DELAY_TIME (TICRATE*4)
#define PICK_DELAY_TIME (TICRATE/2) #define PICK_DELAY_TIME (TICRATE/2)
//#define TEST_VOTES (11) #define MAP_ANGER_MAX (VOTE_NUM_LEVELS)
// Catcher data // Catcher data
enum enum
@ -155,7 +158,7 @@ typedef struct
// Voting roulette variables. // Voting roulette variables.
typedef struct typedef struct
{ {
y_vote_pile pile[MAXPLAYERS]; y_vote_pile pile[VOTE_TOTAL];
UINT8 anim; UINT8 anim;
UINT8 tics; UINT8 tics;
UINT32 offset; UINT32 offset;
@ -211,17 +214,29 @@ boolean Y_PlayerIDCanVote(const UINT8 playerId)
{ {
player_t *player = NULL; player_t *player = NULL;
if (playerId == VOTE_SPECIAL)
{
// Special vote spot, always allow
return true;
}
if (playerId >= MAXPLAYERS || playeringame[playerId] == false) if (playerId >= MAXPLAYERS || playeringame[playerId] == false)
{ {
return false; return false;
} }
player = &players[playerId]; player = &players[playerId];
if (player->spectator == true || player->bot == true) if (player->spectator == true)
{ {
return false; return false;
} }
if (player->bot == true && cv_botscanvote.value == 0)
{
// Bots may only vote if the server allows it
return false;
}
return true; return true;
} }
@ -231,10 +246,7 @@ static void Y_SortPile(void)
UINT8 votesLeft = 0; UINT8 votesLeft = 0;
INT32 i; INT32 i;
#ifdef TEST_VOTES for (i = 0; i < VOTE_TOTAL; i++)
numVotes = TEST_VOTES;
#else
for (i = 0; i < MAXPLAYERS; i++)
{ {
if (g_votes[i] == VOTE_NOT_PICKED) if (g_votes[i] == VOTE_NOT_PICKED)
{ {
@ -243,7 +255,6 @@ static void Y_SortPile(void)
numVotes++; numVotes++;
} }
#endif
if (numVotes == 0) if (numVotes == 0)
{ {
@ -252,16 +263,14 @@ static void Y_SortPile(void)
votesLeft = numVotes; votesLeft = numVotes;
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < VOTE_TOTAL; i++)
{ {
y_vote_pile *const pile = &vote.roulette.pile[i]; y_vote_pile *const pile = &vote.roulette.pile[i];
#ifndef TEST_VOTES
if (g_votes[i] == VOTE_NOT_PICKED) if (g_votes[i] == VOTE_NOT_PICKED)
{ {
continue; continue;
} }
#endif
// Just center it for now. // Just center it for now.
pile->destX = BASEVIDWIDTH << FRACBITS >> 1; pile->destX = BASEVIDWIDTH << FRACBITS >> 1;
@ -313,7 +322,9 @@ static void Y_SortPile(void)
} }
else else
{ {
// TODO: 13+ votes angle_t a = ANGLE_90 + (ANGLE_MAX / numVotes) * (votesLeft - 1);
pile->destX += FixedMul(LOTS_OF_VOTES_X, FINECOSINE(a >> ANGLETOFINESHIFT));
pile->destY += FixedMul(LOTS_OF_VOTES_Y, -FINESINE(a >> ANGLETOFINESHIFT));
} }
votesLeft--; votesLeft--;
@ -448,20 +459,51 @@ static void Y_DrawVoteThumbnail(fixed_t center_x, fixed_t center_y, fixed_t widt
if (playerID >= 0) if (playerID >= 0)
{ {
const INT32 whiteSq = 16 * dupx;
if (playerID < MAXPLAYERS) if (playerID < MAXPLAYERS)
{ {
UINT8 *playerMap = R_GetTranslationColormap(players[playerID].skin, players[playerID].skincolor, GTC_CACHE); UINT8 *playerMap = R_GetTranslationColormap(players[playerID].skin, players[playerID].skincolor, GTC_CACHE);
patch_t *playerPatch = faceprefix[players[playerID].skin][FACE_RANK]; patch_t *playerPatch = faceprefix[players[playerID].skin][FACE_RANK];
V_DrawFixedPatch( V_DrawFixedPatch(
x + width - (playerPatch->width * FRACUNIT) + FRACUNIT - 1, (fx + fw - whiteSq + dupx) * FRACUNIT,
y + height - (playerPatch->height * FRACUNIT) + FRACUNIT, (fy + fh - whiteSq + dupy) * FRACUNIT,
FRACUNIT, flags, FRACUNIT, flags|V_NOSCALESTART,
playerPatch, playerMap playerPatch, playerMap
); );
} }
else else
{ {
; // angry level goes here const fixed_t iconHeight = (14 << FRACBITS);
const fixed_t iconWidth = (iconHeight * 320) / 200;
V_DrawFill(
fx + fw - whiteSq + dupx,
fy + fh - whiteSq + dupy,
whiteSq,
whiteSq,
0|flags|V_NOSCALESTART
);
V_SetClipRect(
fx + fw - whiteSq + (2 * dupx),
fy + fh - whiteSq + (2 * dupy),
whiteSq - (2 * dupx),
whiteSq - (2 * dupy),
flags|V_NOSCALESTART
);
K_DrawMapThumbnail(
((fx + fw - whiteSq + (2 * dupx)) * FRACUNIT) - (iconWidth - iconHeight),
(fy + fh - whiteSq + (2 * dupy)) * FRACUNIT,
iconWidth,
flags | V_NOSCALESTART | ((encore == true) ? V_FLIP : 0),
g_voteLevels[v][0],
NULL
);
V_ClearClipRect();
} }
} }
} }
@ -707,7 +749,7 @@ static void Y_DrawVotePile(void)
{ {
INT32 i; INT32 i;
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < VOTE_TOTAL; i++)
{ {
y_vote_pile *const pile = &vote.roulette.pile[i]; y_vote_pile *const pile = &vote.roulette.pile[i];
y_vote_catcher *const catcher = &pile->catcher; y_vote_catcher *const catcher = &pile->catcher;
@ -717,27 +759,21 @@ static void Y_DrawVotePile(void)
continue; continue;
} }
#ifndef TEST_VOTES
if (g_votes[i] == VOTE_NOT_PICKED) if (g_votes[i] == VOTE_NOT_PICKED)
{ {
continue; continue;
} }
#endif
Y_DrawVoteThumbnail( Y_DrawVoteThumbnail(
pile->x, pile->y, pile->x, pile->y,
PILE_WIDTH, 0, PILE_WIDTH, 0,
#ifdef TEST_VOTES
0,
#else
g_votes[i], g_votes[i],
#endif
(i != vote.roulette.anim || g_pickedVote == VOTE_NOT_PICKED), (i != vote.roulette.anim || g_pickedVote == VOTE_NOT_PICKED),
i i
); );
} }
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < VOTE_TOTAL; i++)
{ {
Y_DrawCatcher(&vote.roulette.pile[i].catcher); Y_DrawCatcher(&vote.roulette.pile[i].catcher);
} }
@ -949,7 +985,7 @@ static void Y_TickPlayerCatcher(const UINT8 localPlayer)
{ {
if (catcher->x == catcher->destX && catcher->y == catcher->destY) if (catcher->x == catcher->destX && catcher->y == catcher->destY)
{ {
D_ModifyClientVote(localPlayer, vote.players[localPlayer].selection); D_ModifyClientVote(g_localplayers[localPlayer], vote.players[localPlayer].selection);
catcher->action = CATCHER_NA; catcher->action = CATCHER_NA;
S_StopSoundByNum(sfx_kc37); S_StopSoundByNum(sfx_kc37);
} }
@ -1023,13 +1059,11 @@ static void Y_TickPlayerPile(const UINT8 playerId)
fixed_t movedX = 0; fixed_t movedX = 0;
fixed_t movedY = 0; fixed_t movedY = 0;
#ifndef TEST_VOTES
if (g_votes[playerId] == VOTE_NOT_PICKED) if (g_votes[playerId] == VOTE_NOT_PICKED)
{ {
catcher->action = CATCHER_NA; catcher->action = CATCHER_NA;
return; return;
} }
#endif
movedX = (pile->destX - pile->x) / 2; movedX = (pile->destX - pile->x) / 2;
movedY = (pile->destY - pile->y) / 2; movedY = (pile->destY - pile->y) / 2;
@ -1058,10 +1092,10 @@ static void Y_TickVoteRoulette(void)
if (vote.endtic == -1) if (vote.endtic == -1)
{ {
UINT8 tempvotes[MAXPLAYERS]; UINT8 tempvotes[VOTE_TOTAL];
UINT8 numvotes = 0; UINT8 numvotes = 0;
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < VOTE_TOTAL; i++)
{ {
if (g_votes[i] == VOTE_NOT_PICKED) if (g_votes[i] == VOTE_NOT_PICKED)
{ {
@ -1086,7 +1120,7 @@ static void Y_TickVoteRoulette(void)
else else
{ {
vote.roulette.offset++; vote.roulette.offset++;
vote.roulette.tics = min(6, 9 * vote.roulette.offset / 40); vote.roulette.tics = min(5, 7 * vote.roulette.offset / 40);
S_StartSound(NULL, sfx_kc39); S_StartSound(NULL, sfx_kc39);
} }
@ -1095,7 +1129,7 @@ static void Y_TickVoteRoulette(void)
vote.roulette.anim = tempvotes[((g_pickedVote + vote.roulette.offset) % numvotes)]; vote.roulette.anim = tempvotes[((g_pickedVote + vote.roulette.offset) % numvotes)];
} }
if (vote.roulette.offset > 30) if (vote.roulette.offset > 20)
{ {
if (vote.roulette.endOffset == 0) if (vote.roulette.endOffset == 0)
{ {
@ -1107,7 +1141,7 @@ static void Y_TickVoteRoulette(void)
{ {
vote.roulette.endOffset = vote.roulette.offset + i; vote.roulette.endOffset = vote.roulette.offset + i;
if (M_RandomChance(FRACUNIT/32)) // Let it cheat occasionally~ if (M_RandomChance(FRACUNIT/4)) // Let it cheat occasionally~
{ {
vote.roulette.endOffset++; vote.roulette.endOffset++;
} }
@ -1153,6 +1187,74 @@ static boolean Y_PlayerCanSelect(const UINT8 localId)
return Y_PlayerIDCanVote(p); return Y_PlayerIDCanVote(p);
} }
static void Y_TryMapAngerVote(void)
{
SINT8 angryMaps[VOTE_NUM_LEVELS] = { -1 };
size_t angryMapsCount = 0;
boolean mapVoted[VOTE_NUM_LEVELS] = { false };
INT32 pick = 0;
INT32 numPlayers = 0;
INT32 i = 0;
for (i = 0; i < MAXPLAYERS; i++)
{
if (Y_PlayerIDCanVote(i) == false)
{
continue;
}
numPlayers++;
if (g_votes[i] != VOTE_NOT_PICKED)
{
mapVoted[ g_votes[i] ] = true;
}
}
if (numPlayers < 3)
{
// Don't handle map anger if there's not enough players.
return;
}
for (i = 0; i < VOTE_NUM_LEVELS; i++)
{
const INT16 mapID = g_voteLevels[i][0];
if (mapVoted[i] == true)
{
// Someone voted for us, no need to be angry anymore :)
mapheaderinfo[ mapID ]->anger = 0;
}
else
{
// Increment map anger for maps that weren't picked by a single soul.
mapheaderinfo[ mapID ]->anger++;
if (mapheaderinfo[ mapID ]->anger > MAP_ANGER_MAX)
{
// If they are angry enough, then it can vote for itself!
angryMaps[ angryMapsCount ] = i;
angryMapsCount++;
}
}
}
if (angryMapsCount == 0)
{
return;
}
// Set the special vote to a random angry map.
pick = M_RandomKey(angryMapsCount);
D_ModifyClientVote(UINT8_MAX, angryMaps[pick]);
// Make it not angry anymore.
mapheaderinfo[ g_voteLevels[ angryMaps[pick] ][0] ]->anger = 0;
}
static void Y_TickVoteSelection(void) static void Y_TickVoteSelection(void)
{ {
boolean everyone_voted = true;/* the default condition */ boolean everyone_voted = true;/* the default condition */
@ -1233,10 +1335,18 @@ static void Y_TickVoteSelection(void)
continue; continue;
} }
if (players[i].bot == true && g_votes[i] == VOTE_NOT_PICKED)
{
if (( M_RandomFixed() % 100 ) == 0)
{
// bots vote randomly
D_ModifyClientVote(i, M_RandomKey(VOTE_NUM_LEVELS));
}
}
if (g_votes[i] == VOTE_NOT_PICKED) if (g_votes[i] == VOTE_NOT_PICKED)
{ {
everyone_voted = false; everyone_voted = false;
break;
} }
} }
@ -1270,6 +1380,7 @@ static void Y_TickVoteSelection(void)
if (server) if (server)
{ {
Y_TryMapAngerVote();
D_PickVote(); D_PickVote();
} }
} }
@ -1306,11 +1417,15 @@ void Y_VoteTicker(void)
return; return;
} }
for (i = 0; i < MAXPLAYERS; i++) // Correct votes as early as possible, before they're processed by the game at all // Correct invalid votes as early as possible,
// before they're processed by the rest of the ticker
for (i = 0; i < MAXPLAYERS; i++)
{ {
if (Y_PlayerIDCanVote(i) == false) if (Y_PlayerIDCanVote(i) == false)
{ {
g_votes[i] = VOTE_NOT_PICKED; // Spectators are the lower class, and have effectively no voice in the government. Democracy sucks. // Spectators are the lower class, and have
// effectively no voice in the government. Democracy sucks.
g_votes[i] = VOTE_NOT_PICKED;
} }
} }
@ -1341,7 +1456,7 @@ void Y_VoteTicker(void)
Y_SortPile(); Y_SortPile();
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < VOTE_TOTAL; i++)
{ {
Y_TickPlayerPile(i); Y_TickPlayerPile(i);
} }
@ -1449,7 +1564,7 @@ void Y_StartVote(void)
catcher->player = -1; catcher->player = -1;
} }
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < VOTE_TOTAL; i++)
{ {
y_vote_pile *const pile = &vote.roulette.pile[i]; y_vote_pile *const pile = &vote.roulette.pile[i];
y_vote_catcher *const catcher = &pile->catcher; y_vote_catcher *const catcher = &pile->catcher;
@ -1556,7 +1671,7 @@ void Y_SetupVoteFinish(SINT8 pick, SINT8 level)
vote.roulette.syncTime = 0; vote.roulette.syncTime = 0;
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < VOTE_TOTAL; i++)
{ {
if (g_votes[i] == VOTE_NOT_PICKED) if (g_votes[i] == VOTE_NOT_PICKED)
{ {

View file

@ -4997,14 +4997,16 @@ static void P_NetArchiveMisc(savebuffer_t *save, boolean resending)
WRITEINT16(save->p, lastmap); WRITEINT16(save->p, lastmap);
WRITEUINT16(save->p, bossdisabled); WRITEUINT16(save->p, bossdisabled);
for (i = 0; i < 4; i++) for (i = 0; i < VOTE_NUM_LEVELS; i++)
{ {
WRITEINT16(save->p, g_voteLevels[i][0]); WRITEINT16(save->p, g_voteLevels[i][0]);
WRITEINT16(save->p, g_voteLevels[i][1]); WRITEINT16(save->p, g_voteLevels[i][1]);
} }
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < VOTE_TOTAL; i++)
{
WRITESINT8(save->p, g_votes[i]); WRITESINT8(save->p, g_votes[i]);
}
WRITESINT8(save->p, g_pickedVote); WRITESINT8(save->p, g_pickedVote);
@ -5169,13 +5171,13 @@ static inline boolean P_NetUnArchiveMisc(savebuffer_t *save, boolean reloading)
lastmap = READINT16(save->p); lastmap = READINT16(save->p);
bossdisabled = READUINT16(save->p); bossdisabled = READUINT16(save->p);
for (i = 0; i < 4; i++) for (i = 0; i < VOTE_NUM_LEVELS; i++)
{ {
g_voteLevels[i][0] = READINT16(save->p); g_voteLevels[i][0] = READINT16(save->p);
g_voteLevels[i][1] = READINT16(save->p); g_voteLevels[i][1] = READINT16(save->p);
} }
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < VOTE_TOTAL; i++)
{ {
g_votes[i] = READSINT8(save->p); g_votes[i] = READSINT8(save->p);
} }

View file

@ -429,6 +429,9 @@ static void P_ClearSingleMapHeaderInfo(INT16 num)
Z_Free(mapheaderinfo[num]->mainrecord); Z_Free(mapheaderinfo[num]->mainrecord);
mapheaderinfo[num]->mainrecord = NULL; mapheaderinfo[num]->mainrecord = NULL;
mapheaderinfo[num]->justPlayed = 0;
mapheaderinfo[num]->anger = 0;
mapheaderinfo[num]->customopts = NULL; mapheaderinfo[num]->customopts = NULL;
mapheaderinfo[num]->numCustomOptions = 0; mapheaderinfo[num]->numCustomOptions = 0;
} }