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);