Do a bunch of major modifications to the voting system's rule change system!

* Add `kartvoterulechanges`, or "Voting Rule Changes" on the menu, to allow some user control over event frequency.
	* "Never" - does what it says on the tin.
	* "Sometimes" - 1/8 chance of Encore if host has unlocked it, only gametype change when buffer is full
	* "Frequent" - 1/2 chance of Encore if host has unlocked it, gametype change every 5 maps
	* "Always" - If host has unlocked Encore, alternates between Encore and Gametype. Otherwise, always a gametype change
	* There's probably room for a setting between "Sometimes" and "Frequent", but I didn't want to overload the host with options and these were the ones that made sense.
* Better handling of buffer refreshes, to prevent two of the same map appearing next to each other in the voting unless there literally aren't that many maps.
* Mostly unrelated: Minor bugfix for Y_SetupVoteFinish, preventing music changes/random sounds playing on the You Will Join Next Race screen. (Branch-appropriate, at least.)
This commit is contained in:
toaster 2018-09-11 15:41:41 +01:00
parent e01f2ff096
commit fd7bc1c1ac
6 changed files with 85 additions and 25 deletions

View File

@ -353,6 +353,8 @@ consvar_t cv_kartbumpers = {"kartbumpers", "3", CV_NETVAR|CV_CHEAT, kartbumpers_
consvar_t cv_kartfrantic = {"kartfrantic", "Off", CV_NETVAR|CV_CHEAT|CV_CALL|CV_NOINIT, CV_OnOff, KartFrantic_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_kartfrantic = {"kartfrantic", "Off", CV_NETVAR|CV_CHEAT|CV_CALL|CV_NOINIT, CV_OnOff, KartFrantic_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_kartcomeback = {"kartcomeback", "On", CV_NETVAR|CV_CHEAT|CV_CALL|CV_NOINIT, CV_OnOff, KartComeback_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_kartcomeback = {"kartcomeback", "On", CV_NETVAR|CV_CHEAT|CV_CALL|CV_NOINIT, CV_OnOff, KartComeback_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_kartencore = {"kartencore", "Off", CV_NETVAR|CV_CALL|CV_NOINIT, CV_OnOff, KartEncore_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_kartencore = {"kartencore", "Off", CV_NETVAR|CV_CALL|CV_NOINIT, CV_OnOff, KartEncore_OnChange, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t kartvoterulechanges_cons_t[] = {{0, "Never"}, {1, "Sometimes"}, {2, "Frequent"}, {3, "Always"}, {0, NULL}};
consvar_t cv_kartvoterulechanges = {"kartvoterulechanges", "Frequent", CV_NETVAR, kartvoterulechanges_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t kartspeedometer_cons_t[] = {{0, "Off"}, {1, "Kilometers"}, {2, "Miles"}, {3, "Fracunits"}, {0, NULL}}; static CV_PossibleValue_t kartspeedometer_cons_t[] = {{0, "Off"}, {1, "Kilometers"}, {2, "Miles"}, {3, "Fracunits"}, {0, NULL}};
consvar_t cv_kartspeedometer = {"kartdisplayspeed", "Off", CV_SAVE, kartspeedometer_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; // use tics in display consvar_t cv_kartspeedometer = {"kartdisplayspeed", "Off", CV_SAVE, kartspeedometer_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; // use tics in display
static CV_PossibleValue_t kartvoices_cons_t[] = {{0, "Never"}, {1, "Tasteful"}, {2, "Meme"}, {0, NULL}}; static CV_PossibleValue_t kartvoices_cons_t[] = {{0, "Never"}, {1, "Tasteful"}, {2, "Meme"}, {0, NULL}};

View File

@ -125,6 +125,7 @@ extern consvar_t cv_kartbumpers;
extern consvar_t cv_kartfrantic; extern consvar_t cv_kartfrantic;
extern consvar_t cv_kartcomeback; extern consvar_t cv_kartcomeback;
extern consvar_t cv_kartencore; extern consvar_t cv_kartencore;
extern consvar_t cv_kartvoterulechanges;
extern consvar_t cv_kartspeedometer; extern consvar_t cv_kartspeedometer;
extern consvar_t cv_kartvoices; extern consvar_t cv_kartvoices;

View File

@ -3113,14 +3113,48 @@ boolean G_BattleGametype(void)
// //
INT16 G_SometimesGetDifferentGametype(void) INT16 G_SometimesGetDifferentGametype(void)
{ {
if (randmapbuffer[NUMMAPS] != -1) boolean encorepossible = (M_SecretUnlocked(SECRET_ENCORE) && G_RaceGametype());
if (!cv_kartvoterulechanges.value) // never
return gametype;
if (randmapbuffer[NUMMAPS] > 0 && (encorepossible || cv_kartvoterulechanges.value != 3))
{ {
if (M_SecretUnlocked(SECRET_ENCORE) && (M_RandomChance(FRACUNIT/2/*56*/) != cv_kartencore.value) && G_RaceGametype()) if (cv_kartvoterulechanges.value != 1)
return (gametype|0x80); randmapbuffer[NUMMAPS]--;
if (encorepossible)
{
switch (cv_kartvoterulechanges.value)
{
case 3: // always
randmapbuffer[NUMMAPS] = 0; // gotta prep this in case it isn't already set
break;
case 2: // frequent
encorepossible = M_RandomChance(FRACUNIT>>1);
break;
case 1: // sometimes
default:
encorepossible = M_RandomChance(FRACUNIT>>3);
break;
}
if (encorepossible != cv_kartencore.value)
return (gametype|0x80);
}
return gametype; return gametype;
} }
randmapbuffer[NUMMAPS] = gametype; switch (cv_kartvoterulechanges.value) // okay, we're having a gametype change! when's the next one, luv?
{
case 3: // always
randmapbuffer[NUMMAPS] = 1; // every other vote (or always if !encorepossible)
break;
case 1: // sometimes
default:
// fallthrough - happens when clearing buffer, but needs a reasonable countdown if cvar is modified
case 2: // frequent
randmapbuffer[NUMMAPS] = 5; // per "cup"
break;
}
if (gametype == GT_MATCH) if (gametype == GT_MATCH)
return GT_RACE; return GT_RACE;
@ -3188,6 +3222,7 @@ INT16 G_TOLFlag(INT32 pgametype)
return INT16_MAX; return INT16_MAX;
} }
#ifdef FLUSHMAPBUFFEREARLY
static INT32 TOLMaps(INT16 tolflags) static INT32 TOLMaps(INT16 tolflags)
{ {
INT32 num = 0; INT32 num = 0;
@ -3205,6 +3240,7 @@ static INT32 TOLMaps(INT16 tolflags)
return num; return num;
} }
#endif
/** Select a random map with the given typeoflevel flags. /** Select a random map with the given typeoflevel flags.
* If no map has those flags, this arbitrarily gives you map 1. * If no map has those flags, this arbitrarily gives you map 1.
@ -3223,6 +3259,8 @@ INT16 G_RandMap(INT16 tolflags, INT16 pprevmap, boolean dontadd, boolean ignoreb
if (!okmaps) if (!okmaps)
okmaps = Z_Malloc(NUMMAPS * sizeof(INT16), PU_STATIC, NULL); okmaps = Z_Malloc(NUMMAPS * sizeof(INT16), PU_STATIC, NULL);
tryagain:
// Find all the maps that are ok and and put them in an array. // Find all the maps that are ok and and put them in an array.
for (ix = 0; ix < NUMMAPS; ix++) for (ix = 0; ix < NUMMAPS; ix++)
{ {
@ -3256,12 +3294,28 @@ INT16 G_RandMap(INT16 tolflags, INT16 pprevmap, boolean dontadd, boolean ignoreb
okmaps[numokmaps++] = ix; okmaps[numokmaps++] = ix;
} }
if (numokmaps == 0) if (numokmaps == 0) // If there's no matches... (Goodbye, incredibly silly function chains :V)
{ {
if (!ignorebuffer) if (!ignorebuffer)
return G_RandMap(tolflags, pprevmap, dontadd, true, maphell, callagainsoon); // If there's no matches, (An incredibly silly function chain, buuut... :V) {
if (maphell) if (randmapbuffer[3] == -1) // Is the buffer basically empty?
return G_RandMap(tolflags, pprevmap, dontadd, true, maphell-1, callagainsoon); {
ignorebuffer = true; // This will probably only help in situations where there's very few maps, but it's folly not to at least try it
goto tryagain; //return G_RandMap(tolflags, pprevmap, dontadd, true, maphell, callagainsoon);
}
for (bufx = 3; bufx < NUMMAPS; bufx++) // Let's clear all but the three most recent maps...
randmapbuffer[bufx] = -1;
if (cv_kartvoterulechanges.value == 1) // sometimes
randmapbuffer[NUMMAPS] = 0;
goto tryagain; //return G_RandMap(tolflags, pprevmap, dontadd, ignorebuffer, maphell, callagainsoon);
}
if (maphell) // Any wiggle room to loosen our restrictions here?
{
maphell--;
goto tryagain; //return G_RandMap(tolflags, pprevmap, dontadd, true, maphell-1, callagainsoon);
}
ix = 0; // Sorry, none match. You get MAP01. ix = 0; // Sorry, none match. You get MAP01.
for (bufx = 0; bufx < NUMMAPS+1; bufx++) for (bufx = 0; bufx < NUMMAPS+1; bufx++)
@ -3423,11 +3477,15 @@ static void G_DoCompleted(void)
automapactive = false; automapactive = false;
if (randmapbuffer[TOLMaps(G_TOLFlag(gametype))-4] != -1) // we're getting pretty full, so lets clear it #ifdef FLUSHMAPBUFFEREARLY
if (randmapbuffer[TOLMaps(G_TOLFlag(gametype))-5] != -1) // We're getting pretty full, so! -- no need for this, handled in G_RandMap
{ {
for (i = 0; i < NUMMAPS+1; i++) for (i = 3; i < NUMMAPS; i++) // Let's clear all but the three most recent maps...
randmapbuffer[i] = -1; randmapbuffer[i] = -1;
if (cv_kartvoterulechanges.value == 1) // sometimes
randmapbuffer[NUMMAPS] = 0;
} }
#endif
if (gametype != GT_COOP) if (gametype != GT_COOP)
{ {

View File

@ -402,6 +402,7 @@ void K_RegisterKartStuff(void)
CV_RegisterVar(&cv_kartfrantic); CV_RegisterVar(&cv_kartfrantic);
CV_RegisterVar(&cv_kartcomeback); CV_RegisterVar(&cv_kartcomeback);
CV_RegisterVar(&cv_kartencore); CV_RegisterVar(&cv_kartencore);
CV_RegisterVar(&cv_kartvoterulechanges);
CV_RegisterVar(&cv_kartspeedometer); CV_RegisterVar(&cv_kartspeedometer);
CV_RegisterVar(&cv_kartvoices); CV_RegisterVar(&cv_kartvoices);
CV_RegisterVar(&cv_karteliminatelast); CV_RegisterVar(&cv_karteliminatelast);

View File

@ -1474,14 +1474,15 @@ static menuitem_t OP_ServerOptionsMenu[] =
{IT_STRING | IT_CVAR, NULL, "Intermission Timer", &cv_inttime, 40}, {IT_STRING | IT_CVAR, NULL, "Intermission Timer", &cv_inttime, 40},
{IT_STRING | IT_CVAR, NULL, "Map Progression", &cv_advancemap, 50}, {IT_STRING | IT_CVAR, NULL, "Map Progression", &cv_advancemap, 50},
{IT_STRING | IT_CVAR, NULL, "Voting Timer", &cv_votetime, 60}, {IT_STRING | IT_CVAR, NULL, "Voting Timer", &cv_votetime, 60},
{IT_STRING | IT_CVAR, NULL, "Voting Rule Changes", &cv_kartvoterulechanges, 70},
#ifndef NONET #ifndef NONET
{IT_STRING | IT_CVAR, NULL, "Max. Player Count", &cv_maxplayers, 80}, {IT_STRING | IT_CVAR, NULL, "Max. Player Count", &cv_maxplayers, 90},
{IT_STRING | IT_CVAR, NULL, "Allow Players to Join", &cv_allownewplayer, 90}, {IT_STRING | IT_CVAR, NULL, "Allow Players to Join", &cv_allownewplayer, 100},
//{IT_STRING | IT_CVAR, NULL, "Join on Map Change", &cv_joinnextround, 100}, //{IT_STRING | IT_CVAR, NULL, "Join on Map Change", &cv_joinnextround, 110},
{IT_STRING | IT_CVAR, NULL, "Allow WAD Downloading", &cv_downloading, 100}, {IT_STRING | IT_CVAR, NULL, "Allow WAD Downloading", &cv_downloading, 110},
{IT_STRING | IT_CVAR, NULL, "Attempts to resynchronise", &cv_resynchattempts, 110}, {IT_STRING | IT_CVAR, NULL, "Attempts to resynchronise", &cv_resynchattempts, 120},
#endif #endif
}; };

View File

@ -1548,13 +1548,13 @@ static void Y_UnloadVoteData(void)
// //
void Y_SetupVoteFinish(SINT8 pick, SINT8 level) void Y_SetupVoteFinish(SINT8 pick, SINT8 level)
{ {
if (!voteclient.loaded)
return;
if (pick == -1) // No other votes? We gotta get out of here, then! if (pick == -1) // No other votes? We gotta get out of here, then!
{ {
if (voteclient.loaded) Y_EndVote();
{ Y_FollowIntermission();
Y_EndVote();
Y_FollowIntermission();
}
return; return;
} }
@ -1600,11 +1600,8 @@ void Y_SetupVoteFinish(SINT8 pick, SINT8 level)
} }
else if (endtype == 0) // Might as well put this here, too. else if (endtype == 0) // Might as well put this here, too.
{ {
if (voteclient.loaded) Y_EndVote();
{ Y_FollowIntermission();
Y_EndVote();
Y_FollowIntermission();
}
return; return;
} }
else else