From cc0c99640f77389f8adb454fe2a12a47579af348 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sat, 27 Jan 2018 01:17:08 -0500 Subject: [PATCH 01/20] Work so far Crashes, but baseline's there --- src/console.c | 3 +- src/d_clisrv.c | 4 + src/d_main.c | 6 + src/d_netcmd.c | 4 +- src/g_game.c | 25 +++- src/g_game.h | 3 +- src/g_state.h | 1 + src/hu_stuff.c | 3 +- src/p_saveg.c | 2 + src/y_inter.c | 374 ++++++++++++++++++++++++++++++++++++++++++++++++- src/y_inter.h | 5 + 11 files changed, 420 insertions(+), 10 deletions(-) diff --git a/src/console.c b/src/console.c index 2270c51f..ab357018 100644 --- a/src/console.c +++ b/src/console.c @@ -1618,6 +1618,7 @@ void CON_Drawer(void) if (con_curlines > 0) CON_DrawConsole(); - else if (gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_CUTSCENE || gamestate == GS_CREDITS) + else if (gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_CUTSCENE || gamestate == GS_CREDITS + || gamestate == GS_VOTING) CON_DrawHudlines(); } diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 634c6b81..c97966f9 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2070,6 +2070,8 @@ static void CL_ConnectToServer(boolean viams) if (gamestate == GS_INTERMISSION) Y_EndIntermission(); // clean up intermission graphics etc + if (gamestate == GS_VOTING) + Y_EndVote(); DEBFILE(va("waiting %d nodes\n", doomcom->numnodes)); G_SetGamestate(GS_WAITINGPLAYERS); @@ -3393,6 +3395,8 @@ void SV_StopServer(void) if (gamestate == GS_INTERMISSION) Y_EndIntermission(); + if (gamestate == GS_VOTING) + Y_EndVote(); gamestate = wipegamestate = GS_NULL; localtextcmd[0] = 0; diff --git a/src/d_main.c b/src/d_main.c index f94331cd..3dd9a674 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -335,6 +335,12 @@ static void D_Display(void) HU_Drawer(); break; + case GS_VOTING: + Y_VoteDrawer(); + HU_Erase(); + HU_Drawer(); + break; + case GS_TIMEATTACK: break; diff --git a/src/d_netcmd.c b/src/d_netcmd.c index b8eb5ec8..9d9e7269 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -422,8 +422,8 @@ consvar_t cv_maxping = {"maxping", "0", CV_SAVE, CV_Unsigned, NULL, 0, NULL, NUL static CV_PossibleValue_t inttime_cons_t[] = {{0, "MIN"}, {3600, "MAX"}, {0, NULL}}; consvar_t cv_inttime = {"inttime", "20", CV_NETVAR, inttime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -static CV_PossibleValue_t advancemap_cons_t[] = {{0, "Off"}, {1, "Next"}, {2, "Random"}, {0, NULL}}; -consvar_t cv_advancemap = {"advancemap", "Next", CV_NETVAR, advancemap_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +static CV_PossibleValue_t advancemap_cons_t[] = {{0, "Off"}, {1, "Next"}, {2, "Random"}, {3, "Vote"}, {0, NULL}}; +consvar_t cv_advancemap = {"advancemap", "Vote", CV_NETVAR, advancemap_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t playersforexit_cons_t[] = {{0, "One"}, {1, "All"}, {0, NULL}}; consvar_t cv_playersforexit = {"playersforexit", "One", CV_NETVAR, playersforexit_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; diff --git a/src/g_game.c b/src/g_game.c index cb20dbe8..41360a4b 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1761,6 +1761,9 @@ void G_DoLoadLevel(boolean resetplayer) if (gamestate == GS_INTERMISSION) Y_EndIntermission(); + if (gamestate == GS_VOTING) + Y_EndVote(); + G_SetGamestate(GS_LEVEL); for (i = 0; i < MAXPLAYERS; i++) @@ -2138,6 +2141,12 @@ void G_Ticker(boolean run) HU_Ticker(); break; + case GS_VOTING: + if (run) + Y_VoteTicker(); + HU_Ticker(); + break; + case GS_TIMEATTACK: break; @@ -3025,7 +3034,7 @@ INT16 G_TOLFlag(INT32 pgametype) * has those flags. * \author Graue */ -static INT16 RandMap(INT16 tolflags, INT16 pprevmap) +INT16 RandMap(INT16 tolflags, INT16 pprevmap) { INT16 *okmaps = Z_Malloc(NUMMAPS * sizeof(INT16), PU_STATIC, NULL); INT32 numokmaps = 0; @@ -3184,7 +3193,7 @@ static void G_DoCompleted(void) P_AllocMapHeader(nextmap); if (skipstats && !modeattacking) // Don't skip stats if we're in record attack - G_AfterIntermission(); + G_AfterIntermission(false); else { G_SetGamestate(GS_INTERMISSION); @@ -3192,15 +3201,21 @@ static void G_DoCompleted(void) } } -void G_AfterIntermission(void) +void G_AfterIntermission(boolean vote) { HU_ClearCEcho(); + G_NextLevel(); if (mapheaderinfo[gamemap-1]->cutscenenum && !modeattacking) // Start a custom cutscene. F_StartCustomCutscene(mapheaderinfo[gamemap-1]->cutscenenum-1, false, false); else { - if (nextmap < 1100-1) + if (cv_advancemap.value == 3 && !vote) + { + G_SetGamestate(GS_VOTING); + Y_StartVote(); + } + else if (nextmap < 1100-1) G_NextLevel(); else Y_EndGame(); @@ -5810,6 +5825,8 @@ void G_StopDemo(void) if (gamestate == GS_INTERMISSION) Y_EndIntermission(); // cleanup + if (gamestate == GS_VOTING) + Y_EndVote(); G_SetGamestate(GS_NULL); wipegamestate = GS_NULL; diff --git a/src/g_game.h b/src/g_game.h index dfc7b0df..4e4365be 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -173,7 +173,7 @@ void G_ExitLevel(void); void G_NextLevel(void); void G_Continue(void); void G_UseContinue(void); -void G_AfterIntermission(void); +void G_AfterIntermission(boolean vote); void G_Ticker(boolean run); boolean G_Responder(event_t *ev); @@ -218,5 +218,6 @@ FUNCMATH INT32 G_TicsToMilliseconds(tic_t tics); // Don't split up TOL handling INT16 G_TOLFlag(INT32 pgametype); +INT16 RandMap(INT16 tolflags, INT16 pprevmap); #endif diff --git a/src/g_state.h b/src/g_state.h index 81548b7c..75ce2c30 100644 --- a/src/g_state.h +++ b/src/g_state.h @@ -23,6 +23,7 @@ typedef enum // Fadable gamestates GS_LEVEL, // Playing, in a level. GS_INTERMISSION, // Gazing at the intermission screen. + GS_VOTING, // SRB2Kart: MP voting screen GS_CONTINUING, // continue screen GS_TITLESCREEN, // title screen diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 24e4da10..f66eb27c 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1145,7 +1145,8 @@ void HU_Drawer(void) if (!Playing() || gamestate == GS_INTERMISSION || gamestate == GS_CUTSCENE || gamestate == GS_CREDITS || gamestate == GS_EVALUATION - || gamestate == GS_GAMEEND) + || gamestate == GS_GAMEEND + || gamestate == GS_VOTING) // SRB2kart return; // draw multiplayer rankings diff --git a/src/p_saveg.c b/src/p_saveg.c index 53ab044d..1a10ce36 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -3364,6 +3364,8 @@ boolean P_LoadGame(INT16 mapoverride) { if (gamestate == GS_INTERMISSION) Y_EndIntermission(); + if (gamestate == GS_VOTING) + Y_EndVote(); G_SetGamestate(GS_NULL); // should be changed in P_UnArchiveMisc P_UnArchiveSPGame(mapoverride); diff --git a/src/y_inter.c b/src/y_inter.c index 5bfed538..4d520a2c 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -36,6 +36,8 @@ #include "m_cond.h" // condition sets +#include "m_random.h" // M_RandomKey + #ifdef HWRENDER #include "hardware/hw_main.h" #endif @@ -164,6 +166,47 @@ static void Y_CalculateMatchWinners(void); static void Y_FollowIntermission(void); static void Y_UnloadData(void); +// SRB2Kart: voting stuff + +typedef struct +{ + char str[40]; + patch_t *pic; + UINT16 num; +} y_votelvlinfo_t; + +typedef struct +{ + UINT8 *color; + INT32 *character; + UINT8 delay; + INT8 selection; + boolean voted; +} y_voteplayers_t; + +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]; + UINT8 numvotes; + INT32 timeleft; +} y_votedata; + +static y_votedata votedata; +static INT32 votetic; +static INT32 voteendtic = -1; +static patch_t *cursor = NULL; + +static void Y_UnloadVoteData(void); +static void Y_FollowVote(void); + // Stuff copy+pasted from st_stuff.c static INT32 SCX(INT32 x) { @@ -2008,7 +2051,7 @@ static void Y_FollowIntermission(void) if (nextmap < 1100-1) { // normal level - G_AfterIntermission(); + G_AfterIntermission(false); return; } @@ -2076,3 +2119,332 @@ static void Y_UnloadData(void) break; } } + +// SRB2Kart: Voting! + +// +// Y_StartVote +// +// MK online style voting screen, appears after intermission +// +void Y_StartVote(void) +{ + INT32 i = 0; + + votetic = -1; + +#ifdef PARANOIA + if (voteendtic != -1) + I_Error("voteendtic is dirty"); +#endif + + bgpatch = W_CachePatchName("INTERSCR", PU_STATIC); + widebgpatch = W_CachePatchName("INTERSCW", PU_STATIC); + cursor = W_CachePatchName("M_CURSOR", PU_STATIC); + + //votedata.timeleft = 30*TICRATE; + votedata.numvotes = 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; + } + + for (i = 0; i < 4; i++) + { + INT32 j; + lumpnum_t lumpnum; + + votedata.levels[i].num = RandMap(G_TOLFlag(gametype), prevmap); + + for (j = 0; j < 4; j++) + { + INT32 loopcount = 0; + if (i == j) + continue; + while (votedata.levels[i].num == votedata.levels[j].num && loopcount < 5) + { + votedata.levels[i].num = RandMap(G_TOLFlag(gametype), prevmap); + loopcount++; + } + } + + if (!mapheaderinfo[votedata.levels[i].num]) + P_AllocMapHeader(votedata.levels[i].num); + + if (i == 3) // Random is actually pre-calculated for ease of coding, shhhhh :V + { + //snprintf(votedata.levels[i].str, sizeof votedata.levels[i].str, "%.32s", "RANDOM"); + //votedata.levels[i].str[sizeof votedata.levels[i].str - 1] = '\0'; + votedata.levels[i].pic = W_CachePatchName("RANDOMLV", PU_STATIC); + } + else + { + // set up the str + /*if (mapheaderinfo[votedata.levels[i].num]->zonttl) + { + if (mapheaderinfo[votedata.levels[i].num]->actnum) + snprintf(votedata.levels[i].str, + sizeof votedata.levels[i].str, + "%.32s %.32s %d", + mapheaderinfo[votedata.levels[i].num]->lvlttl, mapheaderinfo[votedata.levels[i].num-1]->zonttl, mapheaderinfo[votedata.levels[i].num-1]->actnum); + else + snprintf(votedata.levels[i].str, + sizeof votedata.levels[i].str, + "%.32s %.32s", + mapheaderinfo[votedata.levels[i].num]->lvlttl, mapheaderinfo[votedata.levels[i].num-1]->zonttl); + } + else + { + if (mapheaderinfo[votedata.levels[i].num]->actnum) + snprintf(votedata.levels[i].str, + sizeof votedata.levels[i].str, + "%.32s %d", + mapheaderinfo[votedata.levels[i].num]->lvlttl, mapheaderinfo[votedata.levels[i].num-1]->actnum); + else + snprintf(votedata.levels[i].str, + sizeof votedata.levels[i].str, + "%.32s", + mapheaderinfo[votedata.levels[i].num]->lvlttl); + } + + votedata.levels[i].str[sizeof votedata.levels[i].str - 1] = '\0';*/ + + // A 160x100 image of the level as entry MAPxxP + lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(votedata.levels[i].num))); + + if (lumpnum != LUMPERROR) + votedata.levels[i].pic = W_CachePatchName(va("%sP", G_BuildMapName(votedata.levels[i].num+1)), PU_STATIC); + else + votedata.levels[i].pic = W_CachePatchName("BLANKLVL", PU_STATIC); + } + } +} + +// +// Y_VoteTicker +// +// Vote screen thinking :eggthinking: +// +void Y_VoteTicker(void) +{ + UINT8 numplayers; + INT32 i; + + numplayers = 0; + + if (paused || P_AutoPause()) + return; + + votetic++; + + if (votetic >= voteendtic) + { + Y_EndVote(); + Y_FollowVote(); + return; + } + + if (votetic < TICRATE) + return; + + /*if (votedata.timeleft > 0) + votedata.timeleft--;*/ + + for (i = 0; i < MAXPLAYERS; i++) + { + boolean pressed = false; + + if (!playeringame[i] || players[i].spectator) + continue; + + numplayers++; + + if (votedata.playerinfo[i].voted) + continue; + + if (votedata.playerinfo[i].delay > 0) + { + votedata.playerinfo[i].delay--; + continue; + } + + if (players[i].cmd.buttons & BT_FORWARD && !pressed) + { + votedata.playerinfo[i].selection--; + pressed = true; + } + + if (players[i].cmd.buttons & BT_BACKWARD && !pressed) + { + 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 (pressed) + { + if (i == consoleplayer) + S_StartSound(NULL, sfx_menu1); + votedata.playerinfo[i].delay = NEWTICRATE/7; + } + + /*if (votedata.timeleft <= 0 && !votedata.playerinfo[i].voted) + { + votedata.votes[votedata.numvotes].level = 3; // too slow? you pick random + votedata.votes[votedata.numvotes].playernum = i; + votedata.playerinfo[i].voted = true; + votedata.numvotes++; + }*/ + } + + /*if (votedata.numvotes >= numplayers) + votedata.timeleft = 0; + + if (votedata.timeleft == 0 && voteendtic == -1) + { + nextmap = (votedata.votes[P_RandomKey(votedata.numvotes)].level); + voteendtic = votetic+(10*TICRATE); + }*/ + + if (!votetic) + S_ChangeMusicInternal("racent", true); +} + +// +// Y_VoteDrawer +// +// Draws the voting screen! +// +void Y_VoteDrawer(void) +{ + INT32 i, x, y = 0; + + if (rendermode == render_none) + return; + + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); + + if (widebgpatch && rendermode == render_soft && vid.width / vid.dupx == 400) + V_DrawScaledPatch(0, 0, V_SNAPTOLEFT, widebgpatch); + else + V_DrawScaledPatch(0, 0, 0, bgpatch); + + for (i = 0; i < 4; i++) + { + if (i == votedata.playerinfo[consoleplayer].selection) + { + y += 50; + V_DrawScaledPatch(BASEVIDWIDTH-142, y+21, 0, cursor); + //V_DrawFill(BASEVIDWIDTH-102, y-2, 84, 54, 103); + V_DrawSmallScaledPatch(BASEVIDWIDTH-100, y, 0, votedata.levels[i].pic); + //V_DrawRightAlignedThinString(BASEVIDWIDTH-20, 42+y, V_YELLOWMAP, votedata.levels[i].str); + } + else + { + V_DrawTinyScaledPatch(BASEVIDWIDTH-80, y, 0, votedata.levels[i].pic); + y += 62; + } + } + + x = 20; + y = 0; + + for (i = 0; i < votedata.numvotes; i++) + { + V_DrawTinyScaledPatch(x, y, 0, votedata.levels[votedata.votes[i].level].pic); + + if (votedata.playerinfo[votedata.votes[i].playernum].color == 0) + V_DrawSmallScaledPatch(x+48, y+18, 0, faceprefix[*votedata.playerinfo[votedata.votes[i].playernum].character]); + else + { + UINT8 *colormap = R_GetTranslationColormap(*votedata.playerinfo[votedata.votes[i].playernum].character, *votedata.playerinfo[votedata.votes[i].playernum].color, GTC_CACHE); + V_DrawSmallMappedPatch(x+48, y+18, 0, faceprefix[*votedata.playerinfo[votedata.votes[i].playernum].character], colormap); + } + + y += 25; + + if (y > BASEVIDHEIGHT-25) + { + x += 20; + y = 0; + } + } + + /*if (votedata.timeleft) + V_DrawCenteredString(BASEVIDWIDTH/2, 188, V_YELLOWMAP, + va("Vote ends in %d seconds", votedata.timeleft/TICRATE));*/ +} + +// +// Y_EndVote +// +void Y_EndVote(void) +{ + Y_UnloadVoteData(); + voteendtic = -1; +} + +// +// Y_UnloadVoteData +// +static void Y_UnloadVoteData(void) +{ + if (rendermode != render_soft) + return; + + UNLOAD(bgpatch); + UNLOAD(widebgpatch); + UNLOAD(cursor); + + UNLOAD(votedata.levels[3].pic); + UNLOAD(votedata.levels[2].pic); + UNLOAD(votedata.levels[1].pic); + UNLOAD(votedata.levels[0].pic); +} + +// +// Y_FollowVote +// +static void Y_FollowVote(void) +{ + if (modeattacking) + { + M_EndModeAttackRun(); + return; + } + + if (nextmap < 1100-1) + { + G_AfterIntermission(true); + return; + } + + if (mapheaderinfo[gamemap-1]->cutscenenum && !modeattacking) + { + F_StartCustomCutscene(mapheaderinfo[gamemap-1]->cutscenenum-1, false, false); + return; + } + + Y_EndGame(); +} \ No newline at end of file diff --git a/src/y_inter.h b/src/y_inter.h index 358debf7..3f63b3ee 100644 --- a/src/y_inter.h +++ b/src/y_inter.h @@ -17,6 +17,11 @@ void Y_StartIntermission(void); void Y_EndIntermission(void); void Y_EndGame(void); +void Y_StartVote(void); +void Y_VoteTicker(void); +void Y_VoteDrawer(void); +void Y_EndVote(void); + typedef enum { int_none, From 5efac6401fb16d8e5163f89e76f9481754108510 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sat, 27 Jan 2018 20:59:29 -0500 Subject: [PATCH 02/20] Getting there. Should *theoretically* be functional... if it didn't crash on vote end. I'm like 90% sure I'm missing a patch unload somewhere... --- src/g_game.c | 32 +++-- src/g_game.h | 2 +- src/g_state.h | 1 + src/y_inter.c | 355 ++++++++++++++++++++++++-------------------------- src/y_inter.h | 4 +- 5 files changed, 199 insertions(+), 195 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 41360a4b..30171b30 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -72,6 +72,7 @@ static void G_DoCompleted(void); static void G_DoStartContinue(void); static void G_DoContinued(void); static void G_DoWorldDone(void); +static void G_DoStartVote(void); char mapmusname[7]; // Music name UINT16 mapmusflags; // Track and reset bit @@ -2096,6 +2097,7 @@ void G_Ticker(boolean run) case ga_startcont: G_DoStartContinue(); break; case ga_continued: G_DoContinued(); break; case ga_worlddone: G_DoWorldDone(); break; + case ga_startvote: G_DoStartVote(); break; case ga_nothing: break; default: I_Error("gameaction = %d\n", gameaction); } @@ -3193,7 +3195,7 @@ static void G_DoCompleted(void) P_AllocMapHeader(nextmap); if (skipstats && !modeattacking) // Don't skip stats if we're in record attack - G_AfterIntermission(false); + G_AfterIntermission(); else { G_SetGamestate(GS_INTERMISSION); @@ -3201,7 +3203,7 @@ static void G_DoCompleted(void) } } -void G_AfterIntermission(boolean vote) +void G_AfterIntermission(void) { HU_ClearCEcho(); G_NextLevel(); @@ -3210,12 +3212,7 @@ void G_AfterIntermission(boolean vote) F_StartCustomCutscene(mapheaderinfo[gamemap-1]->cutscenenum-1, false, false); else { - if (cv_advancemap.value == 3 && !vote) - { - G_SetGamestate(GS_VOTING); - Y_StartVote(); - } - else if (nextmap < 1100-1) + if (nextmap < 1100-1) G_NextLevel(); else Y_EndGame(); @@ -3230,7 +3227,11 @@ void G_AfterIntermission(boolean vote) // void G_NextLevel(void) { - gameaction = ga_worlddone; + if (cv_advancemap.value == 3 && gamestate != GS_VOTING + && !modeattacking && !skipstats && (multiplayer || netgame)) + gameaction = ga_startvote; + else + gameaction = ga_worlddone; } static void G_DoWorldDone(void) @@ -3304,6 +3305,19 @@ static void G_DoContinued(void) gameaction = ga_nothing; } +// +// G_DoStartVote +// +static void G_DoStartVote(void) +{ + I_Assert(netgame || multiplayer); + + G_SetGamestate(GS_VOTING); + Y_StartVote(); + + gameaction = ga_nothing; +} + // // G_LoadGameSettings // diff --git a/src/g_game.h b/src/g_game.h index 4e4365be..82968da6 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -173,7 +173,7 @@ void G_ExitLevel(void); void G_NextLevel(void); void G_Continue(void); void G_UseContinue(void); -void G_AfterIntermission(boolean vote); +void G_AfterIntermission(void); void G_Ticker(boolean run); boolean G_Responder(event_t *ev); diff --git a/src/g_state.h b/src/g_state.h index 75ce2c30..38ad4145 100644 --- a/src/g_state.h +++ b/src/g_state.h @@ -48,6 +48,7 @@ typedef enum ga_worlddone, ga_startcont, ga_continued, + ga_startvote, } gameaction_t; extern gamestate_t gamestate; diff --git a/src/y_inter.c b/src/y_inter.c index 4d520a2c..56867b98 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -194,7 +194,7 @@ typedef struct { y_votelvlinfo_t levels[4]; y_voteplayers_t playerinfo[MAXPLAYERS]; - y_vote_t votes[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; } y_votedata; @@ -205,7 +205,6 @@ static INT32 voteendtic = -1; static patch_t *cursor = NULL; static void Y_UnloadVoteData(void); -static void Y_FollowVote(void); // Stuff copy+pasted from st_stuff.c static INT32 SCX(INT32 x) @@ -2051,7 +2050,7 @@ static void Y_FollowIntermission(void) if (nextmap < 1100-1) { // normal level - G_AfterIntermission(false); + G_AfterIntermission(); return; } @@ -2123,109 +2122,84 @@ static void Y_UnloadData(void) // SRB2Kart: Voting! // -// Y_StartVote +// Y_VoteDrawer // -// MK online style voting screen, appears after intermission +// Draws the voting screen! // -void Y_StartVote(void) +void Y_VoteDrawer(void) { - INT32 i = 0; + INT32 i, x, y = 0; - votetic = -1; + if (rendermode == render_none) + return; -#ifdef PARANOIA - if (voteendtic != -1) - I_Error("voteendtic is dirty"); -#endif + if (votetic >= voteendtic && voteendtic != -1) + return; - bgpatch = W_CachePatchName("INTERSCR", PU_STATIC); - widebgpatch = W_CachePatchName("INTERSCW", PU_STATIC); - cursor = W_CachePatchName("M_CURSOR", PU_STATIC); + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); - //votedata.timeleft = 30*TICRATE; - votedata.numvotes = 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; - } + /*if (widebgpatch && rendermode == render_soft && vid.width / vid.dupx == 400) + V_DrawScaledPatch(0, 0, V_SNAPTOLEFT, widebgpatch); + else*/ + V_DrawScaledPatch(0, 0, 0, bgpatch); + y = 30; for (i = 0; i < 4; i++) { - INT32 j; - lumpnum_t lumpnum; - - votedata.levels[i].num = RandMap(G_TOLFlag(gametype), prevmap); - - for (j = 0; j < 4; j++) + if (i == votedata.playerinfo[consoleplayer].selection) { - INT32 loopcount = 0; - if (i == j) - continue; - while (votedata.levels[i].num == votedata.levels[j].num && loopcount < 5) - { - votedata.levels[i].num = RandMap(G_TOLFlag(gametype), prevmap); - loopcount++; - } - } + + V_DrawScaledPatch(BASEVIDWIDTH-124, y+21, 0, cursor); - if (!mapheaderinfo[votedata.levels[i].num]) - P_AllocMapHeader(votedata.levels[i].num); + if (votetic % 4 > 1) + V_DrawFill(BASEVIDWIDTH-101, y-1, 82, 52, 120); + else + V_DrawFill(BASEVIDWIDTH-101, y-1, 82, 52, 103); - if (i == 3) // Random is actually pre-calculated for ease of coding, shhhhh :V - { - //snprintf(votedata.levels[i].str, sizeof votedata.levels[i].str, "%.32s", "RANDOM"); - //votedata.levels[i].str[sizeof votedata.levels[i].str - 1] = '\0'; - votedata.levels[i].pic = W_CachePatchName("RANDOMLV", PU_STATIC); + V_DrawSmallScaledPatch(BASEVIDWIDTH-100, y, 0, votedata.levels[i].pic); + V_DrawRightAlignedThinString(BASEVIDWIDTH-20, 42+y, V_YELLOWMAP, votedata.levels[i].str); + y += 55; } else { - // set up the str - /*if (mapheaderinfo[votedata.levels[i].num]->zonttl) - { - if (mapheaderinfo[votedata.levels[i].num]->actnum) - snprintf(votedata.levels[i].str, - sizeof votedata.levels[i].str, - "%.32s %.32s %d", - mapheaderinfo[votedata.levels[i].num]->lvlttl, mapheaderinfo[votedata.levels[i].num-1]->zonttl, mapheaderinfo[votedata.levels[i].num-1]->actnum); - else - snprintf(votedata.levels[i].str, - sizeof votedata.levels[i].str, - "%.32s %.32s", - mapheaderinfo[votedata.levels[i].num]->lvlttl, mapheaderinfo[votedata.levels[i].num-1]->zonttl); - } - else - { - if (mapheaderinfo[votedata.levels[i].num]->actnum) - snprintf(votedata.levels[i].str, - sizeof votedata.levels[i].str, - "%.32s %d", - mapheaderinfo[votedata.levels[i].num]->lvlttl, mapheaderinfo[votedata.levels[i].num-1]->actnum); - else - snprintf(votedata.levels[i].str, - sizeof votedata.levels[i].str, - "%.32s", - mapheaderinfo[votedata.levels[i].num]->lvlttl); - } - - votedata.levels[i].str[sizeof votedata.levels[i].str - 1] = '\0';*/ - - // A 160x100 image of the level as entry MAPxxP - lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(votedata.levels[i].num))); - - if (lumpnum != LUMPERROR) - votedata.levels[i].pic = W_CachePatchName(va("%sP", G_BuildMapName(votedata.levels[i].num+1)), PU_STATIC); - else - votedata.levels[i].pic = W_CachePatchName("BLANKLVL", PU_STATIC); + V_DrawTinyScaledPatch(BASEVIDWIDTH-60, y, 0, votedata.levels[i].pic); + y += 30; } } + + x = 20; + y = 15; + + if (votedata.numvotes > 0) + { + for (i = 0; i < votedata.numvotes; i++) + { + V_DrawTinyScaledPatch(x, y, 0, votedata.levels[votedata.votes[i].level].pic); + + if (votedata.playerinfo[votedata.votes[i].playernum].color == 0) + V_DrawSmallScaledPatch(x+24, y+9, 0, faceprefix[*votedata.playerinfo[votedata.votes[i].playernum].character]); + 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, 0, faceprefix[*votedata.playerinfo[votedata.votes[i].playernum].character], colormap); + } + + y += 30; + + if (y > BASEVIDHEIGHT-38) + { + x += 20; + y = 15; + } + } + } + + if (votedata.timeleft) + V_DrawCenteredString(BASEVIDWIDTH/2, 188, V_YELLOWMAP, + va("Vote ends in %d seconds", votedata.timeleft/TICRATE)); + + V_DrawString(80, 0, V_YELLOWMAP, va("votetic: %d", votetic)); + V_DrawString(80, 8, V_YELLOWMAP, va("voteendtic: %d", voteendtic)); } // @@ -2245,18 +2219,21 @@ void Y_VoteTicker(void) votetic++; - if (votetic >= voteendtic) + if (votetic >= voteendtic && voteendtic != -1) { Y_EndVote(); - Y_FollowVote(); + Y_FollowIntermission(); return; } - if (votetic < TICRATE) + if (!votetic) + S_ChangeMusicInternal("racent", true); + + if (votetic < TICRATE) // give it some time before letting you control it :V return; - /*if (votedata.timeleft > 0) - votedata.timeleft--;*/ + if (votedata.timeleft > 0) + votedata.timeleft--; for (i = 0; i < MAXPLAYERS; i++) { @@ -2270,6 +2247,15 @@ void Y_VoteTicker(void) if (votedata.playerinfo[i].voted) continue; + if (votedata.timeleft <= 0 && !votedata.playerinfo[i].voted) + { + 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; + } + if (votedata.playerinfo[i].delay > 0) { votedata.playerinfo[i].delay--; @@ -2308,92 +2294,121 @@ void Y_VoteTicker(void) S_StartSound(NULL, sfx_menu1); votedata.playerinfo[i].delay = NEWTICRATE/7; } - - /*if (votedata.timeleft <= 0 && !votedata.playerinfo[i].voted) - { - votedata.votes[votedata.numvotes].level = 3; // too slow? you pick random - votedata.votes[votedata.numvotes].playernum = i; - votedata.playerinfo[i].voted = true; - votedata.numvotes++; - }*/ } - /*if (votedata.numvotes >= numplayers) - votedata.timeleft = 0; - if (votedata.timeleft == 0 && voteendtic == -1) { - nextmap = (votedata.votes[P_RandomKey(votedata.numvotes)].level); - voteendtic = votetic+(10*TICRATE); - }*/ + nextmap = (votedata.levels[votedata.votes[P_RandomKey(votedata.numvotes)].level].num); // oh my god + voteendtic = votetic+(3*TICRATE); + } - if (!votetic) - S_ChangeMusicInternal("racent", true); + if (votedata.numvotes >= numplayers) + votedata.timeleft = 0; } // -// Y_VoteDrawer +// Y_StartVote // -// Draws the voting screen! +// MK online style voting screen, appears after intermission // -void Y_VoteDrawer(void) +void Y_StartVote(void) { - INT32 i, x, y = 0; + INT32 i = 0; - if (rendermode == render_none) - return; + votetic = -1; - V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); +#ifdef PARANOIA + if (voteendtic != -1) + I_Error("voteendtic is dirty"); +#endif - if (widebgpatch && rendermode == render_soft && vid.width / vid.dupx == 400) - V_DrawScaledPatch(0, 0, V_SNAPTOLEFT, widebgpatch); - else - V_DrawScaledPatch(0, 0, 0, bgpatch); + widebgpatch = W_CachePatchName("INTERSCW", PU_STATIC); + bgpatch = W_CachePatchName("INTERSCR", PU_STATIC); + cursor = W_CachePatchName("M_CURSOR", PU_STATIC); + + votedata.timeleft = 30*TICRATE; + votedata.numvotes = 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; + } for (i = 0; i < 4; i++) { - if (i == votedata.playerinfo[consoleplayer].selection) + INT32 j; + + votedata.levels[i].num = RandMap(G_TOLFlag(gametype), prevmap); + + for (j = 0; j < 4; j++) { - y += 50; - V_DrawScaledPatch(BASEVIDWIDTH-142, y+21, 0, cursor); - //V_DrawFill(BASEVIDWIDTH-102, y-2, 84, 54, 103); - V_DrawSmallScaledPatch(BASEVIDWIDTH-100, y, 0, votedata.levels[i].pic); - //V_DrawRightAlignedThinString(BASEVIDWIDTH-20, 42+y, V_YELLOWMAP, votedata.levels[i].str); + INT32 loopcount = 0; + if (i == j) + continue; + while (votedata.levels[i].num == votedata.levels[j].num && loopcount < 5) + { + votedata.levels[i].num = RandMap(G_TOLFlag(gametype), prevmap); + loopcount++; + } + } + + if (!mapheaderinfo[votedata.levels[i].num]) + P_AllocMapHeader(votedata.levels[i].num); + + if (i == 3) // Fun fact, "random" isn't actually random; it's pre-calculated like the other :V + { + snprintf(votedata.levels[i].str, sizeof votedata.levels[i].str, "%.32s", "RANDOM"); + votedata.levels[i].str[sizeof votedata.levels[i].str - 1] = '\0'; + votedata.levels[i].pic = W_CachePatchName("RANDOMLV", PU_STATIC); } else { - V_DrawTinyScaledPatch(BASEVIDWIDTH-80, y, 0, votedata.levels[i].pic); - y += 62; + lumpnum_t lumpnum; + + // set up the str + if (mapheaderinfo[votedata.levels[i].num]->zonttl) + { + if (mapheaderinfo[votedata.levels[i].num]->actnum) + snprintf(votedata.levels[i].str, + sizeof votedata.levels[i].str, + "%.32s %.32s %d", + mapheaderinfo[votedata.levels[i].num]->lvlttl, mapheaderinfo[votedata.levels[i].num]->zonttl, mapheaderinfo[votedata.levels[i].num]->actnum); + else + snprintf(votedata.levels[i].str, + sizeof votedata.levels[i].str, + "%.32s %.32s", + mapheaderinfo[votedata.levels[i].num]->lvlttl, mapheaderinfo[votedata.levels[i].num]->zonttl); + } + else + { + if (mapheaderinfo[votedata.levels[i].num]->actnum) + snprintf(votedata.levels[i].str, + sizeof votedata.levels[i].str, + "%.32s %d", + mapheaderinfo[votedata.levels[i].num]->lvlttl, mapheaderinfo[votedata.levels[i].num]->actnum); + else + snprintf(votedata.levels[i].str, + sizeof votedata.levels[i].str, + "%.32s", + mapheaderinfo[votedata.levels[i].num]->lvlttl); + } + + votedata.levels[i].str[sizeof votedata.levels[i].str - 1] = '\0'; + + lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(votedata.levels[i].num+1))); + if (lumpnum != LUMPERROR) + votedata.levels[i].pic = W_CachePatchName(va("%sP", G_BuildMapName(votedata.levels[i].num+1)), PU_STATIC); + else + votedata.levels[i].pic = W_CachePatchName("BLANKLVL", PU_STATIC); } } - - x = 20; - y = 0; - - for (i = 0; i < votedata.numvotes; i++) - { - V_DrawTinyScaledPatch(x, y, 0, votedata.levels[votedata.votes[i].level].pic); - - if (votedata.playerinfo[votedata.votes[i].playernum].color == 0) - V_DrawSmallScaledPatch(x+48, y+18, 0, faceprefix[*votedata.playerinfo[votedata.votes[i].playernum].character]); - else - { - UINT8 *colormap = R_GetTranslationColormap(*votedata.playerinfo[votedata.votes[i].playernum].character, *votedata.playerinfo[votedata.votes[i].playernum].color, GTC_CACHE); - V_DrawSmallMappedPatch(x+48, y+18, 0, faceprefix[*votedata.playerinfo[votedata.votes[i].playernum].character], colormap); - } - - y += 25; - - if (y > BASEVIDHEIGHT-25) - { - x += 20; - y = 0; - } - } - - /*if (votedata.timeleft) - V_DrawCenteredString(BASEVIDWIDTH/2, 188, V_YELLOWMAP, - va("Vote ends in %d seconds", votedata.timeleft/TICRATE));*/ } // @@ -2413,8 +2428,8 @@ static void Y_UnloadVoteData(void) if (rendermode != render_soft) return; - UNLOAD(bgpatch); UNLOAD(widebgpatch); + UNLOAD(bgpatch); UNLOAD(cursor); UNLOAD(votedata.levels[3].pic); @@ -2422,29 +2437,3 @@ static void Y_UnloadVoteData(void) UNLOAD(votedata.levels[1].pic); UNLOAD(votedata.levels[0].pic); } - -// -// Y_FollowVote -// -static void Y_FollowVote(void) -{ - if (modeattacking) - { - M_EndModeAttackRun(); - return; - } - - if (nextmap < 1100-1) - { - G_AfterIntermission(true); - return; - } - - if (mapheaderinfo[gamemap-1]->cutscenenum && !modeattacking) - { - F_StartCustomCutscene(mapheaderinfo[gamemap-1]->cutscenenum-1, false, false); - return; - } - - Y_EndGame(); -} \ No newline at end of file diff --git a/src/y_inter.h b/src/y_inter.h index 3f63b3ee..d36e613d 100644 --- a/src/y_inter.h +++ b/src/y_inter.h @@ -17,9 +17,9 @@ void Y_StartIntermission(void); void Y_EndIntermission(void); void Y_EndGame(void); -void Y_StartVote(void); -void Y_VoteTicker(void); void Y_VoteDrawer(void); +void Y_VoteTicker(void); +void Y_StartVote(void); void Y_EndVote(void); typedef enum From 41f09816ce937122055be131f9227d1cdf37b50d Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sat, 27 Jan 2018 23:52:01 -0500 Subject: [PATCH 03/20] Functional, ready for netgame! --- src/d_main.c | 2 + src/d_netcmd.c | 11 ++-- src/d_netcmd.h | 2 + src/g_game.c | 3 +- src/k_kart.c | 1 + src/m_menu.c | 4 +- src/y_inter.c | 163 +++++++++++++++++++++++++++++-------------------- 7 files changed, 111 insertions(+), 75 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 3dd9a674..a97cafa9 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -301,6 +301,8 @@ static void D_Display(void) else //if (intertype != int_coop) // Multiplayer wipedefindex = wipe_multinter_toblack; } + else if (gamestate == GS_VOTING) + wipedefindex = wipe_multinter_toblack; if (rendermode != render_none) { diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 9d9e7269..f0e33e44 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -355,6 +355,9 @@ consvar_t cv_kartmirror = {"kartmirror", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff, NU static CV_PossibleValue_t speedometer_cons_t[] = {{0, "Off"}, {1, "Kilometers"}, {2, "Miles"}, {3, "Fracunits"}, {0, NULL}}; consvar_t cv_speedometer = {"speedometer", "Kilometers", CV_SAVE, speedometer_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; // use tics in display +static CV_PossibleValue_t votetime_cons_t[] = {{10, "MIN"}, {3600, "MAX"}, {0, NULL}}; +consvar_t cv_votetime = {"votetime", "20", CV_NETVAR, votetime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; + static CV_PossibleValue_t cv_collideminimum_cons_t[] = {{1, "MIN"}, {16384, "MAX"}, {0, NULL}}; consvar_t cv_collideminimum = {"collide_minspeed", "25", CV_NETVAR, cv_collideminimum_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t cv_collidesoundnum_cons_t[] = {{1, "MIN"}, {1208, "MAX"}, {0, NULL}}; @@ -2182,7 +2185,7 @@ static void Command_Pause(void) if (cv_pause.value || server || (IsPlayerAdmin(consoleplayer))) { - if (modeattacking || !(gamestate == GS_LEVEL || gamestate == GS_INTERMISSION)) + if (modeattacking || !(gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_VOTING)) { CONS_Printf(M_GetText("You can't pause here.\n")); return; @@ -2251,7 +2254,7 @@ static void Command_Suicide(void) WRITEINT32(cp, consoleplayer); - if (!(gamestate == GS_LEVEL || gamestate == GS_INTERMISSION)) + if (!(gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_VOTING)) { CONS_Printf(M_GetText("You must be in a level to use this.\n")); return; @@ -4276,7 +4279,7 @@ static void TeamScramble_OnChange(void) boolean success = false; // Don't trigger outside level or intermission! - if (!(gamestate == GS_LEVEL || gamestate == GS_INTERMISSION)) + if (!(gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_VOTING)) return; if (!cv_teamscramble.value) @@ -4619,7 +4622,7 @@ void Command_ExitGame_f(void) void Command_Retry_f(void) { - if (!(gamestate == GS_LEVEL || gamestate == GS_INTERMISSION)) + if (!(gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_VOTING)) CONS_Printf(M_GetText("You must be in a level to use this.\n")); else if (netgame || multiplayer) CONS_Printf(M_GetText("This only works in single player.\n")); diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 1ffe4e21..ed0e9720 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -125,6 +125,8 @@ extern consvar_t cv_kartcomeback; extern consvar_t cv_kartmirror; extern consvar_t cv_speedometer; +extern consvar_t cv_votetime; + extern consvar_t cv_collideminimum; extern consvar_t cv_collidesoundnum; extern consvar_t cv_collidesounds; diff --git a/src/g_game.c b/src/g_game.c index 30171b30..12ba3b20 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1761,7 +1761,6 @@ void G_DoLoadLevel(boolean resetplayer) if (gamestate == GS_INTERMISSION) Y_EndIntermission(); - if (gamestate == GS_VOTING) Y_EndVote(); @@ -1969,7 +1968,7 @@ boolean G_Responder(event_t *ev) else if (gamestate == GS_GAMEEND || gamestate == GS_EVALUATION || gamestate == GS_CREDITS) return true; - else if (gamestate == GS_INTERMISSION) + else if (gamestate == GS_INTERMISSION || gamestate == GS_VOTING) if (HU_Responder(ev)) return true; // chat ate the event diff --git a/src/k_kart.c b/src/k_kart.c index 9e54559b..f9a99393 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -311,6 +311,7 @@ void K_RegisterKartStuff(void) CV_RegisterVar(&cv_kartcomeback); CV_RegisterVar(&cv_kartmirror); CV_RegisterVar(&cv_speedometer); + CV_RegisterVar(&cv_votetime); CV_RegisterVar(&cv_collideminimum); CV_RegisterVar(&cv_collidesoundnum); CV_RegisterVar(&cv_collidesounds); diff --git a/src/m_menu.c b/src/m_menu.c index 72605689..2e129cdd 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3326,7 +3326,7 @@ static void M_DrawGenericMenu(void) static void M_DrawPauseMenu(void) { - if (!netgame && !multiplayer && (gamestate == GS_LEVEL || gamestate == GS_INTERMISSION)) + if (!netgame && !multiplayer && (gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_VOTING)) { emblem_t *emblem_detail[3] = {NULL, NULL, NULL}; char emblem_text[3][20]; @@ -5989,7 +5989,7 @@ static void M_ModeAttackEndGame(INT32 choice) (void)choice; G_CheckDemoStatus(); // Cancel recording - if (gamestate == GS_LEVEL || gamestate == GS_INTERMISSION) + if (gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_VOTING) Command_ExitGame_f(); M_StartControlPanel(); diff --git a/src/y_inter.c b/src/y_inter.c index 56867b98..995f567a 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -197,12 +197,14 @@ typedef struct 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 INT32 votetic; static INT32 voteendtic = -1; static patch_t *cursor = NULL; +static patch_t *randomlvl = NULL; static void Y_UnloadVoteData(void); @@ -2138,31 +2140,50 @@ void Y_VoteDrawer(void) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); - /*if (widebgpatch && rendermode == render_soft && vid.width / vid.dupx == 400) - V_DrawScaledPatch(0, 0, V_SNAPTOLEFT, widebgpatch); - else*/ - V_DrawScaledPatch(0, 0, 0, bgpatch); + if (widebgpatch && rendermode == render_soft && vid.width / vid.dupx > 320) + V_DrawScaledPatch(((vid.width/2) / vid.dupx) - (SHORT(widebgpatch->width)/2), + (vid.height / vid.dupy) - SHORT(widebgpatch->height), + V_SNAPTOTOP|V_SNAPTOLEFT, widebgpatch); + else + V_DrawScaledPatch(((vid.width/2) / vid.dupx) - (SHORT(bgpatch->width)/2), // Keep the width/height adjustments, for screens that are less wide than 320(?) + (vid.height / vid.dupy) - SHORT(bgpatch->height), + V_SNAPTOTOP|V_SNAPTOLEFT, bgpatch); y = 30; for (i = 0; i < 4; i++) { + char str[40]; + patch_t *pic; + + if (i == 3) + { + snprintf(str, sizeof str, "%.32s", "RANDOM"); + str[sizeof str - 1] = '\0'; + pic = randomlvl; + } + else + { + strcpy(str, votedata.levels[i].str); + pic = votedata.levels[i].pic; + } + if (i == votedata.playerinfo[consoleplayer].selection) { - - V_DrawScaledPatch(BASEVIDWIDTH-124, y+21, 0, cursor); - - if (votetic % 4 > 1) - V_DrawFill(BASEVIDWIDTH-101, y-1, 82, 52, 120); - else - V_DrawFill(BASEVIDWIDTH-101, y-1, 82, 52, 103); - - V_DrawSmallScaledPatch(BASEVIDWIDTH-100, y, 0, votedata.levels[i].pic); - V_DrawRightAlignedThinString(BASEVIDWIDTH-20, 42+y, V_YELLOWMAP, votedata.levels[i].str); + if (!votedata.playerinfo[consoleplayer].voted) + { + V_DrawScaledPatch(BASEVIDWIDTH-124, y+21, V_SNAPTORIGHT, cursor); + if (votetic % 4 > 1) + V_DrawFill(BASEVIDWIDTH-101, y-1, 82, 52, 120|V_SNAPTORIGHT); + else + V_DrawFill(BASEVIDWIDTH-101, y-1, 82, 52, 103|V_SNAPTORIGHT); + } + V_DrawSmallScaledPatch(BASEVIDWIDTH-100, y, V_SNAPTORIGHT, pic); + V_DrawRightAlignedThinString(BASEVIDWIDTH-20, 42+y, V_SNAPTORIGHT, str); y += 55; } else { - V_DrawTinyScaledPatch(BASEVIDWIDTH-60, y, 0, votedata.levels[i].pic); + V_DrawTinyScaledPatch(BASEVIDWIDTH-60, y, V_SNAPTORIGHT, pic); y += 30; } } @@ -2174,14 +2195,30 @@ void Y_VoteDrawer(void) { for (i = 0; i < votedata.numvotes; i++) { - V_DrawTinyScaledPatch(x, y, 0, votedata.levels[votedata.votes[i].level].pic); + patch_t *pic; + + if (votedata.votes[i].level == 3 && i != votedata.pickedvote) + pic = randomlvl; + else + pic = votedata.levels[votedata.votes[i].level].pic; + + if (i == votedata.pickedvote) + { + V_DrawScaledPatch(x-18, y+9, V_SNAPTOLEFT, cursor); + if (votetic % 4 > 1) + V_DrawFill(x-1, y-1, 42, 27, 120|V_SNAPTOLEFT); + else + V_DrawFill(x-1, y-1, 42, 27, 103|V_SNAPTOLEFT); + } + + V_DrawTinyScaledPatch(x, y, V_SNAPTOLEFT, pic); if (votedata.playerinfo[votedata.votes[i].playernum].color == 0) - V_DrawSmallScaledPatch(x+24, y+9, 0, faceprefix[*votedata.playerinfo[votedata.votes[i].playernum].character]); + V_DrawSmallScaledPatch(x+24, y+9, V_SNAPTOLEFT, faceprefix[*votedata.playerinfo[votedata.votes[i].playernum].character]); 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, 0, faceprefix[*votedata.playerinfo[votedata.votes[i].playernum].character], colormap); + V_DrawSmallMappedPatch(x+24, y+9, V_SNAPTOLEFT, faceprefix[*votedata.playerinfo[votedata.votes[i].playernum].character], colormap); } y += 30; @@ -2195,11 +2232,8 @@ void Y_VoteDrawer(void) } if (votedata.timeleft) - V_DrawCenteredString(BASEVIDWIDTH/2, 188, V_YELLOWMAP, + V_DrawCenteredString(BASEVIDWIDTH/2, 188, V_YELLOWMAP|V_SNAPTOBOTTOM, va("Vote ends in %d seconds", votedata.timeleft/TICRATE)); - - V_DrawString(80, 0, V_YELLOWMAP, va("votetic: %d", votetic)); - V_DrawString(80, 8, V_YELLOWMAP, va("voteendtic: %d", voteendtic)); } // @@ -2219,9 +2253,9 @@ void Y_VoteTicker(void) votetic++; - if (votetic >= voteendtic && voteendtic != -1) + if (votetic == voteendtic) { - Y_EndVote(); + Y_UnloadVoteData(); // Y_EndVote resets voteendtic too early apparently, causing the game to try to render patches that we just unloaded... Y_FollowIntermission(); return; } @@ -2292,13 +2326,15 @@ void Y_VoteTicker(void) { if (i == consoleplayer) S_StartSound(NULL, sfx_menu1); - votedata.playerinfo[i].delay = NEWTICRATE/7; + votedata.playerinfo[i].delay = 3; } } if (votedata.timeleft == 0 && voteendtic == -1) { - nextmap = (votedata.levels[votedata.votes[P_RandomKey(votedata.numvotes)].level].num); // oh my god + votedata.pickedvote = P_RandomKey(votedata.numvotes); + nextmap = (votedata.levels[votedata.votes[votedata.pickedvote].level].num); // oh my god + S_StartSound(NULL, sfx_ncitem); voteendtic = votetic+(3*TICRATE); } @@ -2325,9 +2361,11 @@ void Y_StartVote(void) widebgpatch = W_CachePatchName("INTERSCW", PU_STATIC); bgpatch = W_CachePatchName("INTERSCR", PU_STATIC); cursor = W_CachePatchName("M_CURSOR", PU_STATIC); + randomlvl = W_CachePatchName("RANDOMLV", PU_STATIC); - votedata.timeleft = 30*TICRATE; + votedata.timeleft = cv_votetime.value*TICRATE; votedata.numvotes = 0; + votedata.pickedvote = -1; for (i = 0; i < MAXPLAYERS; i++) { @@ -2344,6 +2382,7 @@ void Y_StartVote(void) for (i = 0; i < 4; i++) { INT32 j; + lumpnum_t lumpnum; votedata.levels[i].num = RandMap(G_TOLFlag(gametype), prevmap); @@ -2362,52 +2401,41 @@ void Y_StartVote(void) if (!mapheaderinfo[votedata.levels[i].num]) P_AllocMapHeader(votedata.levels[i].num); - if (i == 3) // Fun fact, "random" isn't actually random; it's pre-calculated like the other :V + // set up the str + if (mapheaderinfo[votedata.levels[i].num]->zonttl) { - snprintf(votedata.levels[i].str, sizeof votedata.levels[i].str, "%.32s", "RANDOM"); - votedata.levels[i].str[sizeof votedata.levels[i].str - 1] = '\0'; - votedata.levels[i].pic = W_CachePatchName("RANDOMLV", PU_STATIC); + if (mapheaderinfo[votedata.levels[i].num]->actnum) + snprintf(votedata.levels[i].str, + sizeof votedata.levels[i].str, + "%.32s %.32s %d", + mapheaderinfo[votedata.levels[i].num]->lvlttl, mapheaderinfo[votedata.levels[i].num]->zonttl, mapheaderinfo[votedata.levels[i].num]->actnum); + else + snprintf(votedata.levels[i].str, + sizeof votedata.levels[i].str, + "%.32s %.32s", + mapheaderinfo[votedata.levels[i].num]->lvlttl, mapheaderinfo[votedata.levels[i].num]->zonttl); } else { - lumpnum_t lumpnum; - - // set up the str - if (mapheaderinfo[votedata.levels[i].num]->zonttl) - { - if (mapheaderinfo[votedata.levels[i].num]->actnum) - snprintf(votedata.levels[i].str, - sizeof votedata.levels[i].str, - "%.32s %.32s %d", - mapheaderinfo[votedata.levels[i].num]->lvlttl, mapheaderinfo[votedata.levels[i].num]->zonttl, mapheaderinfo[votedata.levels[i].num]->actnum); - else - snprintf(votedata.levels[i].str, - sizeof votedata.levels[i].str, - "%.32s %.32s", - mapheaderinfo[votedata.levels[i].num]->lvlttl, mapheaderinfo[votedata.levels[i].num]->zonttl); - } + if (mapheaderinfo[votedata.levels[i].num]->actnum) + snprintf(votedata.levels[i].str, + sizeof votedata.levels[i].str, + "%.32s %d", + mapheaderinfo[votedata.levels[i].num]->lvlttl, mapheaderinfo[votedata.levels[i].num]->actnum); else - { - if (mapheaderinfo[votedata.levels[i].num]->actnum) - snprintf(votedata.levels[i].str, - sizeof votedata.levels[i].str, - "%.32s %d", - mapheaderinfo[votedata.levels[i].num]->lvlttl, mapheaderinfo[votedata.levels[i].num]->actnum); - else - snprintf(votedata.levels[i].str, - sizeof votedata.levels[i].str, - "%.32s", - mapheaderinfo[votedata.levels[i].num]->lvlttl); - } - - votedata.levels[i].str[sizeof votedata.levels[i].str - 1] = '\0'; - - lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(votedata.levels[i].num+1))); - if (lumpnum != LUMPERROR) - votedata.levels[i].pic = W_CachePatchName(va("%sP", G_BuildMapName(votedata.levels[i].num+1)), PU_STATIC); - else - votedata.levels[i].pic = W_CachePatchName("BLANKLVL", PU_STATIC); + snprintf(votedata.levels[i].str, + sizeof votedata.levels[i].str, + "%.32s", + mapheaderinfo[votedata.levels[i].num]->lvlttl); } + + votedata.levels[i].str[sizeof votedata.levels[i].str - 1] = '\0'; + + lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(votedata.levels[i].num+1))); + if (lumpnum != LUMPERROR) + votedata.levels[i].pic = W_CachePatchName(va("%sP", G_BuildMapName(votedata.levels[i].num+1)), PU_STATIC); + else + votedata.levels[i].pic = W_CachePatchName("BLANKLVL", PU_STATIC); } } @@ -2431,6 +2459,7 @@ static void Y_UnloadVoteData(void) UNLOAD(widebgpatch); UNLOAD(bgpatch); UNLOAD(cursor); + UNLOAD(randomlvl); UNLOAD(votedata.levels[3].pic); UNLOAD(votedata.levels[2].pic); From 52d835cdedc0ea499b4f0f209b79de2905ef4c9d Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sat, 27 Jan 2018 23:55:43 -0500 Subject: [PATCH 04/20] Remove a really minor 1-tic discrepancy --- src/y_inter.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/y_inter.c b/src/y_inter.c index 995f567a..787cd07e 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -2330,6 +2330,9 @@ void Y_VoteTicker(void) } } + if (votedata.numvotes >= numplayers) + votedata.timeleft = 0; + if (votedata.timeleft == 0 && voteendtic == -1) { votedata.pickedvote = P_RandomKey(votedata.numvotes); @@ -2337,9 +2340,6 @@ void Y_VoteTicker(void) S_StartSound(NULL, sfx_ncitem); voteendtic = votetic+(3*TICRATE); } - - if (votedata.numvotes >= numplayers) - votedata.timeleft = 0; } // From 2cb96bf16c0cafa874bc8ecb502322dfe909de32 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Mon, 29 Jan 2018 19:22:08 -0500 Subject: [PATCH 05/20] Adjust for taller thinstring --- src/y_inter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/y_inter.c b/src/y_inter.c index 9968a044..258c1e96 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -2190,7 +2190,7 @@ void Y_VoteDrawer(void) V_DrawFill(BASEVIDWIDTH-101, y-1, 82, 52, 103|V_SNAPTORIGHT); } V_DrawSmallScaledPatch(BASEVIDWIDTH-100, y, V_SNAPTORIGHT, pic); - V_DrawRightAlignedThinString(BASEVIDWIDTH-20, 42+y, V_SNAPTORIGHT, str); + V_DrawRightAlignedThinString(BASEVIDWIDTH-20, 40+y, V_SNAPTORIGHT, str); y += 55; } else From 116ef8065f90eef80337634aef51e3c04a3c7d82 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Mon, 29 Jan 2018 21:39:13 -0500 Subject: [PATCH 06/20] welp --- src/doomstat.h | 1 + src/g_game.c | 28 ++++++++++++++++++++++++++-- src/g_game.h | 1 - src/p_saveg.c | 6 ++++++ src/y_inter.c | 43 ++++++++++++------------------------------- 5 files changed, 45 insertions(+), 34 deletions(-) diff --git a/src/doomstat.h b/src/doomstat.h index a74e470b..ddd381b0 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -176,6 +176,7 @@ 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 diff --git a/src/g_game.c b/src/g_game.c index 0698a7f2..2efe2293 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -120,6 +120,7 @@ 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; @@ -3088,7 +3089,7 @@ INT16 G_TOLFlag(INT32 pgametype) * has those flags. * \author Graue */ -INT16 RandMap(INT16 tolflags, INT16 pprevmap) +static INT16 RandMap(INT16 tolflags, INT16 pprevmap) { INT16 *okmaps = Z_Malloc(NUMMAPS * sizeof(INT16), PU_STATIC, NULL); INT32 numokmaps = 0; @@ -3105,7 +3106,7 @@ INT16 RandMap(INT16 tolflags, INT16 pprevmap) if (numokmaps == 0) ix = 0; // Sorry, none match. You get MAP01. else - ix = okmaps[M_RandomKey(numokmaps)]; + ix = okmaps[P_RandomKey(numokmaps)]; Z_Free(okmaps); @@ -3238,6 +3239,28 @@ static void G_DoCompleted(void) nextmap = prevmap; else if (cv_advancemap.value == 2) // Go to random map. nextmap = RandMap(G_TOLFlag(gametype), prevmap); + else if (cv_advancemap.value == 3) + { + INT32 j; + for (j = 0; j < 4; j++) + { + INT32 k; + votelevels[j] = RandMap(G_TOLFlag(gametype), prevmap); + for (k = 0; k < 4; k++) // Compare with others to make sure you don't roll multiple :V + { + INT32 loopcount = 0; + if (j == k) + continue; + while (votelevels[j] == votelevels[k] && loopcount < 4) // If this needs more than 4 loops, I think it's safe to assume it's not finding anything :VVV + { + votelevels[j] = RandMap(G_TOLFlag(gametype), prevmap); + loopcount++; + } + } + if (votelevels[j] < NUMMAPS && !mapheaderinfo[votelevels[j]]) + P_AllocMapHeader(votelevels[j]); + } + } } // We are committed to this map now. @@ -3937,6 +3960,7 @@ 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..832a8e0c 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -219,6 +219,5 @@ FUNCMATH INT32 G_TicsToMilliseconds(tic_t tics); // Don't split up TOL handling INT16 G_TOLFlag(INT32 pgametype); -INT16 RandMap(INT16 tolflags, INT16 pprevmap); #endif diff --git a/src/p_saveg.c b/src/p_saveg.c index 012f2888..438ed1da 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -3202,6 +3202,9 @@ static void P_NetArchiveMisc(void) WRITEUINT32(save_p, totalrings); WRITEINT16(save_p, lastmap); + for (i = 0; i < 4; i++) + WRITEINT16(save_p, votelevels[i]); + WRITEUINT16(save_p, emeralds); WRITEUINT8(save_p, stagefailed); @@ -3285,6 +3288,9 @@ static inline boolean P_NetUnArchiveMisc(void) totalrings = READUINT32(save_p); lastmap = READINT16(save_p); + for (i = 0; i < 4; i++) + votelevels[i] = READINT16(save_p); + emeralds = READUINT16(save_p); stagefailed = READUINT8(save_p); diff --git a/src/y_inter.c b/src/y_inter.c index 258c1e96..785047d2 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -172,7 +172,6 @@ typedef struct { char str[40]; patch_t *pic; - UINT16 num; } y_votelvlinfo_t; typedef struct @@ -2293,14 +2292,14 @@ void Y_VoteTicker(void) if (votedata.playerinfo[i].voted) continue; - if (votedata.timeleft <= 0 && !votedata.playerinfo[i].voted) + /*if (votedata.timeleft <= 0 && !votedata.playerinfo[i].voted) { 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; - } + }*/ if (votedata.playerinfo[i].delay > 0) { @@ -2348,7 +2347,7 @@ void Y_VoteTicker(void) if (votedata.timeleft == 0 && voteendtic == -1) { votedata.pickedvote = P_RandomKey(votedata.numvotes); - nextmap = (votedata.levels[votedata.votes[votedata.pickedvote].level].num); // oh my god + nextmap = (votelevels[votedata.votes[votedata.pickedvote].level]); // oh my god S_StartSound(NULL, sfx_ncitem); voteendtic = votetic+(3*TICRATE); } @@ -2393,59 +2392,41 @@ void Y_StartVote(void) for (i = 0; i < 4; i++) { - INT32 j; lumpnum_t lumpnum; - votedata.levels[i].num = RandMap(G_TOLFlag(gametype), prevmap); - - for (j = 0; j < 4; j++) - { - INT32 loopcount = 0; - if (i == j) - continue; - while (votedata.levels[i].num == votedata.levels[j].num && loopcount < 5) - { - votedata.levels[i].num = RandMap(G_TOLFlag(gametype), prevmap); - loopcount++; - } - } - - if (!mapheaderinfo[votedata.levels[i].num]) - P_AllocMapHeader(votedata.levels[i].num); - // set up the str - if (mapheaderinfo[votedata.levels[i].num]->zonttl) + if (mapheaderinfo[votelevels[i]]->zonttl) { - if (mapheaderinfo[votedata.levels[i].num]->actnum) + if (mapheaderinfo[votelevels[i]]->actnum) snprintf(votedata.levels[i].str, sizeof votedata.levels[i].str, "%.32s %.32s %d", - mapheaderinfo[votedata.levels[i].num]->lvlttl, mapheaderinfo[votedata.levels[i].num]->zonttl, mapheaderinfo[votedata.levels[i].num]->actnum); + mapheaderinfo[votelevels[i]]->lvlttl, mapheaderinfo[votelevels[i]]->zonttl, mapheaderinfo[votelevels[i]]->actnum); else snprintf(votedata.levels[i].str, sizeof votedata.levels[i].str, "%.32s %.32s", - mapheaderinfo[votedata.levels[i].num]->lvlttl, mapheaderinfo[votedata.levels[i].num]->zonttl); + mapheaderinfo[votelevels[i]]->lvlttl, mapheaderinfo[votelevels[i]]->zonttl); } else { - if (mapheaderinfo[votedata.levels[i].num]->actnum) + if (mapheaderinfo[votelevels[i]]->actnum) snprintf(votedata.levels[i].str, sizeof votedata.levels[i].str, "%.32s %d", - mapheaderinfo[votedata.levels[i].num]->lvlttl, mapheaderinfo[votedata.levels[i].num]->actnum); + mapheaderinfo[votelevels[i]]->lvlttl, mapheaderinfo[votelevels[i]]->actnum); else snprintf(votedata.levels[i].str, sizeof votedata.levels[i].str, "%.32s", - mapheaderinfo[votedata.levels[i].num]->lvlttl); + mapheaderinfo[votelevels[i]]->lvlttl); } votedata.levels[i].str[sizeof votedata.levels[i].str - 1] = '\0'; - lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(votedata.levels[i].num+1))); + lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(votelevels[i]+1))); if (lumpnum != LUMPERROR) - votedata.levels[i].pic = W_CachePatchName(va("%sP", G_BuildMapName(votedata.levels[i].num+1)), PU_STATIC); + votedata.levels[i].pic = W_CachePatchName(va("%sP", G_BuildMapName(votelevels[i]+1)), PU_STATIC); else votedata.levels[i].pic = W_CachePatchName("BLANKLVL", PU_STATIC); } From 58da420e30b4662da9d130e38138f6eaef1d06d7 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Tue, 30 Jan 2018 16:42:44 -0500 Subject: [PATCH 07/20] Setup vote is a XCMD now But now the rest of voting can get desynced easily now... this is increasingly getting more and more fucked. --- src/d_netcmd.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/d_netcmd.h | 6 +++-- src/g_game.c | 31 +++---------------------- src/g_game.h | 1 + 4 files changed, 69 insertions(+), 30 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 4de98ade..f7819302 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -46,6 +46,7 @@ #include "m_cond.h" #include "m_anigif.h" #include "k_kart.h" // SRB2kart +#include "y_inter.h" #ifdef NETGAME_DEVMODE #define CV_RESTRICT CV_NETVAR @@ -61,6 +62,7 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum); 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_RequestAddfilecmd(UINT8 **cp, INT32 playernum); #ifdef DELFILE static void Got_Delfilecmd(UINT8 **cp, INT32 playernum); @@ -472,6 +474,7 @@ const char *netxcmdnames[MAXNETXCMD - 1] = "SETMOTD", "SUICIDE", "DEMOTED", + "SETUPVOTE", #ifdef HAVE_BLUA "LUACMD", "LUAVAR" @@ -501,6 +504,7 @@ 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 @@ -1942,6 +1946,38 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pultmode, boolean rese } } +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]); + } + + SendNetXCmd(XD_SETUPVOTE, buf, p - buf); +} + // Warp to map code. // Called either from map console command, or idclev cheat. // @@ -4502,6 +4538,31 @@ static void Got_ExitLevelcmd(UINT8 **cp, INT32 playernum) G_ExitLevel(); } +static void Got_SetupVotecmd(UINT8 **cp, INT32 playernum) +{ + INT32 i; + + 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; + } + + for (i = 0; i < 4; i++) + votelevels[i] = (INT16)READUINT16(*cp); + + G_SetGamestate(GS_VOTING); + Y_StartVote(); +} + /** 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 01b80f3c..55341863 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -191,9 +191,10 @@ typedef enum XD_SETMOTD, // 19 XD_SUICIDE, // 20 XD_DEMOTED, // 21 + XD_SETUPVOTE, // 22 #ifdef HAVE_BLUA - XD_LUACMD, // 22 - XD_LUAVAR, // 23 + XD_LUACMD, // 23 + XD_LUAVAR, // 24 #endif MAXNETXCMD } netxcmd_t; @@ -248,6 +249,7 @@ void Command_ExitGame_f(void); 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 ObjectPlace_OnChange(void); boolean IsPlayerAdmin(INT32 playernum); void SetAdminPlayer(INT32 playernum); diff --git a/src/g_game.c b/src/g_game.c index 2efe2293..c0d6c841 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3089,7 +3089,7 @@ INT16 G_TOLFlag(INT32 pgametype) * has those flags. * \author Graue */ -static INT16 RandMap(INT16 tolflags, INT16 pprevmap) +INT16 RandMap(INT16 tolflags, INT16 pprevmap) { INT16 *okmaps = Z_Malloc(NUMMAPS * sizeof(INT16), PU_STATIC, NULL); INT32 numokmaps = 0; @@ -3239,28 +3239,6 @@ static void G_DoCompleted(void) nextmap = prevmap; else if (cv_advancemap.value == 2) // Go to random map. nextmap = RandMap(G_TOLFlag(gametype), prevmap); - else if (cv_advancemap.value == 3) - { - INT32 j; - for (j = 0; j < 4; j++) - { - INT32 k; - votelevels[j] = RandMap(G_TOLFlag(gametype), prevmap); - for (k = 0; k < 4; k++) // Compare with others to make sure you don't roll multiple :V - { - INT32 loopcount = 0; - if (j == k) - continue; - while (votelevels[j] == votelevels[k] && loopcount < 4) // If this needs more than 4 loops, I think it's safe to assume it's not finding anything :VVV - { - votelevels[j] = RandMap(G_TOLFlag(gametype), prevmap); - loopcount++; - } - } - if (votelevels[j] < NUMMAPS && !mapheaderinfo[votelevels[j]]) - P_AllocMapHeader(votelevels[j]); - } - } } // We are committed to this map now. @@ -3385,11 +3363,8 @@ static void G_DoContinued(void) // static void G_DoStartVote(void) { - I_Assert(netgame || multiplayer); - - G_SetGamestate(GS_VOTING); - Y_StartVote(); - + if (server) + D_SetupVote(); gameaction = ga_nothing; } diff --git a/src/g_game.h b/src/g_game.h index 832a8e0c..f6e62ea7 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -219,5 +219,6 @@ FUNCMATH INT32 G_TicsToMilliseconds(tic_t tics); // Don't split up TOL handling INT16 G_TOLFlag(INT32 pgametype); +INT16 RandMap(INT16 tolflags, INT16 pprevmap); #endif From b20e2d55eb2128944f8eec825c896e397173548c Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sat, 3 Feb 2018 23:47:47 -0500 Subject: [PATCH 08/20] 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 { From 2c09dd1df1609381776c323312d3ec988e146ba4 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Wed, 7 Feb 2018 22:45:40 -0500 Subject: [PATCH 09/20] Minor fixes --- src/y_inter.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/y_inter.c b/src/y_inter.c index 0816331e..d57a5ff7 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -2192,7 +2192,7 @@ void Y_VoteDrawer(void) { patch_t *pic; - if ((votes[i] == 3 && i != pickedvote) || voteendtic-votetic > 3*TICRATE) + if (votes[i] == 3 && (i != pickedvote || voteendtic-votetic > 3*TICRATE)) pic = randomlvl; else pic = levelinfo[votes[i]].pic; @@ -2311,14 +2311,14 @@ void Y_VoteTicker(void) numvotes++; } - randomanim = tempvotes[((pickedvote - ((voteendtic-votetic) / (TICRATE/7))) % numvotes)]; + randomanim = tempvotes[((pickedvote + ((voteendtic-votetic) / (TICRATE/7))) % numvotes)]; S_StartSound(NULL, sfx_menu1); } else { randomanim = pickedvote; if (voteendtic-votetic == 3*TICRATE-1) - S_StartSound(NULL, sfx_ncitem); + S_StartSound(NULL, sfx_s3k63); } } else @@ -2353,7 +2353,7 @@ void Y_VoteTicker(void) if (pressed) { - S_StartSound(NULL, sfx_menu1); + S_StartSound(NULL, sfx_s3k5b); voteclient.delay = NEWTICRATE/7; } From 32ee651f434bd60f3f71437b12400c55b7e362e1 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Thu, 8 Feb 2018 00:45:59 -0500 Subject: [PATCH 10/20] /me tears away a piece of drywall What's revealed is that democracy is actually made *entirely* out of extremely minor 1 character long typos eating away at the structural integrity of the building, and then the crack starts oozing green slime, and then a creepy hand comes out and grabs you --- src/g_game.c | 16 ++++++++-------- src/y_inter.c | 18 ++++-------------- 2 files changed, 12 insertions(+), 22 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index a685e951..36a3c942 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -250,7 +250,7 @@ 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 +INT16 randmapbuffer[NUMMAPS-4]; // Buffer for maps RandMap is allowed to roll // Voting system INT16 votelevels[4]; // Levels that were rolled by the host @@ -3138,9 +3138,9 @@ INT16 G_RandMap(INT16 tolflags, INT16 pprevmap, boolean ignorebuffer) if (!ignorebuffer) { - for (bufx = 0; bufx < 3*NUMMAPS/4; bufx++) + for (bufx = 0; bufx < NUMMAPS-4; bufx++) { - if (randmapbuffer[bufx] == 0) // Rest of buffer SHOULD be empty + if (randmapbuffer[bufx] == -1) // Rest of buffer SHOULD be empty break; if (ix == randmapbuffer[bufx]) { @@ -3160,15 +3160,15 @@ INT16 G_RandMap(INT16 tolflags, INT16 pprevmap, boolean 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++) + for (bufx = 0; bufx < 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--) + /*for (bufx = NUMMAPS-4; bufx > 0; bufx--) randmapbuffer[bufx] = randmapbuffer[bufx-1]; - randmapbuffer[0] = ix; + randmapbuffer[0] = ix;*/ } Z_Free(okmaps); @@ -3296,9 +3296,9 @@ static void G_DoCompleted(void) automapactive = false; - if (randmapbuffer[(3*TOLMaps(G_TOLFlag(gametype))/4)]) // filled up, so lets clear it + if (randmapbuffer[TOLMaps(G_TOLFlag(gametype))-4)] != -1) // filled up, so lets clear it { - for (i = 0; i < 3*NUMMAPS/4; i++) + for (i = 0; i < NUMMAPS-4; i++) randmapbuffer[i] = -1; } diff --git a/src/y_inter.c b/src/y_inter.c index d57a5ff7..12ead063 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -2232,18 +2232,8 @@ void Y_VoteDrawer(void) //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...")); - } - } + V_DrawCenteredString(BASEVIDWIDTH/2, 188, V_YELLOWMAP|V_SNAPTOBOTTOM, + va("Vote ends in %d seconds", timer/TICRATE)); } // @@ -2272,7 +2262,7 @@ void Y_VoteTicker(void) { if (!playeringame[i] || players[i].spectator) votes[i] = -1; - else if (pickedvote != -1 && votes[i] == -1) + else if (pickedvote != -1 && votes[i] == -1 && !splitscreen) votes[i] = 3; // Slow people get random } @@ -2312,7 +2302,7 @@ void Y_VoteTicker(void) } randomanim = tempvotes[((pickedvote + ((voteendtic-votetic) / (TICRATE/7))) % numvotes)]; - S_StartSound(NULL, sfx_menu1); + S_StartSound(NULL, sfx_s3k5b); } else { From 56f1263f34a13dd4c43f828b6ce2c80cd184adf2 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Thu, 8 Feb 2018 00:53:25 -0500 Subject: [PATCH 11/20] Guess what. A typo. :V --- src/g_game.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 36a3c942..d2d8ee7b 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3166,9 +3166,9 @@ INT16 G_RandMap(INT16 tolflags, INT16 pprevmap, boolean ignorebuffer) else { ix = okmaps[P_RandomKey(numokmaps)]; - /*for (bufx = NUMMAPS-4; bufx > 0; bufx--) + for (bufx = NUMMAPS-4; bufx > 0; bufx--) randmapbuffer[bufx] = randmapbuffer[bufx-1]; - randmapbuffer[0] = ix;*/ + randmapbuffer[0] = ix; } Z_Free(okmaps); @@ -3296,7 +3296,7 @@ static void G_DoCompleted(void) automapactive = false; - if (randmapbuffer[TOLMaps(G_TOLFlag(gametype))-4)] != -1) // filled up, so lets clear it + if (randmapbuffer[TOLMaps(G_TOLFlag(gametype))-4] != -1) // filled up, so lets clear it { for (i = 0; i < NUMMAPS-4; i++) randmapbuffer[i] = -1; From 85a81ed0871dd4754a4018b264a1404311cbb8d1 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Thu, 8 Feb 2018 17:13:06 -0500 Subject: [PATCH 12/20] Minor adjustments in hopes that I fixed the resynch bomb on gametype switch? --- src/d_clisrv.c | 2 +- src/d_netcmd.c | 10 +++---- src/d_player.h | 1 - src/dehacked.c | 3 +- src/doomstat.h | 3 +- src/g_game.c | 72 +++++++++++++++++++++++++---------------------- src/g_game.h | 4 +-- src/k_kart.c | 6 ++-- src/lua_baselib.c | 12 ++++---- src/p_enemy.c | 2 +- src/p_inter.c | 10 +++---- src/p_map.c | 2 +- src/p_mobj.c | 11 +++----- src/p_setup.c | 2 +- src/p_user.c | 6 ++-- src/st_stuff.c | 10 +++---- 16 files changed, 79 insertions(+), 77 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 3566ed30..06592852 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -4328,7 +4328,7 @@ static INT16 Consistancy(void) } // I give up // Coop desynching enemies is painful - if (!G_PlatformGametype()) + if (!G_RaceGametype()) ret += P_GetRandSeed(); #ifdef MOBJCONSISTANCY diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 209008fe..5dc0a180 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2325,7 +2325,7 @@ static void Command_Suicide(void) return; } - /*if (!G_PlatformGametype()) // srb2kart: not necessary, suiciding makes you lose a balloon in battle, so it's not desirable to use as a way to escape a hit + /*if (!G_RaceGametype()) // srb2kart: not necessary, suiciding makes you lose a balloon in battle, so it's not desirable to use as a way to escape a hit { CONS_Printf(M_GetText("You may only use this in co-op, race, and competition!\n")); return; @@ -2346,7 +2346,7 @@ static void Got_Suicide(UINT8 **cp, INT32 playernum) INT32 suicideplayer = READINT32(*cp); // You can't suicide someone else. Nice try, there. - if (suicideplayer != playernum) // srb2kart: "|| (!G_PlatformGametype())" + if (suicideplayer != playernum) // srb2kart: "|| (!G_RaceGametype())" { CONS_Alert(CONS_WARNING, M_GetText("Illegal suicide command received from %s\n"), player_names[playernum]); if (server) @@ -4078,7 +4078,7 @@ void ItemFinder_OnChange(void) static void PointLimit_OnChange(void) { // Don't allow pointlimit in Single Player/Co-Op/Race! - if (server && Playing() && G_PlatformGametype()) + if (server && Playing() && G_RaceGametype()) { if (cv_pointlimit.value) CV_StealthSetValue(&cv_pointlimit, 0); @@ -4126,7 +4126,7 @@ UINT32 timelimitintics = 0; static void TimeLimit_OnChange(void) { // Don't allow timelimit in Single Player/Co-Op/Race! - if (server && Playing() && cv_timelimit.value != 0 && G_PlatformGametype()) + if (server && Playing() && cv_timelimit.value != 0 && G_RaceGametype()) { CV_SetValue(&cv_timelimit, 0); return; @@ -4229,7 +4229,7 @@ void D_GameTypeChanged(INT32 lastgametype) // reset timelimit and pointlimit in race/coop, prevent stupid cheats if (server) { - if (G_PlatformGametype()) + if (G_RaceGametype()) { if (cv_timelimit.value) CV_SetValue(&cv_timelimit, 0); diff --git a/src/d_player.h b/src/d_player.h index accbacc9..2d0edd1b 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -313,7 +313,6 @@ typedef enum k_balloon, // Number of balloons left k_comebackpoints, // Number of times you've bombed or gave an item to someone; once it's 3 it gets set back to 0 and you're given a balloon k_comebackmode, // 0 = bomb, 1 = item - k_comebackshowninfo,// Have you already seen the info screen before? NUMKARTSTUFF } kartstufftype_t; diff --git a/src/dehacked.c b/src/dehacked.c index 1240a4a9..9ef048e2 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -7425,8 +7425,7 @@ static const char *const KARTSTUFF_LIST[] = { "BALLOON", "COMEBACKPOINTS", - "COMEBACKMODE", - "COMEBACKSHOWNINFO" + "COMEBACKMODE" }; static const char *const HUDITEMS_LIST[] = { diff --git a/src/doomstat.h b/src/doomstat.h index 9fc7dc82..785998ae 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -445,8 +445,9 @@ extern boolean franticitems; extern boolean mirrormode; extern boolean comeback; -extern tic_t curlap, bestlap; extern boolean legitimateexit; +extern boolean comebackshowninfo; +extern tic_t curlap, bestlap; extern INT16 votelevels[4]; extern INT8 votes[MAXPLAYERS]; diff --git a/src/g_game.c b/src/g_game.c index d2d8ee7b..64188e59 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -241,22 +241,24 @@ INT16 scramblecount; //for CTF team scramble INT32 cheats; //for multiplayer cheat commands // SRB2Kart +// Cvars that we don't want changed mid-game UINT8 gamespeed; // Game's current speed (or difficulty, or cc, or etc); 0-2 for relaxed, standard, & turbo boolean mirrormode; // Mirror Mode currently enabled? boolean franticitems; // Frantic items currently enabled? boolean comeback; // Battle Mode's karma comeback is on/off -boolean legitimateexit; // Did this client actually finish the match? Calculated locally -tic_t curlap; // Current lap time, calculated locally -tic_t bestlap; // Best lap time, locally - -INT16 randmapbuffer[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 +// Client-sided variables (NEVER use in anything that needs to be synced with other players) +boolean legitimateexit; // Did this client actually finish the match? +boolean comebackshowninfo; // Have you already seen the "ATTACK OR PROTECT" message? +tic_t curlap; // Current lap time +tic_t bestlap; // Best lap time +static INT16 randmapbuffer[NUMMAPS-4]; // Buffer for maps RandMap is allowed to roll + tic_t hidetime; // Grading @@ -1867,7 +1869,7 @@ boolean G_Responder(event_t *ev) && (players[consoleplayer].pflags & PF_TAGIT) != (players[displayplayer].pflags & PF_TAGIT)) continue; } - else if (G_GametypeHasSpectators() && G_RingSlingerGametype()) + else if (G_GametypeHasSpectators() && G_BattleGametype()) { if (!players[consoleplayer].spectator) continue; @@ -2358,7 +2360,6 @@ void G_PlayerReborn(INT32 player) INT32 offroad; INT32 balloon; INT32 comebackpoints; - INT32 comebackshowninfo; score = players[player].score; lives = players[player].lives; @@ -2416,7 +2417,6 @@ void G_PlayerReborn(INT32 player) offroad = players[player].kartstuff[k_offroad]; balloon = players[player].kartstuff[k_balloon]; comebackpoints = players[player].kartstuff[k_comebackpoints]; - comebackshowninfo = players[player].kartstuff[k_comebackshowninfo]; p = &players[player]; memset(p, 0, sizeof (*p)); @@ -2476,7 +2476,6 @@ void G_PlayerReborn(INT32 player) p->kartstuff[k_balloon] = balloon; p->kartstuff[k_comebackpoints] = comebackpoints; - p->kartstuff[k_comebackshowninfo] = comebackshowninfo; p->kartstuff[k_comebacktimer] = comebacktime; // Don't do anything immediately @@ -2988,9 +2987,10 @@ void G_ExitLevel(void) // boolean G_IsSpecialStage(INT32 mapnum) { +#if 0 if (gametype == GT_COOP && modeattacking != ATTACKING_RECORD && mapnum >= sstage_start && mapnum <= sstage_end) return true; - +#endif return false; } @@ -3002,13 +3002,18 @@ boolean G_IsSpecialStage(INT32 mapnum) // boolean G_GametypeUsesLives(void) { - // Coop, Competitive + // SRB2kart NEEDS no lives +#if 0 + // Coop, Competitive if ((gametype == GT_COOP || gametype == GT_COMPETITION) && !modeattacking // No lives in Time Attack //&& !G_IsSpecialStage(gamemap) && !(maptol & TOL_NIGHTS)) // No lives in NiGHTS return true; return false; +#else + return false; +#endif } // @@ -3039,30 +3044,30 @@ boolean G_GametypeHasSpectators(void) } // -// G_RingSlingerGametype +// G_BattleGametype // -// Returns true if the current gametype supports firing rings. -// ANY gametype can be a ringslinger gametype, just flick a switch. +// Returns true in Battle gamemodes, previously was G_RingSlingerGametype. // -boolean G_RingSlingerGametype(void) +boolean G_BattleGametype(void) { - return ((gametype != GT_COOP && gametype != GT_COMPETITION && gametype != GT_RACE) || (cv_ringslinger.value)); + return (gametype == GT_MATCH); } // -// G_PlatformGametype +// G_RaceGametype // -// Returns true if a gametype is a more traditional platforming-type. +// Returns true in racing gamemodes, previously was G_PlatformGametype. // -boolean G_PlatformGametype(void) +boolean G_RaceGametype(void) { - return (gametype == GT_COOP || gametype == GT_RACE || gametype == GT_COMPETITION); + return (gametype == GT_RACE); //(gametype == GT_COOP || gametype == GT_RACE || gametype == GT_COMPETITION); } // // G_TagGametype // -// For Jazz's Tag/HnS modes that have a lot of special cases.. +// For Jazz's Tag/HnS modes that have a lot of special cases... +// SRB2Kart: do we actually want to add Kart tag later? :V // boolean G_TagGametype(void) { @@ -3328,7 +3333,7 @@ static void G_DoCompleted(void) void G_AfterIntermission(void) { HU_ClearCEcho(); - G_NextLevel(); + //G_NextLevel(); if (mapheaderinfo[gamemap-1]->cutscenenum && !modeattacking) // Start a custom cutscene. F_StartCustomCutscene(mapheaderinfo[gamemap-1]->cutscenenum-1, false, false); @@ -3371,6 +3376,16 @@ static void G_DoWorldDone(void) gameaction = ga_nothing; } +// +// G_DoStartVote +// +static void G_DoStartVote(void) +{ + if (server) + D_SetupVote(); + gameaction = ga_nothing; +} + // // G_UseContinue // @@ -3427,16 +3442,6 @@ static void G_DoContinued(void) gameaction = ga_nothing; } -// -// G_DoStartVote -// -static void G_DoStartVote(void) -{ - if (server) - D_SetupVote(); - gameaction = ga_nothing; -} - // // G_LoadGameSettings // @@ -3995,6 +4000,7 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean ultimatemode = false; legitimateexit = false; // SRB2Kart + comebackshowninfo = false; if (!demoplayback && !netgame) // Netgame sets random seed elsewhere, demo playback sets seed just before us! P_SetRandSeed(M_RandomizedSeed()); // Use a more "Random" random seed diff --git a/src/g_game.h b/src/g_game.h index 28ea2ef7..e11ac386 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -166,8 +166,8 @@ boolean G_IsSpecialStage(INT32 mapnum); boolean G_GametypeUsesLives(void); boolean G_GametypeHasTeams(void); boolean G_GametypeHasSpectators(void); -boolean G_RingSlingerGametype(void); -boolean G_PlatformGametype(void); +boolean G_BattleGametype(void); +boolean G_RaceGametype(void); boolean G_TagGametype(void); void G_ExitLevel(void); void G_NextLevel(void); diff --git a/src/k_kart.c b/src/k_kart.c index 44ec8b0f..3dfb142c 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1486,8 +1486,8 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) else if (player->kartstuff[k_comebacktimer]) { player->kartstuff[k_comebacktimer]--; - if (player->kartstuff[k_balloon] <= 0 && player->kartstuff[k_comebacktimer] <= 0) - player->kartstuff[k_comebackshowninfo] = 1; + if (player == &players[consoleplayer] && player->kartstuff[k_balloon] <= 0 && player->kartstuff[k_comebacktimer] <= 0) + comebackshowninfo = true; // client has already seen the message } if (player->kartstuff[k_spinout] == 0 && player->kartstuff[k_spinouttimer] == 0 && player->powers[pw_flashing] == K_GetKartFlashing()) @@ -5300,7 +5300,7 @@ static void K_drawBattleFullscreen(void) ty += (BASEVIDHEIGHT/2); } - if (!stplyr->kartstuff[k_comebackshowninfo]) + if (!comebackshowninfo) V_DrawFixedPatch(x<powers[pw_invulnerability] > player2->powers[pw_invulnerability]) return -1; diff --git a/src/p_inter.c b/src/p_inter.c index 5b3addd5..3544b712 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1574,7 +1574,7 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour char targetname[MAXPLAYERNAME+4]; char sourcename[MAXPLAYERNAME+4]; - if (G_PlatformGametype()) + if (G_RaceGametype()) return; // Not in coop, etc. if (!player) @@ -1769,7 +1769,7 @@ void P_CheckTimeLimit(void) if (!(multiplayer || netgame)) return; - if (G_PlatformGametype()) + if (G_RaceGametype()) return; if (leveltime < timelimitintics) @@ -1882,7 +1882,7 @@ void P_CheckPointLimit(void) if (!(multiplayer || netgame)) return; - if (G_PlatformGametype()) + if (G_RaceGametype()) return; // pointlimit is nonzero, check if it's been reached by this player @@ -2716,7 +2716,7 @@ static inline boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj // In COOP/RACE/CHAOS, you can't hurt other players unless cv_friendlyfire is on // ...But in SRB2kart, you can! - //if (!cv_friendlyfire.value && (G_PlatformGametype())) + //if (!cv_friendlyfire.value && (G_RaceGametype())) // return false; // Tag handling @@ -3141,7 +3141,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL) return false; // Invincible to fire objects - if (G_PlatformGametype() && source && source->player) + if (G_RaceGametype() && source && source->player) return false; // Don't get hurt by fire generated from friends. } diff --git a/src/p_map.c b/src/p_map.c index 6674e0b1..aac39c86 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1560,7 +1560,7 @@ static boolean PIT_CheckThing(mobj_t *thing) else if (thing->player->kartstuff[k_startimer] && !tmthing->player->kartstuff[k_startimer]) P_DamageMobj(tmthing, thing, thing, 1); - if (G_RingSlingerGametype() && (!G_GametypeHasTeams() || tmthing->player->ctfteam != thing->player->ctfteam)) + if (G_BattleGametype() && (!G_GametypeHasTeams() || tmthing->player->ctfteam != thing->player->ctfteam)) { if ((tmthing->player->powers[pw_invulnerability] || tmthing->player->powers[pw_super]) && !thing->player->powers[pw_super]) diff --git a/src/p_mobj.c b/src/p_mobj.c index b8a3e93f..3baba0d0 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9510,10 +9510,7 @@ void P_SpawnPlayer(INT32 playernum) p->spectator = false; } else if (netgame && p->jointime < 1) - { - //p->spectator = true; - p->kartstuff[k_comebackshowninfo] = 0; - } + /*p->spectator = true*/; else if (multiplayer && !netgame) { // If you're in a team game and you don't have a team assigned yet... @@ -9968,7 +9965,7 @@ void P_SpawnMapThing(mapthing_t *mthing) return; } - if (!G_RingSlingerGametype() || !cv_specialrings.value) + if (!G_BattleGametype() || !cv_specialrings.value) if (P_WeaponOrPanel(i)) return; // Don't place weapons/panels in non-ringslinger modes @@ -10001,7 +9998,7 @@ void P_SpawnMapThing(mapthing_t *mthing) runemeraldmanager = true; } - if (!G_PlatformGametype()) // No enemies in match or CTF modes + if (!G_RaceGametype()) // No enemies in match or CTF modes if ((mobjinfo[i].flags & MF_ENEMY) || (mobjinfo[i].flags & MF_BOSS)) return; @@ -10056,7 +10053,7 @@ void P_SpawnMapThing(mapthing_t *mthing) } } - if (!G_PlatformGametype() && (i == MT_SIGN || i == MT_STARPOST)) + if (!G_RaceGametype() && (i == MT_SIGN || i == MT_STARPOST)) return; // Don't spawn exit signs or starposts in wrong game modes if (modeattacking) // Record Attack special stuff diff --git a/src/p_setup.c b/src/p_setup.c index 371a70b7..cc707baf 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2810,7 +2810,7 @@ boolean P_SetupLevel(boolean skipprecip) // Start players with pity shields if possible players[i].pity = -1; - if (!G_PlatformGametype()) + if (!G_RaceGametype()) { players[i].mo = NULL; G_DoReborn(i); diff --git a/src/p_user.c b/src/p_user.c index c1864ad3..5097d2b2 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -3311,7 +3311,7 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd) // SRB2kart - unused. P_SpawnPlayerMissile(player->mo, MT_FIREBALL, 0); S_StartSound(player->mo, sfx_mario7); } - else if (G_RingSlingerGametype() && (!G_TagGametype() || player->pflags & PF_TAGIT) + else if (G_BattleGametype() && (!G_TagGametype() || player->pflags & PF_TAGIT) && !player->weapondelay && !player->climbing && !(player->pflags & PF_ATTACKDOWN)) { @@ -7786,7 +7786,7 @@ void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius) if (mo->flags & MF_MONITOR) continue; // Monitors cannot be 'nuked'. - //if (!G_RingSlingerGametype() && mo->type == MT_PLAYER) + //if (!G_BattleGametype() && mo->type == MT_PLAYER) // continue; // Don't hurt players in Co-Op! if (abs(inflictor->x - mo->x) > radius || abs(inflictor->y - mo->y) > radius || abs(inflictor->z - mo->z) > radius) @@ -8016,7 +8016,7 @@ static void P_DeathThink(player_t *player) } // Force respawn if idle for more than 30 seconds in shooter modes. - if (player->deadtimer > 30*TICRATE && !G_PlatformGametype()) + if (player->deadtimer > 30*TICRATE && !G_RaceGametype()) player->playerstate = PST_REBORN; else if (player->lives > 0 && !G_IsSpecialStage(gamemap) && leveltime >= 140) // Don't allow "click to respawn" in special stages! { diff --git a/src/st_stuff.c b/src/st_stuff.c index 6a5bc796..7ddb50ef 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -177,7 +177,7 @@ hudinfo_t hudinfo[NUMHUDITEMS] = boolean ST_SameTeam(player_t *a, player_t *b) { // Just pipe team messages to everyone in co-op or race. - if (!G_RingSlingerGametype()) + if (!G_BattleGametype()) return true; // Spectator chat. @@ -1412,7 +1412,7 @@ static void ST_drawMatchHUD(void) // SRB2kart - unused. { INT32 offset = (BASEVIDWIDTH / 2) - (NUM_WEAPONS * 10); - if (!G_RingSlingerGametype()) + if (!G_BattleGametype()) return; if (G_TagGametype() && !(stplyr->pflags & PF_TAGIT)) @@ -1850,7 +1850,7 @@ static void ST_overlayDrawer(void) /* SRB2kart doesn't need this stuff, I think // If you are in overtime, put a big honkin' flashin' message on the screen. - if (G_RingSlingerGametype() && cv_overtime.value + if (G_BattleGametype() && cv_overtime.value && (leveltime > (timelimitintics + TICRATE/2)) && cv_timelimit.value && (leveltime/TICRATE % 2 == 0)) { if (splitscreen) @@ -1937,7 +1937,7 @@ static void ST_overlayDrawer(void) V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(116), 0, M_GetText("You cannot move while hiding.")); V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), 0, M_GetText("Press F12 to watch another player.")); } - /*else if (!G_PlatformGametype() && stplyr->playerstate == PST_DEAD && stplyr->lives) //Death overrides spectator text. + /*else if (!G_RaceGametype() && stplyr->playerstate == PST_DEAD && stplyr->lives) //Death overrides spectator text. { INT32 respawntime = cv_respawntime.value - stplyr->deadtimer/TICRATE; if (respawntime > 0 && !stplyr->spectator) @@ -1980,7 +1980,7 @@ void ST_Drawer(void) va("%s%s", G_GametypeHasTeams() ? ((seenplayer->ctfteam == 1) ? "\x85" : "\x84") : "", player_names[seenplayer-players])); else //if (cv_seenames.value == 3) V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2 + 15, V_HUDTRANSHALF, - va("%s%s", !G_RingSlingerGametype() || (G_GametypeHasTeams() && players[consoleplayer].ctfteam == seenplayer->ctfteam) + va("%s%s", !G_BattleGametype() || (G_GametypeHasTeams() && players[consoleplayer].ctfteam == seenplayer->ctfteam) ? "\x83" : "\x85", player_names[seenplayer-players])); } #endif From ec84b46bb4634cdbce7b69a09aaa565a3487262d Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Thu, 8 Feb 2018 18:14:56 -0500 Subject: [PATCH 13/20] P != M --- src/d_clisrv.c | 7 ++++--- src/d_netcmd.c | 2 +- src/g_game.c | 4 ++-- src/lua_consolelib.c | 2 +- src/m_menu.c | 16 +++++++++++++--- 5 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 06592852..3d864e39 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -3518,7 +3518,7 @@ static void HandleConnect(SINT8 node) #ifdef JOININGAME if (nodewaiting[node]) { - if ((gamestate == GS_LEVEL || gamestate == GS_INTERMISSION) && newnode) + if ((gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_VOTING) && newnode) { SV_SendSaveGame(node); // send a complete game state DEBFILE("send savegame\n"); @@ -3730,8 +3730,9 @@ static void HandlePacketFromAwayNode(SINT8 node) /// \note Wait. What if a Lua script uses some global custom variables synched with the NetVars hook? /// Shouldn't them be downloaded even at intermission time? /// Also, according to HandleConnect, the server will send the savegame even during intermission... - if (netbuffer->u.servercfg.gamestate == GS_LEVEL/* || - netbuffer->u.servercfg.gamestate == GS_INTERMISSION*/) + if (netbuffer->u.servercfg.gamestate == GS_LEVEL + /*|| netbuffer->u.servercfg.gamestate == GS_INTERMISSION + || netbuffer->u.servercfg.gamestate == GS_VOTING*/) cl_mode = CL_DOWNLOADSAVEGAME; else #endif diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 5dc0a180..cb212ede 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1994,7 +1994,7 @@ void D_PickVote(void) } } - key = P_RandomKey(numvotes); + key = M_RandomKey(numvotes); buf[0] = temppicks[key]; buf[1] = templevels[key]; diff --git a/src/g_game.c b/src/g_game.c index 64188e59..adc67a1b 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3170,7 +3170,7 @@ INT16 G_RandMap(INT16 tolflags, INT16 pprevmap, boolean ignorebuffer) } else { - ix = okmaps[P_RandomKey(numokmaps)]; + ix = okmaps[M_RandomKey(numokmaps)]; for (bufx = NUMMAPS-4; bufx > 0; bufx--) randmapbuffer[bufx] = randmapbuffer[bufx-1]; randmapbuffer[0] = ix; @@ -3354,7 +3354,7 @@ void G_AfterIntermission(void) // void G_NextLevel(void) { - if (cv_advancemap.value == 3 && gamestate != GS_VOTING + if ((cv_advancemap.value == 3 && gamestate != GS_VOTING) && !modeattacking && !skipstats && (multiplayer || netgame)) gameaction = ga_startvote; else diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index b9ae76b0..d27d6fb0 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -159,7 +159,7 @@ void COM_Lua_f(void) return; } - // Do the command locally, NetXCmds don't go through outside of GS_LEVEL || GS_INTERMISSION + // Do the command locally, NetXCmds don't go through outside of GS_LEVEL || GS_INTERMISSION || GS_VOTING lua_rawgeti(gL, -1, 1); // push function from command info table I_Assert(lua_isfunction(gL, -1)); lua_remove(gL, -2); // pop command info table diff --git a/src/m_menu.c b/src/m_menu.c index d048ade4..0553b984 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3349,10 +3349,20 @@ static void M_DrawPauseMenu(void) // Draw any and all emblems at the top. M_DrawMapEmblems(gamemap, 272, 28); - if (mapheaderinfo[gamemap-1]->actnum != 0) - V_DrawString(40, 28, V_YELLOWMAP, va("%s %d", mapheaderinfo[gamemap-1]->lvlttl, mapheaderinfo[gamemap-1]->actnum)); + if (mapheaderinfo[gamemap-1]->zonttl) + { + if (mapheaderinfo[gamemap-1]->actnum != 0) + V_DrawString(40, 28, V_YELLOWMAP, va("%s %s %d", mapheaderinfo[gamemap-1]->lvlttl, mapheaderinfo[gamemap-1]->zonttl, mapheaderinfo[gamemap-1]->actnum)); + else + V_DrawString(40, 28, V_YELLOWMAP, va("%s %s", mapheaderinfo[gamemap-1]->lvlttl, mapheaderinfo[gamemap-1]->zonttl)); + } else - V_DrawString(40, 28, V_YELLOWMAP, mapheaderinfo[gamemap-1]->lvlttl); + { + if (mapheaderinfo[gamemap-1]->actnum != 0) + V_DrawString(40, 28, V_YELLOWMAP, va("%s %d", mapheaderinfo[gamemap-1]->lvlttl, mapheaderinfo[gamemap-1]->actnum)); + else + V_DrawString(40, 28, V_YELLOWMAP, mapheaderinfo[gamemap-1]->lvlttl); + } // Set up the detail boxes. { From 98fa8c14096fdc7c2bd6a019091ac57431d7d0a5 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Thu, 8 Feb 2018 21:24:44 -0500 Subject: [PATCH 14/20] Added axis support --- src/g_game.c | 14 +------------- src/g_game.h | 14 ++++++++++++++ src/y_inter.c | 4 ++-- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index adc67a1b..9487c413 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -416,18 +416,6 @@ consvar_t cv_useranalog3 = {"useranalog3", "Off", CV_SAVE|CV_CALL, CV_OnOff, Use consvar_t cv_useranalog4 = {"useranalog4", "Off", CV_SAVE|CV_CALL, CV_OnOff, UserAnalog4_OnChange, 0, NULL, NULL, 0, 0, NULL}; #endif -typedef enum -{ - AXISNONE = 0, - AXISTURN, - AXISMOVE, - AXISLOOK, - AXISSTRAFE, - AXISDEAD, //Axises that don't want deadzones - AXISFIRE, - AXISFIRENORMAL, -} axis_input_e; - #if defined (_WII) || defined (WMINPUT) consvar_t cv_turnaxis = {"joyaxis_turn", "LStick.X", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_moveaxis = {"joyaxis_move", "LStick.Y", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -1166,7 +1154,7 @@ static boolean InputDown(INT32 gc, UINT8 p) } } -static INT32 JoyAxis(axis_input_e axissel, UINT8 p) +INT32 JoyAxis(axis_input_e axissel, UINT8 p) { switch (p) { diff --git a/src/g_game.h b/src/g_game.h index e11ac386..b389f8fa 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -62,6 +62,18 @@ extern consvar_t cv_sideaxis3,cv_turnaxis3,cv_moveaxis3,cv_lookaxis3,cv_fireaxis extern consvar_t cv_sideaxis4,cv_turnaxis4,cv_moveaxis4,cv_lookaxis4,cv_fireaxis4,cv_firenaxis4; extern consvar_t cv_ghost_besttime, cv_ghost_bestlap, cv_ghost_last, cv_ghost_guest, cv_ghost_staff; +typedef enum +{ + AXISNONE = 0, + AXISTURN, + AXISMOVE, + AXISLOOK, + AXISSTRAFE, + AXISDEAD, //Axises that don't want deadzones + AXISFIRE, + AXISFIRENORMAL, +} axis_input_e; + // mouseaiming (looking up/down with the mouse or keyboard) #define KB_LOOKSPEED (1<<25) #define MAXPLMOVE (50) @@ -80,6 +92,8 @@ ticcmd_t *G_MoveTiccmd(ticcmd_t* dest, const ticcmd_t* src, const size_t n); INT16 G_ClipAimingPitch(INT32 *aiming); INT16 G_SoftwareClipAimingPitch(INT32 *aiming); +INT32 JoyAxis(axis_input_e axissel, UINT8 p); + extern angle_t localangle, localangle2, localangle3, localangle4; extern INT32 localaiming, localaiming2, localaiming3, localaiming4; // should be an angle_t but signed extern boolean camspin, camspin2, camspin3, camspin4; // SRB2Kart diff --git a/src/y_inter.c b/src/y_inter.c index 12ead063..ec1b7196 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -2320,12 +2320,12 @@ void Y_VoteTicker(void) D_ModifyClientVote(-1); else if (pickedvote == -1 && votes[consoleplayer] == -1 && !voteclient.delay) { - if (PLAYER1INPUTDOWN(gc_aimforward)) + if (PLAYER1INPUTDOWN(gc_aimforward) || JoyAxis(AXISMOVE, 1) < 0) { voteclient.selection--; pressed = true; } - if (PLAYER1INPUTDOWN(gc_aimbackward) && !pressed) + if ((PLAYER1INPUTDOWN(gc_aimbackward) || JoyAxis(AXISMOVE, 1) > 0) && !pressed) { voteclient.selection++; pressed = true; From 9088e3dbabd71cc696d93e28da0d31160e16da19 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Fri, 9 Feb 2018 16:04:52 -0500 Subject: [PATCH 15/20] Slight adjustment --- src/g_game.c | 2 +- src/g_game.h | 1 + src/y_inter.c | 10 +++++----- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 9487c413..731b9d82 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1139,7 +1139,7 @@ static INT32 Joy4Axis(axis_input_e axissel) return retaxis; } -static boolean InputDown(INT32 gc, UINT8 p) +boolean InputDown(INT32 gc, UINT8 p) { switch (p) { diff --git a/src/g_game.h b/src/g_game.h index b389f8fa..9a69fd12 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -92,6 +92,7 @@ ticcmd_t *G_MoveTiccmd(ticcmd_t* dest, const ticcmd_t* src, const size_t n); INT16 G_ClipAimingPitch(INT32 *aiming); INT16 G_SoftwareClipAimingPitch(INT32 *aiming); +boolean InputDown(INT32 gc, UINT8 p); INT32 JoyAxis(axis_input_e axissel, UINT8 p); extern angle_t localangle, localangle2, localangle3, localangle4; diff --git a/src/y_inter.c b/src/y_inter.c index ec1b7196..6895f5a3 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -2290,7 +2290,7 @@ void Y_VoteTicker(void) UINT8 tempvotes[MAXPLAYERS]; UINT8 numvotes = 0; - if (votetic % (TICRATE/7) != 0) + if (votetic % (TICRATE/3) != 0) return; for (i = 0; i < MAXPLAYERS; i++) @@ -2301,7 +2301,7 @@ void Y_VoteTicker(void) numvotes++; } - randomanim = tempvotes[((pickedvote + ((voteendtic-votetic) / (TICRATE/7))) % numvotes)]; + randomanim = tempvotes[((pickedvote + ((voteendtic-votetic) / (TICRATE/3))) % numvotes)]; S_StartSound(NULL, sfx_s3k5b); } else @@ -2320,12 +2320,12 @@ void Y_VoteTicker(void) D_ModifyClientVote(-1); else if (pickedvote == -1 && votes[consoleplayer] == -1 && !voteclient.delay) { - if (PLAYER1INPUTDOWN(gc_aimforward) || JoyAxis(AXISMOVE, 1) < 0) + if (InputDown(gc_aimforward, 1) || JoyAxis(AXISMOVE, 1) < 0) { voteclient.selection--; pressed = true; } - if ((PLAYER1INPUTDOWN(gc_aimbackward) || JoyAxis(AXISMOVE, 1) > 0) && !pressed) + if ((InputDown(gc_aimbackward, 1) || JoyAxis(AXISMOVE, 1) > 0) && !pressed) { voteclient.selection++; pressed = true; @@ -2334,7 +2334,7 @@ void Y_VoteTicker(void) voteclient.selection = 3; if (voteclient.selection > 3) voteclient.selection = 0; - if (PLAYER1INPUTDOWN(gc_accelerate) && !pressed) + if (InputDown(gc_accelerate, 1) && !pressed) { D_ModifyClientVote(voteclient.selection); pressed = true; From 8f74b1afcd506994ed67e240a2896ef3619d3006 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Fri, 9 Feb 2018 21:14:14 -0500 Subject: [PATCH 16/20] Faster --- src/y_inter.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/y_inter.c b/src/y_inter.c index 6895f5a3..22aa59b9 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -2290,7 +2290,7 @@ void Y_VoteTicker(void) UINT8 tempvotes[MAXPLAYERS]; UINT8 numvotes = 0; - if (votetic % (TICRATE/3) != 0) + if (votetic % 5) return; for (i = 0; i < MAXPLAYERS; i++) @@ -2301,7 +2301,7 @@ void Y_VoteTicker(void) numvotes++; } - randomanim = tempvotes[((pickedvote + ((voteendtic-votetic) / (TICRATE/3))) % numvotes)]; + randomanim = tempvotes[((pickedvote + ((voteendtic-votetic) / 5)) % numvotes)]; S_StartSound(NULL, sfx_s3k5b); } else From bc99e0963e2b3ade68b76fe5cae84f6a6479a1b7 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sat, 10 Feb 2018 16:28:45 -0500 Subject: [PATCH 17/20] Maybe fixed --- src/g_game.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 731b9d82..b967a1e1 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -257,7 +257,7 @@ boolean legitimateexit; // Did this client actually finish the match? boolean comebackshowninfo; // Have you already seen the "ATTACK OR PROTECT" message? tic_t curlap; // Current lap time tic_t bestlap; // Best lap time -static INT16 randmapbuffer[NUMMAPS-4]; // Buffer for maps RandMap is allowed to roll +static INT16 randmapbuffer[NUMMAPS]; // Buffer for maps RandMap is allowed to roll tic_t hidetime; @@ -3131,7 +3131,7 @@ INT16 G_RandMap(INT16 tolflags, INT16 pprevmap, boolean ignorebuffer) if (!ignorebuffer) { - for (bufx = 0; bufx < NUMMAPS-4; bufx++) + for (bufx = 0; bufx < NUMMAPS; bufx++) { if (randmapbuffer[bufx] == -1) // Rest of buffer SHOULD be empty break; @@ -3153,13 +3153,13 @@ INT16 G_RandMap(INT16 tolflags, INT16 pprevmap, boolean 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 < NUMMAPS-4; bufx++) + for (bufx = 0; bufx < NUMMAPS; bufx++) randmapbuffer[bufx] = -1; // if we're having trouble finding a map we should probably clear it } else { ix = okmaps[M_RandomKey(numokmaps)]; - for (bufx = NUMMAPS-4; bufx > 0; bufx--) + for (bufx = NUMMAPS; bufx > 0; bufx--) randmapbuffer[bufx] = randmapbuffer[bufx-1]; randmapbuffer[0] = ix; } @@ -3289,9 +3289,9 @@ static void G_DoCompleted(void) automapactive = false; - if (randmapbuffer[TOLMaps(G_TOLFlag(gametype))-4] != -1) // filled up, so lets clear it + if (randmapbuffer[TOLMaps(G_TOLFlag(gametype))-5] != -1) // we're getting pretty full, so lets clear it { - for (i = 0; i < NUMMAPS-4; i++) + for (i = 0; i < NUMMAPS; i++) randmapbuffer[i] = -1; } From 2af4f0451a2812512355ae9b79166ac96c4018c3 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sat, 10 Feb 2018 16:50:44 -0500 Subject: [PATCH 18/20] One last thing: don't add whatever the game rolls for the random option Makes it even more of a wild-card option, also makes sure that you actually *see* all of the maps before it empties --- src/d_netcmd.c | 7 ++++++- src/g_game.c | 8 ++++---- src/g_game.h | 2 +- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index cb212ede..e449a831 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1962,7 +1962,12 @@ void D_SetupVote(void) p = buf; for (i = 0; i < 4; i++) - WRITEUINT16(p, G_RandMap(G_TOLFlag(gametype), prevmap, false)); + { + if (i == 3) + WRITEUINT16(p, G_RandMap(G_TOLFlag(gametype), prevmap, true, false)); + else + WRITEUINT16(p, G_RandMap(G_TOLFlag(gametype), prevmap, false, false)); + } SendNetXCmd(XD_SETUPVOTE, buf, p - buf); } diff --git a/src/g_game.c b/src/g_game.c index b967a1e1..30b771f7 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3110,7 +3110,7 @@ static INT32 TOLMaps(INT16 tolflags) * has those flags. * \author Graue */ -INT16 G_RandMap(INT16 tolflags, INT16 pprevmap, boolean ignorebuffer) +INT16 G_RandMap(INT16 tolflags, INT16 pprevmap, boolean dontadd, boolean ignorebuffer) { INT16 *okmaps = Z_Malloc(NUMMAPS * sizeof(INT16), PU_STATIC, NULL); INT32 numokmaps = 0; @@ -3150,7 +3150,7 @@ INT16 G_RandMap(INT16 tolflags, INT16 pprevmap, boolean ignorebuffer) if (numokmaps == 0) { if (!ignorebuffer) - return G_RandMap(tolflags, pprevmap, true); // If there's no matches, (An incredibly silly function chain, buuut... :V) + return G_RandMap(tolflags, pprevmap, dontadd, 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 < NUMMAPS; bufx++) @@ -3289,7 +3289,7 @@ static void G_DoCompleted(void) automapactive = false; - if (randmapbuffer[TOLMaps(G_TOLFlag(gametype))-5] != -1) // we're getting pretty full, so lets clear it + if (randmapbuffer[TOLMaps(G_TOLFlag(gametype))-4] != -1) // we're getting pretty full, so lets clear it { for (i = 0; i < NUMMAPS; i++) randmapbuffer[i] = -1; @@ -3300,7 +3300,7 @@ static void G_DoCompleted(void) if (cv_advancemap.value == 0) // Stay on same map. nextmap = prevmap; else if (cv_advancemap.value == 2) // Go to random map. - nextmap = G_RandMap(G_TOLFlag(gametype), prevmap, false); + nextmap = G_RandMap(G_TOLFlag(gametype), prevmap, false, false); } // We are committed to this map now. diff --git a/src/g_game.h b/src/g_game.h index 9a69fd12..8ea9d8f6 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -235,6 +235,6 @@ FUNCMATH INT32 G_TicsToMilliseconds(tic_t tics); // Don't split up TOL handling INT16 G_TOLFlag(INT32 pgametype); -INT16 G_RandMap(INT16 tolflags, INT16 pprevmap, boolean ignorebuffer); +INT16 G_RandMap(INT16 tolflags, INT16 pprevmap, boolean dontadd, boolean ignorebuffer); #endif From bfd7915a01a2c176cefe9a5e51c5c694a1c4ba63 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sat, 10 Feb 2018 19:02:15 -0500 Subject: [PATCH 19/20] Random picking animation --- src/y_inter.c | 46 +++++++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/src/y_inter.c b/src/y_inter.c index 22aa59b9..42b348c0 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -179,11 +179,13 @@ typedef struct { INT8 selection; UINT8 delay; + UINT8 ranim; + UINT8 rtics; + UINT8 roffset; } y_voteclient; 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; @@ -2192,12 +2194,12 @@ void Y_VoteDrawer(void) { patch_t *pic; - if (votes[i] == 3 && (i != pickedvote || voteendtic-votetic > 3*TICRATE)) + if (votes[i] == 3 && (i != pickedvote || voteendtic == -1)) pic = randomlvl; else pic = levelinfo[votes[i]].pic; - if (!timer && i == randomanim) + if (!timer && i == voteclient.ranim) { V_DrawScaledPatch(x-18, y+9, V_SNAPTOLEFT, cursor); if (votetic % 4 > 1) @@ -2283,16 +2285,10 @@ void Y_VoteTicker(void) timer = 0; if (voteendtic == -1) - return; - - if (voteendtic-votetic > 3*TICRATE) { UINT8 tempvotes[MAXPLAYERS]; UINT8 numvotes = 0; - if (votetic % 5) - return; - for (i = 0; i < MAXPLAYERS; i++) { if (votes[i] == -1) @@ -2301,15 +2297,25 @@ void Y_VoteTicker(void) numvotes++; } - randomanim = tempvotes[((pickedvote + ((voteendtic-votetic) / 5)) % numvotes)]; - S_StartSound(NULL, sfx_s3k5b); + voteclient.rtics--; + + if (voteclient.rtics <= 0) + { + voteclient.roffset++; + voteclient.rtics = min(TICRATE/2, (voteclient.roffset/3)+1); + S_StartSound(NULL, sfx_s3k5b); + } + + voteclient.ranim = tempvotes[((pickedvote + voteclient.roffset) % numvotes)]; + + if (voteclient.ranim == pickedvote && voteclient.roffset >= 30) + { + voteendtic = votetic + (4*TICRATE); + S_StartSound(NULL, sfx_s3k63); + } } else - { - randomanim = pickedvote; - if (voteendtic-votetic == 3*TICRATE-1) - S_StartSound(NULL, sfx_s3k63); - } + voteclient.ranim = pickedvote; } else { @@ -2401,10 +2407,12 @@ void Y_StartVote(void) timer = cv_votetime.value*TICRATE; pickedvote = -1; - randomanim = 0; voteclient.selection = 0; voteclient.delay = 0; + voteclient.ranim = 0; + voteclient.rtics = 1; + voteclient.roffset = 0; for (i = 0; i < MAXPLAYERS; i++) votes[i] = -1; @@ -2490,7 +2498,7 @@ void Y_SetupVoteFinish(INT8 pick, INT8 level) if (voteendtic == -1) { - UINT8 numplayers = 0; + /*UINT8 numplayers = 0; if (splitscreen) numplayers = 1; @@ -2507,6 +2515,6 @@ void Y_SetupVoteFinish(INT8 pick, INT8 level) if (numplayers > 1) voteendtic = votetic+(6*TICRATE); else - voteendtic = votetic+(3*TICRATE); + voteendtic = votetic+(3*TICRATE);*/ } } \ No newline at end of file From 51029b288030b20149bb8852938cfa4f99b3cbea Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sat, 10 Feb 2018 19:56:05 -0500 Subject: [PATCH 20/20] Remove comment --- src/y_inter.c | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/src/y_inter.c b/src/y_inter.c index 42b348c0..4c75dfc2 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -2495,26 +2495,4 @@ 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