mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-10 14:51:40 +00:00
- added cutscene creation code
This commit is contained in:
parent
ea007f56f2
commit
99d98cf79d
6 changed files with 106 additions and 7 deletions
|
@ -98,6 +98,7 @@ enum gameaction_t : int
|
|||
ga_resumeconversation,
|
||||
ga_intro,
|
||||
ga_intermission,
|
||||
ga_titleloop,
|
||||
};
|
||||
|
||||
extern gameaction_t gameaction;
|
||||
|
|
|
@ -136,7 +136,7 @@ void DrawHUD();
|
|||
void D_DoAnonStats();
|
||||
void I_DetectOS();
|
||||
void UpdateGenericUI(bool cvar);
|
||||
|
||||
void Local_Job_Init();
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
|
@ -306,6 +306,7 @@ CUSTOM_CVAR(Int, I_FriendlyWindowTitle, 1, CVAR_GLOBALCONFIG|CVAR_ARCHIVE|CVAR_N
|
|||
{
|
||||
I_UpdateWindowTitle();
|
||||
}
|
||||
CVAR(Bool, cl_nointros, false, CVAR_ARCHIVE)
|
||||
|
||||
|
||||
bool hud_toggled = false;
|
||||
|
@ -3371,6 +3372,7 @@ static int D_InitGame(const FIWADInfo* iwad_info, TArray<FString>& allwads, TArr
|
|||
twod->End();
|
||||
UpdateJoystickMenu(NULL);
|
||||
UpdateVRModes();
|
||||
Local_Job_Init();
|
||||
|
||||
v = Args->CheckValue ("-loadgame");
|
||||
if (v)
|
||||
|
@ -3417,7 +3419,16 @@ static int D_InitGame(const FIWADInfo* iwad_info, TArray<FString>& allwads, TArr
|
|||
}
|
||||
else
|
||||
{
|
||||
D_StartTitle(); // start up intro loop
|
||||
if (multiplayer || cl_nointros || Args->CheckParm("-nointro"))
|
||||
{
|
||||
D_StartTitle();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!StartCutscene(gameinfo.IntroScene, SJ_BLOCKUI, [=](bool) {
|
||||
gameaction = ga_titleloop;
|
||||
})) D_StartTitle();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (demorecording)
|
||||
|
|
|
@ -1198,6 +1198,9 @@ void G_Ticker ()
|
|||
gamestate = GS_CUTSCENE;
|
||||
gameaction = ga_nothing;
|
||||
break;
|
||||
case ga_titleloop:
|
||||
D_StartTitle();
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
|
@ -3077,7 +3080,7 @@ void G_StartSlideshow(FLevelLocals *Level, FName whichone)
|
|||
{
|
||||
auto SelectedSlideshow = whichone == NAME_None ? Level->info->slideshow : whichone;
|
||||
auto slide = F_StartIntermission(SelectedSlideshow);
|
||||
RunIntermission(slide, nullptr, [](bool)
|
||||
RunIntermission(nullptr, nullptr, slide, nullptr, [](bool)
|
||||
{
|
||||
primaryLevel->SetMusic();
|
||||
gamestate = GS_LEVEL;
|
||||
|
|
|
@ -107,7 +107,8 @@ class FBaseCVar;
|
|||
FBaseCVar* G_GetUserCVar(int playernum, const char* cvarname);
|
||||
|
||||
class DIntermissionController;
|
||||
void RunIntermission(DIntermissionController* intermissionScreen, DObject* statusScreen, std::function<void(bool)> completionf);
|
||||
struct level_info_t;
|
||||
void RunIntermission(level_info_t* oldlevel, level_info_t* newlevel, DIntermissionController* intermissionScreen, DObject* statusScreen, std::function<void(bool)> completionf);
|
||||
|
||||
extern const AActor *SendItemUse, *SendItemDrop;
|
||||
extern int SendItemDropAmount;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
@ -949,6 +1009,20 @@ void RunIntermission(DIntermissionController* intermissionScreen, DObject* statu
|
|||
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();
|
||||
|
|
|
@ -955,6 +955,6 @@ CCMD(testfinale)
|
|||
}
|
||||
|
||||
auto controller = F_StartFinale(gameinfo.finaleMusic, gameinfo.finaleOrder, -1, 0, gameinfo.FinaleFlat, text, false, false, true, true);
|
||||
RunIntermission(controller, nullptr, [=](bool) { gameaction = ga_nothing; });
|
||||
RunIntermission(nullptr, nullptr, controller, nullptr, [=](bool) { gameaction = ga_nothing; });
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue