mirror of
https://git.do.srb2.org/KartKrew/Kart-Public.git
synced 2024-12-27 04:41:23 +00:00
New kartgametypepreference
cvar.
* A "canon" adaptation of the community-created server option `lessbattlevotes`. * If set to "None", voting behaves as before. * If set to "Race" or "Battle". that gametype is considered the preference. * The voting screen is always operated from the perspective of the preferred gametype. * If you're in an un-preferred gametype, the third vote option will always allow you to continue the gametype. * If the preferred gametype is Race and you've just exited a Battle map, Encore may now appear on the second vote option. * A number of bugs with voting have been corrected. * If `kartencore` is on, the third vote option will now correctly have Encore applied. * If a custom EXE or malformed packet sends an Encore flag alongside a Battle gametype ID, actively strip it. * Just to note, clients do not enter Battle Encore with or without this change - this just prevents a promise the rest of the game couldn't fulfill.
This commit is contained in:
parent
7bf672a399
commit
7e7bd7dbb2
6 changed files with 72 additions and 32 deletions
|
@ -370,6 +370,8 @@ consvar_t cv_kartcomeback = {"kartcomeback", "On", CV_NETVAR|CV_CHEAT|CV_CALL|CV
|
||||||
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}};
|
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};
|
consvar_t cv_kartvoterulechanges = {"kartvoterulechanges", "Frequent", CV_NETVAR, kartvoterulechanges_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
static CV_PossibleValue_t kartgametypepreference_cons_t[] = {{-1, "None"}, {GT_RACE, "Race"}, {GT_MATCH, "Battle"}, {0, NULL}};
|
||||||
|
consvar_t cv_kartgametypepreference = {"kartgametypepreference", "None", CV_NETVAR, kartgametypepreference_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}};
|
||||||
|
@ -2397,13 +2399,14 @@ void D_SetupVote(void)
|
||||||
UINT8 buf[5*2]; // four UINT16 maps (at twice the width of a UINT8), and two gametypes
|
UINT8 buf[5*2]; // four UINT16 maps (at twice the width of a UINT8), and two gametypes
|
||||||
UINT8 *p = buf;
|
UINT8 *p = buf;
|
||||||
INT32 i;
|
INT32 i;
|
||||||
UINT8 secondgt = G_SometimesGetDifferentGametype();
|
UINT8 gt = (cv_kartgametypepreference.value == -1) ? gametype : cv_kartgametypepreference.value;
|
||||||
|
UINT8 secondgt = G_SometimesGetDifferentGametype(gt);
|
||||||
INT16 votebuffer[4] = {-1,-1,-1,0};
|
INT16 votebuffer[4] = {-1,-1,-1,0};
|
||||||
|
|
||||||
if (cv_kartencore.value && G_RaceGametype())
|
if (cv_kartencore.value && gt == GT_RACE)
|
||||||
WRITEUINT8(p, (gametype|0x80));
|
WRITEUINT8(p, (gt|0x80));
|
||||||
else
|
else
|
||||||
WRITEUINT8(p, gametype);
|
WRITEUINT8(p, gt);
|
||||||
WRITEUINT8(p, secondgt);
|
WRITEUINT8(p, secondgt);
|
||||||
secondgt &= ~0x80;
|
secondgt &= ~0x80;
|
||||||
|
|
||||||
|
@ -2413,9 +2416,9 @@ void D_SetupVote(void)
|
||||||
if (i == 2) // sometimes a different gametype
|
if (i == 2) // sometimes a different gametype
|
||||||
m = G_RandMap(G_TOLFlag(secondgt), prevmap, false, 0, true, votebuffer);
|
m = G_RandMap(G_TOLFlag(secondgt), prevmap, false, 0, true, votebuffer);
|
||||||
else if (i >= 3) // unknown-random and force-unknown MAP HELL
|
else if (i >= 3) // unknown-random and force-unknown MAP HELL
|
||||||
m = G_RandMap(G_TOLFlag(gametype), prevmap, false, (i-2), (i < 4), votebuffer);
|
m = G_RandMap(G_TOLFlag(gt), prevmap, false, (i-2), (i < 4), votebuffer);
|
||||||
else
|
else
|
||||||
m = G_RandMap(G_TOLFlag(gametype), prevmap, false, 0, true, votebuffer);
|
m = G_RandMap(G_TOLFlag(gt), prevmap, false, 0, true, votebuffer);
|
||||||
if (i < 3)
|
if (i < 3)
|
||||||
votebuffer[min(i, 2)] = m; // min() is a dumb workaround for gcc 4.4 array-bounds error
|
votebuffer[min(i, 2)] = m; // min() is a dumb workaround for gcc 4.4 array-bounds error
|
||||||
WRITEUINT16(p, m);
|
WRITEUINT16(p, m);
|
||||||
|
@ -5136,9 +5139,17 @@ static void Got_SetupVotecmd(UINT8 **cp, INT32 playernum)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get gametype data.
|
||||||
gt = (UINT8)READUINT8(*cp);
|
gt = (UINT8)READUINT8(*cp);
|
||||||
secondgt = (UINT8)READUINT8(*cp);
|
secondgt = (UINT8)READUINT8(*cp);
|
||||||
|
|
||||||
|
// Strip illegal Encore flag.
|
||||||
|
if (gt == (GT_MATCH|0x80))
|
||||||
|
{
|
||||||
|
gt &= ~0x80;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply most data.
|
||||||
for (i = 0; i < 4; i++)
|
for (i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
votelevels[i][0] = (UINT16)READUINT16(*cp);
|
votelevels[i][0] = (UINT16)READUINT16(*cp);
|
||||||
|
@ -5147,8 +5158,20 @@ static void Got_SetupVotecmd(UINT8 **cp, INT32 playernum)
|
||||||
P_AllocMapHeader(votelevels[i][0]);
|
P_AllocMapHeader(votelevels[i][0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Correct third entry's gametype/Encore status.
|
||||||
votelevels[2][1] = secondgt;
|
votelevels[2][1] = secondgt;
|
||||||
|
|
||||||
|
// If third entry has an illelegal Encore flag...
|
||||||
|
if (secondgt == (GT_MATCH|0x80))
|
||||||
|
{
|
||||||
|
votelevels[2][1] &= ~0x80;
|
||||||
|
// Apply it to the second entry instead, gametype permitting!
|
||||||
|
if (gt != GT_MATCH)
|
||||||
|
{
|
||||||
|
votelevels[1][1] |= 0x80;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
G_SetGamestate(GS_VOTING);
|
G_SetGamestate(GS_VOTING);
|
||||||
Y_StartVote();
|
Y_StartVote();
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,6 +118,7 @@ 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_kartvoterulechanges;
|
||||||
|
extern consvar_t cv_kartgametypepreference;
|
||||||
extern consvar_t cv_kartspeedometer;
|
extern consvar_t cv_kartspeedometer;
|
||||||
extern consvar_t cv_kartvoices;
|
extern consvar_t cv_kartvoices;
|
||||||
|
|
||||||
|
|
48
src/g_game.c
48
src/g_game.c
|
@ -3401,35 +3401,47 @@ boolean G_BattleGametype(void)
|
||||||
//
|
//
|
||||||
// Oh, yeah, and we sometimes flip encore mode on here too.
|
// Oh, yeah, and we sometimes flip encore mode on here too.
|
||||||
//
|
//
|
||||||
INT16 G_SometimesGetDifferentGametype(void)
|
UINT8 G_SometimesGetDifferentGametype(UINT8 prefgametype)
|
||||||
{
|
{
|
||||||
boolean encorepossible = (M_SecretUnlocked(SECRET_ENCORE) && G_RaceGametype());
|
// Most of the gametype references in this condition are intentionally not prefgametype.
|
||||||
|
// This is so a server CAN continue playing a gametype if they like the taste of it.
|
||||||
|
// The encore check needs prefgametype so can't use G_RaceGametype...
|
||||||
|
boolean encorepossible = (M_SecretUnlocked(SECRET_ENCORE)
|
||||||
|
&& (gametype == GT_RACE || prefgametype == GT_RACE));
|
||||||
|
boolean encoreactual = false;
|
||||||
|
UINT8 encoremodifier = 0;
|
||||||
|
|
||||||
if (!cv_kartvoterulechanges.value) // never
|
|
||||||
return gametype;
|
|
||||||
|
|
||||||
if (randmapbuffer[NUMMAPS] > 0 && (encorepossible || cv_kartvoterulechanges.value != 3))
|
|
||||||
{
|
|
||||||
randmapbuffer[NUMMAPS]--;
|
|
||||||
if (encorepossible)
|
if (encorepossible)
|
||||||
{
|
{
|
||||||
switch (cv_kartvoterulechanges.value)
|
switch (cv_kartvoterulechanges.value)
|
||||||
{
|
{
|
||||||
case 3: // always
|
case 3: // always
|
||||||
randmapbuffer[NUMMAPS] = 0; // gotta prep this in case it isn't already set
|
encoreactual = true;
|
||||||
break;
|
break;
|
||||||
case 2: // frequent
|
case 2: // frequent
|
||||||
encorepossible = M_RandomChance(FRACUNIT>>1);
|
encoreactual = M_RandomChance(FRACUNIT>>1);
|
||||||
break;
|
break;
|
||||||
case 1: // sometimes
|
case 1: // sometimes
|
||||||
|
encoreactual = M_RandomChance(FRACUNIT>>2);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
encorepossible = M_RandomChance(FRACUNIT>>2);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (encorepossible != (boolean)cv_kartencore.value)
|
if (encoreactual != (boolean)cv_kartencore.value)
|
||||||
return (gametype|0x80);
|
encoremodifier = 0x80;
|
||||||
}
|
}
|
||||||
return gametype;
|
|
||||||
|
if (!cv_kartvoterulechanges.value) // never
|
||||||
|
return (gametype|encoremodifier);
|
||||||
|
|
||||||
|
if (randmapbuffer[NUMMAPS] > 0 && (encorepossible || cv_kartvoterulechanges.value != 3))
|
||||||
|
{
|
||||||
|
randmapbuffer[NUMMAPS]--;
|
||||||
|
if (cv_kartvoterulechanges.value == 3) // always
|
||||||
|
{
|
||||||
|
randmapbuffer[NUMMAPS] = 0; // gotta prep this in case it isn't already set
|
||||||
|
}
|
||||||
|
return (gametype|encoremodifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (cv_kartvoterulechanges.value) // okay, we're having a gametype change! when's the next one, luv?
|
switch (cv_kartvoterulechanges.value) // okay, we're having a gametype change! when's the next one, luv?
|
||||||
|
@ -3447,9 +3459,11 @@ INT16 G_SometimesGetDifferentGametype(void)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gametype == GT_MATCH)
|
// Only this response is prefgametype-based.
|
||||||
return GT_RACE;
|
// Also intentionally does not use encoremodifier!
|
||||||
return GT_MATCH;
|
if (prefgametype == GT_MATCH)
|
||||||
|
return (GT_RACE);
|
||||||
|
return (GT_MATCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -290,7 +290,7 @@ boolean G_GametypeUsesLives(void);
|
||||||
boolean G_GametypeHasTeams(void);
|
boolean G_GametypeHasTeams(void);
|
||||||
boolean G_GametypeHasSpectators(void);
|
boolean G_GametypeHasSpectators(void);
|
||||||
boolean G_BattleGametype(void);
|
boolean G_BattleGametype(void);
|
||||||
INT16 G_SometimesGetDifferentGametype(void);
|
UINT8 G_SometimesGetDifferentGametype(UINT8 prefgametype);
|
||||||
UINT8 G_GetGametypeColor(INT16 gt);
|
UINT8 G_GetGametypeColor(INT16 gt);
|
||||||
boolean G_RaceGametype(void);
|
boolean G_RaceGametype(void);
|
||||||
boolean G_TagGametype(void);
|
boolean G_TagGametype(void);
|
||||||
|
|
|
@ -575,6 +575,7 @@ void K_RegisterKartStuff(void)
|
||||||
CV_RegisterVar(&cv_kartcomeback);
|
CV_RegisterVar(&cv_kartcomeback);
|
||||||
CV_RegisterVar(&cv_kartencore);
|
CV_RegisterVar(&cv_kartencore);
|
||||||
CV_RegisterVar(&cv_kartvoterulechanges);
|
CV_RegisterVar(&cv_kartvoterulechanges);
|
||||||
|
CV_RegisterVar(&cv_kartgametypepreference);
|
||||||
CV_RegisterVar(&cv_kartspeedometer);
|
CV_RegisterVar(&cv_kartspeedometer);
|
||||||
CV_RegisterVar(&cv_kartvoices);
|
CV_RegisterVar(&cv_kartvoices);
|
||||||
CV_RegisterVar(&cv_karteliminatelast);
|
CV_RegisterVar(&cv_karteliminatelast);
|
||||||
|
|
|
@ -1445,6 +1445,7 @@ void Y_VoteTicker(void)
|
||||||
void Y_StartVote(void)
|
void Y_StartVote(void)
|
||||||
{
|
{
|
||||||
INT32 i = 0;
|
INT32 i = 0;
|
||||||
|
UINT8 prefgametype = (votelevels[0][1] & ~0x80);
|
||||||
|
|
||||||
votetic = -1;
|
votetic = -1;
|
||||||
|
|
||||||
|
@ -1453,8 +1454,8 @@ void Y_StartVote(void)
|
||||||
I_Error("voteendtic is dirty");
|
I_Error("voteendtic is dirty");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
widebgpatch = W_CachePatchName(((gametype == GT_MATCH) ? "BATTLSCW" : "INTERSCW"), PU_STATIC);
|
widebgpatch = W_CachePatchName(((prefgametype == GT_MATCH) ? "BATTLSCW" : "INTERSCW"), PU_STATIC);
|
||||||
bgpatch = W_CachePatchName(((gametype == GT_MATCH) ? "BATTLSCR" : "INTERSCR"), PU_STATIC);
|
bgpatch = W_CachePatchName(((prefgametype == GT_MATCH) ? "BATTLSCR" : "INTERSCR"), PU_STATIC);
|
||||||
cursor = W_CachePatchName("M_CURSOR", PU_STATIC);
|
cursor = W_CachePatchName("M_CURSOR", PU_STATIC);
|
||||||
cursor1 = W_CachePatchName("P1CURSOR", PU_STATIC);
|
cursor1 = W_CachePatchName("P1CURSOR", PU_STATIC);
|
||||||
cursor2 = W_CachePatchName("P2CURSOR", PU_STATIC);
|
cursor2 = W_CachePatchName("P2CURSOR", PU_STATIC);
|
||||||
|
|
Loading…
Reference in a new issue