From b20e2d55eb2128944f8eec825c896e397173548c Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sat, 3 Feb 2018 23:47:47 -0500 Subject: [PATCH] Everything Been a while since I synced :V --- src/d_netcmd.c | 96 ++++++++++++--- src/d_netcmd.h | 8 +- src/dehacked.c | 1 - src/doomstat.h | 6 +- src/g_game.c | 82 ++++++++++-- src/g_game.h | 3 +- src/p_saveg.c | 10 ++ src/y_inter.c | 329 +++++++++++++++++++++++++++++-------------------- src/y_inter.h | 1 + 9 files changed, 368 insertions(+), 168 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index f7819302..209008fe 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -63,6 +63,8 @@ static void Got_WeaponPref(UINT8 **cp, INT32 playernum); static void Got_Mapcmd(UINT8 **cp, INT32 playernum); static void Got_ExitLevelcmd(UINT8 **cp, INT32 playernum); static void Got_SetupVotecmd(UINT8 **cp, INT32 playernum); +static void Got_ModifyVotecmd(UINT8 **cp, INT32 playernum); +static void Got_PickVotecmd(UINT8 **cp, INT32 playernum); static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum); #ifdef DELFILE static void Got_Delfilecmd(UINT8 **cp, INT32 playernum); @@ -475,6 +477,8 @@ const char *netxcmdnames[MAXNETXCMD - 1] = "SUICIDE", "DEMOTED", "SETUPVOTE", + "MODIFYVOTE", + "PICKVOTE", #ifdef HAVE_BLUA "LUACMD", "LUAVAR" @@ -504,11 +508,14 @@ void D_RegisterServerCommands(void) RegisterNetXCmd(XD_PAUSE, Got_Pause); RegisterNetXCmd(XD_SUICIDE, Got_Suicide); RegisterNetXCmd(XD_RUNSOC, Got_RunSOCcmd); - RegisterNetXCmd(XD_SETUPVOTE, Got_SetupVotecmd); #ifdef HAVE_BLUA RegisterNetXCmd(XD_LUACMD, Got_Luacmd); #endif + RegisterNetXCmd(XD_SETUPVOTE, Got_SetupVotecmd); + RegisterNetXCmd(XD_MODIFYVOTE, Got_ModifyVotecmd); + RegisterNetXCmd(XD_PICKVOTE, Got_PickVotecmd); + // Remote Administration COM_AddCommand("password", Command_Changepassword_f); RegisterNetXCmd(XD_LOGIN, Got_Login); @@ -1950,34 +1957,51 @@ void D_SetupVote(void) { XBOXSTATIC char buf[8]; char *p; - UINT16 maps[4]; INT32 i; p = buf; for (i = 0; i < 4; i++) - { - INT32 j; - maps[i] = RandMap(G_TOLFlag(gametype), prevmap); - - for (j = 0; j < 4; j++) // Compare with others to make sure you don't roll duplicates - { - INT32 loops = 0; - if (j >= i) - continue; - while (maps[i] == maps[j] && loops < 4) // If this needs more than 4 loops, I think it's safe to assume it's not finding any suitable matches :V - { - maps[i] = RandMap(G_TOLFlag(gametype), prevmap); - loops++; - } - } - - WRITEUINT16(p, maps[i]); - } + WRITEUINT16(p, G_RandMap(G_TOLFlag(gametype), prevmap, false)); SendNetXCmd(XD_SETUPVOTE, buf, p - buf); } +void D_ModifyClientVote(INT8 voted) +{ + XBOXSTATIC UINT8 buf[1]; + buf[0] = (UINT8)(voted+1); + SendNetXCmd(XD_MODIFYVOTE, &buf, 1); +} + +void D_PickVote(void) +{ + XBOXSTATIC UINT8 buf[2]; + UINT8 temppicks[MAXPLAYERS]; + UINT8 templevels[MAXPLAYERS]; + UINT8 numvotes = 0, key = 0; + INT32 i; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator) + continue; + if (votes[i] != -1) + { + temppicks[numvotes] = (UINT8)i; + templevels[numvotes] = (UINT8)votes[i]; + numvotes++; + } + } + + key = P_RandomKey(numvotes); + + buf[0] = temppicks[key]; + buf[1] = templevels[key]; + + SendNetXCmd(XD_PICKVOTE, &buf, 2); +} + // Warp to map code. // Called either from map console command, or idclev cheat. // @@ -4557,12 +4581,44 @@ static void Got_SetupVotecmd(UINT8 **cp, INT32 playernum) } for (i = 0; i < 4; i++) + { votelevels[i] = (INT16)READUINT16(*cp); + if (!mapheaderinfo[votelevels[i]]) + P_AllocMapHeader(votelevels[i]); + } G_SetGamestate(GS_VOTING); Y_StartVote(); } +static void Got_ModifyVotecmd(UINT8 **cp, INT32 playernum) +{ + INT8 voted = READUINT8(*cp); + votes[playernum] = (INT8)(voted-1); +} + +static void Got_PickVotecmd(UINT8 **cp, INT32 playernum) +{ + INT8 pick = READUINT8(*cp); + INT8 level = READUINT8(*cp); + + if (playernum != serverplayer && !IsPlayerAdmin(playernum)) + { + CONS_Alert(CONS_WARNING, M_GetText("Illegal vote setup received from %s\n"), player_names[playernum]); + if (server) + { + XBOXSTATIC UINT8 buf[2]; + + buf[0] = (UINT8)playernum; + buf[1] = KICK_MSG_CON_FAIL; + SendNetXCmd(XD_KICK, &buf, 2); + } + return; + } + + Y_SetupVoteFinish((INT8)pick, (INT8)level); +} + /** Prints the number of the displayplayer. * * \todo Possibly remove this; it was useful for debugging at one point. diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 55341863..f1c6790c 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -192,9 +192,11 @@ typedef enum XD_SUICIDE, // 20 XD_DEMOTED, // 21 XD_SETUPVOTE, // 22 + XD_MODIFYVOTE, // 23 + XD_PICKVOTE, // 24 #ifdef HAVE_BLUA - XD_LUACMD, // 23 - XD_LUAVAR, // 24 + XD_LUACMD, // 25 + XD_LUAVAR, // 26 #endif MAXNETXCMD } netxcmd_t; @@ -250,6 +252,8 @@ void Command_Retry_f(void); void D_GameTypeChanged(INT32 lastgametype); // not a real _OnChange function anymore void D_MapChange(INT32 pmapnum, INT32 pgametype, boolean pultmode, boolean presetplayers, INT32 pdelay, boolean pskipprecutscene, boolean pfromlevelselect); void D_SetupVote(void); +void D_ModifyClientVote(INT8 voted); +void D_PickVote(void); void ObjectPlace_OnChange(void); boolean IsPlayerAdmin(INT32 playernum); void SetAdminPlayer(INT32 playernum); diff --git a/src/dehacked.c b/src/dehacked.c index ed6aee55..abbe835a 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -7338,7 +7338,6 @@ static const char *const KARTSTUFF_LIST[] = { "LAKITU", "THROWDIR", - "CAMSPIN", "LAPANIMATION", "CARDANIMATION", "SOUNDS", diff --git a/src/doomstat.h b/src/doomstat.h index ddd381b0..9fc7dc82 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -176,7 +176,6 @@ extern UINT32 totalrings; // Total # of rings in a level // Fun extra stuff extern INT16 lastmap; // Last level you were at (returning from special stages). -extern INT16 votelevels[4]; // srb2kart extern mobj_t *redflag, *blueflag; // Pointers to physical flags extern mapthing_t *rflagpoint, *bflagpoint; // Pointers to the flag spawn locations #define GF_REDFLAG 1 @@ -445,9 +444,14 @@ extern UINT8 gamespeed; extern boolean franticitems; extern boolean mirrormode; extern boolean comeback; + extern tic_t curlap, bestlap; extern boolean legitimateexit; +extern INT16 votelevels[4]; +extern INT8 votes[MAXPLAYERS]; +extern INT8 pickedvote; + extern tic_t hidetime; extern UINT32 timesBeaten; // # of times the game has been beaten. diff --git a/src/g_game.c b/src/g_game.c index c0d6c841..4104d35a 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -120,7 +120,6 @@ tic_t gametic; tic_t levelstarttic; // gametic at level start UINT32 totalrings; // for intermission INT16 lastmap; // last level you were at (returning from special stages) -INT16 votelevels[4]; // srb2kart tic_t timeinmap; // Ticker for time spent in level (used for levelcard display) INT16 spstage_start; @@ -251,6 +250,13 @@ boolean legitimateexit; // Did this client actually finish the match? Calculated tic_t curlap; // Current lap time, calculated locally tic_t bestlap; // Best lap time, locally +INT16 randmapbuffer[3*NUMMAPS/4]; // Buffer for maps RandMap is allowed to roll + +// Voting system +INT16 votelevels[4]; // Levels that were rolled by the host +INT8 votes[MAXPLAYERS]; // Each player's vote +INT8 pickedvote; // What vote the host rolls + tic_t hidetime; // Grading @@ -3081,6 +3087,24 @@ INT16 G_TOLFlag(INT32 pgametype) return INT16_MAX; } +static INT32 TOLMaps(INT16 tolflags) +{ + INT32 num = 0; + INT16 i; + + // Find all the maps that are ok and and put them in an array. + for (i = 0; i < NUMMAPS; i++) + { + if (!mapheaderinfo[i]) + continue; + + if ((mapheaderinfo[i]->typeoflevel & tolflags) == tolflags) + num++; + } + + return num; +} + /** Select a random map with the given typeoflevel flags. * If no map has those flags, this arbitrarily gives you map 1. * \param tolflags The typeoflevel flags to insist on. Other bits may @@ -3089,24 +3113,59 @@ INT16 G_TOLFlag(INT32 pgametype) * has those flags. * \author Graue */ -INT16 RandMap(INT16 tolflags, INT16 pprevmap) +INT16 G_RandMap(INT16 tolflags, INT16 pprevmap, boolean ignorebuffer) { INT16 *okmaps = Z_Malloc(NUMMAPS * sizeof(INT16), PU_STATIC, NULL); INT32 numokmaps = 0; - INT16 ix; + INT16 ix, bufx; // Find all the maps that are ok and and put them in an array. for (ix = 0; ix < NUMMAPS; ix++) - if (mapheaderinfo[ix] && (mapheaderinfo[ix]->typeoflevel & tolflags) == tolflags - && ix != pprevmap // Don't pick the same map. - && (dedicated || !M_MapLocked(ix+1)) // Don't pick locked maps. - ) + { + boolean isokmap = true; + + if (!mapheaderinfo[ix]) + continue; + + if ((mapheaderinfo[ix]->typeoflevel & tolflags) != tolflags + || ix == pprevmap + || (M_MapLocked(ix+1) && !dedicated)) + isokmap = false; + + if (!ignorebuffer) + { + for (bufx = 0; bufx < 3*NUMMAPS/4; bufx++) + { + if (randmapbuffer[bufx] == 0) // Rest of buffer SHOULD be empty + break; + if (ix == randmapbuffer[bufx]) + { + isokmap = false; + break; + } + } + } + + if (isokmap) okmaps[numokmaps++] = ix; + } if (numokmaps == 0) + { + if (!ignorebuffer) + return G_RandMap(tolflags, pprevmap, true); // If there's no matches, (An incredibly silly function chain, buuut... :V) + ix = 0; // Sorry, none match. You get MAP01. + for (bufx = 0; bufx < 3*NUMMAPS/4; bufx++) + randmapbuffer[bufx] = -1; // if we're having trouble finding a map we should probably clear it + } else + { ix = okmaps[P_RandomKey(numokmaps)]; + for (bufx = 3*NUMMAPS/4; bufx > 0; bufx--) + randmapbuffer[bufx] = randmapbuffer[bufx-1]; + randmapbuffer[0] = ix; + } Z_Free(okmaps); @@ -3233,12 +3292,18 @@ static void G_DoCompleted(void) automapactive = false; + if (randmapbuffer[(3*TOLMaps(G_TOLFlag(gametype))/4)]) // filled up, so lets clear it + { + for (i = 0; i < 3*NUMMAPS/4; i++) + randmapbuffer[i] = -1; + } + if (gametype != GT_COOP) { if (cv_advancemap.value == 0) // Stay on same map. nextmap = prevmap; else if (cv_advancemap.value == 2) // Go to random map. - nextmap = RandMap(G_TOLFlag(gametype), prevmap); + nextmap = G_RandMap(G_TOLFlag(gametype), prevmap, false); } // We are committed to this map now. @@ -3935,7 +4000,6 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean // Clear a bunch of variables tokenlist = token = sstimer = redscore = bluescore = lastmap = 0; countdown = countdown2 = 0; - votelevels[0] = votelevels[1] = votelevels[2] = votelevels[3] = 0; for (i = 0; i < MAXPLAYERS; i++) { diff --git a/src/g_game.h b/src/g_game.h index f6e62ea7..28ea2ef7 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -219,6 +219,7 @@ FUNCMATH INT32 G_TicsToMilliseconds(tic_t tics); // Don't split up TOL handling INT16 G_TOLFlag(INT32 pgametype); -INT16 RandMap(INT16 tolflags, INT16 pprevmap); + +INT16 G_RandMap(INT16 tolflags, INT16 pprevmap, boolean ignorebuffer); #endif diff --git a/src/p_saveg.c b/src/p_saveg.c index 438ed1da..5518c4f8 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -3205,6 +3205,11 @@ static void P_NetArchiveMisc(void) for (i = 0; i < 4; i++) WRITEINT16(save_p, votelevels[i]); + for (i = 0; i < MAXPLAYERS; i++) + WRITESINT8(save_p, votes[i]); + + WRITESINT8(save_p, pickedvote); + WRITEUINT16(save_p, emeralds); WRITEUINT8(save_p, stagefailed); @@ -3291,6 +3296,11 @@ static inline boolean P_NetUnArchiveMisc(void) for (i = 0; i < 4; i++) votelevels[i] = READINT16(save_p); + for (i = 0; i < MAXPLAYERS; i++) + votes[i] = READSINT8(save_p); + + pickedvote = READSINT8(save_p); + emeralds = READUINT16(save_p); stagefailed = READUINT8(save_p); diff --git a/src/y_inter.c b/src/y_inter.c index 785047d2..0816331e 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -36,7 +36,8 @@ #include "m_cond.h" // condition sets -#include "m_random.h" // M_RandomKey +#include "m_random.h" // P_RandomKey +#include "g_input.h" // PLAYER1INPUTDOWN #ifdef HWRENDER #include "hardware/hw_main.h" @@ -172,34 +173,17 @@ typedef struct { char str[40]; patch_t *pic; -} y_votelvlinfo_t; +} y_votelvlinfo; typedef struct { - UINT8 *color; - INT32 *character; - UINT8 delay; INT8 selection; - boolean voted; -} y_voteplayers_t; + UINT8 delay; +} y_voteclient; -typedef struct -{ - UINT8 level; // 0 to 3; 3 is random - UINT8 playernum; -} y_vote_t; - -typedef struct -{ - y_votelvlinfo_t levels[4]; - y_voteplayers_t playerinfo[MAXPLAYERS]; - y_vote_t votes[MAXPLAYERS]; // votes have their own struct instead of being attached to the player so they can be listed in order - UINT8 numvotes; - INT32 timeleft; - INT8 pickedvote; -} y_votedata; - -static y_votedata votedata; +static y_votelvlinfo levelinfo[4]; +static y_voteclient voteclient; +static UINT8 randomanim = 0; static INT32 votetic; static INT32 voteendtic = -1; static patch_t *cursor = NULL; @@ -2174,13 +2158,13 @@ void Y_VoteDrawer(void) } else { - strcpy(str, votedata.levels[i].str); - pic = votedata.levels[i].pic; + strcpy(str, levelinfo[i].str); + pic = levelinfo[i].pic; } - if (i == votedata.playerinfo[consoleplayer].selection) + if (i == voteclient.selection) { - if (!votedata.playerinfo[consoleplayer].voted) + if (votes[consoleplayer] == -1) { V_DrawScaledPatch(BASEVIDWIDTH-124, y+21, V_SNAPTORIGHT, cursor); if (votetic % 4 > 1) @@ -2202,18 +2186,18 @@ void Y_VoteDrawer(void) x = 20; y = 15; - if (votedata.numvotes > 0) + for (i = 0; i < MAXPLAYERS; i++) { - for (i = 0; i < votedata.numvotes; i++) + if (votes[i] != -1) { patch_t *pic; - if (votedata.votes[i].level == 3 && i != votedata.pickedvote) + if ((votes[i] == 3 && i != pickedvote) || voteendtic-votetic > 3*TICRATE) pic = randomlvl; else - pic = votedata.levels[votedata.votes[i].level].pic; + pic = levelinfo[votes[i]].pic; - if (i == votedata.pickedvote) + if (!timer && i == randomanim) { V_DrawScaledPatch(x-18, y+9, V_SNAPTOLEFT, cursor); if (votetic % 4 > 1) @@ -2224,27 +2208,42 @@ void Y_VoteDrawer(void) V_DrawTinyScaledPatch(x, y, V_SNAPTOLEFT, pic); - if (votedata.playerinfo[votedata.votes[i].playernum].color == 0) - V_DrawSmallScaledPatch(x+24, y+9, V_SNAPTOLEFT, faceprefix[*votedata.playerinfo[votedata.votes[i].playernum].character]); + if (players[i].skincolor == 0) + V_DrawSmallScaledPatch(x+24, y+9, V_SNAPTOLEFT, faceprefix[players[i].skin]); else { - UINT8 *colormap = R_GetTranslationColormap(*votedata.playerinfo[votedata.votes[i].playernum].character, *votedata.playerinfo[votedata.votes[i].playernum].color, GTC_CACHE); - V_DrawSmallMappedPatch(x+24, y+9, V_SNAPTOLEFT, faceprefix[*votedata.playerinfo[votedata.votes[i].playernum].character], colormap); + UINT8 *colormap = R_GetTranslationColormap(players[i].skin, players[i].skincolor, GTC_CACHE); + V_DrawSmallMappedPatch(x+24, y+9, V_SNAPTOLEFT, faceprefix[players[i].skin], colormap); } + } - y += 30; + if (splitscreen) // only 1p has a vote in splitscreen + break; - if (y > BASEVIDHEIGHT-38) - { - x += 20; - y = 15; - } + y += 30; + + if (y > BASEVIDHEIGHT-38) + { + x += 100; + y = 15; } } - if (votedata.timeleft) - V_DrawCenteredString(BASEVIDWIDTH/2, 188, V_YELLOWMAP|V_SNAPTOBOTTOM, - va("Vote ends in %d seconds", votedata.timeleft/TICRATE)); + //V_DrawScaledPatch(x, y, V_SNAPTOBOTTOM, pic); + + if (timer) + { + if (votes[consoleplayer] == -1) + { + V_DrawCenteredString(BASEVIDWIDTH/2, 188, V_YELLOWMAP|V_SNAPTOBOTTOM, + va("Vote ends in %d seconds", timer/TICRATE)); + } + else + { + V_DrawCenteredString(BASEVIDWIDTH/2, 188, V_YELLOWMAP|V_SNAPTOBOTTOM, + va("Waiting for everyone to vote...")); + } + } } // @@ -2254,11 +2253,9 @@ void Y_VoteDrawer(void) // void Y_VoteTicker(void) { - UINT8 numplayers; + boolean pressed = false; INT32 i; - numplayers = 0; - if (paused || P_AutoPause()) return; @@ -2271,85 +2268,123 @@ void Y_VoteTicker(void) return; } + for (i = 0; i < MAXPLAYERS; i++) // Correct votes as early as possible, before they're processed by the game at all + { + if (!playeringame[i] || players[i].spectator) + votes[i] = -1; + else if (pickedvote != -1 && votes[i] == -1) + votes[i] = 3; // Slow people get random + } + + if (server && votes[pickedvote] == -1) // Uh oh! The person who got picked left! Recalculate, quick! + D_PickVote(); + if (!votetic) S_ChangeMusicInternal("racent", true); - if (votetic < TICRATE) // give it some time before letting you control it :V - return; + if (timer) + timer--; - if (votedata.timeleft > 0) - votedata.timeleft--; + if (voteclient.delay) + voteclient.delay--; - for (i = 0; i < MAXPLAYERS; i++) + if (pickedvote != -1) { - boolean pressed = false; + timer = 0; - if (!playeringame[i] || players[i].spectator) - continue; + if (voteendtic == -1) + return; - numplayers++; - - if (votedata.playerinfo[i].voted) - continue; - - /*if (votedata.timeleft <= 0 && !votedata.playerinfo[i].voted) + if (voteendtic-votetic > 3*TICRATE) { - votedata.votes[votedata.numvotes].level = 3; // too slow? you pick random - votedata.votes[votedata.numvotes].playernum = i; - votedata.playerinfo[i].voted = true; - votedata.numvotes++; - continue; - }*/ + UINT8 tempvotes[MAXPLAYERS]; + UINT8 numvotes = 0; - if (votedata.playerinfo[i].delay > 0) - { - votedata.playerinfo[i].delay--; - continue; + if (votetic % (TICRATE/7) != 0) + return; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (votes[i] == -1) + continue; + tempvotes[numvotes] = i; + numvotes++; + } + + randomanim = tempvotes[((pickedvote - ((voteendtic-votetic) / (TICRATE/7))) % numvotes)]; + S_StartSound(NULL, sfx_menu1); } - - if (players[i].cmd.buttons & BT_FORWARD && !pressed) + else { - votedata.playerinfo[i].selection--; - pressed = true; + randomanim = pickedvote; + if (voteendtic-votetic == 3*TICRATE-1) + S_StartSound(NULL, sfx_ncitem); } + } + else + { + if (votetic < 3*(NEWTICRATE/7)) // give it some time before letting you control it :V + return; - if (players[i].cmd.buttons & BT_BACKWARD && !pressed) + if ((!playeringame[consoleplayer] || players[consoleplayer].spectator) && votes[consoleplayer] != -1) + D_ModifyClientVote(-1); + else if (pickedvote == -1 && votes[consoleplayer] == -1 && !voteclient.delay) { - votedata.playerinfo[i].selection++; - pressed = true; - } - - if (votedata.playerinfo[i].selection < 0) - votedata.playerinfo[i].selection = 3; - if (votedata.playerinfo[i].selection > 3) - votedata.playerinfo[i].selection = 0; - - if (players[i].cmd.buttons & BT_ACCELERATE && !pressed) - { - votedata.votes[votedata.numvotes].level = votedata.playerinfo[i].selection; - votedata.votes[votedata.numvotes].playernum = i; - votedata.playerinfo[i].voted = true; - pressed = true; - votedata.numvotes++; + if (PLAYER1INPUTDOWN(gc_aimforward)) + { + voteclient.selection--; + pressed = true; + } + if (PLAYER1INPUTDOWN(gc_aimbackward) && !pressed) + { + voteclient.selection++; + pressed = true; + } + if (voteclient.selection < 0) + voteclient.selection = 3; + if (voteclient.selection > 3) + voteclient.selection = 0; + if (PLAYER1INPUTDOWN(gc_accelerate) && !pressed) + { + D_ModifyClientVote(voteclient.selection); + pressed = true; + } } if (pressed) { - if (i == consoleplayer) - S_StartSound(NULL, sfx_menu1); - votedata.playerinfo[i].delay = 3; + S_StartSound(NULL, sfx_menu1); + voteclient.delay = NEWTICRATE/7; } - } - if (votedata.numvotes >= numplayers) - votedata.timeleft = 0; + if (server) + { + UINT8 numplayers = 0, numvotes = 0; - if (votedata.timeleft == 0 && voteendtic == -1) - { - votedata.pickedvote = P_RandomKey(votedata.numvotes); - nextmap = (votelevels[votedata.votes[votedata.pickedvote].level]); // oh my god - S_StartSound(NULL, sfx_ncitem); - voteendtic = votetic+(3*TICRATE); + if (splitscreen) + { + numplayers = 1; + if (votes[0] != -1) + numvotes = 1; + } + else + { + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator) + continue; + numplayers++; + if (votes[i] != -1) + numvotes++; + } + } + + if (numvotes >= numplayers) + timer = 0; + + if (timer == 0 && voteendtic == -1) + D_PickVote(); + } } } @@ -2374,21 +2409,15 @@ void Y_StartVote(void) cursor = W_CachePatchName("M_CURSOR", PU_STATIC); randomlvl = W_CachePatchName("RANDOMLV", PU_STATIC); - votedata.timeleft = cv_votetime.value*TICRATE; - votedata.numvotes = 0; - votedata.pickedvote = -1; + timer = cv_votetime.value*TICRATE; + pickedvote = -1; + randomanim = 0; + + voteclient.selection = 0; + voteclient.delay = 0; for (i = 0; i < MAXPLAYERS; i++) - { - votedata.playerinfo[i].color = &players[i].skincolor; - votedata.playerinfo[i].character = &players[i].skin; - votedata.playerinfo[i].delay = 0; - votedata.playerinfo[i].selection = 0; - votedata.playerinfo[i].voted = false; - - votedata.votes[i].level = 0; - votedata.votes[i].playernum = 0; - } + votes[i] = -1; for (i = 0; i < 4; i++) { @@ -2398,37 +2427,37 @@ void Y_StartVote(void) if (mapheaderinfo[votelevels[i]]->zonttl) { if (mapheaderinfo[votelevels[i]]->actnum) - snprintf(votedata.levels[i].str, - sizeof votedata.levels[i].str, + snprintf(levelinfo[i].str, + sizeof levelinfo[i].str, "%.32s %.32s %d", mapheaderinfo[votelevels[i]]->lvlttl, mapheaderinfo[votelevels[i]]->zonttl, mapheaderinfo[votelevels[i]]->actnum); else - snprintf(votedata.levels[i].str, - sizeof votedata.levels[i].str, + snprintf(levelinfo[i].str, + sizeof levelinfo[i].str, "%.32s %.32s", mapheaderinfo[votelevels[i]]->lvlttl, mapheaderinfo[votelevels[i]]->zonttl); } else { if (mapheaderinfo[votelevels[i]]->actnum) - snprintf(votedata.levels[i].str, - sizeof votedata.levels[i].str, + snprintf(levelinfo[i].str, + sizeof levelinfo[i].str, "%.32s %d", mapheaderinfo[votelevels[i]]->lvlttl, mapheaderinfo[votelevels[i]]->actnum); else - snprintf(votedata.levels[i].str, - sizeof votedata.levels[i].str, + snprintf(levelinfo[i].str, + sizeof levelinfo[i].str, "%.32s", mapheaderinfo[votelevels[i]]->lvlttl); } - votedata.levels[i].str[sizeof votedata.levels[i].str - 1] = '\0'; + levelinfo[i].str[sizeof levelinfo[i].str - 1] = '\0'; lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(votelevels[i]+1))); if (lumpnum != LUMPERROR) - votedata.levels[i].pic = W_CachePatchName(va("%sP", G_BuildMapName(votelevels[i]+1)), PU_STATIC); + levelinfo[i].pic = W_CachePatchName(va("%sP", G_BuildMapName(votelevels[i]+1)), PU_STATIC); else - votedata.levels[i].pic = W_CachePatchName("BLANKLVL", PU_STATIC); + levelinfo[i].pic = W_CachePatchName("BLANKLVL", PU_STATIC); } } @@ -2454,8 +2483,40 @@ static void Y_UnloadVoteData(void) UNLOAD(cursor); UNLOAD(randomlvl); - UNLOAD(votedata.levels[3].pic); - UNLOAD(votedata.levels[2].pic); - UNLOAD(votedata.levels[1].pic); - UNLOAD(votedata.levels[0].pic); + UNLOAD(levelinfo[3].pic); + UNLOAD(levelinfo[2].pic); + UNLOAD(levelinfo[1].pic); + UNLOAD(levelinfo[0].pic); } + +// +// Y_SetupVoteFinish +// +void Y_SetupVoteFinish(INT8 pick, INT8 level) +{ + pickedvote = pick; + nextmap = votelevels[level]; + timer = 0; + + if (voteendtic == -1) + { + UINT8 numplayers = 0; + + if (splitscreen) + numplayers = 1; + else + { + UINT8 i; + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i] && !players[i].spectator) + numplayers++; + } + } + + if (numplayers > 1) + voteendtic = votetic+(6*TICRATE); + else + voteendtic = votetic+(3*TICRATE); + } +} \ No newline at end of file diff --git a/src/y_inter.h b/src/y_inter.h index d36e613d..6ba83583 100644 --- a/src/y_inter.h +++ b/src/y_inter.h @@ -21,6 +21,7 @@ void Y_VoteDrawer(void); void Y_VoteTicker(void); void Y_StartVote(void); void Y_EndVote(void); +void Y_SetupVoteFinish(INT8 pick, INT8 level); typedef enum {