mirror of
https://github.com/ZDoom/Raze.git
synced 2024-11-23 20:42:45 +00:00
346 lines
7 KiB
C++
346 lines
7 KiB
C++
#pragma once
|
|
|
|
#include "gstrings.h"
|
|
#include "cmdlib.h"
|
|
#include "quotemgr.h"
|
|
#include "palentry.h"
|
|
#include "vectors.h"
|
|
#include "screenjob.h"
|
|
#include "maptypes.h"
|
|
#include "d_net.h"
|
|
|
|
#ifdef GetMessage
|
|
#undef GetMessage // Windows strikes...
|
|
#endif
|
|
|
|
enum EMax
|
|
{
|
|
MAXSKILLS = 7,
|
|
MAXMENUGAMEPLAYENTRIES = 7,
|
|
};
|
|
|
|
enum EVolFlags
|
|
{
|
|
VF_HIDEFROMSP = 1,
|
|
VF_OPTIONAL = 2,
|
|
VF_SHAREWARELOCK = 4, // show in shareware but lock access.
|
|
VF_NOSKILL = 8,
|
|
};
|
|
|
|
enum EMapFlags
|
|
{
|
|
LEVEL_NOINTERMISSION = 1,
|
|
LEVEL_SECRETEXITOVERRIDE = 2, // when given an explicit level number, override with secret exit in the map, mainly for compiling episodes out of single levels.
|
|
LEVEL_CLEARINVENTORY = 4,
|
|
LEVEL_CLEARWEAPONS = 8,
|
|
LEVEL_FORCENOEOG = 16, // RR E1L7 needs this to override its boss's death ending the game.
|
|
};
|
|
|
|
enum EMapGameFlags
|
|
{
|
|
LEVEL_RR_HULKSPAWN = 1,
|
|
LEVEL_RR_CLEARMOONSHINE = 2,
|
|
|
|
LEVEL_EX_COUNTDOWN = 4,
|
|
LEVEL_EX_TRAINING = 8,
|
|
LEVEL_EX_ALTSOUND = 16,
|
|
LEVEL_EX_MULTI = 32,
|
|
|
|
LEVEL_SW_SPAWNMINES = 64,
|
|
LEVEL_SW_BOSSMETER_SERPENT = 128,
|
|
LEVEL_SW_BOSSMETER_SUMO = 256,
|
|
LEVEL_SW_BOSSMETER_ZILLA = 512,
|
|
LEVEL_SW_DEATHEXIT_SERPENT = 1024,
|
|
LEVEL_SW_DEATHEXIT_SUMO = 2048,
|
|
LEVEL_SW_DEATHEXIT_ZILLA = 4096,
|
|
LEVEL_SW_DEATHEXIT_SERPENT_NEXT = 8192,
|
|
|
|
LEVEL_WT_BOSSSPAWN = 16384,
|
|
|
|
LEVEL_BOSSONLYCUTSCENE = 32768,
|
|
};
|
|
|
|
// These get filled in by the map definition parsers of the front ends.
|
|
extern FString gSkillNames[MAXSKILLS];
|
|
extern int gDefaultVolume, gDefaultSkill;
|
|
|
|
|
|
// Localization capable replacement of the game specific solutions.
|
|
|
|
enum
|
|
{
|
|
MI_FORCEEOG = 1,
|
|
MI_USERMAP = 2,
|
|
};
|
|
|
|
enum {
|
|
MAX_MESSAGES = 32
|
|
};
|
|
|
|
class DObject;
|
|
struct MapRecord;
|
|
|
|
struct GlobalCutscenes
|
|
{
|
|
CutsceneDef Intro;
|
|
CutsceneDef DefaultMapIntro;
|
|
CutsceneDef DefaultMapOutro;
|
|
CutsceneDef DefaultGameover;
|
|
CutsceneDef SharewareEnd;
|
|
CutsceneDef LoadingScreen;
|
|
FString MPSummaryScreen;
|
|
FString SummaryScreen;
|
|
FString StatusBarClass;
|
|
};
|
|
|
|
struct ClusterDef
|
|
{
|
|
FString name; // What gets displayed for this cluster. In Duke this is normally the corresponding volume name but does not have to be.
|
|
CutsceneDef intro; // plays when entering this cluster
|
|
CutsceneDef outro; // plays when leaving this cluster
|
|
CutsceneDef gameover; // when defined, plays when the player dies in this cluster
|
|
FString InterBackground;
|
|
int index = -1;
|
|
int flags = 0; // engine and common flags
|
|
};
|
|
|
|
struct VolumeRecord // episodes
|
|
{
|
|
FString startmap;
|
|
FString name;
|
|
FString subtitle;
|
|
int index = -1;
|
|
int flags = 0;
|
|
int shortcut = 0;
|
|
};
|
|
|
|
struct MapRecord
|
|
{
|
|
int parTime = 0;
|
|
int designerTime = 0;
|
|
FString fileName;
|
|
FString labelName;
|
|
FString name;
|
|
FString music;
|
|
FString Author;
|
|
FString NextMap;
|
|
FString NextSecret;
|
|
int cdSongId = -1;
|
|
int musicorder = -1;
|
|
|
|
CutsceneDef intro;
|
|
CutsceneDef outro;
|
|
int flags = 0;
|
|
int gameflags = 0;
|
|
int levelNumber = -1;
|
|
int cluster = -1;
|
|
|
|
PalEntry fadeto = 0;
|
|
int fogdensity = 0;
|
|
int skyfog = 0;
|
|
FString BorderTexture;
|
|
FString InterBackground;
|
|
TArray<FString> PrecacheTextures;
|
|
FVector4 skyrotatevector;
|
|
|
|
// The rest is only used by Blood
|
|
FString messages[MAX_MESSAGES];
|
|
int8_t fog = -1, weather = -1; // Blood defines these but they aren't used.
|
|
|
|
// game specific stuff
|
|
int rr_startsound = 0;
|
|
int rr_mamaspawn = 15;
|
|
DAngle ex_ramses_horiz = maphoriz(-11);
|
|
int ex_ramses_cdtrack = -1; // this is not music, it is the actual dialogue!
|
|
FString ex_ramses_pup;
|
|
FString ex_ramses_text;
|
|
|
|
const char* LabelName() const
|
|
{
|
|
if (flags & MI_USERMAP) return GStrings("MNU_USERMAP");
|
|
return labelName.GetChars();
|
|
}
|
|
const char *DisplayName() const
|
|
{
|
|
if (name.IsEmpty()) return labelName.GetChars();
|
|
return GStrings.localize(name.GetChars());
|
|
}
|
|
void SetName(const char *n)
|
|
{
|
|
name = n;
|
|
name.StripRight();
|
|
name = FStringTable::MakeMacro(name.GetChars());
|
|
}
|
|
void SetFileName(const char* n)
|
|
{
|
|
if (*n == '/' || *n == '\\') n++;
|
|
fileName = n;
|
|
FixPathSeperator(fileName);
|
|
labelName = ExtractFileBase(n);
|
|
}
|
|
const char* GetMessage(int num)
|
|
{
|
|
if (num < 0 || num>= MAX_MESSAGES) return "";
|
|
return GStrings(messages[num]);
|
|
}
|
|
|
|
void AddMessage(int num, const FString &msg)
|
|
{
|
|
messages[num] = msg;
|
|
}
|
|
};
|
|
|
|
struct StatRecord
|
|
{
|
|
int max;
|
|
int got;
|
|
int player[MAXPLAYERS];
|
|
|
|
void addTotal(int amount = 1)
|
|
{
|
|
max += amount;
|
|
if (amount < 0 && max < 0) max = 0;
|
|
}
|
|
|
|
void add(int playerno, int amount = 1)
|
|
{
|
|
got += amount;
|
|
if (amount < 0 && got < 0) got = 0;
|
|
if (playerno >= 0 && playerno < MAXPLAYERS)
|
|
{
|
|
player[playerno] += amount;
|
|
if (amount < 0 && player[playerno] < 0) player[playerno] = 0;
|
|
}
|
|
}
|
|
|
|
void clear()
|
|
{
|
|
memset(this, 0, sizeof(*this));
|
|
}
|
|
};
|
|
|
|
struct SummaryInfo
|
|
{
|
|
int kills;
|
|
int maxkills;
|
|
int secrets;
|
|
int maxsecrets;
|
|
int supersecrets;
|
|
int time;
|
|
int totaltime;
|
|
int playercount;
|
|
bool cheated;
|
|
bool endofgame;
|
|
};
|
|
|
|
struct MapLocals
|
|
{
|
|
StatRecord kills, secrets, superSecrets;
|
|
|
|
void fillSummary(SummaryInfo& sum);
|
|
|
|
void clearStats()
|
|
{
|
|
kills.clear();
|
|
secrets.clear();
|
|
superSecrets.clear();
|
|
}
|
|
|
|
void setKills(int num)
|
|
{
|
|
kills.clear();
|
|
kills.max = num;
|
|
}
|
|
|
|
void setSecrets(int num, int supernum = 0)
|
|
{
|
|
secrets.clear();
|
|
secrets.max = num;
|
|
superSecrets.clear();
|
|
superSecrets.max = supernum;
|
|
}
|
|
|
|
void addKillCount(int amount = 1)
|
|
{
|
|
kills.addTotal(amount);
|
|
}
|
|
|
|
void addSecretCount(int amount = 1)
|
|
{
|
|
secrets.addTotal(amount);
|
|
}
|
|
|
|
void addKill(int playerno, int amount = 1)
|
|
{
|
|
kills.add(playerno, amount);
|
|
}
|
|
|
|
void addSecret(int playerno, int amount = 1)
|
|
{
|
|
secrets.add(playerno, amount);
|
|
}
|
|
|
|
void addSuperSecret(int playerno, int amount = 1)
|
|
{
|
|
superSecrets.add(playerno, amount);
|
|
}
|
|
|
|
void addFrags(int playerno, int amount)
|
|
{
|
|
// todo
|
|
}
|
|
|
|
};
|
|
|
|
|
|
extern GlobalCutscenes globalCutscenes;
|
|
extern MapRecord* currentLevel; // level that is currently played.
|
|
extern MapLocals Level;
|
|
|
|
void SetMusicReplacement(const char *mapname, const char *music);
|
|
void ReplaceMusics(bool namehack = false);
|
|
bool SetMusicForMap(const char* mapname, const char* music, bool namehack = false);
|
|
|
|
MapRecord *FindMapByName(const char *nm);
|
|
MapRecord *FindMapByLevelNum(int num);
|
|
MapRecord* FindMapByIndexOnly(int clst, int num); // this is for map setup where fallbacks are undesirable.
|
|
MapRecord* FindMapByIndex(int clst, int num);
|
|
MapRecord *FindNextMap(MapRecord *thismap);
|
|
MapRecord* FindNextSecretMap(MapRecord* thismap);
|
|
MapRecord* SetupUserMap(const char* boardfilename, const char *defaultmusic = nullptr);
|
|
MapRecord* AllocateMap();
|
|
|
|
VolumeRecord* FindVolume(int index);
|
|
ClusterDef* FindCluster(int index);
|
|
ClusterDef* AllocateCluster();
|
|
VolumeRecord* AllocateVolume();
|
|
void SetLevelNum(MapRecord* info, int num);
|
|
|
|
inline VolumeRecord* MustFindVolume(int index)
|
|
{
|
|
auto r = FindVolume(index);
|
|
if (r) return r;
|
|
r = AllocateVolume();
|
|
r->index = index;
|
|
return r;
|
|
}
|
|
inline ClusterDef* MustFindCluster(int index)
|
|
{
|
|
auto r = FindCluster(index);
|
|
if (r) return r;
|
|
r = AllocateCluster();
|
|
r->index = index;
|
|
return r;
|
|
}
|
|
|
|
|
|
// These should be the only places converting between level numbers and volume/map pairs
|
|
constexpr inline int makelevelnum(int vol, int map)
|
|
{
|
|
return vol * 1000 + map;
|
|
}
|
|
|
|
enum
|
|
{
|
|
RRENDSLOT = 127
|
|
};
|