From 8881ade6fef4d74fcd167b520078ad8cd8b38b72 Mon Sep 17 00:00:00 2001 From: NepDisk Date: Fri, 12 Dec 2025 16:15:43 -0500 Subject: [PATCH] Port some votescreen cleanup from RR --- src/d_netcmd.c | 42 ++++++------ src/d_netcmd.h | 2 +- src/doomstat.h | 6 +- src/g_game.c | 6 +- src/k_bot.cpp | 5 +- src/k_bot.h | 1 + src/k_kart.c | 1 + src/p_saveg.c | 10 +-- src/y_inter.c | 172 ++++++++++++++++++++++++++++++------------------- src/y_inter.h | 7 ++ 10 files changed, 152 insertions(+), 100 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 71c62b073..c0a1e7959 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -3179,17 +3179,21 @@ void D_SetupVote(void) SendNetXCmd(XD_SETUPVOTE, buf, p - buf); } -void D_ModifyClientVote(UINT8 player, SINT8 voted, UINT8 splitplayer) +void D_ModifyClientVote(UINT8 player, SINT8 voted) { - char buf[2]; + char buf[1]; char *p = buf; - if (splitplayer > 0) - player = g_localplayers[splitplayer]; + if (player >= MAXSPLITSCREENPLAYERS) + { + if (!server) + { + return; + } + } WRITESINT8(p, voted); - WRITEUINT8(p, player); - SendNetXCmd(XD_MODIFYVOTE, &buf, 2); + SendNetXCmdForPlayer(player, XD_MODIFYVOTE, &buf, p - buf); } void D_PickVote(void) @@ -3198,21 +3202,21 @@ void D_PickVote(void) char* p = buf; SINT8 temppicks[MAXPLAYERS]; SINT8 templevels[MAXPLAYERS]; - SINT8 votecompare = -1; + SINT8 votecompare = VOTE_NOT_PICKED; UINT8 numvotes = 0, key = 0; INT32 i; for (i = 0; i < MAXPLAYERS; i++) { - if (!playeringame[i] || players[i].spectator) + if (!Y_PlayerIDCanVote(i)) continue; - if (votes[i] != -1) + if (g_votes[i] != VOTE_NOT_PICKED) { temppicks[numvotes] = i; - templevels[numvotes] = votes[i]; + templevels[numvotes] = g_votes[i]; numvotes++; - if (votecompare == -1) - votecompare = votes[i]; + if (votecompare == VOTE_NOT_PICKED) + votecompare = g_votes[i]; } } @@ -3224,7 +3228,7 @@ void D_PickVote(void) } else { - WRITESINT8(p, -1); + WRITESINT8(p, VOTE_NOT_PICKED); WRITESINT8(p, 0); } @@ -6123,7 +6127,7 @@ static void Got_SetupVotecmd(UINT8 **cp, INT32 playernum) tempvotelevels[2][1] = secondgt; - memcpy(votelevels, tempvotelevels, sizeof(votelevels)); + memcpy(g_voteLevels, tempvotelevels, sizeof(g_voteLevels)); // If third entry has an illelegal Encore flag... (illelegal!?) if ((secondgt & VOTEMODIFIER_ENCORE) @@ -6133,12 +6137,12 @@ static void Got_SetupVotecmd(UINT8 **cp, INT32 playernum) // Apply it to the second entry instead, gametype permitting! if (gametypedefaultrules[gt] & GTR_CIRCUIT) { - votelevels[1][1] |= VOTEMODIFIER_ENCORE; + g_voteLevels[1][1] |= VOTEMODIFIER_ENCORE; } } // Finally, set third entry's gametype/Encore status. - votelevels[2][1] = secondgt; + g_voteLevels[2][1] = secondgt; G_SetGamestate(GS_VOTING); Y_StartVote(); @@ -6146,11 +6150,7 @@ static void Got_SetupVotecmd(UINT8 **cp, INT32 playernum) static void Got_ModifyVotecmd(UINT8 **cp, INT32 playernum) { - SINT8 voted = READSINT8(*cp); - UINT8 p = READUINT8(*cp); - - (void)playernum; - votes[p] = voted; + g_votes[playernum] = READSINT8(*cp); } static void Got_PickVotecmd(UINT8 **cp, INT32 playernum) diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 491351a99..c569726cd 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -363,7 +363,7 @@ void Command_Retry_f(void); void D_GameTypeChanged(INT32 lastgametype); // not a real _OnChange function anymore void D_MapChange(INT32 pmapnum, INT32 pgametype, boolean pencoremode, boolean presetplayers, INT32 pdelay, boolean pskipprecutscene, boolean pfromlevelselect); void D_SetupVote(void); -void D_ModifyClientVote(UINT8 player, SINT8 voted, UINT8 splitplayer); +void D_ModifyClientVote(UINT8 player, SINT8 voted); void D_PickVote(void); void ObjectPlace_OnChange(void); boolean IsPlayerAdmin(INT32 playernum); diff --git a/src/doomstat.h b/src/doomstat.h index 752350643..8f0d018ce 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -683,9 +683,9 @@ extern boolean legitimateexit; extern boolean comebackshowninfo; extern tic_t antibumptime; -extern INT16 votelevels[12][2]; -extern SINT8 votes[MAXPLAYERS]; -extern SINT8 pickedvote; +extern INT16 g_voteLevels[12][2]; +extern SINT8 g_votes[MAXPLAYERS]; +extern SINT8 g_pickedVote; extern UINT32 timesBeaten; // # of times the game has been beaten. diff --git a/src/g_game.c b/src/g_game.c index e72ac20a3..51cbf835a 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -301,9 +301,9 @@ boolean franticitems; // Frantic items currently enabled? boolean comeback; // Battle Mode's karma comeback is on/off // Voting system -INT16 votelevels[12][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[12][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 SINT8 battlewanted[4]; // WANTED players in battle, worth x2 points diff --git a/src/k_bot.cpp b/src/k_bot.cpp index 9502792b6..bea9f1580 100644 --- a/src/k_bot.cpp +++ b/src/k_bot.cpp @@ -46,9 +46,10 @@ #include "k_waypoint.h" #include "k_items.h" -consvar_t cv_forcebots = CVAR_INIT ("kartforcebots", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); -consvar_t cv_botcontrol = CVAR_INIT ("kartbotcontrol", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); +consvar_t cv_forcebots = CVAR_INIT ("kartbot_force", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); +consvar_t cv_botcontrol = CVAR_INIT ("kartbot_control", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); consvar_t cv_forcerival = CVAR_INIT ("kartbot_forcerival", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); +consvar_t cv_botcanvote = CVAR_INIT ("kartbot_canvote", "Off", CV_NETVAR, CV_OnOff, NULL); botdata_t botdata[MAXPLAYERS]; diff --git a/src/k_bot.h b/src/k_bot.h index f8002f61d..cd8f3645c 100644 --- a/src/k_bot.h +++ b/src/k_bot.h @@ -24,6 +24,7 @@ extern "C" { extern consvar_t cv_forcebots; extern consvar_t cv_botcontrol; extern consvar_t cv_forcerival; +extern consvar_t cv_botcanvote; // Maximum value of botvars.difficulty #define MAXBOTDIFFICULTY (13) diff --git a/src/k_kart.c b/src/k_kart.c index 9bee8a17d..a9dc747b7 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -253,6 +253,7 @@ void K_RegisterKartStuff(void) CV_RegisterVar(&cv_forcebots); CV_RegisterVar(&cv_botcontrol); CV_RegisterVar(&cv_forcerival); + CV_RegisterVar(&cv_botcanvote); CV_RegisterVar(&cv_karteliminatelast); CV_RegisterVar(&cv_kartusepwrlv); CV_RegisterVar(&cv_votetime); diff --git a/src/p_saveg.c b/src/p_saveg.c index 26d40a9d6..e89325d48 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -4225,16 +4225,16 @@ static boolean P_NetSyncMisc(savebuffer_t *save, boolean resending) SYNC(bumpsparkactive); SYNC(antibumptime); - for (i = 0; i < sizeof(votelevels)/sizeof(*votelevels); i++) + for (i = 0; i < sizeof(g_voteLevels)/sizeof(*g_voteLevels); i++) { - SYNC(votelevels[i][0]); - SYNC(votelevels[i][1]); + SYNC(g_voteLevels[i][0]); + SYNC(g_voteLevels[i][1]); } for (i = 0; i < MAXPLAYERS; i++) - SYNC(votes[i]); + SYNC(g_votes[i]); - SYNC(pickedvote); + SYNC(g_pickedVote); SYNC(emeralds); if (save->write) diff --git a/src/y_inter.c b/src/y_inter.c index d43e0a535..bc4c006ca 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -47,6 +47,7 @@ #include "k_pwrlv.h" #include "console.h" // cons_menuhighlight #include "k_grandprix.h" +#include "k_bot.h" // cv_botcanvote #include "r_fps.h" // R_GetTimeFrac #ifdef HWRENDER @@ -1111,7 +1112,7 @@ static void Y_VoteScreenCheck(void) } // non lua vote background handling - boolean prefbattletype = ((votelevels[0][1] & ~0x80) == GT_BATTLE); + boolean prefbattletype = ((g_voteLevels[0][1] & ~VOTEMODIFIER_ENCORE) == GT_BATTLE); VoteScreen.widebgpatch = W_CachePatchName((prefbattletype ? "BATTLSCW" : "INTERSCW"), PU_PATCH); VoteScreen.bgpatch = W_CachePatchName((prefbattletype ? "BATTLSCR" : "INTERSCR"), PU_PATCH); } @@ -1200,7 +1201,7 @@ static void Y_DrawVoteScreenPatch(void) // non widescreen patch votebg = VoteScreen.bgpatch; - UINT8 prefgametype = (votelevels[0][1] & ~0x80); + UINT8 prefgametype = (g_voteLevels[0][1] & ~VOTEMODIFIER_ENCORE); const boolean widebgreplaced = (prefgametype == GT_BATTLE) ? VoteScreen.replaced.widebattle : VoteScreen.replaced.widerace; const boolean bgreplaced = (prefgametype == GT_BATTLE) ? VoteScreen.replaced.battle : VoteScreen.replaced.race; @@ -1230,6 +1231,27 @@ static fixed_t Y_CalculatePicScale(fixed_t picscale, INT32 hypoti) return picscale; } +boolean Y_PlayerIDCanVote(const UINT8 id) +{ + if (id >= MAXPLAYERS) + { + return false; + } + + if (playeringame[id] == false || players[id].spectator == true) + { + return false; + } + + if (players[id].bot /*&& !cv_botcanvote.value*/) + { + // Bots may only vote if the server allows it + return false; + } + + return true; +} + // // Y_VoteDrawer // @@ -1346,7 +1368,7 @@ void Y_VoteDrawer(void) else { str = levelinfo[i].str; - mapnum = votelevels[i][0]; + mapnum = g_voteLevels[i][0]; } scale = M_GetMapThumbnail(mapnum, &pic)/2; @@ -1397,7 +1419,7 @@ void Y_VoteDrawer(void) colormap = R_GetTranslationColormap(TC_DEFAULT, players[p].skincolor, GTC_CACHE); } - if (votes[p] != -1 || players[p].spectator) + if (g_votes[p] != -1 || !Y_PlayerIDCanVote(p)) continue; handy += 3*(3-splitscreen) + (13*j); @@ -1519,12 +1541,12 @@ void Y_VoteDrawer(void) if (dedicated && i == 0) // While leaving blank spots for non-existent players is largely intentional, the first spot *always* being blank looks a tad silly :V continue; - if ((playeringame[i] && !players[i].spectator) && votes[i] != -1) + if (Y_PlayerIDCanVote(i) && g_votes[i] != VOTE_NOT_PICKED) { - if (votes[i] >= ((votemax*3)+((votemax > 1) ? (votemax - 1) : 0)) && (i != pickedvote || voteendtic == -1)) + if (g_votes[i] >= ((votemax*3)+((votemax > 1) ? (votemax - 1) : 0)) && (i != g_pickedVote || voteendtic == -1)) mapnum = -1; // randomlvl else - mapnum = votelevels[votes[i]][0]; + mapnum = g_voteLevels[g_votes[i]][0]; scale = M_GetMapThumbnail(mapnum, &pic)/8; @@ -1534,14 +1556,14 @@ void Y_VoteDrawer(void) if (voteendtic != -1 && !(votetic % 4)) V_DrawFill(x-1, y-1, 42, (highplayers ? smallrectheight : bigrectheight), 0|V_SNAPTOLEFT); else - V_DrawFill(x-1, y-1, 42, (highplayers ? smallrectheight : bigrectheight), levelinfo[votes[i]].gtc|V_SNAPTOLEFT); + V_DrawFill(x-1, y-1, 42, (highplayers ? smallrectheight : bigrectheight), levelinfo[g_votes[i]].gtc|V_SNAPTOLEFT); } if (highplayers) { V_SetClipRect(x< 1) ? (votemax - 1) : 0); // Slow people get random + if (!Y_PlayerIDCanVote(i)) + g_votes[i] = VOTE_NOT_PICKED; // Spectators are the lower class, and have effectively no voice in the government. Democracy sucks. + else if (g_pickedVote != VOTE_NOT_PICKED && g_votes[i] == VOTE_NOT_PICKED) + g_votes[i] = (votemax*3)+((votemax > 1) ? (votemax - 1) : 0); // Slow people get random } - if (server && pickedvote != -1 && votes[pickedvote] == -1) // 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(); if (!votetic) @@ -1684,21 +1706,21 @@ void Y_VoteTicker(void) if (timer) timer--; - if (pickedvote != -1) + if (g_pickedVote != VOTE_NOT_PICKED) { timer = 0; voteclient.rsynctime++; if (voteendtic == -1) { - UINT8 tempvotes[MAXPLAYERS]; + UINT8 tempg_votes[MAXPLAYERS]; UINT8 numvotes = 0; for (i = 0; i < MAXPLAYERS; i++) { - if (votes[i] == -1) + if (g_votes[i] == VOTE_NOT_PICKED) continue; - tempvotes[numvotes] = i; + tempg_votes[numvotes] = i; numvotes++; } @@ -1719,7 +1741,7 @@ void Y_VoteTicker(void) } if (voteclient.rendoff == 0 || voteclient.roffset < voteclient.rendoff) - voteclient.ranim = tempvotes[((pickedvote + voteclient.roffset) % numvotes)]; + voteclient.ranim = tempg_votes[((g_pickedVote + voteclient.roffset) % numvotes)]; if (voteclient.roffset >= 20) { @@ -1729,7 +1751,7 @@ void Y_VoteTicker(void) { for (i = 5; i >= 3; i--) // Find a suitable place to stop { - if (tempvotes[((pickedvote + voteclient.roffset + i) % numvotes)] == pickedvote) + if (tempg_votes[((g_pickedVote + voteclient.roffset + i) % numvotes)] == g_pickedVote) { voteclient.rendoff = voteclient.roffset+i; if (M_RandomChance(FRACUNIT/32)) // Let it cheat occasionally~ @@ -1744,12 +1766,12 @@ void Y_VoteTicker(void) else if (voteclient.roffset >= voteclient.rendoff) { voteendtic = votetic + (3*TICRATE); - Y_VoteStops(pickedvote, deferredlevel); + Y_VoteStops(g_pickedVote, deferredlevel); } } } else - voteclient.ranim = pickedvote; + voteclient.ranim = g_pickedVote; } else if (votenotyetpicked) { @@ -1792,9 +1814,9 @@ void Y_VoteTicker(void) if (voteclient.playerinfo[i].delay) voteclient.playerinfo[i].delay--; - if ((playeringame[p] && !players[p].spectator) + if (Y_PlayerIDCanVote(i) && !voteclient.playerinfo[i].delay - && pickedvote == -1 && votes[p] == -1) + && g_pickedVote == VOTE_NOT_PICKED && g_votes[p] == VOTE_NOT_PICKED) { if (G_PlayerInputDown(i, gc_aimforward, false)) { @@ -1837,7 +1859,7 @@ void Y_VoteTicker(void) if (G_PlayerInputDown(i, gc_accelerate, false) && pressed == false) { - D_ModifyClientVote(consoleplayer, voteclient.playerinfo[i].selection, i); + D_ModifyClientVote(i, voteclient.playerinfo[i].selection); pressed = true; } } @@ -1858,24 +1880,44 @@ void Y_VoteTicker(void) { for (i = 0; i < MAXPLAYERS; i++) { - if ((playeringame[i] && !players[i].spectator) && votes[i] == -1) - votes[i] = (votemax*3)+((votemax > 1) ? (votemax-1) : 0); + if (Y_PlayerIDCanVote(i) && g_votes[i] == VOTE_NOT_PICKED) + g_votes[i] = (votemax*3)+((votemax > 1) ? (votemax-1) : 0); } } else { for (i = 0; i < MAXPLAYERS; i++) { - if ((playeringame[i] && !players[i].spectator) && votes[i] == -1) + if (!Y_PlayerIDCanVote(i)) { - if (players[i].bot) - { - if (( M_RandomFixed() % 100 ) == 0) - D_ModifyClientVote(i, M_RandomKey(4), 0); - } + continue; + } - if (votes[i] == -1) - everyone_voted = false; + if (server && players[i].bot && g_votes[i] == VOTE_NOT_PICKED) + { + if (( M_RandomFixed() % 100 ) == 0) + { +#define VOTEROWSADDSONE ((cv_votemaxrows.value*3) + 1 + ((cv_votemaxrows.value > 1) ? (cv_votemaxrows.value - 1) : 0)) + // bots vote randomly + INT32 rng = M_RandomKey(VOTEROWSADDSONE); + for (j = 0; j < VOTEROWSADDSONE; j++) + { + rng++; + + if (rng >= VOTEROWSADDSONE || rng < 0) + { + rng = 0; + } + } +#undef VOTEROWSADDSONE + + D_ModifyClientVote(i, rng); + } + } + + if (g_votes[i] == VOTE_NOT_PICKED) + { + everyone_voted = false; } } } @@ -1936,7 +1978,7 @@ void Y_StartVote(void) Y_InitVoteDrawing(); timer = cv_votetime.value*TICRATE; - pickedvote = -1; + g_pickedVote = VOTE_NOT_PICKED; votenotyetpicked = true; @@ -1953,48 +1995,48 @@ void Y_StartVote(void) voteclient.rendoff = 0; for (i = 0; i < MAXPLAYERS; i++) - votes[i] = -1; + g_votes[i] = VOTE_NOT_PICKED; for (i = 0; i < (rowval + 1); i++) { // set up the encore - levelinfo[i].encore = (votelevels[i][1] & VOTEMODIFIER_ENCORE); - votelevels[i][1] &= ~VOTEMODIFIER_ENCORE; + levelinfo[i].encore = (g_voteLevels[i][1] & VOTEMODIFIER_ENCORE); + g_voteLevels[i][1] &= ~VOTEMODIFIER_ENCORE; // set up the levelstring - if (mapheaderinfo[votelevels[i][0]]->levelflags & LF_NOZONE || !mapheaderinfo[votelevels[i][0]]->zonttl[0]) + if (mapheaderinfo[g_voteLevels[i][0]]->levelflags & LF_NOZONE || !mapheaderinfo[g_voteLevels[i][0]]->zonttl[0]) { - if (mapheaderinfo[votelevels[i][0]]->actnum[0]) + if (mapheaderinfo[g_voteLevels[i][0]]->actnum[0]) snprintf(levelinfo[i].str, sizeof levelinfo[i].str, "%s %s", - mapheaderinfo[votelevels[i][0]]->lvlttl, mapheaderinfo[votelevels[i][0]]->actnum); + mapheaderinfo[g_voteLevels[i][0]]->lvlttl, mapheaderinfo[g_voteLevels[i][0]]->actnum); else snprintf(levelinfo[i].str, sizeof levelinfo[i].str, "%s", - mapheaderinfo[votelevels[i][0]]->lvlttl); + mapheaderinfo[g_voteLevels[i][0]]->lvlttl); } else { - if (mapheaderinfo[votelevels[i][0]]->actnum[0]) + if (mapheaderinfo[g_voteLevels[i][0]]->actnum[0]) snprintf(levelinfo[i].str, sizeof levelinfo[i].str, "%s %s %s", - mapheaderinfo[votelevels[i][0]]->lvlttl, mapheaderinfo[votelevels[i][0]]->zonttl, mapheaderinfo[votelevels[i][0]]->actnum); + mapheaderinfo[g_voteLevels[i][0]]->lvlttl, mapheaderinfo[g_voteLevels[i][0]]->zonttl, mapheaderinfo[g_voteLevels[i][0]]->actnum); else snprintf(levelinfo[i].str, sizeof levelinfo[i].str, "%s %s", - mapheaderinfo[votelevels[i][0]]->lvlttl, mapheaderinfo[votelevels[i][0]]->zonttl); + mapheaderinfo[g_voteLevels[i][0]]->lvlttl, mapheaderinfo[g_voteLevels[i][0]]->zonttl); } levelinfo[i].str[sizeof levelinfo[i].str - 1] = '\0'; // set up the gtc and gts - levelinfo[i].gtc = G_GetGametypeColor(votelevels[i][1]); - if (i == 2 && votelevels[i][1] != votelevels[0][1]) - levelinfo[i].gts = gametype_cons_t[votelevels[i][1]].strvalue; + levelinfo[i].gtc = G_GetGametypeColor(g_voteLevels[i][1]); + if (i == 2 && g_voteLevels[i][1] != g_voteLevels[0][1]) + levelinfo[i].gts = gametype_cons_t[g_voteLevels[i][1]].strvalue; else levelinfo[i].gts = NULL; } @@ -2051,38 +2093,38 @@ void Y_SetupVoteFinish(SINT8 pick, SINT8 level) if (!voteclient.loaded) return; - if (pick == -1) // No other votes? We gotta get out of here, then! + if (pick == VOTE_NOT_PICKED) // No other votes? We gotta get out of here, then! { Y_EndVote(); Y_FollowIntermission(); return; } - if (pickedvote == -1) + if (g_pickedVote == VOTE_NOT_PICKED) { INT32 i; - SINT8 votecompare = -1; + SINT8 votecompare = VOTE_NOT_PICKED; INT32 endtype = 0; voteclient.rsynctime = 0; for (i = 0; i < MAXPLAYERS; i++) { - if ((playeringame[i] && !players[i].spectator) && votes[i] == -1) - votes[i] = (votemax*3)+((votemax > 1) ? (votemax - 1) : 0); + if (Y_PlayerIDCanVote(i) && g_votes[i] == VOTE_NOT_PICKED) + g_votes[i] = (votemax*3)+((votemax > 1) ? (votemax - 1) : 0); - if (votes[i] == -1 || endtype > 1) // Don't need to go on + if (g_votes[i] == VOTE_NOT_PICKED || endtype > 1) // Don't need to go on continue; if (endtype == 2) continue; - if (votecompare == -1) + if (votecompare == VOTE_NOT_PICKED) { - votecompare = votes[i]; + votecompare = g_votes[i]; endtype = 1; } - else if (votes[i] != votecompare) + else if (g_votes[i] != votecompare) endtype = 2; } @@ -2107,6 +2149,6 @@ void Y_SetupVoteFinish(SINT8 pick, SINT8 level) } deferredlevel = level; - pickedvote = pick; + g_pickedVote = pick; timer = 0; } diff --git a/src/y_inter.h b/src/y_inter.h index 88d610ac8..f712b96db 100644 --- a/src/y_inter.h +++ b/src/y_inter.h @@ -80,6 +80,13 @@ typedef struct } votescreen_t; extern votescreen_t VoteScreen; +boolean Y_PlayerIDCanVote(const UINT8 id); + +typedef enum +{ + VOTE_NOT_PICKED = -1, +} votetype_e; + #ifdef __cplusplus } // extern "C" #endif