Merge branch 'nonightsbot2' into 'master'

Properly fix bot showing up in NiGHTS stages (resolves #261 for real).

Closes #261

See merge request STJr/SRB2Internal!417
This commit is contained in:
MascaraSnake 2019-11-12 15:41:01 -05:00
commit b04452f7de
2 changed files with 98 additions and 94 deletions

View file

@ -1646,7 +1646,31 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pultmode, boolean rese
// The supplied data are assumed to be good. // The supplied data are assumed to be good.
I_Assert(delay >= 0 && delay <= 2); I_Assert(delay >= 0 && delay <= 2);
if (mapnum != -1) if (mapnum != -1)
{
CV_SetValue(&cv_nextmap, mapnum); CV_SetValue(&cv_nextmap, mapnum);
// Kick bot from special stages
if (botskin)
{
if (G_IsSpecialStage(mapnum) || (mapheaderinfo[mapnum-1] && (mapheaderinfo[mapnum-1]->typeoflevel & TOL_NIGHTS)))
{
if (botingame)
{
//CL_RemoveSplitscreenPlayer();
botingame = false;
playeringame[1] = false;
}
}
else if (!botingame)
{
//CL_AddSplitscreenPlayer();
botingame = true;
secondarydisplayplayer = 1;
playeringame[1] = true;
players[1].bot = 1;
SendNameAndColor2();
}
}
}
CONS_Debug(DBG_GAMELOGIC, "Map change: mapnum=%d gametype=%d ultmode=%d resetplayers=%d delay=%d skipprecutscene=%d\n", CONS_Debug(DBG_GAMELOGIC, "Map change: mapnum=%d gametype=%d ultmode=%d resetplayers=%d delay=%d skipprecutscene=%d\n",
mapnum, newgametype, pultmode, resetplayers, delay, skipprecutscene); mapnum, newgametype, pultmode, resetplayers, delay, skipprecutscene);
if ((netgame || multiplayer) && !((gametype == newgametype) && (newgametype == GT_COOP))) if ((netgame || multiplayer) && !((gametype == newgametype) && (newgametype == GT_COOP)))
@ -1689,29 +1713,6 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pultmode, boolean rese
return; return;
} }
// Kick bot from special stages
if (botskin)
{
if (G_IsSpecialStage(mapnum) || (mapheaderinfo[mapnum-1] && (mapheaderinfo[mapnum-1]->typeoflevel & TOL_NIGHTS)))
{
if (botingame)
{
//CL_RemoveSplitscreenPlayer();
botingame = false;
playeringame[1] = false;
}
}
else if (!botingame)
{
//CL_AddSplitscreenPlayer();
botingame = true;
secondarydisplayplayer = 1;
playeringame[1] = true;
players[1].bot = 1;
SendNameAndColor2();
}
}
chmappending++; chmappending++;
if (netgame) if (netgame)
WRITEUINT32(buf_p, M_RandomizedSeed()); // random seed WRITEUINT32(buf_p, M_RandomizedSeed()); // random seed

View file

@ -6560,7 +6560,7 @@ static void M_LevelSelectWarp(INT32 choice)
if (W_CheckNumForName(G_BuildMapName(cv_nextmap.value)) == LUMPERROR) if (W_CheckNumForName(G_BuildMapName(cv_nextmap.value)) == LUMPERROR)
{ {
// CONS_Alert(CONS_WARNING, "Internal game map '%s' not found\n", G_BuildMapName(cv_nextmap.value)); CONS_Alert(CONS_WARNING, "Internal game map '%s' not found\n", G_BuildMapName(cv_nextmap.value));
return; return;
} }
@ -7977,81 +7977,80 @@ static void M_SetupChoosePlayer(INT32 choice)
char *and; char *and;
(void)choice; (void)choice;
SP_PlayerMenu[0].status &= ~IT_DYBIGSPACE; // Correcting a hack that may be made below. if (!(mapheaderinfo[startmap-1]
&& (mapheaderinfo[startmap-1]->forcecharacter[0] != '\0'
for (i = 0; i < 32; i++) // Handle charsels, availability, and unlocks. || (mapheaderinfo[startmap-1]->typeoflevel & TOL_NIGHTS)) // remove this later when everyone gets their own nights sprites, maybe
))
{ {
if (description[i].used) // If the character's disabled through SOC, there's nothing we can do for it. for (i = 0; i < 32; i++) // Handle charsels, availability, and unlocks.
{ {
and = strchr(description[i].skinname, '&'); if (description[i].used) // If the character's disabled through SOC, there's nothing we can do for it.
if (and)
{ {
char firstskin[SKINNAMESIZE+1]; and = strchr(description[i].skinname, '&');
strncpy(firstskin, description[i].skinname, (and - description[i].skinname)); if (and)
firstskin[(and - description[i].skinname)] = '\0'; {
description[i].skinnum[0] = R_SkinAvailable(firstskin); char firstskin[SKINNAMESIZE+1];
description[i].skinnum[1] = R_SkinAvailable(and+1); strncpy(firstskin, description[i].skinname, (and - description[i].skinname));
} firstskin[(and - description[i].skinname)] = '\0';
else description[i].skinnum[0] = R_SkinAvailable(firstskin);
{ description[i].skinnum[1] = R_SkinAvailable(and+1);
description[i].skinnum[0] = R_SkinAvailable(description[i].skinname); }
description[i].skinnum[1] = -1;
}
skinnum = description[i].skinnum[0];
if ((skinnum != -1) && (R_SkinUsable(-1, skinnum)))
{
// Handling order.
if (firstvalid == 255)
firstvalid = i;
else else
{ {
description[i].prev = lastvalid; description[i].skinnum[0] = R_SkinAvailable(description[i].skinname);
description[lastvalid].next = i; description[i].skinnum[1] = -1;
} }
lastvalid = i; skinnum = description[i].skinnum[0];
if ((skinnum != -1) && (R_SkinUsable(-1, skinnum)))
if (i == char_on)
allowed = true;
if (!(description[i].picname[0]))
{ {
if (skins[skinnum].sprites[SPR2_XTRA].numframes >= XTRA_CHARSEL+1) // Handling order.
if (firstvalid == 255)
firstvalid = i;
else
{ {
spritedef_t *sprdef = &skins[skinnum].sprites[SPR2_XTRA]; description[i].prev = lastvalid;
spriteframe_t *sprframe = &sprdef->spriteframes[XTRA_CHARSEL]; description[lastvalid].next = i;
description[i].charpic = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); }
lastvalid = i;
if (i == char_on)
allowed = true;
if (!(description[i].picname[0]))
{
if (skins[skinnum].sprites[SPR2_XTRA].numframes >= XTRA_CHARSEL+1)
{
spritedef_t *sprdef = &skins[skinnum].sprites[SPR2_XTRA];
spriteframe_t *sprframe = &sprdef->spriteframes[XTRA_CHARSEL];
description[i].charpic = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE);
}
else
description[i].charpic = W_CachePatchName("MISSING", PU_CACHE);
} }
else else
description[i].charpic = W_CachePatchName("MISSING", PU_CACHE); description[i].charpic = W_CachePatchName(description[i].picname, PU_CACHE);
}
else
description[i].charpic = W_CachePatchName(description[i].picname, PU_CACHE);
if (description[i].nametag[0]) if (description[i].nametag[0])
{ {
const char *nametag = description[i].nametag; const char *nametag = description[i].nametag;
description[i].namepic = NULL; description[i].namepic = NULL;
if (W_LumpExists(nametag)) if (W_LumpExists(nametag))
description[i].namepic = W_CachePatchName(nametag, PU_CACHE); description[i].namepic = W_CachePatchName(nametag, PU_CACHE);
}
} }
// else -- Technically, character select icons without corresponding skins get bundled away behind this too. Sucks to be them.
} }
// else -- Technically, character select icons without corresponding skins get bundled away behind this too. Sucks to be them.
} }
} }
if ((firstvalid != 255) if (firstvalid != 255)
&& !(mapheaderinfo[startmap-1]
&& (mapheaderinfo[startmap-1]->forcecharacter[0] != '\0')
)
)
{ // One last bit of order we can't do in the iteration above. { // One last bit of order we can't do in the iteration above.
description[firstvalid].prev = lastvalid; description[firstvalid].prev = lastvalid;
description[lastvalid].next = firstvalid; description[lastvalid].next = firstvalid;
} }
else // We're being forced into a specific character, so might as well. else // We're being forced into a specific character, so might as well just skip it.
{ {
SP_PlayerMenu[0].status |= IT_DYBIGSPACE; // This is a dummy flag hack to make a non-IT_CALL character in slot 0 not softlock the game. M_ChoosePlayer(-1);
M_ChoosePlayer(0);
return; return;
} }
@ -8378,38 +8377,42 @@ static void M_DrawSetupChoosePlayerMenu(void)
static void M_ChoosePlayer(INT32 choice) static void M_ChoosePlayer(INT32 choice)
{ {
boolean ultmode = (ultimate_selectable && SP_PlayerDef.prevMenu == &SP_LoadDef && saveSlotSelected == NOSAVESLOT); boolean ultmode = (ultimate_selectable && SP_PlayerDef.prevMenu == &SP_LoadDef && saveSlotSelected == NOSAVESLOT);
UINT8 skinnum;
// skip this if forcecharacter or no characters available // skip this if forcecharacter or no characters available
if (!(SP_PlayerMenu[0].status & IT_DYBIGSPACE)) if (choice == -1)
{
skinnum = botskin = 0;
botingame = false;
}
// M_SetupChoosePlayer didn't call us directly, that means we've been properly set up.
else
{ {
// M_SetupChoosePlayer didn't call us directly, that means we've been properly set up.
char_scroll = 0; // finish scrolling the menu char_scroll = 0; // finish scrolling the menu
M_DrawSetupChoosePlayerMenu(); // draw the finally selected character one last time for the fadeout M_DrawSetupChoosePlayerMenu(); // draw the finally selected character one last time for the fadeout
// Is this a hack? // Is this a hack?
charseltimer = 0; charseltimer = 0;
}
M_ClearMenus(true);
if (description[choice].skinnum[1] != -1) { skinnum = description[choice].skinnum[0];
// this character has a second skin
botingame = true; if ((botingame = (description[choice].skinnum[1] != -1))) {
botskin = (UINT8)(description[choice].skinnum[1]+1); // this character has a second skin
botcolor = skins[description[choice].skinnum[1]].prefcolor; botskin = (UINT8)(description[choice].skinnum[1]+1);
} botcolor = skins[description[choice].skinnum[1]].prefcolor;
else }
{ else
botingame = false; botskin = botcolor = 0;
botskin = 0;
botcolor = 0;
} }
M_ClearMenus(true);
if (startmap != spstage_start) if (startmap != spstage_start)
cursaveslot = 0; cursaveslot = 0;
//lastmapsaved = 0; //lastmapsaved = 0;
gamecomplete = false; gamecomplete = false;
G_DeferedInitNew(ultmode, G_BuildMapName(startmap), (UINT8)description[choice].skinnum[0], false, fromlevelselect); G_DeferedInitNew(ultmode, G_BuildMapName(startmap), skinnum, false, fromlevelselect);
COM_BufAddText("dummyconsvar 1\n"); // G_DeferedInitNew doesn't do this COM_BufAddText("dummyconsvar 1\n"); // G_DeferedInitNew doesn't do this
if (levelselect.rows) if (levelselect.rows)