* Properly handle gametype changes when a different-gametype level pops up on the voting screen.

* Defer the change until you're actually modifying the map, in service of the following.
	* Reset score.
	* Call that gametype change function.
* Collary of the above: Don't reset score if you're `map mapxx`ing in the console, unless it's `force`'d.
* Fix the basic, obvious issues that'd prevent us shipping with the new level title system.
	* Correct the non-green resolution support, which was ALMOST there but which I accidentially fucked up one of the signs on.
	* Adjust the subttl position if it'd get overwritten.
	* Draw the gametype with the subttl.
* Adjust the gametype constants for easier gametype_cons_t array access.
This commit is contained in:
toaster 2018-06-29 14:14:24 +01:00
parent 2f82227d6e
commit ef8a5b2a7f
7 changed files with 65 additions and 96 deletions

View file

@ -3705,7 +3705,8 @@ static void HandlePacketFromAwayNode(SINT8 node)
if (client) if (client)
{ {
maketic = gametic = neededtic = (tic_t)LONG(netbuffer->u.servercfg.gametic); maketic = gametic = neededtic = (tic_t)LONG(netbuffer->u.servercfg.gametic);
gametype = netbuffer->u.servercfg.gametype; if ((gametype = netbuffer->u.servercfg.gametype) >= NUMGAMETYPES)
I_Error("Bad gametype in cliserv!");
modifiedgame = netbuffer->u.servercfg.modifiedgame; modifiedgame = netbuffer->u.servercfg.modifiedgame;
for (j = 0; j < MAXPLAYERS; j++) for (j = 0; j < MAXPLAYERS; j++)
adminplayers[j] = netbuffer->u.servercfg.adminplayers[j]; adminplayers[j] = netbuffer->u.servercfg.adminplayers[j];

View file

@ -447,6 +447,7 @@ consvar_t cv_mute = {"mute", "Off", CV_NETVAR|CV_CALL, CV_OnOff, Mute_OnChange,
consvar_t cv_sleep = {"cpusleep", "-1", CV_SAVE, sleeping_cons_t, NULL, -1, NULL, NULL, 0, 0, NULL}; consvar_t cv_sleep = {"cpusleep", "-1", CV_SAVE, sleeping_cons_t, NULL, -1, NULL, NULL, 0, 0, NULL};
INT16 gametype = GT_RACE; // SRB2kart INT16 gametype = GT_RACE; // SRB2kart
INT16 deferredgametype = GT_RACE; // SRB2kart
UINT8 splitscreen = 0; UINT8 splitscreen = 0;
boolean circuitmap = true; // SRB2kart boolean circuitmap = true; // SRB2kart
INT32 adminplayers[MAXPLAYERS]; INT32 adminplayers[MAXPLAYERS];
@ -2117,7 +2118,6 @@ static void Command_Map_f(void)
// Don't do any variable setting here. Wait until you get your // Don't do any variable setting here. Wait until you get your
// map packet first to avoid sending the same info twice! // map packet first to avoid sending the same info twice!
newgametype = gametype_cons_t[j].value; newgametype = gametype_cons_t[j].value;
break; break;
} }
@ -2135,26 +2135,23 @@ static void Command_Map_f(void)
} }
} }
if (!(i = COM_CheckParm("-force")) && newgametype == gametype) // SRB2Kart
newresetplayers = false; // if not forcing and gametypes is the same
// don't use a gametype the map doesn't support // don't use a gametype the map doesn't support
if (cv_debug || COM_CheckParm("-force") || cv_skipmapcheck.value) if (cv_debug || i || cv_skipmapcheck.value)
; // The player wants us to trek on anyway. Do so. ; // The player wants us to trek on anyway. Do so.
// G_TOLFlag handles both multiplayer gametype and ignores it for !multiplayer // G_TOLFlag handles both multiplayer gametype and ignores it for !multiplayer
// Alternatively, bail if the map header is completely missing anyway. // Alternatively, bail if the map header is completely missing anyway.
else if (!mapheaderinfo[newmapnum-1] else
|| !(mapheaderinfo[newmapnum-1]->typeoflevel & G_TOLFlag(newgametype)))
{ {
char gametypestring[32] = "Single Player"; if (!mapheaderinfo[newmapnum-1]
|| !(mapheaderinfo[newmapnum-1]->typeoflevel & G_TOLFlag(newgametype)))
if (multiplayer) {
for (i = 0; gametype_cons_t[i].strvalue != NULL; i++) CONS_Alert(CONS_WARNING, M_GetText("%s doesn't support %s mode!\n(Use -force to override)\n"), mapname,
if (gametype_cons_t[i].value == newgametype) (multiplayer ? gametype_cons_t[newgametype].strvalue : "Single Player"));
{ return;
strcpy(gametypestring, gametype_cons_t[i].strvalue); }
break;
}
CONS_Alert(CONS_WARNING, M_GetText("%s doesn't support %s mode!\n(Use -force to override)\n"), mapname, gametypestring);
return;
} }
// Prevent warping to locked levels // Prevent warping to locked levels
@ -4044,24 +4041,12 @@ static void Command_ShowGametype_f(void)
INT32 j; INT32 j;
const char *gametypestr = NULL; const char *gametypestr = NULL;
if (!(netgame || multiplayer)) // print "Single player" instead of "Co-op" if (!(netgame || multiplayer)) // print "Single player" instead of "Race"
{ {
CONS_Printf(M_GetText("Current gametype is %s\n"), M_GetText("Single player")); CONS_Printf(M_GetText("Current gametype is %s\n"), "Single Player");
return; return;
} }
// find name string for current gametype CONS_Printf(M_GetText("Current gametype is %s\n"), gametype_cons_t[gametype].strvalue);
for (j = 0; gametype_cons_t[j].strvalue; j++)
{
if (gametype_cons_t[j].value == gametype)
{
gametypestr = gametype_cons_t[j].strvalue;
break;
}
}
if (gametypestr)
CONS_Printf(M_GetText("Current gametype is %s\n"), gametypestr);
else // string for current gametype was not found above (should never happen)
CONS_Printf(M_GetText("Unknown gametype set (%d)\n"), gametype);
} }
/** Plays the intro. /** Plays the intro.
@ -4195,19 +4180,8 @@ static void TimeLimit_OnChange(void)
void D_GameTypeChanged(INT32 lastgametype) void D_GameTypeChanged(INT32 lastgametype)
{ {
if (netgame) if (netgame)
{ CONS_Printf(M_GetText("Gametype was changed from %s to %s\n"), gametype_cons_t[lastgametype].strvalue, gametype_cons_t[gametype].strvalue);
INT32 j;
const char *oldgt = NULL, *newgt = NULL;
for (j = 0; gametype_cons_t[j].strvalue; j++)
{
if (gametype_cons_t[j].value == lastgametype)
oldgt = gametype_cons_t[j].strvalue;
if (gametype_cons_t[j].value == gametype)
newgt = gametype_cons_t[j].strvalue;
}
if (oldgt && newgt)
CONS_Printf(M_GetText("Gametype was changed from %s to %s\n"), oldgt, newgt);
}
// Only do the following as the server, not as remote admin. // Only do the following as the server, not as remote admin.
// There will always be a server, and this only needs to be done once. // There will always be a server, and this only needs to be done once.
if (server && (multiplayer || netgame)) if (server && (multiplayer || netgame))

View file

@ -76,7 +76,7 @@ extern boolean addedtogame; // true after the server has added you
// Only true if >1 player. netgame => multiplayer but not (multiplayer=>netgame) // Only true if >1 player. netgame => multiplayer but not (multiplayer=>netgame)
extern boolean multiplayer; extern boolean multiplayer;
extern INT16 gametype; extern INT16 gametype, deferredgametype;
extern UINT8 splitscreen; extern UINT8 splitscreen;
extern boolean circuitmap; // Does this level have 'circuit mode'? extern boolean circuitmap; // Does this level have 'circuit mode'?
extern boolean fromlevelselect; extern boolean fromlevelselect;
@ -303,21 +303,19 @@ enum TypeOfLevel
}; };
// Gametypes // Gametypes
enum GameType enum GameType // SRB2Kart
{ {
GT_COOP = 0, // also used in single player GT_RACE = 0, // also used in record attack
GT_COMPETITION, // Classic "Race" GT_MATCH, // battle, but renaming would be silly
GT_RACE, NUMGAMETYPES,
GT_MATCH, // the following have been left in on account of just not wanting to deal with removing all the checks for them
GT_COOP,
GT_COMPETITION,
GT_TEAMMATCH, GT_TEAMMATCH,
GT_TAG, GT_TAG,
GT_HIDEANDSEEK, GT_HIDEANDSEEK,
GT_CTF
GT_CTF, // capture the flag
NUMGAMETYPES
}; };
// If you alter this list, update gametype_cons_t in m_menu.c // If you alter this list, update gametype_cons_t in m_menu.c

View file

@ -3379,7 +3379,11 @@ void G_NextLevel(void)
&& !modeattacking && !skipstats && (multiplayer || netgame)) && !modeattacking && !skipstats && (multiplayer || netgame))
gameaction = ga_startvote; gameaction = ga_startvote;
else else
{
if (gamestate != GS_VOTING)
deferredgametype = gametype;
gameaction = ga_worlddone; gameaction = ga_worlddone;
}
} }
static void G_DoWorldDone(void) static void G_DoWorldDone(void)
@ -3387,7 +3391,7 @@ static void G_DoWorldDone(void)
if (server) if (server)
{ {
// SRB2kart: don't reset player between maps // SRB2kart: don't reset player between maps
D_MapChange(nextmap+1, gametype, ultimatemode, false, 0, false, false); D_MapChange(nextmap+1, deferredgametype, ultimatemode, (deferredgametype != gametype), 0, false, false);
} }
gameaction = ga_nothing; gameaction = ga_nothing;
@ -4032,7 +4036,8 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean
if (!demoplayback && !netgame) // Netgame sets random seed elsewhere, demo playback sets seed just before us! 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 P_SetRandSeed(M_RandomizedSeed()); // Use a more "Random" random seed
if (resetplayer) //SRB2Kart - Score is literally the only thing you SHOULDN'T reset at all times
//if (resetplayer)
{ {
// Clear a bunch of variables // Clear a bunch of variables
tokenlist = token = sstimer = redscore = bluescore = lastmap = 0; tokenlist = token = sstimer = redscore = bluescore = lastmap = 0;
@ -4045,7 +4050,7 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean
players[i].starpostx = players[i].starposty = players[i].starpostz = 0; players[i].starpostx = players[i].starposty = players[i].starpostz = 0;
players[i].starpostcount = 0; // srb2kart players[i].starpostcount = 0; // srb2kart
if (netgame || multiplayer) /*if (netgame || multiplayer)
{ {
players[i].lives = cv_startinglives.value; players[i].lives = cv_startinglives.value;
players[i].continues = 0; players[i].continues = 0;
@ -4061,13 +4066,18 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean
players[i].continues = 1; players[i].continues = 1;
} }
players[i].xtralife = 0;*/
// The latter two should clear by themselves, but just in case // The latter two should clear by themselves, but just in case
players[i].pflags &= ~(PF_TAGIT|PF_TAGGED|PF_FULLSTASIS); players[i].pflags &= ~(PF_TAGIT|PF_TAGGED|PF_FULLSTASIS);
// Clear cheatcodes too, just in case. // Clear cheatcodes too, just in case.
players[i].pflags &= ~(PF_GODMODE|PF_NOCLIP|PF_INVIS); players[i].pflags &= ~(PF_GODMODE|PF_NOCLIP|PF_INVIS);
players[i].score = players[i].xtralife = 0; if (resetplayer) // SRB2Kart
{
players[i].score = 0;
}
} }
// Reset unlockable triggers // Reset unlockable triggers
@ -5601,8 +5611,7 @@ void G_DoPlayDemo(char *defdemoname)
memset(playeringame,0,sizeof(playeringame)); memset(playeringame,0,sizeof(playeringame));
playeringame[0] = true; playeringame[0] = true;
P_SetRandSeed(randseed); P_SetRandSeed(randseed);
//G_InitNew(false, G_BuildMapName(gamemap), false, true); // resetplayer needs to be false to retain score G_InitNew(false, G_BuildMapName(gamemap), true, true); // Doesn't matter whether you reset or not here, given changes to resetplayer.
G_InitNew(false, G_BuildMapName(gamemap), true, true); // ...but uh, for demos? doing that makes them start in different positions depending on the last demo you watched
// Set skin // Set skin
SetPlayerSkin(0, skin); SetPlayerSkin(0, skin);

View file

@ -1123,19 +1123,7 @@ static void HU_DrawCEcho(void)
static void HU_drawGametype(void) static void HU_drawGametype(void)
{ {
INT32 i = 0; V_DrawString(4, (splitscreen ? 184 : 192), 0, gametype_cons_t[gametype].strvalue);
for (i = 0; gametype_cons_t[i].strvalue; i++)
{
if (gametype_cons_t[i].value == gametype)
{
if (splitscreen)
V_DrawString(4, 184, 0, gametype_cons_t[i].strvalue);
else
V_DrawString(4, 192, 0, gametype_cons_t[i].strvalue);
return;
}
}
} }
// //

View file

@ -774,11 +774,14 @@ static void ST_drawLevelTitle(void)
else else
lvlttlxpos = ((BASEVIDWIDTH/2) - (lvlw/2)); lvlttlxpos = ((BASEVIDWIDTH/2) - (lvlw/2));
ttlnumxpos = lvlttlxpos + lvlw; zonexpos = ttlnumxpos = lvlttlxpos + lvlw;
if (zonttl[0]) if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE))
zonexpos = ttlnumxpos - V_LevelNameWidth(zonttl); // SRB2kart {
else if (zonttl[0])
zonexpos = ttlnumxpos - V_LevelNameWidth(M_GetText("ZONE")); zonexpos -= V_LevelNameWidth(zonttl); // SRB2kart
else
zonexpos -= V_LevelNameWidth(M_GetText("ZONE"));
}
if (lvlttlxpos < 0) if (lvlttlxpos < 0)
lvlttlxpos = 0; lvlttlxpos = 0;
@ -795,11 +798,14 @@ static void ST_drawLevelTitle(void)
{ {
dupcalc = (dupcalc - BASEVIDWIDTH)>>1; dupcalc = (dupcalc - BASEVIDWIDTH)>>1;
INT32 h = lvlttly + V_LevelNameHeight(lvlttl) + 2; INT32 h = lvlttly + V_LevelNameHeight(lvlttl) + 2;
V_DrawFill(sub - dupcalc, h+9, lvlttlxpos + lvlw + 1 - dupcalc, 2, 31); V_DrawFill(sub - dupcalc, h+9, ttlnumxpos+dupcalc + 1, 2, 31);
V_DrawDiag(sub + lvlttlxpos + lvlw + 1, h, 11, 31); V_DrawDiag(sub + ttlnumxpos + 1, h, 11, 31);
V_DrawFill(sub - dupcalc, h, lvlttlxpos + lvlw - dupcalc, 10, gtc); V_DrawFill(sub - dupcalc, h, ttlnumxpos+dupcalc, 10, gtc);
V_DrawDiag(sub + lvlttlxpos + lvlw, h, 10, gtc); V_DrawDiag(sub + ttlnumxpos, h, 10, gtc);
V_DrawString(sub + lvlttlxpos, h+1, V_ALLOWLOWERCASE, subttl); if (subttl[0])
V_DrawRightAlignedString(sub + zonexpos - 8, h+1, V_ALLOWLOWERCASE, va("%s - %s", gametype_cons_t[gametype].strvalue, subttl));
else
V_DrawRightAlignedString(sub + zonexpos - 8, h+1, V_ALLOWLOWERCASE, gametype_cons_t[gametype].strvalue);
} }
ttlnumxpos += sub; ttlnumxpos += sub;

View file

@ -2617,16 +2617,13 @@ void Y_StartVote(void)
levelinfo[i].str[sizeof levelinfo[i].str - 1] = '\0'; levelinfo[i].str[sizeof levelinfo[i].str - 1] = '\0';
// set up the gtc and gts // set up the gtc and gts
levelinfo[i].gts = NULL;
if (i == 2 && votelevels[i][1] != votelevels[0][1]) if (i == 2 && votelevels[i][1] != votelevels[0][1])
{ {
levelinfo[i].gtc = G_GetGametypeColor(votelevels[i][1]); levelinfo[i].gtc = G_GetGametypeColor(votelevels[i][1]);
for (j = 0; gametype_cons_t[j].strvalue; j++) levelinfo[i].gts = gametype_cons_t[votelevels[i][1]].strvalue;
{
if (gametype_cons_t[j].value == votelevels[i][1])
levelinfo[i].gts = gametype_cons_t[j].strvalue;
}
} }
else
levelinfo[i].gts = NULL; // gtc is never accessed in this case
// set up the pic // set up the pic
lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(votelevels[i][0]+1))); lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(votelevels[i][0]+1)));
@ -2726,10 +2723,6 @@ void Y_SetupVoteFinish(SINT8 pick, SINT8 level)
pickedvote = pick; pickedvote = pick;
nextmap = votelevels[level][0]; nextmap = votelevels[level][0];
if (gametype != votelevels[level][1]) deferredgametype = votelevels[level][1];
{
//CONS_Printf("yer dun\n"); -- if we want to do anything else special for a gametype switch, it'd be here
gametype = votelevels[level][1];
}
timer = 0; timer = 0;
} }