- added cutscene creation code
This commit is contained in:
parent
ea007f56f2
commit
99d98cf79d
6 changed files with 106 additions and 7 deletions
|
|
@ -83,9 +83,11 @@
|
|||
#include "stringtable.h"
|
||||
#include "c_buttons.h"
|
||||
#include "screenjob.h"
|
||||
#include "types.h"
|
||||
|
||||
#include "gi.h"
|
||||
|
||||
|
||||
#include "g_hub.h"
|
||||
#include "g_levellocals.h"
|
||||
#include "actorinlines.h"
|
||||
|
|
@ -178,6 +180,7 @@ void *statcopy; // for statistics driver
|
|||
FLevelLocals level; // info about current level
|
||||
FLevelLocals *primaryLevel = &level; // level for which to display the user interface.
|
||||
FLevelLocals *currentVMLevel = &level; // level which currently ticks. Used as global input to the VM and some functions called by it.
|
||||
static PType* maprecordtype;
|
||||
|
||||
|
||||
//==========================================================================
|
||||
|
|
@ -938,7 +941,64 @@ DIntermissionController* FLevelLocals::CreateIntermission()
|
|||
return controller;
|
||||
}
|
||||
|
||||
void RunIntermission(DIntermissionController* intermissionScreen, DObject* statusScreen, std::function<void(bool)> completionf)
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
void Local_Job_Init()
|
||||
{
|
||||
maprecordtype = NewPointer(NewStruct("MapRecord", nullptr, true));
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
static void CallCreateMapFunction(const char* qname, DObject* runner, level_info_t* map)
|
||||
{
|
||||
auto func = LookupFunction(qname);
|
||||
if (func->Proto->ArgumentTypes.Size() == 1) return CallCreateFunction(qname, runner); // accept functions without map parameter as well here.
|
||||
if (func->Proto->ArgumentTypes.Size() != 2) I_Error("Bad map-cutscene function %s. Must receive precisely two arguments.", qname);
|
||||
if (func->Proto->ArgumentTypes[0] != runnerclasstype && func->Proto->ArgumentTypes[1] != maprecordtype)
|
||||
I_Error("Bad cutscene function %s. Must receive ScreenJobRunner and LevelInfo reference.", qname);
|
||||
VMValue val[2] = { runner, map };
|
||||
VMCall(func, val, 2, nullptr, 0);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
bool CreateCutscene(CutsceneDef* cs, DObject* runner, level_info_t* map)
|
||||
{
|
||||
if (cs->function.CompareNoCase("none") == 0)
|
||||
return true; // play nothing but return as being validated
|
||||
if (cs->function.IsNotEmpty())
|
||||
{
|
||||
CallCreateMapFunction(cs->function, runner, map);
|
||||
return true;
|
||||
}
|
||||
else if (cs->video.IsNotEmpty())
|
||||
{
|
||||
AddGenericVideo(runner, cs->video, cs->GetSound(), cs->framespersec);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
void RunIntermission(level_info_t* fromMap, level_info_t* toMap, DIntermissionController* intermissionScreen, DObject* statusScreen, std::function<void(bool)> completionf)
|
||||
{
|
||||
if (!intermissionScreen && !statusScreen)
|
||||
{
|
||||
|
|
@ -948,6 +1008,20 @@ void RunIntermission(DIntermissionController* intermissionScreen, DObject* statu
|
|||
runner = CreateRunner(false);
|
||||
GC::WriteBarrier(runner);
|
||||
completion = std::move(completionf);
|
||||
|
||||
// retrieve cluster relations for cluster-based cutscenes.
|
||||
cluster_info_t* fromcluster = nullptr, *tocluster = nullptr;
|
||||
if (fromMap) fromcluster = FindClusterInfo(fromMap->cluster);
|
||||
if (toMap) tocluster = FindClusterInfo(toMap->cluster);
|
||||
if (fromcluster == tocluster) fromcluster = tocluster = nullptr;
|
||||
|
||||
if (fromMap)
|
||||
{
|
||||
if (!CreateCutscene(&fromMap->outro, runner, fromMap))
|
||||
{
|
||||
if (fromcluster != nullptr) CreateCutscene(&fromcluster->outro, runner, fromMap);
|
||||
}
|
||||
}
|
||||
|
||||
auto func = LookupFunction("DoomCutscenes.BuildMapTransition");
|
||||
if (func == nullptr)
|
||||
|
|
@ -957,6 +1031,14 @@ void RunIntermission(DIntermissionController* intermissionScreen, DObject* statu
|
|||
VMValue val[3] = { runner, intermissionScreen, statusScreen };
|
||||
VMCall(func, val, 3, nullptr, 0);
|
||||
|
||||
if (toMap)
|
||||
{
|
||||
if (!CreateCutscene(&toMap->intro, runner, toMap))
|
||||
{
|
||||
if (tocluster != nullptr) CreateCutscene(&tocluster->intro, runner, toMap);
|
||||
}
|
||||
}
|
||||
|
||||
if (!ScreenJobValidate())
|
||||
{
|
||||
DeleteScreenJob();
|
||||
|
|
@ -1012,7 +1094,8 @@ void G_DoCompleted (void)
|
|||
}
|
||||
bool endgame = strncmp(nextlevel, "enDSeQ", 6) == 0;
|
||||
intermissionScreen = primaryLevel->CreateIntermission();
|
||||
RunIntermission(intermissionScreen, statusScreen, [=](bool)
|
||||
auto nextinfo = endgame? nullptr : FindLevelInfo(nextlevel, false);
|
||||
RunIntermission(primaryLevel->info, nextinfo, intermissionScreen, statusScreen, [=](bool)
|
||||
{
|
||||
if (!endgame) primaryLevel->WorldDone();
|
||||
else D_StartTitle();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue