mirror of
https://github.com/ZDoom/raze-gles.git
synced 2025-01-15 20:20:54 +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_RFFDEFINEID,
|
||||||
T_EXTRA,
|
T_EXTRA,
|
||||||
T_ROTATE,
|
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;
|
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 },
|
{ "shadefactor", T_SHADEFACTOR },
|
||||||
{ "newgamechoices", T_NEWGAMECHOICES },
|
{ "newgamechoices", T_NEWGAMECHOICES },
|
||||||
{ "rffdefineid", T_RFFDEFINEID }, // dummy
|
{ "rffdefineid", T_RFFDEFINEID }, // dummy
|
||||||
|
{ "map", T_MAP },
|
||||||
|
{ "definecutscene", T_DEFINECUTSCENE },
|
||||||
};
|
};
|
||||||
|
|
||||||
script->SetNoOctals(true);
|
script->SetNoOctals(true);
|
||||||
|
@ -376,6 +378,9 @@ static int32_t defsparser(scriptfile *script)
|
||||||
auto pos = scriptfile_getposition(script);
|
auto pos = scriptfile_getposition(script);
|
||||||
switch (tokn)
|
switch (tokn)
|
||||||
{
|
{
|
||||||
|
case T_DEFINECUTSCENE:
|
||||||
|
parseDefineCutscene(*script, pos);
|
||||||
|
break;
|
||||||
case T_ERROR:
|
case T_ERROR:
|
||||||
pos.Message(MSG_ERROR, "Unknown error");
|
pos.Message(MSG_ERROR, "Unknown error");
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1287,6 +1287,42 @@ void FScanner::AddSymbol(const char* name, double value)
|
||||||
symbols.Insert(name, sym);
|
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
|
// 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)); }
|
inline void AddSymbol(const char* name, uint32_t value) { return AddSymbol(name, uint64_t(value)); }
|
||||||
void AddSymbol(const char* name, double value);
|
void AddSymbol(const char* name, double value);
|
||||||
void SkipToEndOfBlock();
|
void SkipToEndOfBlock();
|
||||||
|
int StartBraces(FScanner::SavedPos* braceend);
|
||||||
|
bool FoundEndBrace(FScanner::SavedPos& braceend);
|
||||||
|
|
||||||
static FString TokenName(int token, const char *string=NULL);
|
static FString TokenName(int token, const char *string=NULL);
|
||||||
|
|
||||||
|
@ -120,7 +122,30 @@ public:
|
||||||
return true;
|
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(bool evaluate = false);
|
||||||
|
|
||||||
|
bool GetFloat(double& var, bool evaluate = false)
|
||||||
|
{
|
||||||
|
if (!GetFloat(evaluate)) return false;
|
||||||
|
var = Float;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void MustGetFloat(bool evaluate = false);
|
void MustGetFloat(bool evaluate = false);
|
||||||
bool CheckFloat(bool evaluate = false);
|
bool CheckFloat(bool evaluate = false);
|
||||||
|
|
||||||
|
|
|
@ -599,15 +599,16 @@ void SetDefaultStrings()
|
||||||
if ((g_gameType & GAMEFLAG_DUKE) && fileSystem.FindFile("E4L1.MAP") < 0)
|
if ((g_gameType & GAMEFLAG_DUKE) && fileSystem.FindFile("E4L1.MAP") < 0)
|
||||||
{
|
{
|
||||||
// Pre-Atomic releases do not define this.
|
// Pre-Atomic releases do not define this.
|
||||||
gVolumeNames[0] = "$L.A. Meltdown";
|
volumeList[0].name = "$L.A. Meltdown";
|
||||||
gVolumeNames[1] = "$Lunar Apocalypse";
|
volumeList[1].name = "$Lunar Apocalypse";
|
||||||
gVolumeNames[2] = "$Shrapnel City";
|
volumeList[2].name = "$Shrapnel City";
|
||||||
if (g_gameType & GAMEFLAG_SHAREWARE) gVolumeNames[3] = "$The Birth";
|
if (g_gameType & GAMEFLAG_SHAREWARE) volumeList[3].name = "$The Birth";
|
||||||
gSkillNames[0] = "$Piece of Cake";
|
gSkillNames[0] = "$Piece of Cake";
|
||||||
gSkillNames[1] = "$Let's Rock";
|
gSkillNames[1] = "$Let's Rock";
|
||||||
gSkillNames[2] = "$Come get Some";
|
gSkillNames[2] = "$Come get Some";
|
||||||
gSkillNames[3] = "$Damn I'm Good";
|
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.
|
// Blood hard codes its skill names, so we have to define them manually.
|
||||||
if (isBlood())
|
if (isBlood())
|
||||||
{
|
{
|
||||||
|
|
|
@ -41,30 +41,28 @@
|
||||||
#include "raze_sound.h"
|
#include "raze_sound.h"
|
||||||
|
|
||||||
FString gSkillNames[MAXSKILLS];
|
FString gSkillNames[MAXSKILLS];
|
||||||
FString gVolumeNames[MAXVOLUMES];
|
|
||||||
FString gVolumeSubtitles[MAXVOLUMES];
|
|
||||||
int32_t gVolumeFlags[MAXVOLUMES];
|
|
||||||
int gDefaultVolume = 0, gDefaultSkill = 1;
|
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.
|
GlobalCutscenes globalCutscenes;
|
||||||
MapRecord *currentLevel; // level that is currently played. (The real level, not what script hacks modfifying the current level index can pretend.)
|
VolumeRecord volumeList[MAXVOLUMES];
|
||||||
|
TArray<MapRecord> mapList;
|
||||||
|
MapRecord *currentLevel; // level that is currently played.
|
||||||
MapRecord* lastLevel; // Same here, for the last level.
|
MapRecord* lastLevel; // Same here, for the last level.
|
||||||
unsigned int numUsedSlots;
|
|
||||||
|
|
||||||
|
|
||||||
CCMD(listmaps)
|
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)
|
if (lump >= 0)
|
||||||
{
|
{
|
||||||
int rfnum = fileSystem.GetFileContainer(lump);
|
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
|
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)
|
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)
|
if (map.labelName.CompareNoCase(nm) == 0)
|
||||||
{
|
{
|
||||||
return ↦
|
return ↦
|
||||||
|
@ -86,9 +83,8 @@ MapRecord *FindMapByName(const char *nm)
|
||||||
|
|
||||||
MapRecord *FindMapByLevelNum(int num)
|
MapRecord *FindMapByLevelNum(int num)
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < numUsedSlots; i++)
|
for (auto& map : mapList)
|
||||||
{
|
{
|
||||||
auto &map = mapList[i];
|
|
||||||
if (map.levelNumber == num)
|
if (map.levelNumber == num)
|
||||||
{
|
{
|
||||||
return ↦
|
return ↦
|
||||||
|
@ -142,15 +138,14 @@ bool SetMusicForMap(const char* mapname, const char* music, bool namehack)
|
||||||
|
|
||||||
MapRecord *AllocateMap()
|
MapRecord *AllocateMap()
|
||||||
{
|
{
|
||||||
return &mapList[numUsedSlots++];
|
return &mapList[mapList.Reserve(1)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MapRecord* SetupUserMap(const char* boardfilename, const char *defaultmusic)
|
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)
|
if (map.fileName.CompareNoCase(boardfilename) == 0)
|
||||||
{
|
{
|
||||||
return ↦
|
return ↦
|
||||||
|
|
|
@ -18,13 +18,11 @@ enum EMax
|
||||||
enum EVolFlags
|
enum EVolFlags
|
||||||
{
|
{
|
||||||
EF_HIDEFROMSP = 1,
|
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.
|
// These get filled in by the map definition parsers of the front ends.
|
||||||
extern FString gSkillNames[MAXSKILLS];
|
extern FString gSkillNames[MAXSKILLS];
|
||||||
extern FString gVolumeNames[MAXVOLUMES];
|
|
||||||
extern FString gVolumeSubtitles[MAXVOLUMES];
|
|
||||||
extern int32_t gVolumeFlags[MAXVOLUMES];
|
|
||||||
extern int gDefaultVolume, gDefaultSkill;
|
extern int gDefaultVolume, gDefaultSkill;
|
||||||
|
|
||||||
|
|
||||||
|
@ -46,6 +44,42 @@ enum {
|
||||||
MAX_MESSAGES = 32
|
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
|
struct MapRecord
|
||||||
{
|
{
|
||||||
int parTime = 0;
|
int parTime = 0;
|
||||||
|
@ -54,6 +88,8 @@ struct MapRecord
|
||||||
FString labelName;
|
FString labelName;
|
||||||
FString name;
|
FString name;
|
||||||
FString music;
|
FString music;
|
||||||
|
CutsceneDef intro;
|
||||||
|
CutsceneDef outro;
|
||||||
int cdSongId = -1;
|
int cdSongId = -1;
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
int levelNumber = -1;
|
int levelNumber = -1;
|
||||||
|
@ -101,8 +137,8 @@ struct MapRecord
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern GlobalCutscenes globalCutscenes;
|
||||||
extern MapRecord mapList[512];
|
extern VolumeRecord volumeList[MAXVOLUMES];
|
||||||
extern MapRecord *currentLevel;
|
extern MapRecord *currentLevel;
|
||||||
|
|
||||||
bool SetMusicForMap(const char* mapname, const char* music, bool namehack = false);
|
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))
|
if (gi->StartGame(NewGameStartupInfo))
|
||||||
{
|
{
|
||||||
M_ClearMenus();
|
M_ClearMenus();
|
||||||
STAT_StartNewGame(gVolumeNames[NewGameStartupInfo.Episode], NewGameStartupInfo.Skill);
|
STAT_StartNewGame(volumeList[NewGameStartupInfo.Episode].name, NewGameStartupInfo.Skill);
|
||||||
inputState.ClearAllInput();
|
inputState.ClearAllInput();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -387,20 +387,21 @@ static void BuildEpisodeMenu()
|
||||||
|
|
||||||
for (int i = 0; i < MAXVOLUMES; i++)
|
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);
|
int isShareware = ((g_gameType & GAMEFLAG_DUKE) && (g_gameType & GAMEFLAG_SHAREWARE) && i > 0);
|
||||||
auto it = CreateCustomListMenuItemText(ld->mXpos, y, ld->mLinespacing, gVolumeNames[i][0],
|
auto it = CreateCustomListMenuItemText(ld->mXpos, y, ld->mLinespacing, vol.name[0],
|
||||||
gVolumeNames[i], ld->mFont, CR_UNTRANSLATED, isShareware, NAME_Skillmenu, i); // font colors are not used, so hijack one for the shareware flag.
|
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;
|
y += ld->mLinespacing;
|
||||||
ld->mItems.Push(it);
|
ld->mItems.Push(it);
|
||||||
addedVolumes++;
|
addedVolumes++;
|
||||||
if (gVolumeSubtitles[i].IsNotEmpty())
|
if (vol.subtitle.IsNotEmpty())
|
||||||
{
|
{
|
||||||
auto it = CreateCustomListMenuItemText(ld->mXpos, y, ld->mLinespacing * 6 / 10, 1,
|
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;
|
y += ld->mLinespacing * 6 / 10;
|
||||||
ld->mItems.Push(it);
|
ld->mItems.Push(it);
|
||||||
textadded = true;
|
textadded = true;
|
||||||
|
|
|
@ -35,7 +35,6 @@
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
void parseAnimTileRange(FScanner& sc, FScriptPosition& pos)
|
void parseAnimTileRange(FScanner& sc, FScriptPosition& pos)
|
||||||
{
|
{
|
||||||
SetAnim set;
|
SetAnim set;
|
||||||
|
@ -46,3 +45,90 @@ void parseAnimTileRange(FScanner& sc, FScriptPosition& pos)
|
||||||
processSetAnim("animtilerange", pos, set);
|
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;
|
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;
|
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,
|
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();
|
ambKillAll();
|
||||||
seqKillAll();
|
seqKillAll();
|
||||||
EPISODEINFO *pEpisode = &gEpisodeInfo[nEpisode];
|
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)
|
void levelPlayEndScene(int nEpisode, CompletionFunc completion)
|
||||||
|
@ -156,7 +156,7 @@ void levelPlayEndScene(int nEpisode, CompletionFunc completion)
|
||||||
ambKillAll();
|
ambKillAll();
|
||||||
seqKillAll();
|
seqKillAll();
|
||||||
EPISODEINFO *pEpisode = &gEpisodeInfo[nEpisode];
|
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;
|
break;
|
||||||
EPISODEINFO *pEpisodeInfo = &gEpisodeInfo[i];
|
EPISODEINFO *pEpisodeInfo = &gEpisodeInfo[i];
|
||||||
auto ep_str = BloodINI->GetKeyString(buffer, "Title", buffer);
|
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);
|
strncpy(pEpisodeInfo->cutsceneAName, BloodINI->GetKeyString(buffer, "CutSceneA", ""), BMAX_PATH);
|
||||||
pEpisodeInfo->at9028 = BloodINI->GetKeyInt(buffer, "CutWavA", -1);
|
pEpisodeInfo->cutsceneAWave = BloodINI->GetKeyInt(buffer, "CutWavA", -1);
|
||||||
if (pEpisodeInfo->at9028 == 0)
|
if (pEpisodeInfo->cutsceneAWave == 0)
|
||||||
strncpy(pEpisodeInfo->cutsceneASound, BloodINI->GetKeyString(buffer, "CutWavA", ""), BMAX_PATH);
|
strncpy(pEpisodeInfo->cutsceneASound, BloodINI->GetKeyString(buffer, "CutWavA", ""), BMAX_PATH);
|
||||||
else
|
else
|
||||||
pEpisodeInfo->cutsceneASound[0] = 0;
|
pEpisodeInfo->cutsceneASound[0] = 0;
|
||||||
strncpy(pEpisodeInfo->cutsceneBName, BloodINI->GetKeyString(buffer, "CutSceneB", ""), BMAX_PATH);
|
strncpy(pEpisodeInfo->cutsceneBName, BloodINI->GetKeyString(buffer, "CutSceneB", ""), BMAX_PATH);
|
||||||
pEpisodeInfo->at902c = BloodINI->GetKeyInt(buffer, "CutWavB", -1);
|
pEpisodeInfo->cutsceneBWave = BloodINI->GetKeyInt(buffer, "CutWavB", -1);
|
||||||
if (pEpisodeInfo->at902c == 0)
|
if (pEpisodeInfo->cutsceneBWave == 0)
|
||||||
strncpy(pEpisodeInfo->cutsceneBSound, BloodINI->GetKeyString(buffer, "CutWavB", ""), BMAX_PATH);
|
strncpy(pEpisodeInfo->cutsceneBSound, BloodINI->GetKeyString(buffer, "CutWavB", ""), BMAX_PATH);
|
||||||
else
|
else
|
||||||
pEpisodeInfo->cutsceneBSound[0] = 0;
|
pEpisodeInfo->cutsceneBSound[0] = 0;
|
||||||
|
|
|
@ -79,8 +79,8 @@ struct EPISODEINFO
|
||||||
unsigned int cutALevel : 4;
|
unsigned int cutALevel : 4;
|
||||||
char cutsceneAName[BMAX_PATH];
|
char cutsceneAName[BMAX_PATH];
|
||||||
char cutsceneBName[BMAX_PATH];
|
char cutsceneBName[BMAX_PATH];
|
||||||
int at9028;
|
int cutsceneAWave;
|
||||||
int at902c;
|
int cutsceneBWave;
|
||||||
char cutsceneASound[BMAX_PATH];
|
char cutsceneASound[BMAX_PATH];
|
||||||
char cutsceneBSound[BMAX_PATH];
|
char cutsceneBSound[BMAX_PATH];
|
||||||
};
|
};
|
||||||
|
|
|
@ -233,6 +233,7 @@ void PlayerColorChanged(void);
|
||||||
bool movementBlocked(player_struct *p);
|
bool movementBlocked(player_struct *p);
|
||||||
void loadcons();
|
void loadcons();
|
||||||
void recordoldspritepos();
|
void recordoldspritepos();
|
||||||
|
void FixMapinfo();
|
||||||
|
|
||||||
int* animateptr(int i);
|
int* animateptr(int i);
|
||||||
|
|
||||||
|
|
|
@ -325,6 +325,7 @@ void GameInterface::app_init()
|
||||||
screenpeek = myconnectindex;
|
screenpeek = myconnectindex;
|
||||||
|
|
||||||
LoadDefinitions();
|
LoadDefinitions();
|
||||||
|
FixMapinfo(); // Add some corrections. Can only be done after .def has been parsed.
|
||||||
fi.InitFonts();
|
fi.InitFonts();
|
||||||
SetTileNames();
|
SetTileNames();
|
||||||
TileFiles.SetBackup();
|
TileFiles.SetBackup();
|
||||||
|
|
|
@ -1658,7 +1658,7 @@ int ConCompiler::parsecommand()
|
||||||
textptr++, i++;
|
textptr++, i++;
|
||||||
}
|
}
|
||||||
parsebuffer.Push(0);
|
parsebuffer.Push(0);
|
||||||
gVolumeNames[j] = FStringTable::MakeMacro(parsebuffer.Data(), i);
|
volumeList[j].name = FStringTable::MakeMacro(parsebuffer.Data(), i);
|
||||||
return 0;
|
return 0;
|
||||||
case concmd_defineskillname:
|
case concmd_defineskillname:
|
||||||
popscriptvalue();
|
popscriptvalue();
|
||||||
|
@ -3206,8 +3206,16 @@ void loadcons()
|
||||||
InitGameVarPointers();
|
InitGameVarPointers();
|
||||||
ResetSystemDefaults();
|
ResetSystemDefaults();
|
||||||
S_WorldTourMappingsForOldSounds(); // create a sound mapping for World Tour.
|
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())
|
if (isWorldTour())
|
||||||
{
|
{
|
||||||
|
// fix broken secret exit in WT's super secret map.
|
||||||
int num = fileSystem.CheckNumForName("e1l7.map");
|
int num = fileSystem.CheckNumForName("e1l7.map");
|
||||||
int file = fileSystem.GetFileContainer(num);
|
int file = fileSystem.GetFileContainer(num);
|
||||||
if (file <= fileSystem.GetMaxIwadNum())
|
if (file <= fileSystem.GetMaxIwadNum())
|
||||||
|
@ -3216,24 +3224,25 @@ void loadcons()
|
||||||
if (maprec) maprec->nextLevel = levelnum(0, 4);
|
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())
|
else if (isRR())
|
||||||
|
{
|
||||||
|
if (volumeList[0].flags & EF_GOTONEXTVOLUME)
|
||||||
|
{
|
||||||
|
// 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.
|
// 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 maprec1 = FindMapByLevelNum(levelnum(1, 6)); // E2L7 must exist
|
||||||
auto maprec2 = FindMapByLevelNum(levelnum(1, 7));
|
auto maprec2 = FindMapByLevelNum(levelnum(1, 7)); // E2L8 must not exist
|
||||||
auto maprec3 = FindMapByName("endgame");
|
auto maprec3 = FindMapByName("endgame"); // endgame must not have a map record already
|
||||||
int num3 = fileSystem.FindFile("endgame.map");
|
int num3 = fileSystem.FindFile("endgame.map"); // endgame.map must exist.
|
||||||
if (maprec1 && !maprec2 && !maprec3 && num3 >= 0)
|
if (maprec1 && !maprec2 && !maprec3 && num3 >= 0)
|
||||||
{
|
{
|
||||||
auto maprec = AllocateMap();
|
auto maprec = AllocateMap();
|
||||||
|
@ -3244,7 +3253,7 @@ void loadcons()
|
||||||
maprec->levelNumber = levelnum(1, 7);
|
maprec->levelNumber = levelnum(1, 7);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
comp.setmusic();
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
END_DUKE_NS
|
END_DUKE_NS
|
||||||
|
|
|
@ -523,13 +523,13 @@ void LoadCustomInfoFromScript(const char *filename)
|
||||||
case CM_TITLE:
|
case CM_TITLE:
|
||||||
{
|
{
|
||||||
sc.MustGetString();
|
sc.MustGetString();
|
||||||
if (curep != -1) gVolumeNames[curep] = sc.String;
|
if (curep != -1) volumeList[curep].name = sc.String;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CM_SUBTITLE:
|
case CM_SUBTITLE:
|
||||||
{
|
{
|
||||||
sc.MustGetString();
|
sc.MustGetString();
|
||||||
if (curep != -1) gVolumeSubtitles[curep] = sc.String;
|
if (curep != -1) volumeList[curep].subtitle = sc.String;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
Loading…
Reference in a new issue