mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-27 20:20:40 +00:00
- added the data structures to hold the cutscene data.
This commit is contained in:
parent
57853bf8fe
commit
e05f900315
16 changed files with 267 additions and 71 deletions
|
@ -207,7 +207,7 @@ enum scripttoken_t
|
|||
T_RFFDEFINEID,
|
||||
T_EXTRA,
|
||||
T_ROTATE,
|
||||
T_SURFACE, T_VIEW,
|
||||
T_SURFACE, T_VIEW, T_MAP, T_DEFINECUTSCENE,
|
||||
};
|
||||
|
||||
static int32_t lastmodelid = -1, lastvoxid = -1, modelskin = -1, lastmodelskin = -1, seenframe = 0;
|
||||
|
@ -360,6 +360,8 @@ static int32_t defsparser(scriptfile *script)
|
|||
{ "shadefactor", T_SHADEFACTOR },
|
||||
{ "newgamechoices", T_NEWGAMECHOICES },
|
||||
{ "rffdefineid", T_RFFDEFINEID }, // dummy
|
||||
{ "map", T_MAP },
|
||||
{ "definecutscene", T_DEFINECUTSCENE },
|
||||
};
|
||||
|
||||
script->SetNoOctals(true);
|
||||
|
@ -376,6 +378,9 @@ static int32_t defsparser(scriptfile *script)
|
|||
auto pos = scriptfile_getposition(script);
|
||||
switch (tokn)
|
||||
{
|
||||
case T_DEFINECUTSCENE:
|
||||
parseDefineCutscene(*script, pos);
|
||||
break;
|
||||
case T_ERROR:
|
||||
pos.Message(MSG_ERROR, "Unknown error");
|
||||
break;
|
||||
|
|
|
@ -1287,6 +1287,42 @@ void FScanner::AddSymbol(const char* name, double value)
|
|||
symbols.Insert(name, sym);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int FScanner::StartBraces(FScanner::SavedPos* braceend)
|
||||
{
|
||||
if (CheckString("{"))
|
||||
{
|
||||
auto here = SavePos();
|
||||
SkipToEndOfBlock();
|
||||
*braceend = SavePos();
|
||||
RestorePos(here);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ScriptError("'{' expected");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool FScanner::FoundEndBrace(FScanner::SavedPos& braceend)
|
||||
{
|
||||
auto here = SavePos();
|
||||
return here.SavedScriptPtr >= braceend.SavedScriptPtr;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// a class that remembers a parser position
|
||||
|
|
|
@ -94,6 +94,8 @@ public:
|
|||
inline void AddSymbol(const char* name, uint32_t value) { return AddSymbol(name, uint64_t(value)); }
|
||||
void AddSymbol(const char* name, double value);
|
||||
void SkipToEndOfBlock();
|
||||
int StartBraces(FScanner::SavedPos* braceend);
|
||||
bool FoundEndBrace(FScanner::SavedPos& braceend);
|
||||
|
||||
static FString TokenName(int token, const char *string=NULL);
|
||||
|
||||
|
@ -120,7 +122,30 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
bool GetNumber(int64_t& var, bool evaluate = false)
|
||||
{
|
||||
if (!GetNumber(evaluate)) return false;
|
||||
var = BigNumber;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GetString(FString& var)
|
||||
{
|
||||
if (!GetString()) return false;
|
||||
var = String;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GetFloat(bool evaluate = false);
|
||||
|
||||
bool GetFloat(double& var, bool evaluate = false)
|
||||
{
|
||||
if (!GetFloat(evaluate)) return false;
|
||||
var = Float;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void MustGetFloat(bool evaluate = false);
|
||||
bool CheckFloat(bool evaluate = false);
|
||||
|
||||
|
|
|
@ -599,15 +599,16 @@ void SetDefaultStrings()
|
|||
if ((g_gameType & GAMEFLAG_DUKE) && fileSystem.FindFile("E4L1.MAP") < 0)
|
||||
{
|
||||
// Pre-Atomic releases do not define this.
|
||||
gVolumeNames[0] = "$L.A. Meltdown";
|
||||
gVolumeNames[1] = "$Lunar Apocalypse";
|
||||
gVolumeNames[2] = "$Shrapnel City";
|
||||
if (g_gameType & GAMEFLAG_SHAREWARE) gVolumeNames[3] = "$The Birth";
|
||||
volumeList[0].name = "$L.A. Meltdown";
|
||||
volumeList[1].name = "$Lunar Apocalypse";
|
||||
volumeList[2].name = "$Shrapnel City";
|
||||
if (g_gameType & GAMEFLAG_SHAREWARE) volumeList[3].name = "$The Birth";
|
||||
gSkillNames[0] = "$Piece of Cake";
|
||||
gSkillNames[1] = "$Let's Rock";
|
||||
gSkillNames[2] = "$Come get Some";
|
||||
gSkillNames[3] = "$Damn I'm Good";
|
||||
}
|
||||
if (g_gameType & GAMEFLAG_RR) volumeList[0].flags |= EF_GOTONEXTVOLUME;
|
||||
// Blood hard codes its skill names, so we have to define them manually.
|
||||
if (isBlood())
|
||||
{
|
||||
|
|
|
@ -41,30 +41,28 @@
|
|||
#include "raze_sound.h"
|
||||
|
||||
FString gSkillNames[MAXSKILLS];
|
||||
FString gVolumeNames[MAXVOLUMES];
|
||||
FString gVolumeSubtitles[MAXVOLUMES];
|
||||
int32_t gVolumeFlags[MAXVOLUMES];
|
||||
int gDefaultVolume = 0, gDefaultSkill = 1;
|
||||
|
||||
MapRecord mapList[512]; // Due to how this gets used it needs to be static. EDuke defines 7 episode plus one spare episode with 64 potential levels each and relies on the static array which is freely accessible by scripts.
|
||||
MapRecord *currentLevel; // level that is currently played. (The real level, not what script hacks modfifying the current level index can pretend.)
|
||||
GlobalCutscenes globalCutscenes;
|
||||
VolumeRecord volumeList[MAXVOLUMES];
|
||||
TArray<MapRecord> mapList;
|
||||
MapRecord *currentLevel; // level that is currently played.
|
||||
MapRecord* lastLevel; // Same here, for the last level.
|
||||
unsigned int numUsedSlots;
|
||||
|
||||
|
||||
CCMD(listmaps)
|
||||
{
|
||||
for (unsigned int i = 0; i < numUsedSlots; i++)
|
||||
for (auto& map : mapList)
|
||||
{
|
||||
int lump = fileSystem.FindFile(mapList[i].fileName);
|
||||
int lump = fileSystem.FindFile(map.fileName);
|
||||
if (lump >= 0)
|
||||
{
|
||||
int rfnum = fileSystem.GetFileContainer(lump);
|
||||
Printf("%s - %s (%s)\n", mapList[i].fileName.GetChars(), mapList[i].DisplayName(), fileSystem.GetResourceFileName(rfnum));
|
||||
Printf("%s - %s (%s)\n", map.fileName.GetChars(), map.DisplayName(), fileSystem.GetResourceFileName(rfnum));
|
||||
}
|
||||
else
|
||||
{
|
||||
Printf("%s - %s (defined but does not exist)\n", mapList[i].fileName.GetChars(), mapList[i].DisplayName());
|
||||
Printf("%s - %s (defined but does not exist)\n", map.fileName.GetChars(), map.DisplayName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -72,9 +70,8 @@ CCMD(listmaps)
|
|||
|
||||
MapRecord *FindMapByName(const char *nm)
|
||||
{
|
||||
for (unsigned i = 0; i < numUsedSlots; i++)
|
||||
for (auto& map : mapList)
|
||||
{
|
||||
auto &map = mapList[i];
|
||||
if (map.labelName.CompareNoCase(nm) == 0)
|
||||
{
|
||||
return ↦
|
||||
|
@ -86,9 +83,8 @@ MapRecord *FindMapByName(const char *nm)
|
|||
|
||||
MapRecord *FindMapByLevelNum(int num)
|
||||
{
|
||||
for (unsigned i = 0; i < numUsedSlots; i++)
|
||||
for (auto& map : mapList)
|
||||
{
|
||||
auto &map = mapList[i];
|
||||
if (map.levelNumber == num)
|
||||
{
|
||||
return ↦
|
||||
|
@ -142,15 +138,14 @@ bool SetMusicForMap(const char* mapname, const char* music, bool namehack)
|
|||
|
||||
MapRecord *AllocateMap()
|
||||
{
|
||||
return &mapList[numUsedSlots++];
|
||||
return &mapList[mapList.Reserve(1)];
|
||||
}
|
||||
|
||||
|
||||
MapRecord* SetupUserMap(const char* boardfilename, const char *defaultmusic)
|
||||
{
|
||||
for (unsigned i = 0; i < numUsedSlots; i++)
|
||||
for (auto& map : mapList)
|
||||
{
|
||||
auto &map = mapList[i];
|
||||
if (map.fileName.CompareNoCase(boardfilename) == 0)
|
||||
{
|
||||
return ↦
|
||||
|
|
|
@ -18,13 +18,11 @@ enum EMax
|
|||
enum EVolFlags
|
||||
{
|
||||
EF_HIDEFROMSP = 1,
|
||||
EF_GOTONEXTVOLUME = 2, // for RR which continues the game in the next volume
|
||||
};
|
||||
|
||||
// These get filled in by the map definition parsers of the front ends.
|
||||
extern FString gSkillNames[MAXSKILLS];
|
||||
extern FString gVolumeNames[MAXVOLUMES];
|
||||
extern FString gVolumeSubtitles[MAXVOLUMES];
|
||||
extern int32_t gVolumeFlags[MAXVOLUMES];
|
||||
extern int gDefaultVolume, gDefaultSkill;
|
||||
|
||||
|
||||
|
@ -46,6 +44,42 @@ enum {
|
|||
MAX_MESSAGES = 32
|
||||
};
|
||||
|
||||
// Cutscene rules for maps are as follows:
|
||||
// * when an episode is started, the episode intro will play, if none is defined, the map's intro will play.
|
||||
// * when an episde is ended, the episode outro will play after the summary screen.
|
||||
// * when a map ends, its own outro scene will play before the summary screen, if none is defined, use the default map outro handler.
|
||||
// * when a new map starts after the summary screen, its own intro scene will play, if none is defined, use the default map intro handler.
|
||||
// * setting any of these fields to 'none' will override any default and play nothing, even if a default is set.
|
||||
class DObject;
|
||||
|
||||
struct CutsceneDef
|
||||
{
|
||||
FString video;
|
||||
FString function;
|
||||
int sound = 0;
|
||||
int framespersec = 0; // only relevant for ANM.
|
||||
|
||||
void Create(DObject* runner);
|
||||
};
|
||||
|
||||
struct GlobalCutscenes
|
||||
{
|
||||
CutsceneDef Intro;
|
||||
CutsceneDef DefaultMapIntro;
|
||||
CutsceneDef DefaultMapOutro;
|
||||
FString MPSummaryScreen;
|
||||
FString SummaryScreen;
|
||||
};
|
||||
|
||||
struct VolumeRecord
|
||||
{
|
||||
FString name;
|
||||
FString subtitle;
|
||||
CutsceneDef intro;
|
||||
CutsceneDef outro;
|
||||
int32_t flags = 0;
|
||||
};
|
||||
|
||||
struct MapRecord
|
||||
{
|
||||
int parTime = 0;
|
||||
|
@ -54,6 +88,8 @@ struct MapRecord
|
|||
FString labelName;
|
||||
FString name;
|
||||
FString music;
|
||||
CutsceneDef intro;
|
||||
CutsceneDef outro;
|
||||
int cdSongId = -1;
|
||||
int flags = 0;
|
||||
int levelNumber = -1;
|
||||
|
@ -101,8 +137,8 @@ struct MapRecord
|
|||
|
||||
};
|
||||
|
||||
|
||||
extern MapRecord mapList[512];
|
||||
extern GlobalCutscenes globalCutscenes;
|
||||
extern VolumeRecord volumeList[MAXVOLUMES];
|
||||
extern MapRecord *currentLevel;
|
||||
|
||||
bool SetMusicForMap(const char* mapname, const char* music, bool namehack = false);
|
||||
|
|
|
@ -121,7 +121,7 @@ bool M_SetSpecialMenu(FName& menu, int param)
|
|||
if (gi->StartGame(NewGameStartupInfo))
|
||||
{
|
||||
M_ClearMenus();
|
||||
STAT_StartNewGame(gVolumeNames[NewGameStartupInfo.Episode], NewGameStartupInfo.Skill);
|
||||
STAT_StartNewGame(volumeList[NewGameStartupInfo.Episode].name, NewGameStartupInfo.Skill);
|
||||
inputState.ClearAllInput();
|
||||
}
|
||||
return false;
|
||||
|
@ -387,20 +387,21 @@ static void BuildEpisodeMenu()
|
|||
|
||||
for (int i = 0; i < MAXVOLUMES; i++)
|
||||
{
|
||||
if (gVolumeNames[i].IsNotEmpty() && !(gVolumeFlags[i] & EF_HIDEFROMSP))
|
||||
auto& vol = volumeList[i];
|
||||
if (vol.name.IsNotEmpty() && !(vol.flags & EF_HIDEFROMSP))
|
||||
|
||||
{
|
||||
int isShareware = ((g_gameType & GAMEFLAG_DUKE) && (g_gameType & GAMEFLAG_SHAREWARE) && i > 0);
|
||||
auto it = CreateCustomListMenuItemText(ld->mXpos, y, ld->mLinespacing, gVolumeNames[i][0],
|
||||
gVolumeNames[i], ld->mFont, CR_UNTRANSLATED, isShareware, NAME_Skillmenu, i); // font colors are not used, so hijack one for the shareware flag.
|
||||
auto it = CreateCustomListMenuItemText(ld->mXpos, y, ld->mLinespacing, vol.name[0],
|
||||
vol.name, ld->mFont, CR_UNTRANSLATED, isShareware, NAME_Skillmenu, i); // font colors are not used, so hijack one for the shareware flag.
|
||||
|
||||
y += ld->mLinespacing;
|
||||
ld->mItems.Push(it);
|
||||
addedVolumes++;
|
||||
if (gVolumeSubtitles[i].IsNotEmpty())
|
||||
if (vol.subtitle.IsNotEmpty())
|
||||
{
|
||||
auto it = CreateCustomListMenuItemText(ld->mXpos, y, ld->mLinespacing * 6 / 10, 1,
|
||||
gVolumeSubtitles[i], SmallFont, CR_GRAY, false, NAME_None, i);
|
||||
vol.subtitle, SmallFont, CR_GRAY, false, NAME_None, i);
|
||||
y += ld->mLinespacing * 6 / 10;
|
||||
ld->mItems.Push(it);
|
||||
textadded = true;
|
||||
|
|
|
@ -35,7 +35,6 @@
|
|||
**
|
||||
*/
|
||||
|
||||
|
||||
void parseAnimTileRange(FScanner& sc, FScriptPosition& pos)
|
||||
{
|
||||
SetAnim set;
|
||||
|
@ -46,3 +45,90 @@ void parseAnimTileRange(FScanner& sc, FScriptPosition& pos)
|
|||
processSetAnim("animtilerange", pos, set);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
static void parseCutscene(FScanner& sc, CutsceneDef& cdef)
|
||||
{
|
||||
FScanner::SavedPos eblockend;
|
||||
|
||||
if (sc.StartBraces(&eblockend)) return;
|
||||
FString sound;
|
||||
while (!sc.FoundEndBrace(eblockend))
|
||||
{
|
||||
sc.MustGetString();
|
||||
if (sc.Compare("video")) { sc.GetString(cdef.video); cdef.function = ""; }
|
||||
else if (sc.Compare("function")) { sc.GetString(cdef.function); cdef.video = ""; }
|
||||
else if (sc.Compare("sound")) sc.GetString(sound);
|
||||
else if (sc.Compare("clear")) { cdef.function = "none"; cdef.video = ""; } // this means 'play nothing', not 'not defined'.
|
||||
}
|
||||
if (sound.IsNotEmpty())
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void parseDefineCutscene(FScanner& sc, FScriptPosition& pos)
|
||||
{
|
||||
int scenenum = -1;
|
||||
|
||||
if (!sc.GetString()) return;
|
||||
|
||||
if (sc.Compare("intro"))
|
||||
{
|
||||
parseCutscene(sc, globalCutscenes.Intro);
|
||||
}
|
||||
if (sc.Compare("mapintro")) // sets the global default for a map entry handler.
|
||||
{
|
||||
parseCutscene(sc, globalCutscenes.DefaultMapIntro);
|
||||
}
|
||||
if (sc.Compare("mapoutro")) // sets the global default for a map exit handler.
|
||||
{
|
||||
parseCutscene(sc, globalCutscenes.DefaultMapOutro);
|
||||
}
|
||||
else if (sc.Compare("episode"))
|
||||
{
|
||||
FScanner::SavedPos eblockend;
|
||||
sc.MustGetNumber();
|
||||
if (sc.Number < 1 || sc.Number > MAXVOLUMES)
|
||||
{
|
||||
sc.ScriptError("episode number %d out of range. Must be positive", sc.Number);
|
||||
return;
|
||||
}
|
||||
int vol = sc.Number - 1;
|
||||
|
||||
if (sc.StartBraces(&eblockend)) return;
|
||||
while (!sc.FoundEndBrace(eblockend))
|
||||
{
|
||||
sc.MustGetString();
|
||||
if (sc.Compare("intro")) parseCutscene(sc, volumeList[vol].intro);
|
||||
else if (sc.Compare("outro")) parseCutscene(sc, volumeList[vol].outro);
|
||||
else if (sc.Compare("flags")) sc.GetNumber(volumeList[vol].flags);
|
||||
}
|
||||
}
|
||||
else if (sc.Compare("map"))
|
||||
{
|
||||
FScanner::SavedPos eblockend;
|
||||
sc.MustGetString();
|
||||
auto maprec = FindMapByName(sc.String);
|
||||
if (!maprec)
|
||||
{
|
||||
sc.ScriptError("%s: map not found", sc.String);
|
||||
return;
|
||||
}
|
||||
if (sc.StartBraces(&eblockend)) return;
|
||||
while (!sc.FoundEndBrace(eblockend))
|
||||
{
|
||||
sc.MustGetString();
|
||||
if (sc.Compare("intro")) parseCutscene(sc, maprec->intro);
|
||||
else if (sc.Compare("outro")) parseCutscene(sc, maprec->outro);
|
||||
}
|
||||
}
|
||||
else if (sc.Compare("summary")) sc.GetString(globalCutscenes.SummaryScreen);
|
||||
else if (sc.Compare("mpsummary")) sc.GetString(globalCutscenes.MPSummaryScreen);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -240,7 +240,7 @@ void DBaseStatusBar::PrintAutomapInfo(FLevelStats& stats, bool forcetextfont)
|
|||
{
|
||||
y = 200 - stats.screenbottomspace - spacing;
|
||||
}
|
||||
const auto &volname = gVolumeNames[volfromlevelnum(lev->levelNumber)];
|
||||
const auto &volname = volumeList[volfromlevelnum(lev->levelNumber)].name;
|
||||
if (volname.IsEmpty() && am_nameontop) y = 1;
|
||||
|
||||
DrawText(twod, stats.font, stats.standardColor, 2 * hud_statscale, y, mapname, DTA_FullscreenScale, FSMode_ScaleToHeight, DTA_VirtualWidth, 320, DTA_VirtualHeight, 200,
|
||||
|
|
|
@ -144,7 +144,7 @@ void levelPlayIntroScene(int nEpisode, CompletionFunc completion)
|
|||
ambKillAll();
|
||||
seqKillAll();
|
||||
EPISODEINFO *pEpisode = &gEpisodeInfo[nEpisode];
|
||||
playSmk(pEpisode->cutsceneAName, pEpisode->cutsceneASound, pEpisode->at9028, completion);
|
||||
playSmk(pEpisode->cutsceneAName, pEpisode->cutsceneASound, pEpisode->cutsceneAWave, completion);
|
||||
}
|
||||
|
||||
void levelPlayEndScene(int nEpisode, CompletionFunc completion)
|
||||
|
@ -156,7 +156,7 @@ void levelPlayEndScene(int nEpisode, CompletionFunc completion)
|
|||
ambKillAll();
|
||||
seqKillAll();
|
||||
EPISODEINFO *pEpisode = &gEpisodeInfo[nEpisode];
|
||||
playSmk(pEpisode->cutsceneBName, pEpisode->cutsceneBSound, pEpisode->at902c, completion);
|
||||
playSmk(pEpisode->cutsceneBName, pEpisode->cutsceneBSound, pEpisode->cutsceneBWave, completion);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -157,16 +157,16 @@ void levelLoadDefaults(void)
|
|||
break;
|
||||
EPISODEINFO *pEpisodeInfo = &gEpisodeInfo[i];
|
||||
auto ep_str = BloodINI->GetKeyString(buffer, "Title", buffer);
|
||||
gVolumeNames[i] = ep_str; // only keep one table for the names. Todo: Consolidate this across games.
|
||||
volumeList[i].name = ep_str;
|
||||
strncpy(pEpisodeInfo->cutsceneAName, BloodINI->GetKeyString(buffer, "CutSceneA", ""), BMAX_PATH);
|
||||
pEpisodeInfo->at9028 = BloodINI->GetKeyInt(buffer, "CutWavA", -1);
|
||||
if (pEpisodeInfo->at9028 == 0)
|
||||
pEpisodeInfo->cutsceneAWave = BloodINI->GetKeyInt(buffer, "CutWavA", -1);
|
||||
if (pEpisodeInfo->cutsceneAWave == 0)
|
||||
strncpy(pEpisodeInfo->cutsceneASound, BloodINI->GetKeyString(buffer, "CutWavA", ""), BMAX_PATH);
|
||||
else
|
||||
pEpisodeInfo->cutsceneASound[0] = 0;
|
||||
strncpy(pEpisodeInfo->cutsceneBName, BloodINI->GetKeyString(buffer, "CutSceneB", ""), BMAX_PATH);
|
||||
pEpisodeInfo->at902c = BloodINI->GetKeyInt(buffer, "CutWavB", -1);
|
||||
if (pEpisodeInfo->at902c == 0)
|
||||
pEpisodeInfo->cutsceneBWave = BloodINI->GetKeyInt(buffer, "CutWavB", -1);
|
||||
if (pEpisodeInfo->cutsceneBWave == 0)
|
||||
strncpy(pEpisodeInfo->cutsceneBSound, BloodINI->GetKeyString(buffer, "CutWavB", ""), BMAX_PATH);
|
||||
else
|
||||
pEpisodeInfo->cutsceneBSound[0] = 0;
|
||||
|
|
|
@ -79,8 +79,8 @@ struct EPISODEINFO
|
|||
unsigned int cutALevel : 4;
|
||||
char cutsceneAName[BMAX_PATH];
|
||||
char cutsceneBName[BMAX_PATH];
|
||||
int at9028;
|
||||
int at902c;
|
||||
int cutsceneAWave;
|
||||
int cutsceneBWave;
|
||||
char cutsceneASound[BMAX_PATH];
|
||||
char cutsceneBSound[BMAX_PATH];
|
||||
};
|
||||
|
|
|
@ -233,6 +233,7 @@ void PlayerColorChanged(void);
|
|||
bool movementBlocked(player_struct *p);
|
||||
void loadcons();
|
||||
void recordoldspritepos();
|
||||
void FixMapinfo();
|
||||
|
||||
int* animateptr(int i);
|
||||
|
||||
|
|
|
@ -325,6 +325,7 @@ void GameInterface::app_init()
|
|||
screenpeek = myconnectindex;
|
||||
|
||||
LoadDefinitions();
|
||||
FixMapinfo(); // Add some corrections. Can only be done after .def has been parsed.
|
||||
fi.InitFonts();
|
||||
SetTileNames();
|
||||
TileFiles.SetBackup();
|
||||
|
|
|
@ -1658,7 +1658,7 @@ int ConCompiler::parsecommand()
|
|||
textptr++, i++;
|
||||
}
|
||||
parsebuffer.Push(0);
|
||||
gVolumeNames[j] = FStringTable::MakeMacro(parsebuffer.Data(), i);
|
||||
volumeList[j].name = FStringTable::MakeMacro(parsebuffer.Data(), i);
|
||||
return 0;
|
||||
case concmd_defineskillname:
|
||||
popscriptvalue();
|
||||
|
@ -3206,8 +3206,16 @@ void loadcons()
|
|||
InitGameVarPointers();
|
||||
ResetSystemDefaults();
|
||||
S_WorldTourMappingsForOldSounds(); // create a sound mapping for World Tour.
|
||||
S_CacheAllSounds();
|
||||
comp.setmusic();
|
||||
}
|
||||
|
||||
void FixMapinfo()
|
||||
{
|
||||
// todo: export this to proper map definition features.
|
||||
if (isWorldTour())
|
||||
{
|
||||
// fix broken secret exit in WT's super secret map.
|
||||
int num = fileSystem.CheckNumForName("e1l7.map");
|
||||
int file = fileSystem.GetFileContainer(num);
|
||||
if (file <= fileSystem.GetMaxIwadNum())
|
||||
|
@ -3216,35 +3224,36 @@ void loadcons()
|
|||
if (maprec) maprec->nextLevel = levelnum(0, 4);
|
||||
}
|
||||
}
|
||||
else if (isRRRA())
|
||||
{
|
||||
// RRRA goes directly to the second episode after E1L7 to continue the game.
|
||||
int num = fileSystem.CheckNumForName("e1l7.map");
|
||||
int file = fileSystem.GetFileContainer(num);
|
||||
if (file <= fileSystem.GetMaxIwadNum())
|
||||
{
|
||||
auto maprec = FindMapByName("e1l7");
|
||||
if (maprec) maprec->nextLevel = levelnum(1, 0);
|
||||
}
|
||||
}
|
||||
else if (isRR())
|
||||
{
|
||||
// RR does not define its final level and crudely hacked it into the progression. This puts it into the E2L8 slot so that the game can naturally progress there.
|
||||
auto maprec1 = FindMapByLevelNum(levelnum(1, 6));
|
||||
auto maprec2 = FindMapByLevelNum(levelnum(1, 7));
|
||||
auto maprec3 = FindMapByName("endgame");
|
||||
int num3 = fileSystem.FindFile("endgame.map");
|
||||
if (maprec1 && !maprec2 && !maprec3 && num3 >= 0)
|
||||
if (volumeList[0].flags & EF_GOTONEXTVOLUME)
|
||||
{
|
||||
auto maprec = AllocateMap();
|
||||
maprec->designerTime = 0;
|
||||
maprec->parTime = 0;
|
||||
maprec->SetFileName("endgame.map");
|
||||
maprec->SetName("$TXT_CLOSEENCOUNTERS");
|
||||
maprec->levelNumber = levelnum(1, 7);
|
||||
// RR goes directly to the second episode after E1L7 to continue the game.
|
||||
auto maprec1 = FindMapByLevelNum(levelnum(0, 6)); // E1L7 must exist
|
||||
auto maprec2 = FindMapByLevelNum(levelnum(0, 7)); // E1L8 must not exist
|
||||
if (maprec1 && !maprec2)
|
||||
{
|
||||
maprec1->nextLevel = levelnum(1, 0);
|
||||
}
|
||||
}
|
||||
if (!isRRRA())
|
||||
{
|
||||
// RR does not define its final level and crudely hacked it into the progression. This puts it into the E2L8 slot so that the game can naturally progress there.
|
||||
auto maprec1 = FindMapByLevelNum(levelnum(1, 6)); // E2L7 must exist
|
||||
auto maprec2 = FindMapByLevelNum(levelnum(1, 7)); // E2L8 must not exist
|
||||
auto maprec3 = FindMapByName("endgame"); // endgame must not have a map record already
|
||||
int num3 = fileSystem.FindFile("endgame.map"); // endgame.map must exist.
|
||||
if (maprec1 && !maprec2 && !maprec3 && num3 >= 0)
|
||||
{
|
||||
auto maprec = AllocateMap();
|
||||
maprec->designerTime = 0;
|
||||
maprec->parTime = 0;
|
||||
maprec->SetFileName("endgame.map");
|
||||
maprec->SetName("$TXT_CLOSEENCOUNTERS");
|
||||
maprec->levelNumber = levelnum(1, 7);
|
||||
}
|
||||
}
|
||||
}
|
||||
comp.setmusic();
|
||||
}
|
||||
|
||||
END_DUKE_NS
|
||||
|
|
|
@ -523,13 +523,13 @@ void LoadCustomInfoFromScript(const char *filename)
|
|||
case CM_TITLE:
|
||||
{
|
||||
sc.MustGetString();
|
||||
if (curep != -1) gVolumeNames[curep] = sc.String;
|
||||
if (curep != -1) volumeList[curep].name = sc.String;
|
||||
break;
|
||||
}
|
||||
case CM_SUBTITLE:
|
||||
{
|
||||
sc.MustGetString();
|
||||
if (curep != -1) gVolumeSubtitles[curep] = sc.String;
|
||||
if (curep != -1) volumeList[curep].subtitle = sc.String;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
Loading…
Reference in a new issue