- transitioned Blood to the new level change messaging system

This commit is contained in:
Christoph Oelckers 2020-09-04 20:46:44 +02:00
parent 77f96a1c75
commit 97f395bd72
17 changed files with 102 additions and 170 deletions

View File

@ -70,15 +70,12 @@ void InitCheats();
bool bNoDemo = false; bool bNoDemo = false;
int gNetPlayers; int gNetPlayers;
int gQuitRequest;
int gChokeCounter = 0; int gChokeCounter = 0;
bool gQuitGame;
int blood_globalflags; int blood_globalflags;
PLAYER gPlayerTemp[kMaxPlayers]; PLAYER gPlayerTemp[kMaxPlayers];
int gHealthTemp[kMaxPlayers]; int gHealthTemp[kMaxPlayers];
vec3_t startpos; vec3_t startpos;
int16_t startang, startsectnum; int16_t startang, startsectnum;
MapRecord* gStartNewGame = nullptr;
void QuitGame(void) void QuitGame(void)
@ -104,7 +101,6 @@ void StartLevel(MapRecord* level)
STAT_Update(0); STAT_Update(0);
EndLevel(); EndLevel();
gInput = {}; gInput = {};
gStartNewGame = nullptr;
currentLevel = level; currentLevel = level;
if (gGameOptions.nGameType == 0) if (gGameOptions.nGameType == 0)
@ -114,14 +110,14 @@ void StartLevel(MapRecord* level)
/////// ///////
} }
#if 0 #if 0
else if (gGameOptions.nGameType > 0 && !(gGameOptions.uGameFlags & 1)) else if (gGameOptions.nGameType > 0 && !(gGameOptions.uGameFlags & GF_AdvanceLevel))
{ {
// todo // todo
gBlueFlagDropped = false; gBlueFlagDropped = false;
gRedFlagDropped = false; gRedFlagDropped = false;
} }
#endif #endif
if (gGameOptions.uGameFlags & 1) if (gGameOptions.uGameFlags & GF_AdvanceLevel)
{ {
for (int i = connecthead; i >= 0; i = connectpoint2[i]) for (int i = connecthead; i >= 0; i = connectpoint2[i])
{ {
@ -204,7 +200,7 @@ void StartLevel(MapRecord* level)
evInit(); evInit();
for (int i = connecthead; i >= 0; i = connectpoint2[i]) for (int i = connecthead; i >= 0; i = connectpoint2[i])
{ {
if (!(gGameOptions.uGameFlags & 1)) if (!(gGameOptions.uGameFlags & GF_AdvanceLevel))
{ {
if (numplayers == 1) if (numplayers == 1)
{ {
@ -214,7 +210,7 @@ void StartLevel(MapRecord* level)
} }
playerStart(i, 1); playerStart(i, 1);
} }
if (gGameOptions.uGameFlags & 1) if (gGameOptions.uGameFlags & GF_AdvanceLevel)
{ {
for (int i = connecthead; i >= 0; i = connectpoint2[i]) for (int i = connecthead; i >= 0; i = connectpoint2[i])
{ {
@ -231,7 +227,7 @@ void StartLevel(MapRecord* level)
pPlayer->nextWeapon = gPlayerTemp[i].nextWeapon; pPlayer->nextWeapon = gPlayerTemp[i].nextWeapon;
} }
} }
gGameOptions.uGameFlags &= ~3; gGameOptions.uGameFlags &= ~(GF_AdvanceLevel|GF_EndGame);
PreloadCache(); PreloadCache();
InitMirrors(); InitMirrors();
trInit(); trInit();
@ -249,60 +245,44 @@ void StartLevel(MapRecord* level)
} }
bool gRestartGame = false; void NewLevel(MapRecord *sng, int skill)
static void commonTicker()
{ {
if (TestBitString(gotpic, 2342)) auto completion = [=](bool = false)
{ {
FireProcess(); gGameOptions.nDifficulty = skill;
ClearBitString(gotpic, 2342); gSkill = skill;
} cheatReset();
if (gStartNewGame) StartLevel(sng);
gamestate = GS_LEVEL;
};
bool startedCutscene = false;
if (!(sng->flags & MI_USERMAP))
{ {
auto sng = gStartNewGame; int episode = volfromlevelnum(sng->levelNumber);
gStartNewGame = nullptr; int level = mapfromlevelnum(sng->levelNumber);
gQuitGame = false; if (gEpisodeInfo[episode].cutALevel == level && gEpisodeInfo[episode].cutsceneAName[0])
auto completion = [=](bool = false)
{ {
StartLevel(sng); levelPlayIntroScene(episode, completion);
startedCutscene = true;
gamestate = GS_LEVEL;
};
bool startedCutscene = false;
if (!(sng->flags & MI_USERMAP))
{
int episode = volfromlevelnum(sng->levelNumber);
int level = mapfromlevelnum(sng->levelNumber);
if (gEpisodeInfo[episode].cutALevel == level && gEpisodeInfo[episode].cutsceneAName[0])
{
levelPlayIntroScene(episode, completion);
startedCutscene = true;
}
} }
if (!startedCutscene) completion(false);
}
else if (gRestartGame)
{
Mus_Stop();
soundEngine->StopAllChannels();
gQuitGame = 0;
gQuitRequest = 0;
gRestartGame = 0;
// Don't switch to startup if we're already outside the game.
if (gamestate == GS_LEVEL)
{
gamestate = GS_MENUSCREEN;
M_StartControlPanel(false);
M_SetMenu(NAME_Mainmenu);
}
} }
if (!startedCutscene) completion(false);
} }
void GameInterface::NewGame(MapRecord *sng, int skill)
{
gGameOptions.uGameFlags = 0;
NewLevel(sng, skill);
}
void GameInterface::NextLevel(MapRecord *map, int skill)
{
gGameOptions.uGameFlags = GF_AdvanceLevel;
NewLevel(map, skill);
}
void GameInterface::Ticker() void GameInterface::Ticker()
{ {
@ -369,25 +349,20 @@ void GameInterface::Ticker()
dword_21EFD0[i] = 0; dword_21EFD0[i] = 0;
} }
if ((gGameOptions.uGameFlags & 1) != 0 && !gStartNewGame) if ((gGameOptions.uGameFlags & GF_AdvanceLevel) != 0)
{ {
seqKillAll(); seqKillAll();
if (gGameOptions.uGameFlags & 2) if (gGameOptions.uGameFlags & GF_EndGame)
{ {
STAT_Update(true); STAT_Update(true);
if (gGameOptions.nGameType == 0) if (gGameOptions.nGameType == 0)
{ {
auto completion = [](bool) { auto completion = [](bool) {
gamestate = GS_MENUSCREEN; gGameOptions.uGameFlags &= ~(GF_AdvanceLevel|GF_EndGame);
M_StartControlPanel(false); gameaction = ga_creditsmenu;
M_SetMenu(NAME_Mainmenu);
M_SetMenu(NAME_CreditsMenu);
gGameOptions.uGameFlags &= ~3;
gQuitGame = 1;
gRestartGame = true;
}; };
if (gGameOptions.uGameFlags & 8) if (gGameOptions.uGameFlags & GF_PlayCutscene)
{ {
levelPlayEndScene(volfromlevelnum(currentLevel->levelNumber), completion); levelPlayEndScene(volfromlevelnum(currentLevel->levelNumber), completion);
} }
@ -395,27 +370,29 @@ void GameInterface::Ticker()
} }
else else
{ {
gGameOptions.uGameFlags &= ~3; gGameOptions.uGameFlags &= ~(GF_AdvanceLevel|GF_EndGame);
gRestartGame = 1;
gQuitGame = 1;
} }
} }
else else
{ {
ShowSummaryScreen(); STAT_Update(false);
EndLevel();
Mus_Stop();
// Fixme: Link maps, not episode/level pairs.
int ep = volfromlevelnum(currentLevel->levelNumber);
auto map = FindMapByLevelNum(levelnum(ep, gNextLevel));
CompleteLevel(map);
} }
} }
r_NoInterpolate = false; r_NoInterpolate = false;
} }
else r_NoInterpolate = true; else r_NoInterpolate = true;
commonTicker();
} }
void GameInterface::DrawBackground() void GameInterface::DrawBackground()
{ {
twod->ClearScreen(); twod->ClearScreen();
DrawTexture(twod, tileGetTexture(2518, true), 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, TAG_DONE); DrawTexture(twod, tileGetTexture(2518, true), 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, TAG_DONE);
commonTicker();
} }
@ -488,8 +465,6 @@ static void gameInit()
pProfile->skill = gSkill; pProfile->skill = gSkill;
UpdateNetworkMenus(); UpdateNetworkMenus();
gQuitGame = 0;
gRestartGame = 0;
if (gGameOptions.nGameType > 0) if (gGameOptions.nGameType > 0)
{ {
inputState.ClearAllInput(); inputState.ClearAllInput();

View File

@ -46,16 +46,9 @@ struct INICHAIN {
extern INICHAIN *pINIChain; extern INICHAIN *pINIChain;
extern MapRecord* gStartNewGame;
extern int gNetPlayers; extern int gNetPlayers;
extern bool gRestartGame;
extern int blood_globalflags; extern int blood_globalflags;
extern bool gSavingGame;
extern bool gQuitGame;
extern int gQuitRequest;
void QuitGame(void); void QuitGame(void);
void PreloadCache(void); void PreloadCache(void);
void StartLevel(MapRecord *gameOptions); void StartLevel(MapRecord *gameOptions);
@ -101,6 +94,10 @@ struct GameInterface : ::GameInterface
void Startup() override; void Startup() override;
void Render() override; void Render() override;
const char* GenericCheat(int player, int cheat) override; const char* GenericCheat(int player, int cheat) override;
void NewGame(MapRecord *sng, int skill) override;
void NextLevel(MapRecord* map, int skill) override;
void LevelCompleted(MapRecord* map, int skill) override;
GameStats getStats() override; GameStats getStats() override;
}; };

View File

@ -129,7 +129,6 @@ void playSmk(const char *smk, const char *wav, int wavid, CompletionFunc func)
void levelPlayIntroScene(int nEpisode, CompletionFunc completion) void levelPlayIntroScene(int nEpisode, CompletionFunc completion)
{ {
gGameOptions.uGameFlags &= ~4;
Mus_Stop(); Mus_Stop();
sndKillAllSounds(); sndKillAllSounds();
sfxKillAllSounds(); sfxKillAllSounds();
@ -141,7 +140,7 @@ void levelPlayIntroScene(int nEpisode, CompletionFunc completion)
void levelPlayEndScene(int nEpisode, CompletionFunc completion) void levelPlayEndScene(int nEpisode, CompletionFunc completion)
{ {
gGameOptions.uGameFlags &= ~8; gGameOptions.uGameFlags &= ~GF_PlayCutscene;
Mus_Stop(); Mus_Stop();
sndKillAllSounds(); sndKillAllSounds();
sfxKillAllSounds(); sfxKillAllSounds();

View File

@ -242,10 +242,8 @@ bool GameInterface::CanSave()
void GameInterface::StartGame(FNewGameStartup& gs) void GameInterface::StartGame(FNewGameStartup& gs)
{ {
sfxKillAllSounds(); sfxKillAllSounds();
gGameOptions.nDifficulty = gs.Skill; auto map = FindMapByLevelNum(levelnum(gs.Episode, gs.Level));
gSkill = gs.Skill; DeferedStartGame(map, gs.Skill);
gStartNewGame = FindMapByLevelNum(levelnum(gs.Episode, gs.Level));
cheatReset();
} }
FSavegameInfo GameInterface::GetSaveSig() FSavegameInfo GameInterface::GetSaveSig()
@ -290,12 +288,7 @@ void GameInterface::DrawCenteredTextScreen(const DVector2& origin, const char* t
void GameInterface::QuitToTitle() void GameInterface::QuitToTitle()
{ {
if (gGameOptions.nGameType == 0 || numplayers == 1) gameaction = ga_mainmenu;
{
gQuitGame = true;
gRestartGame = true;
}
//else gQuitRequest = 2;
} }
END_BLD_NS END_BLD_NS

View File

@ -164,24 +164,17 @@ class DBloodSummaryScreen : public DScreenJob
} }
}; };
void GameInterface::LevelCompleted(MapRecord *map, int skill)
void ShowSummaryScreen()
{ {
JobDesc job = { Create<DBloodSummaryScreen>() }; JobDesc job = { Create<DBloodSummaryScreen>() };
STAT_Update(false);
EndLevel();
Mus_Stop();
sndStartSample(268, 128, -1, false); sndStartSample(268, 128, -1, false);
RunScreenJob(&job, 1, [](bool) RunScreenJob(&job, 1, [=](bool)
{ {
int ep = volfromlevelnum(currentLevel->levelNumber);
gStartNewGame = FindMapByLevelNum(levelnum(ep, gNextLevel));
gamestate = GS_LEVEL;
soundEngine->StopAllChannels(); soundEngine->StopAllChannels();
gameaction = ga_nextlevel;
}); });
}
}
CKillMgr::CKillMgr() CKillMgr::CKillMgr()

View File

@ -49,6 +49,5 @@ public:
extern CSecretMgr gSecretMgr; extern CSecretMgr gSecretMgr;
extern CKillMgr gKillMgr; extern CKillMgr gKillMgr;
void ShowSummaryScreen();
END_BLD_NS END_BLD_NS

View File

@ -199,7 +199,7 @@ void levelEndLevel(int arg)
int nEndingA, nEndingB; int nEndingA, nEndingB;
auto episode = volfromlevelnum(currentLevel->levelNumber); auto episode = volfromlevelnum(currentLevel->levelNumber);
EPISODEINFO *pEpisodeInfo = &gEpisodeInfo[episode]; EPISODEINFO *pEpisodeInfo = &gEpisodeInfo[episode];
gGameOptions.uGameFlags |= 1; gGameOptions.uGameFlags |= GF_AdvanceLevel;
levelGetNextLevels(&nEndingA, &nEndingB); levelGetNextLevels(&nEndingA, &nEndingB);
switch (arg) switch (arg)
{ {
@ -207,8 +207,8 @@ void levelEndLevel(int arg)
if (nEndingA == -1) if (nEndingA == -1)
{ {
if (pEpisodeInfo->cutsceneBName[0]) if (pEpisodeInfo->cutsceneBName[0])
gGameOptions.uGameFlags |= 8; gGameOptions.uGameFlags |= GF_PlayCutscene;
gGameOptions.uGameFlags |= 2; gGameOptions.uGameFlags |= GF_EndGame;
} }
else else
gNextLevel = nEndingA; gNextLevel = nEndingA;
@ -219,12 +219,12 @@ void levelEndLevel(int arg)
if (episode + 1 < gEpisodeCount) if (episode + 1 < gEpisodeCount)
{ {
if (pEpisodeInfo->cutsceneBName[0]) if (pEpisodeInfo->cutsceneBName[0])
gGameOptions.uGameFlags |= 8; gGameOptions.uGameFlags |= GF_PlayCutscene;
gGameOptions.uGameFlags |= 2; gGameOptions.uGameFlags |= GF_EndGame;
} }
else else
{ {
gGameOptions.uGameFlags |= 1; gGameOptions.uGameFlags |= GF_AdvanceLevel;
} }
} }
else else

View File

@ -35,6 +35,14 @@ BEGIN_BLD_NS
#pragma pack(push, 1) #pragma pack(push, 1)
enum EGameFlag
{
GF_AdvanceLevel = 1,
GF_EndGame = 2,
// 4 was for playing intro cutscenes but is no longer used.
GF_PlayCutscene = 8,
};
struct GAMEOPTIONS { struct GAMEOPTIONS {
unsigned char nGameType; unsigned char nGameType;
unsigned char nDifficulty; unsigned char nDifficulty;

View File

@ -267,12 +267,6 @@ void ToggleDelirium(void)
} }
} }
void LevelWarp(int nEpisode, int nLevel)
{
auto map = FindMapByLevelNum(levelnum(nEpisode, nLevel));
if (map) StartLevel(map);
}
bool bPlayerCheated = false; bool bPlayerCheated = false;
static int parseArgs(char *pzArgs, int *nArg1, int *nArg2) static int parseArgs(char *pzArgs, int *nArg1, int *nArg2)
@ -434,7 +428,10 @@ static bool cheatMario(cheatseq_t* c)
{ {
int nEpisode, nLevel; int nEpisode, nLevel;
if (parseArgs((char*)c->Args, &nEpisode, &nLevel) == 2) if (parseArgs((char*)c->Args, &nEpisode, &nLevel) == 2)
LevelWarp(nEpisode, nLevel); {
auto map = FindMapByLevelNum(levelnum(nEpisode, nLevel));
if (map) DeferedStartGame(map, -1);
}
return true; return true;
} }

View File

@ -5169,10 +5169,10 @@ void seqSpawnerOffSameTx(XSPRITE* pXSource) {
// it allows to set custom next level instead of taking it from INI file. // it allows to set custom next level instead of taking it from INI file.
void levelEndLevelCustom(int nLevel) { void levelEndLevelCustom(int nLevel) {
gGameOptions.uGameFlags |= 1; gGameOptions.uGameFlags |= GF_AdvanceLevel;
if (nLevel >= 16 || nLevel < 0) { if (nLevel >= 16 || nLevel < 0) {
gGameOptions.uGameFlags |= 2; gGameOptions.uGameFlags |= GF_EndGame;
return; return;
} }

View File

@ -38,53 +38,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
BEGIN_BLD_NS BEGIN_BLD_NS
void LevelWarp(int nEpisode, int nLevel);
static int osdcmd_map(CCmdFuncPtr parm)
{
if (parm->numparms != 1)
return CCMD_SHOWHELP;
FString mapname = parm->parms[0];
FString mapfilename = mapname;
DefaultExtension(mapfilename, ".map");
if (!fileSystem.FileExists(mapfilename))
{
Printf(TEXTCOLOR_RED "map: file \"%s\" not found.\n", mapfilename.GetChars());
return CCMD_OK;
}
auto maprec = FindMapByName(mapname);
if (maprec)
{
StartLevel(maprec);
}
else
{
// Map has not been defined. Treat as user map.
StartLevel(SetupUserMap(mapfilename));
}
return CCMD_OK;
}
static int osdcmd_levelwarp(CCmdFuncPtr parm)
{
if (parm->numparms != 2)
return CCMD_SHOWHELP;
int e = atoi(parm->parms[0]);
int m = atoi(parm->parms[1]);
if (e == 0 || m == 0)
{
Printf(TEXTCOLOR_RED "Invalid level!: E%sM%s\n", parm->parms[0], parm->parms[1]);
return CCMD_OK;
}
LevelWarp(e - 1, m - 1);
return CCMD_OK;
}
static int osdcmd_warptocoords(CCmdFuncPtr parm) static int osdcmd_warptocoords(CCmdFuncPtr parm)
{ {
if (parm->numparms < 3 || parm->numparms > 5) if (parm->numparms < 3 || parm->numparms > 5)
@ -160,8 +113,6 @@ static int osdcmd_show_weapon(CCmdFuncPtr parm)
int32_t registerosdcommands(void) int32_t registerosdcommands(void)
{ {
C_RegisterFunction("map","map <mapname>: loads the given map", osdcmd_map);
C_RegisterFunction("levelwarp","levelwarp <e> <m>: warp to episode 'e' and map 'm'", osdcmd_levelwarp);
C_RegisterFunction("warptocoords","warptocoords [x] [y] [z] [ang] (optional) [horiz] (optional): warps the player to the specified coordinates",osdcmd_warptocoords); C_RegisterFunction("warptocoords","warptocoords [x] [y] [z] [ang] (optional) [horiz] (optional): warps the player to the specified coordinates",osdcmd_warptocoords);
C_RegisterFunction("third_person_view", "Switch to third person view", osdcmd_third_person_view); C_RegisterFunction("third_person_view", "Switch to third person view", osdcmd_third_person_view);
C_RegisterFunction("coop_view", "Switch player to view from in coop", osdcmd_coop_view); C_RegisterFunction("coop_view", "Switch player to view from in coop", osdcmd_coop_view);

View File

@ -1369,7 +1369,7 @@ void ProcessInput(PLAYER *pPlayer)
playerReset(pPlayer); playerReset(pPlayer);
if (gGameOptions.nGameType == 0 && numplayers == 1) if (gGameOptions.nGameType == 0 && numplayers == 1)
{ {
gStartNewGame = currentLevel; DeferedStartGame(currentLevel, -1);
} }
else else
playerStart(pPlayer->nPlayer); playerStart(pPlayer->nPlayer);

View File

@ -601,6 +601,13 @@ void viewDrawScreen(bool sceneonly)
{ {
int nPalette = 0; int nPalette = 0;
int defaultHoriz = r_horizcenter ? 100 : 90; int defaultHoriz = r_horizcenter ? 100 : 90;
if (TestBitString(gotpic, 2342))
{
FireProcess();
ClearBitString(gotpic, 2342);
}
#ifdef USE_OPENGL #ifdef USE_OPENGL
polymostcenterhoriz = defaultHoriz; polymostcenterhoriz = defaultHoriz;

View File

@ -26,6 +26,7 @@ enum gameaction_t : int
ga_nothing, ga_nothing,
ga_startup, // go back to intro after uninitializing the game state ga_startup, // go back to intro after uninitializing the game state
ga_mainmenu, // go back to main menu after uninitializing the game state ga_mainmenu, // go back to main menu after uninitializing the game state
ga_creditsmenu, // go to the credits menu after uninitializing the game state
ga_newgame, // start a new game ga_newgame, // start a new game
ga_recordgame, // start a new demo recording (later) ga_recordgame, // start a new demo recording (later)
ga_loadgame, // load a savegame and resume play. ga_loadgame, // load a savegame and resume play.

View File

@ -182,6 +182,12 @@ static void GameTicker()
startmainmenu(); startmainmenu();
break; break;
case ga_creditsmenu:
gi->FreeLevelData();
startmainmenu();
M_SetMenu(NAME_CreditsMenu);
break;
case ga_savegame: case ga_savegame:
// We only need this for multiplayer saves that need to go through the network. // We only need this for multiplayer saves that need to go through the network.
// gi->SaveGame(); // gi->SaveGame();

View File

@ -589,11 +589,17 @@ void DeleteScreenJob()
void RunScreenJobFrame() void RunScreenJobFrame()
{ {
// we cannot recover from this because we have no completion callback to call. // we cannot recover from this because we have no completion callback to call.
if (!runner) I_Error("Trying to run a non-existent screen job"); if (!runner)
{
// We can get here before a gameaction has been processed. In that case just draw a black screen and wait.
if (gameaction == ga_nothing) I_Error("Trying to run a non-existent screen job");
twod->ClearScreen();
return;
}
auto res = runner->RunFrame(); auto res = runner->RunFrame();
if (!res) if (!res)
{ {
assert(gamestate != GS_INTERMISSION && gamestate != GS_INTRO); assert((gamestate != GS_INTERMISSION && gamestate != GS_INTRO) || gameaction != ga_nothing);
DeleteScreenJob(); DeleteScreenJob();
} }
} }

View File

@ -337,7 +337,7 @@ void GameInterface::DrawPlayerSprite(const DVector2& origin, bool onteam)
void GameInterface::QuitToTitle() void GameInterface::QuitToTitle()
{ {
gamestate = GS_STARTUP; gameaction = ga_startup;
} }
END_DUKE_NS END_DUKE_NS