- first stage of migrating intermissions to screenjobs.

This commit is contained in:
Christoph Oelckers 2022-04-10 08:54:45 +02:00
parent d994369fd0
commit 390bf58698
15 changed files with 171 additions and 329 deletions

View file

@ -15,7 +15,6 @@ enum gamestate_t : int
GS_TITLELEVEL, // [RH] A combination of GS_LEVEL and GS_DEMOSCREEN
GS_INTRO,
GS_CUTSCENE,
GS_MENUSCREEN = GS_DEMOSCREEN,
GS_FORCEWIPE = -1,

View file

@ -240,11 +240,14 @@ void CT_Drawer (void)
if (players[consoleplayer].camera != NULL &&
(buttonMap.ButtonDown(Button_ShowScores) ||
players[consoleplayer].camera->health <= 0 ||
SB_ForceActive) &&
// Don't draw during intermission, since it has its own scoreboard in wi_stuff.cpp.
gamestate != GS_INTERMISSION)
SB_ForceActive))
{
HU_DrawScores (&players[consoleplayer]);
bool skipit = false;
if (gamestate == GS_CUTSCENE)
{
// todo: check for summary screen
}
if (!skipit) HU_DrawScores (&players[consoleplayer]);
}
if (chatmodeon)
{

View file

@ -118,6 +118,7 @@
#include "hw_clock.h"
#include "hwrenderer/scene/hw_drawinfo.h"
#include "doomfont.h"
#include "screenjob.h"
#ifdef __unix__
#include "i_system.h" // for SHARE_DIR
@ -1018,18 +1019,20 @@ void D_Display ()
End2DAndUpdate ();
return;
case GS_INTERMISSION:
WI_Drawer ();
break;
case GS_FINALE:
F_Drawer ();
break;
case GS_DEMOSCREEN:
D_PageDrawer ();
break;
case GS_CUTSCENE:
case GS_INTRO:
if (ScreenJobTick())
{
// synchronize termination with the playsim.
Net_WriteByte(DEM_ENDSCREENJOB);
}
break;
default:
break;
}
@ -1168,7 +1171,6 @@ void D_ErrorCleanup ()
{
menuactive = MENU_Off;
}
if (gamestate == GS_INTERMISSION) gamestate = GS_DEMOSCREEN;
insave = false;
ClearGlobalVMStack();
}
@ -2735,7 +2737,7 @@ static bool System_CaptureModeInGame()
case 0:
return gamestate == GS_LEVEL;
case 1:
return gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_FINALE;
return gamestate == GS_LEVEL || gamestate == GS_CUTSCENE;
case 2:
return true;
}
@ -2975,7 +2977,6 @@ extern DThinker* NextToThink;
static void GC_MarkGameRoots()
{
GC::Mark(DIntermissionController::CurrentIntermission);
GC::Mark(staticEventManager.FirstEventHandler);
GC::Mark(staticEventManager.LastEventHandler);
for (auto Level : AllLevels())
@ -3694,7 +3695,6 @@ void D_Cleanup()
G_ClearMapinfo();
M_ClearMenus(); // close menu if open
F_EndFinale(); // If an intermission is active, end it now
AM_ClearColorsets();
DeinitSWColorMaps();
FreeSBarInfoScript();

View file

@ -68,6 +68,7 @@
#include "vm.h"
#include "gstrings.h"
#include "s_music.h"
#include "screenjob.h"
EXTERN_CVAR (Int, disableautosave)
EXTERN_CVAR (Int, autosavecount)
@ -1851,7 +1852,7 @@ void TryRunTics (void)
int counts;
int numplaying;
bool doWait = (cl_capfps || pauseext || (r_NoInterpolate && !M_IsAnimated() /*&& gamestate != GS_INTERMISSION && gamestate != GS_INTRO*/));
bool doWait = (cl_capfps || pauseext || (r_NoInterpolate && !M_IsAnimated()));
// get real tics
if (doWait)
@ -2696,10 +2697,6 @@ void Net_DoCommand (int type, uint8_t **stream, int player)
players[player].MaxPitch = (double)ReadByte(stream); // down
break;
case DEM_ADVANCEINTER:
F_AdvanceIntermission();
break;
case DEM_REVERTCAMERA:
players[player].camera = players[player].mo;
break;
@ -2721,6 +2718,10 @@ void Net_DoCommand (int type, uint8_t **stream, int player)
}
break;
case DEM_ENDSCREENJOB:
EndScreenJob();
break;
default:
I_Error ("Unknown net command: %d", type);
break;

View file

@ -162,6 +162,7 @@ enum EDemoCommand
DEM_NETEVENT, // 70 String: Event name, Byte: Arg count; each arg is a 4-byte int
DEM_MDK, // 71 String: Damage type
DEM_SETINV, // 72 SetInventory
DEM_ENDSCREENJOB,
};
// The following are implemented by cht_DoCheat in m_cheat.cpp

View file

@ -1018,11 +1018,6 @@ bool G_Responder (event_t *ev)
if (!viewactive && primaryLevel->automap && primaryLevel->automap->Responder (ev, false))
return true; // automap ate it
}
else if (gamestate == GS_FINALE)
{
if (F_Responder (ev))
return true; // finale ate the event
}
switch (ev->type)
{
@ -1204,14 +1199,6 @@ void G_Ticker ()
C_AdjustBottom ();
}
if (oldgamestate != gamestate)
{
if (oldgamestate == GS_FINALE)
{
F_EndFinale ();
}
}
// get commands, check consistancy, and build new consistancy check
int buf = (gametic/ticdup)%BACKUPTICS;
@ -1294,14 +1281,6 @@ void G_Ticker ()
P_Ticker ();
break;
case GS_INTERMISSION:
WI_Ticker ();
break;
case GS_FINALE:
F_Ticker ();
break;
case GS_DEMOSCREEN:
D_PageTicker ();
break;

View file

@ -828,6 +828,114 @@ DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, SecretExitLevel, LevelLocals_SecretE
//==========================================================================
static wbstartstruct_t staticWmInfo;
DIntermissionController* FLevelLocals::CreateIntermission()
{
DIntermissionController* controller;
cluster_info_t *nextcluster;
cluster_info_t *thiscluster;
if (flags & LEVEL_CHANGEMAPCHEAT)
return nullptr;
thiscluster = FindClusterInfo (cluster);
if (strncmp (nextlevel, "enDSeQ", 6) == 0)
{
FName endsequence = ENamedName(strtoll(nextlevel.GetChars()+6, NULL, 16));
// Strife needs a special case here to choose between good and sad ending. Bad is handled elsewhere.
if (endsequence == NAME_Inter_Strife)
{
if (Players[0]->mo->FindInventory (NAME_QuestItem25) ||
Players[0]->mo->FindInventory (NAME_QuestItem28))
{
endsequence = NAME_Inter_Strife_Good;
}
else
{
endsequence = NAME_Inter_Strife_Sad;
}
}
auto ext = info->ExitMapTexts.CheckKey(flags3 & LEVEL3_EXITSECRETUSED ? NAME_Secret : NAME_Normal);
if (ext != nullptr && (ext->mDefined & FExitText::DEF_TEXT))
{
controller = F_StartFinale(ext->mDefined & FExitText::DEF_MUSIC ? ext->mMusic : gameinfo.finaleMusic,
ext->mDefined & FExitText::DEF_MUSIC ? ext->mOrder : gameinfo.finaleOrder,
-1, 0,
ext->mDefined & FExitText::DEF_BACKDROP ? ext->mBackdrop : gameinfo.FinaleFlat,
ext->mText,
false,
ext->mDefined & FExitText::DEF_PIC,
ext->mDefined & FExitText::DEF_LOOKUP,
true, endsequence);
}
else if (!(info->flags2 & LEVEL2_NOCLUSTERTEXT))
{
controller = F_StartFinale(thiscluster->MessageMusic, thiscluster->musicorder,
thiscluster->cdtrack, thiscluster->cdid,
thiscluster->FinaleFlat, thiscluster->ExitText,
thiscluster->flags & CLUSTER_EXITTEXTINLUMP,
thiscluster->flags & CLUSTER_FINALEPIC,
thiscluster->flags & CLUSTER_LOOKUPEXITTEXT,
true, endsequence);
}
}
else if (!deathmatch)
{
FExitText *ext = nullptr;
if (flags3 & LEVEL3_EXITSECRETUSED) ext = info->ExitMapTexts.CheckKey(NAME_Secret);
else if (flags3 & LEVEL3_EXITNORMALUSED) ext = info->ExitMapTexts.CheckKey(NAME_Normal);
if (ext == nullptr) ext = info->ExitMapTexts.CheckKey(nextlevel);
if (ext != nullptr)
{
if ((ext->mDefined & FExitText::DEF_TEXT))
{
controller = F_StartFinale(ext->mDefined & FExitText::DEF_MUSIC ? ext->mMusic : gameinfo.finaleMusic,
ext->mDefined & FExitText::DEF_MUSIC ? ext->mOrder : gameinfo.finaleOrder,
-1, 0,
ext->mDefined & FExitText::DEF_BACKDROP ? ext->mBackdrop : gameinfo.FinaleFlat,
ext->mText,
false,
ext->mDefined & FExitText::DEF_PIC,
ext->mDefined & FExitText::DEF_LOOKUP,
false);
}
return controller;
}
nextcluster = FindClusterInfo (FindLevelInfo (nextlevel)->cluster);
if (nextcluster->cluster != cluster && !(info->flags2 & LEVEL2_NOCLUSTERTEXT))
{
// Only start the finale if the next level's cluster is different
// than the current one and we're not in deathmatch.
if (nextcluster->EnterText.IsNotEmpty())
{
controller = F_StartFinale (nextcluster->MessageMusic, nextcluster->musicorder,
nextcluster->cdtrack, nextcluster->cdid,
nextcluster->FinaleFlat, nextcluster->EnterText,
nextcluster->flags & CLUSTER_ENTERTEXTINLUMP,
nextcluster->flags & CLUSTER_FINALEPIC,
nextcluster->flags & CLUSTER_LOOKUPENTERTEXT,
false);
}
else if (thiscluster->ExitText.IsNotEmpty())
{
controller = F_StartFinale (thiscluster->MessageMusic, thiscluster->musicorder,
thiscluster->cdtrack, nextcluster->cdid,
thiscluster->FinaleFlat, thiscluster->ExitText,
thiscluster->flags & CLUSTER_EXITTEXTINLUMP,
thiscluster->flags & CLUSTER_FINALEPIC,
thiscluster->flags & CLUSTER_LOOKUPEXITTEXT,
false);
}
}
}
return controller;
}
void G_DoCompleted (void)
{
gameaction = ga_nothing;
@ -860,9 +968,10 @@ void G_DoCompleted (void)
SN_StopAllSequences(Level);
}
// todo: create end of level screenjob
DObject* statusScreen = nullptr, *intermissionScreen = nullptr;
if (playinter)
{
gamestate = GS_INTERMISSION;
viewactive = false;
automapactive = false;
@ -870,8 +979,10 @@ void G_DoCompleted (void)
// if (statcopy)
// memcpy (statcopy, &wminfo, sizeof(wminfo));
WI_Start (&staticWmInfo);
statusScreen = WI_Start (&staticWmInfo);
}
intermissionScreen = primaryLevel->CreateIntermission();
// todo: create start of level screenjob.
}
//==========================================================================
@ -1281,10 +1392,7 @@ void FLevelLocals::DoLoadLevel(const FString &nextmapname, int position, bool au
//==========================================================================
void FLevelLocals::WorldDone (void)
{
cluster_info_t *nextcluster;
cluster_info_t *thiscluster;
{
gameaction = ga_worlddone;
@ -1294,110 +1402,11 @@ void FLevelLocals::WorldDone (void)
BotInfo.RemoveAllBots(this, consoleplayer != Net_Arbitrator);
}
if (flags & LEVEL_CHANGEMAPCHEAT)
return;
thiscluster = FindClusterInfo (cluster);
if (strncmp (nextlevel, "enDSeQ", 6) == 0)
{
FName endsequence = ENamedName(strtoll(nextlevel.GetChars()+6, NULL, 16));
// Strife needs a special case here to choose between good and sad ending. Bad is handled elsewhere.
if (endsequence == NAME_Inter_Strife)
{
if (Players[0]->mo->FindInventory (NAME_QuestItem25) ||
Players[0]->mo->FindInventory (NAME_QuestItem28))
{
endsequence = NAME_Inter_Strife_Good;
}
else
{
endsequence = NAME_Inter_Strife_Sad;
}
}
auto ext = info->ExitMapTexts.CheckKey(flags3 & LEVEL3_EXITSECRETUSED ? NAME_Secret : NAME_Normal);
if (ext != nullptr && (ext->mDefined & FExitText::DEF_TEXT))
{
F_StartFinale(ext->mDefined & FExitText::DEF_MUSIC ? ext->mMusic : gameinfo.finaleMusic,
ext->mDefined & FExitText::DEF_MUSIC ? ext->mOrder : gameinfo.finaleOrder,
-1, 0,
ext->mDefined & FExitText::DEF_BACKDROP ? ext->mBackdrop : gameinfo.FinaleFlat,
ext->mText,
false,
ext->mDefined & FExitText::DEF_PIC,
ext->mDefined & FExitText::DEF_LOOKUP,
true, endsequence);
}
else if (!(info->flags2 & LEVEL2_NOCLUSTERTEXT))
{
F_StartFinale(thiscluster->MessageMusic, thiscluster->musicorder,
thiscluster->cdtrack, thiscluster->cdid,
thiscluster->FinaleFlat, thiscluster->ExitText,
thiscluster->flags & CLUSTER_EXITTEXTINLUMP,
thiscluster->flags & CLUSTER_FINALEPIC,
thiscluster->flags & CLUSTER_LOOKUPEXITTEXT,
true, endsequence);
}
}
else if (!deathmatch)
{
FExitText *ext = nullptr;
if (flags3 & LEVEL3_EXITSECRETUSED) ext = info->ExitMapTexts.CheckKey(NAME_Secret);
else if (flags3 & LEVEL3_EXITNORMALUSED) ext = info->ExitMapTexts.CheckKey(NAME_Normal);
if (ext == nullptr) ext = info->ExitMapTexts.CheckKey(nextlevel);
if (ext != nullptr)
{
if ((ext->mDefined & FExitText::DEF_TEXT))
{
F_StartFinale(ext->mDefined & FExitText::DEF_MUSIC ? ext->mMusic : gameinfo.finaleMusic,
ext->mDefined & FExitText::DEF_MUSIC ? ext->mOrder : gameinfo.finaleOrder,
-1, 0,
ext->mDefined & FExitText::DEF_BACKDROP ? ext->mBackdrop : gameinfo.FinaleFlat,
ext->mText,
false,
ext->mDefined & FExitText::DEF_PIC,
ext->mDefined & FExitText::DEF_LOOKUP,
false);
}
return;
}
nextcluster = FindClusterInfo (FindLevelInfo (nextlevel)->cluster);
if (nextcluster->cluster != cluster && !(info->flags2 & LEVEL2_NOCLUSTERTEXT))
{
// Only start the finale if the next level's cluster is different
// than the current one and we're not in deathmatch.
if (nextcluster->EnterText.IsNotEmpty())
{
F_StartFinale (nextcluster->MessageMusic, nextcluster->musicorder,
nextcluster->cdtrack, nextcluster->cdid,
nextcluster->FinaleFlat, nextcluster->EnterText,
nextcluster->flags & CLUSTER_ENTERTEXTINLUMP,
nextcluster->flags & CLUSTER_FINALEPIC,
nextcluster->flags & CLUSTER_LOOKUPENTERTEXT,
false);
}
else if (thiscluster->ExitText.IsNotEmpty())
{
F_StartFinale (thiscluster->MessageMusic, thiscluster->musicorder,
thiscluster->cdtrack, nextcluster->cdid,
thiscluster->FinaleFlat, thiscluster->ExitText,
thiscluster->flags & CLUSTER_EXITTEXTINLUMP,
thiscluster->flags & CLUSTER_FINALEPIC,
thiscluster->flags & CLUSTER_LOOKUPEXITTEXT,
false);
}
}
}
}
}
DEFINE_ACTION_FUNCTION(FLevelLocals, WorldDone)
{
primaryLevel->WorldDone();
// This is just a dummy to make old status screens happy.
return 0;
}

View file

@ -102,6 +102,7 @@ struct EventManager;
typedef TMap<int, int> FDialogueIDMap; // maps dialogue IDs to dialogue array index (for ACS)
typedef TMap<FName, int> FDialogueMap; // maps actor class names to dialogue array index
typedef TMap<int, FUDMFKeys> FUDMFKeyMap;
class DIntermissionController;
struct FLevelLocals
{
@ -122,6 +123,7 @@ struct FLevelLocals
friend class MapLoader;
DIntermissionController* CreateIntermission();
void Tick();
void Mark();
void AddScroller(int secnum);

View file

@ -589,7 +589,7 @@ CCMD(printstats)
CCMD(finishgame)
{
bool gamestatecheck = gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_FINALE;
bool gamestatecheck = gamestate == GS_LEVEL || gamestate == GS_CUTSCENE;
if (!gamestatecheck)
{
Printf("Cannot use 'finishgame' while not in a game!\n");

View file

@ -835,8 +835,6 @@ void DIntermissionScreenScroller::Drawer ()
//
//==========================================================================
DIntermissionController *DIntermissionController::CurrentIntermission;
DIntermissionController::DIntermissionController(FIntermissionDescriptor *Desc, bool DeleteDesc, uint8_t state)
{
mDesc = Desc;
@ -932,10 +930,9 @@ bool DIntermissionController::Responder (event_t *ev)
if (mScreen->mTicker < 2) return false; // prevent some leftover events from auto-advancing
int res = mScreen->Responder(ev);
if (res == -1 && !mSentAdvance)
if (res == -1)
{
Net_WriteByte(DEM_ADVANCEINTER);
mSentAdvance = true;
mAdvance = true;
}
return !!res;
}
@ -995,7 +992,6 @@ void DIntermissionController::OnDestroy ()
if (mScreen != NULL) mScreen->Destroy();
if (mDeleteDesc) delete mDesc;
mDesc = NULL;
if (CurrentIntermission == this) CurrentIntermission = NULL;
}
@ -1005,28 +1001,25 @@ void DIntermissionController::OnDestroy ()
//
//==========================================================================
void F_StartIntermission(FIntermissionDescriptor *desc, bool deleteme, uint8_t state)
DIntermissionController* F_StartIntermission(FIntermissionDescriptor *desc, bool deleteme, uint8_t state)
{
ScaleOverrider s(twod);
if (DIntermissionController::CurrentIntermission != NULL)
{
DIntermissionController::CurrentIntermission->Destroy();
}
S_StopAllChannels ();
gameaction = ga_nothing;
gamestate = GS_FINALE;
if (state == FSTATE_InLevel) wipegamestate = GS_FINALE; // don't wipe when within a level.
viewactive = false;
automapactive = false;
DIntermissionController::CurrentIntermission = Create<DIntermissionController>(desc, deleteme, state);
auto CurrentIntermission = Create<DIntermissionController>(desc, deleteme, state);
// If the intermission finishes straight away then cancel the wipe.
if (!DIntermissionController::CurrentIntermission->NextPage())
if (!CurrentIntermission->NextPage())
{
wipegamestate = GS_FINALE;
CurrentIntermission->Destroy();
}
GC::WriteBarrier(DIntermissionController::CurrentIntermission);
GC::WriteBarrier(CurrentIntermission);
return CurrentIntermission;
}
@ -1036,12 +1029,12 @@ void F_StartIntermission(FIntermissionDescriptor *desc, bool deleteme, uint8_t s
//
//==========================================================================
void F_StartIntermission(FName seq, uint8_t state)
DIntermissionController* F_StartIntermission(FName seq, uint8_t state)
{
FIntermissionDescriptor **pdesc = IntermissionDescriptors.CheckKey(seq);
if (pdesc == nullptr)
{
gameaction = ga_nothing;
return nullptr;
}
else
{
@ -1049,83 +1042,6 @@ void F_StartIntermission(FName seq, uint8_t state)
}
}
//==========================================================================
//
// Called by main loop.
//
//==========================================================================
bool F_Responder (event_t* ev)
{
ScaleOverrider s(twod);
if (DIntermissionController::CurrentIntermission != NULL)
{
return DIntermissionController::CurrentIntermission->Responder(ev);
}
return false;
}
//==========================================================================
//
// Called by main loop.
//
//==========================================================================
void F_Ticker ()
{
ScaleOverrider s(twod);
if (DIntermissionController::CurrentIntermission != NULL)
{
DIntermissionController::CurrentIntermission->Ticker();
}
}
//==========================================================================
//
// Called by main loop.
//
//==========================================================================
void F_Drawer ()
{
ScaleOverrider s(twod);
if (DIntermissionController::CurrentIntermission != NULL)
{
DIntermissionController::CurrentIntermission->Drawer();
}
}
//==========================================================================
//
// Called by main loop.
//
//==========================================================================
void F_EndFinale ()
{
if (DIntermissionController::CurrentIntermission != NULL)
{
DIntermissionController::CurrentIntermission->Destroy();
DIntermissionController::CurrentIntermission = NULL;
}
}
//==========================================================================
//
// Called by net loop.
//
//==========================================================================
void F_AdvanceIntermission()
{
ScaleOverrider s(twod);
if (DIntermissionController::CurrentIntermission != NULL)
{
DIntermissionController::CurrentIntermission->mAdvance = true;
}
}
#include "c_dispatch.h"
CCMD(measureintermissions)

View file

@ -299,8 +299,6 @@ class DIntermissionController : public DObject
uint8_t mGameState;
int mIndex;
bool NextPage();
public:
static DIntermissionController *CurrentIntermission;
@ -309,23 +307,18 @@ public:
void Ticker ();
void Drawer ();
void OnDestroy() override;
bool NextPage();
friend void F_AdvanceIntermission();
friend void F_StartIntermission(FIntermissionDescriptor *, bool, uint8_t);
friend DIntermissionController* F_StartIntermission(FIntermissionDescriptor *, bool, uint8_t);
};
// Interface for main loop
bool F_Responder (event_t* ev);
void F_Ticker ();
void F_Drawer ();
void F_StartIntermission(FIntermissionDescriptor *desc, bool deleteme, uint8_t state);
void F_StartIntermission(FName desc, uint8_t state);
void F_EndFinale ();
void F_AdvanceIntermission();
DIntermissionController* F_StartIntermission(FIntermissionDescriptor *desc, bool deleteme, uint8_t state);
DIntermissionController* F_StartIntermission(FName desc, uint8_t state);
// Create an intermission from old cluster data
void F_StartFinale (const char *music, int musicorder, int cdtrack, unsigned int cdid, const char *flat,
DIntermissionController* F_StartFinale (const char *music, int musicorder, int cdtrack, unsigned int cdid, const char *flat,
const char *text, INTBOOL textInLump, INTBOOL finalePic, INTBOOL lookupText,
bool ending, FName endsequence = NAME_None);

View file

@ -849,7 +849,7 @@ FName FMapInfoParser::CheckEndSequence()
//
//==========================================================================
void F_StartFinale (const char *music, int musicorder, int cdtrack, unsigned int cdid, const char *flat,
DIntermissionController* F_StartFinale (const char *music, int musicorder, int cdtrack, unsigned int cdid, const char *flat,
const char *text, INTBOOL textInLump, INTBOOL finalePic, INTBOOL lookupText,
bool ending, FName endsequence)
{
@ -909,16 +909,17 @@ void F_StartFinale (const char *music, int musicorder, int cdtrack, unsigned int
desc->mActions.Push(wiper);
}
F_StartIntermission(desc, true, ending? FSTATE_EndingGame : FSTATE_ChangingLevel);
return F_StartIntermission(desc, true, ending? FSTATE_EndingGame : FSTATE_ChangingLevel);
}
else if (ending)
{
FIntermissionDescriptor **pdesc = IntermissionDescriptors.CheckKey(endsequence);
if (pdesc != NULL)
{
F_StartIntermission(*pdesc, false, ending? FSTATE_EndingGame : FSTATE_ChangingLevel);
return F_StartIntermission(*pdesc, false, ending? FSTATE_EndingGame : FSTATE_ChangingLevel);
}
}
return nullptr;
}
@ -952,5 +953,6 @@ CCMD(testfinale)
return;
}
F_StartFinale(gameinfo.finaleMusic, gameinfo.finaleOrder, -1, 0, gameinfo.FinaleFlat, text, false, false, true, true);
auto controller = F_StartFinale(gameinfo.finaleMusic, gameinfo.finaleOrder, -1, 0, gameinfo.FinaleFlat, text, false, false, true, true);
// todo: play it
}

View file

@ -155,7 +155,7 @@ CVAR (Int, bot_next_color, 11, 0)
CCMD (addbot)
{
if (gamestate != GS_LEVEL && gamestate != GS_INTERMISSION)
if (gamestate != GS_LEVEL)
{
Printf ("Bots cannot be added when not in a game!\n");
return;

View file

@ -708,66 +708,13 @@ DEFINE_ACTION_FUNCTION(DInterBackground, drawBackground)
IMPLEMENT_CLASS(DInterBackground, true, false)
DObject *WI_Screen;
//====================================================================
//
//
//
//====================================================================
void WI_Ticker()
{
if (WI_Screen)
{
ScaleOverrider s(twod);
IFVIRTUALPTRNAME(WI_Screen, "StatusScreen", Ticker)
{
VMValue self = WI_Screen;
VMCall(func, &self, 1, nullptr, 0);
}
}
}
//====================================================================
//
// Called by main loop,
// draws the intermission directly into the screen buffer.
//
//====================================================================
void WI_Drawer()
{
if (WI_Screen)
{
ScaleOverrider s(twod);
IFVIRTUALPTRNAME(WI_Screen, "StatusScreen", Drawer)
{
twod->ClearClipRect();
twod->ClearScreen();
VMValue self = WI_Screen;
VMCall(func, &self, 1, nullptr, 0);
twod->ClearClipRect(); // make sure the scripts don't leave a valid clipping rect behind.
// The internal handling here is somewhat poor. After being set to 'LeavingIntermission'
// the screen is needed for one more draw operation so we cannot delete it right away but only here.
if (WI_Screen->IntVar("CurState") == LeavingIntermission)
{
WI_Screen->Destroy();
GC::DelSoftRoot(WI_Screen);
WI_Screen = nullptr;
}
}
}
}
//====================================================================
//
// Setup for an intermission screen.
//
//====================================================================
void WI_Start(wbstartstruct_t *wbstartstruct)
DObject* WI_Start(wbstartstruct_t *wbstartstruct)
{
FName screenclass = deathmatch ? gameinfo.statusscreen_dm : multiplayer ? gameinfo.statusscreen_coop : gameinfo.statusscreen_single;
auto cls = PClass::FindClass(screenclass);
@ -784,7 +731,7 @@ void WI_Start(wbstartstruct_t *wbstartstruct)
}
}
WI_Screen = cls->CreateNew();
auto WI_Screen = cls->CreateNew();
ScaleOverrider s(twod);
@ -814,7 +761,7 @@ void WI_Start(wbstartstruct_t *wbstartstruct)
}
}
GC::AddSoftRoot(WI_Screen);
return WI_Screen;
}
//====================================================================

View file

@ -81,17 +81,7 @@ struct wbstartstruct_t
};
// Intermission stats.
// Parameters for world map / intermission.
// Called by main loop, animate the intermission.
void WI_Ticker ();
// Called by main loop,
// draws the intermission directly into the screen buffer.
void WI_Drawer ();
// Setup for an intermission screen.
void WI_Start (wbstartstruct_t *wbstartstruct);
DObject* WI_Start (wbstartstruct_t *wbstartstruct);
#endif