- fixed the design by merging the episode start handler into ShowIntermission.

Tying the start-of-episode cutscene to the cluster does not really work because it gets triggered by all maps of the cluster.
All currently existing intro cutscenes are tied to the map anyway.
Also correcting transition movie name for RRRA E2L1.
This commit is contained in:
Christoph Oelckers 2021-04-28 01:15:15 +02:00
parent cdccdec3e7
commit 869dbd70e5
9 changed files with 58 additions and 67 deletions

View file

@ -133,6 +133,18 @@ void G_BuildTiccmd(ticcmd_t* cmd)
//==========================================================================
bool newGameStarted;
void NewGame(MapRecord* map, int skill, bool ns = false)
{
newGameStarted = true;
ShowIntermission(nullptr, map, nullptr, [=](bool) { gi->NewGame(map, skill, ns); });
}
//==========================================================================
//
//
//
//==========================================================================
static void GameTicker()
{
int i;
@ -159,7 +171,6 @@ static void GameTicker()
FX_SetReverb(0);
gi->FreeLevelData();
gameaction = ga_level;
newGameStarted = true;
NewGame(g_nextmap, -1);
BackupSaveGame = "";
}
@ -197,7 +208,6 @@ static void GameTicker()
C_FlushDisplay();
gameaction = ga_level;
BackupSaveGame = "";
newGameStarted = true;
NewGame(g_nextmap, g_nextskill, ga == ga_newgamenostopsound);
break;
@ -648,7 +658,6 @@ void MainLoop ()
userConfig.CommandMap = "";
if (maprecord)
{
newGameStarted = true;
NewGame(maprecord, /*userConfig.skill*/2); // todo: fix the skill.
}
}

View file

@ -53,9 +53,10 @@ struct CutsceneDef
FString function;
int sound = 0;
int framespersec = 0; // only relevant for ANM.
bool transitiononly = false; // only play when transitioning between maps, but not when starting on a map or ending a game.
void Create(DObject* runner);
bool Create(DObject* runner, MapRecord* map);
bool Create(DObject* runner, MapRecord* map, bool transition);
};
struct GlobalCutscenes

View file

@ -64,6 +64,7 @@ static void parseCutscene(FScanner& sc, CutsceneDef& cdef)
else if (sc.Compare("function")) { sc.GetString(cdef.function); cdef.video = ""; }
else if (sc.Compare("sound")) sc.GetString(sound);
else if (sc.Compare("fps")) sc.GetNumber(cdef.framespersec);
else if (sc.Compare("transitiononly")) cdef.transitiononly = true;
else if (sc.Compare("clear")) { cdef.function = "none"; cdef.video = ""; } // this means 'play nothing', not 'not defined'.
}
if (sound.IsNotEmpty())

View file

@ -212,8 +212,9 @@ void CutsceneDef::Create(DObject* runner)
//
//=============================================================================
bool CutsceneDef::Create(DObject* runner, MapRecord* map)
bool CutsceneDef::Create(DObject* runner, MapRecord* map, bool transition)
{
if (!transition && transitiononly) return false;
if (function.CompareNoCase("none") == 0)
return true; // play nothing but return as being validated
if (function.IsNotEmpty())
@ -440,43 +441,6 @@ void ShowScoreboard(int numplayers, const CompletionFunc& completion_)
gameaction = ga_intermission;
}
//==========================================================================
//
//
//
//==========================================================================
void NewGame(MapRecord* map, int skill, bool ns)
{
completion = [=](bool) { gi->NewGame(map, skill, ns); };
runner = CreateRunner();
GC::WriteBarrier(runner);
try
{
int volume = map->cluster - 1;
if (volume >= 0 && volume < MAXVOLUMES)
volumeList[volume].intro.Create(runner);
globalCutscenes.LoadingScreen.Create(runner, map);
if (!ScreenJobValidate())
{
runner->Destroy();
runner = nullptr;
completion(false);
completion = nullptr;
return;
}
gameaction = ga_intermission;
}
catch (...)
{
if (runner) runner->Destroy();
runner = nullptr;
throw;
}
}
//---------------------------------------------------------------------------
//
//
@ -489,26 +453,42 @@ void ShowIntermission(MapRecord* fromMap, MapRecord* toMap, SummaryInfo* info, C
runner = CreateRunner();
GC::WriteBarrier(runner);
// retrieve cluster relations for cluster-based cutscenes.
int fromcluster = -1, tocluster = -1;
if (fromMap)
{
fromcluster = fromMap->cluster - 1;
if (fromcluster < 0 || fromcluster >= MAXVOLUMES) fromcluster = -1;
}
if (toMap)
{
tocluster = toMap->cluster - 1;
if (tocluster < 0 || tocluster >= MAXVOLUMES) tocluster = -1;
}
if (fromcluster == tocluster) fromcluster = tocluster = -1;
try
{
// outro: first check the map's own outro.
// if that is empty, check the cluster's outro
// if that also fails, check the default outro
if (!fromMap->outro.Create(runner, fromMap))
if (fromMap)
{
auto& cluster = volumeList[fromMap->cluster - 1];
if ((toMap == nullptr || toMap->cluster != fromMap->cluster) && !cluster.outro.Create(runner, fromMap))
globalCutscenes.DefaultMapOutro.Create(runner, fromMap);
}
if (!fromMap->outro.Create(runner, fromMap, !!toMap))
{
if (fromcluster != -1 && !volumeList[fromcluster].outro.Create(runner, fromMap, !!toMap))
globalCutscenes.DefaultMapOutro.Create(runner, fromMap, !!toMap);
}
CallCreateSummaryFunction(globalCutscenes.SummaryScreen, runner, fromMap, info);
CallCreateSummaryFunction(globalCutscenes.SummaryScreen, runner, fromMap, info);
}
if (toMap)
{
if (!toMap->intro.Create(runner, toMap))
globalCutscenes.DefaultMapIntro.Create(runner, toMap);
globalCutscenes.LoadingScreen.Create(runner, toMap);
if (!toMap->intro.Create(runner, toMap, !!fromMap))
{
if (tocluster != -1 && !volumeList[tocluster].intro.Create(runner, toMap, !!fromMap))
globalCutscenes.DefaultMapIntro.Create(runner, toMap, !!fromMap);
}
globalCutscenes.LoadingScreen.Create(runner, toMap, true);
}
else if (isShareware())
{
@ -555,11 +535,6 @@ CCMD(testcutscene)
/*
Duke:
if (!userConfig.nologo) fi.ShowLogo([](bool) { gameaction = ga_mainmenunostopsound; });
else gameaction = ga_mainmenunostopsound;
Blood:
if (!userConfig.nologo && gGameOptions.nGameType == 0) playlogos();
else

View file

@ -28,4 +28,3 @@ bool StartCutscene(const char* s, int flags, const CompletionFunc& completion);
void PlayLogos(gameaction_t complete_ga, gameaction_t def_ga, bool stopmusic);
void ShowScoreboard(int numplayers, const CompletionFunc& completion_);
void ShowIntermission(MapRecord* fromMap, MapRecord* toMap, SummaryInfo* info, CompletionFunc completion_);
void NewGame(MapRecord* map, int skill, bool ns = false);

View file

@ -1,6 +1,8 @@
// names for everything that gets accessed by scripts.
x(MENUBAR, 2038)
x(BackTile, 253)
x(Monolithscreen, 2050)
x(GTIScreen, 2052)
x(CrosshairTile, 2319)
x(LoadScreen, 2049)

View file

@ -31,10 +31,6 @@ definecutscene episode 3
definecutscene episode 4
{
intro
{
function DukeCutscenes.BuildE4Intro
}
outro
{
function DukeCutscenes.BuildE4End
@ -49,6 +45,14 @@ definecutscene episode 5
}
}
definecutscene map e4l1
{
intro
{
function DukeCutscenes.BuildE4Intro
}
}
definecutscene sharewareend
{
function DukeCutscenes.BuildSharewareEnd

View file

@ -25,6 +25,7 @@ definecutscene episode 2
definecutscene mapintro
{
function RRCutscenes.BuildMapIntro // this plays the 'travel' animation.
transitiononly
}
definecutscene loading

View file

@ -352,11 +352,10 @@ class RRCutscenes
if (!raze.isRRRA()) return;
int ln = map.levelnumber;
if (ln == 0) return;
if (ln > 1000) ln -= 1000-7;
if (ln >= 1000) ln -= 1000-7;
let fn = String.Format("lvl%d.anm", ln);
Array<int> soundinfo;
runner.Append(MoviePlayerJob.CreateWithSoundinfo(fn, soundinfo, 0, 20, 20, 7200)); // wait for one minute on the final frame so that the video doesn't stop before the user notices.
}
}