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

View file

@ -46,16 +46,9 @@ struct INICHAIN {
extern INICHAIN *pINIChain;
extern MapRecord* gStartNewGame;
extern int gNetPlayers;
extern bool gRestartGame;
extern int blood_globalflags;
extern bool gSavingGame;
extern bool gQuitGame;
extern int gQuitRequest;
void QuitGame(void);
void PreloadCache(void);
void StartLevel(MapRecord *gameOptions);
@ -101,6 +94,10 @@ struct GameInterface : ::GameInterface
void Startup() override;
void Render() 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;
};

View file

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

View file

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

View file

@ -164,24 +164,17 @@ class DBloodSummaryScreen : public DScreenJob
}
};
void ShowSummaryScreen()
void GameInterface::LevelCompleted(MapRecord *map, int skill)
{
JobDesc job = { Create<DBloodSummaryScreen>() };
STAT_Update(false);
EndLevel();
Mus_Stop();
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();
gameaction = ga_nextlevel;
});
}
}
CKillMgr::CKillMgr()

View file

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

View file

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

View file

@ -35,6 +35,14 @@ BEGIN_BLD_NS
#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 {
unsigned char nGameType;
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;
static int parseArgs(char *pzArgs, int *nArg1, int *nArg2)
@ -434,7 +428,10 @@ static bool cheatMario(cheatseq_t* c)
{
int nEpisode, nLevel;
if (parseArgs((char*)c->Args, &nEpisode, &nLevel) == 2)
LevelWarp(nEpisode, nLevel);
{
auto map = FindMapByLevelNum(levelnum(nEpisode, nLevel));
if (map) DeferedStartGame(map, -1);
}
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.
void levelEndLevelCustom(int nLevel) {
gGameOptions.uGameFlags |= 1;
gGameOptions.uGameFlags |= GF_AdvanceLevel;
if (nLevel >= 16 || nLevel < 0) {
gGameOptions.uGameFlags |= 2;
gGameOptions.uGameFlags |= GF_EndGame;
return;
}

View file

@ -38,53 +38,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
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)
{
if (parm->numparms < 3 || parm->numparms > 5)
@ -160,8 +113,6 @@ static int osdcmd_show_weapon(CCmdFuncPtr parm)
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("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);

View file

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

View file

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

View file

@ -26,6 +26,7 @@ enum gameaction_t : int
ga_nothing,
ga_startup, // go back to intro 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_recordgame, // start a new demo recording (later)
ga_loadgame, // load a savegame and resume play.

View file

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

View file

@ -589,11 +589,17 @@ void DeleteScreenJob()
void RunScreenJobFrame()
{
// 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();
if (!res)
{
assert(gamestate != GS_INTERMISSION && gamestate != GS_INTRO);
assert((gamestate != GS_INTERMISSION && gamestate != GS_INTRO) || gameaction != ga_nothing);
DeleteScreenJob();
}
}

View file

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