2019-12-09 23:01:45 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "gstrings.h"
|
2019-12-10 16:35:28 +00:00
|
|
|
#include "cmdlib.h"
|
2019-12-10 23:57:53 +00:00
|
|
|
#include "quotemgr.h"
|
|
|
|
#ifdef GetMessage
|
|
|
|
#undef GetMessage // Windows strikes...
|
|
|
|
#endif
|
2019-12-09 23:01:45 +00:00
|
|
|
|
2020-10-04 16:31:48 +00:00
|
|
|
|
|
|
|
enum EMax
|
|
|
|
{
|
|
|
|
MAXSKILLS = 7,
|
|
|
|
MAXVOLUMES = 7,
|
|
|
|
MAXMENUGAMEPLAYENTRIES = 7,
|
|
|
|
};
|
|
|
|
|
2020-10-06 23:31:41 +00:00
|
|
|
enum EVolFlags
|
|
|
|
{
|
|
|
|
EF_HIDEFROMSP = 1,
|
2021-04-25 23:45:16 +00:00
|
|
|
EF_GOTONEXTVOLUME = 2, // for RR which continues the game in the next volume
|
2020-10-06 23:31:41 +00:00
|
|
|
};
|
|
|
|
|
2020-10-04 16:31:48 +00:00
|
|
|
// These get filled in by the map definition parsers of the front ends.
|
|
|
|
extern FString gSkillNames[MAXSKILLS];
|
|
|
|
extern int gDefaultVolume, gDefaultSkill;
|
|
|
|
|
|
|
|
|
2019-12-09 23:01:45 +00:00
|
|
|
// Localization capable replacement of the game specific solutions.
|
|
|
|
|
|
|
|
inline void MakeStringLocalizable(FString "e)
|
|
|
|
{
|
|
|
|
// Only prepend a quote if the string is localizable.
|
|
|
|
if (quote.Len() > 0 && quote[0] != '$' && GStrings[quote]) quote.Insert(0, "$");
|
|
|
|
}
|
|
|
|
|
2019-12-10 21:22:59 +00:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
MI_FORCEEOG = 1,
|
2020-07-07 11:19:09 +00:00
|
|
|
MI_USERMAP = 2,
|
2019-12-10 21:22:59 +00:00
|
|
|
};
|
|
|
|
|
2020-08-03 18:12:33 +00:00
|
|
|
enum {
|
|
|
|
MAX_MESSAGES = 32
|
|
|
|
};
|
|
|
|
|
2021-04-25 23:45:16 +00:00
|
|
|
// 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;
|
|
|
|
};
|
|
|
|
|
2019-12-09 23:01:45 +00:00
|
|
|
struct MapRecord
|
|
|
|
{
|
2020-07-01 18:31:29 +00:00
|
|
|
int parTime = 0;
|
|
|
|
int designerTime = 0;
|
2019-12-09 23:01:45 +00:00
|
|
|
FString fileName;
|
2019-12-10 16:35:28 +00:00
|
|
|
FString labelName;
|
2019-12-09 23:01:45 +00:00
|
|
|
FString name;
|
|
|
|
FString music;
|
2021-04-25 23:45:16 +00:00
|
|
|
CutsceneDef intro;
|
|
|
|
CutsceneDef outro;
|
2019-12-10 23:57:53 +00:00
|
|
|
int cdSongId = -1;
|
2019-12-11 22:41:05 +00:00
|
|
|
int flags = 0;
|
2020-07-01 18:31:29 +00:00
|
|
|
int levelNumber = -1;
|
2019-12-09 23:01:45 +00:00
|
|
|
|
|
|
|
// The rest is only used by Blood
|
2019-12-10 23:57:53 +00:00
|
|
|
int nextLevel = -1;
|
|
|
|
int nextSecret = -1;
|
2020-08-03 18:12:33 +00:00
|
|
|
FString messages[MAX_MESSAGES];
|
2019-12-09 23:01:45 +00:00
|
|
|
FString author;
|
2019-12-10 23:57:53 +00:00
|
|
|
int8_t fog = -1, weather = -1; // Blood defines these but they aren't used.
|
2019-12-09 23:01:45 +00:00
|
|
|
|
2020-07-07 11:19:09 +00:00
|
|
|
const char* LabelName() const
|
|
|
|
{
|
|
|
|
if (flags & MI_USERMAP) return GStrings("TXT_USERMAP");
|
|
|
|
return labelName;
|
|
|
|
}
|
|
|
|
const char *DisplayName() const
|
2019-12-09 23:01:45 +00:00
|
|
|
{
|
2019-12-10 16:35:28 +00:00
|
|
|
if (name.IsEmpty()) return labelName;
|
2019-12-09 23:01:45 +00:00
|
|
|
return GStrings.localize(name);
|
|
|
|
}
|
|
|
|
void SetName(const char *n)
|
|
|
|
{
|
|
|
|
name = n;
|
|
|
|
MakeStringLocalizable(name);
|
|
|
|
}
|
2019-12-10 16:35:28 +00:00
|
|
|
void SetFileName(const char* n)
|
|
|
|
{
|
2020-09-03 21:10:28 +00:00
|
|
|
if (*n == '/' || *n == '\\') n++;
|
2019-12-10 16:35:28 +00:00
|
|
|
fileName = n;
|
2020-03-01 06:28:40 +00:00
|
|
|
FixPathSeperator(fileName);
|
2019-12-10 16:35:28 +00:00
|
|
|
labelName = ExtractFileBase(n);
|
|
|
|
}
|
2019-12-10 23:57:53 +00:00
|
|
|
const char* GetMessage(int num)
|
|
|
|
{
|
2020-08-03 18:12:33 +00:00
|
|
|
if (num < 0 || num>= MAX_MESSAGES) return "";
|
|
|
|
return GStrings(messages[num]);
|
|
|
|
}
|
|
|
|
|
|
|
|
void AddMessage(int num, const FString &msg)
|
|
|
|
{
|
|
|
|
messages[num] = msg;
|
2019-12-10 23:57:53 +00:00
|
|
|
}
|
2020-08-03 18:12:33 +00:00
|
|
|
|
2019-12-10 16:35:28 +00:00
|
|
|
|
2019-12-09 23:01:45 +00:00
|
|
|
};
|
|
|
|
|
2021-04-26 00:00:40 +00:00
|
|
|
struct SummaryInfo
|
|
|
|
{
|
|
|
|
int kills;
|
|
|
|
int maxkills;
|
|
|
|
int secrets;
|
|
|
|
int maxsecrets;
|
|
|
|
int supersecrets;
|
|
|
|
int time;
|
|
|
|
bool cheated;
|
|
|
|
bool endofgame;
|
|
|
|
};
|
|
|
|
|
2021-04-25 23:45:16 +00:00
|
|
|
extern GlobalCutscenes globalCutscenes;
|
|
|
|
extern VolumeRecord volumeList[MAXVOLUMES];
|
2019-12-10 21:22:59 +00:00
|
|
|
extern MapRecord *currentLevel;
|
2020-06-23 22:40:22 +00:00
|
|
|
|
2020-07-07 11:19:09 +00:00
|
|
|
bool SetMusicForMap(const char* mapname, const char* music, bool namehack = false);
|
2020-06-23 22:40:22 +00:00
|
|
|
|
2020-07-07 11:19:09 +00:00
|
|
|
MapRecord *FindMapByName(const char *nm);
|
|
|
|
MapRecord *FindMapByLevelNum(int num);
|
|
|
|
MapRecord *FindNextMap(MapRecord *thismap);
|
2020-07-07 18:27:21 +00:00
|
|
|
MapRecord* SetupUserMap(const char* boardfilename, const char *defaultmusic = nullptr);
|
|
|
|
MapRecord* AllocateMap();
|
2019-12-10 21:22:59 +00:00
|
|
|
|
2020-08-03 18:11:30 +00:00
|
|
|
// These should be the only places converting between level numbers and volume/map pairs
|
|
|
|
constexpr inline int levelnum(int vol, int map)
|
|
|
|
{
|
|
|
|
return vol * 1000 + map;
|
|
|
|
}
|
|
|
|
|
|
|
|
constexpr inline int volfromlevelnum(int num)
|
|
|
|
{
|
2020-08-18 18:12:04 +00:00
|
|
|
return num >= 0 ? num / 1000 : 0;
|
2020-08-03 18:11:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
constexpr inline int mapfromlevelnum(int num)
|
|
|
|
{
|
2020-08-18 18:12:04 +00:00
|
|
|
return num >= 0 ? num % 1000 : -1;
|
2020-08-03 18:11:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-12-10 21:22:59 +00:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
RRENDSLOT = 127
|
2020-08-03 18:11:30 +00:00
|
|
|
};
|