- migrated Exhumed's level setup to RMAPINFO.

This game never had a proper setup so this also fixes the crashes with visiting the multiplayer maps.
This commit is contained in:
Christoph Oelckers 2021-05-02 15:54:19 +02:00
parent bb9d492db6
commit 4b064b9f34
17 changed files with 381 additions and 145 deletions

View file

@ -557,6 +557,39 @@ DEFINE_MAP_OPTION(rr_mamaspawn, false)
info->rr_mamaspawn = parse.sc.Number; info->rr_mamaspawn = parse.sc.Number;
} }
DEFINE_MAP_OPTION(ex_ramses_horiz, false)
{
parse.ParseAssign();
parse.sc.MustGetNumber();
info->ex_ramses_horiz = parse.sc.Number;
}
DEFINE_MAP_OPTION(ex_ramses_cdtrack, false)
{
parse.ParseAssign();
parse.sc.MustGetNumber();
info->ex_ramses_cdtrack = parse.sc.Number;
}
DEFINE_MAP_OPTION(ex_ramses_pup, false)
{
parse.ParseAssign();
parse.sc.MustGetString();
info->ex_ramses_pup = parse.sc.Number;
}
DEFINE_MAP_OPTION(ex_ramses_text, false)
{
parse.ParseAssign();
parse.sc.MustGetString();
info->ex_ramses_text = parse.sc.Number;
}
int ex_ramses_horiz = 11;
int ex_ramses_cdtrack = -1; // this is not music, it is the actual dialogue!
FString ex_ramses_pup;
FString ex_ramses_text;
//========================================================================== //==========================================================================
// //
// All flag based map options // All flag based map options
@ -592,6 +625,10 @@ MapFlagHandlers[] =
{ "forcenoeog", MITYPE_SETFLAG, LEVEL_FORCENOEOG, 0, -1 }, { "forcenoeog", MITYPE_SETFLAG, LEVEL_FORCENOEOG, 0, -1 },
{ "rrra_hulkspawn", MITYPE_SETFLAGG,LEVEL_RR_HULKSPAWN, 0, GAMEFLAG_RRRA }, { "rrra_hulkspawn", MITYPE_SETFLAGG,LEVEL_RR_HULKSPAWN, 0, GAMEFLAG_RRRA },
{ "rr_clearmoonshine", MITYPE_SETFLAGG,LEVEL_RR_CLEARMOONSHINE, 0, GAMEFLAG_RR }, { "rr_clearmoonshine", MITYPE_SETFLAGG,LEVEL_RR_CLEARMOONSHINE, 0, GAMEFLAG_RR },
{ "ex_training", MITYPE_SETFLAGG,LEVEL_EX_TRAINING, 0, GAMEFLAG_PSEXHUMED },
{ "ex_altsound", MITYPE_SETFLAGG,LEVEL_EX_ALTSOUND, 0, GAMEFLAG_PSEXHUMED },
{ "ex_countdown", MITYPE_SETFLAGG,LEVEL_EX_COUNTDOWN, 0, GAMEFLAG_PSEXHUMED },
{ "ex_multi", MITYPE_SETFLAGG,LEVEL_EX_MULTI, 0, GAMEFLAG_PSEXHUMED },
{ NULL, MITYPE_IGNORE, 0, 0} { NULL, MITYPE_IGNORE, 0, 0}
}; };

View file

@ -36,6 +36,12 @@ enum EMapGameFlags
{ {
LEVEL_RR_HULKSPAWN = 1, LEVEL_RR_HULKSPAWN = 1,
LEVEL_RR_CLEARMOONSHINE = 2, LEVEL_RR_CLEARMOONSHINE = 2,
LEVEL_EX_COUNTDOWN = 4,
LEVEL_EX_TRAINING = 8,
LEVEL_EX_ALTSOUND = 16,
LEVEL_EX_MULTI = 32,
}; };
// 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.
@ -151,6 +157,10 @@ struct MapRecord
// game specific stuff // game specific stuff
int rr_startsound = 0; int rr_startsound = 0;
int rr_mamaspawn = 15; int rr_mamaspawn = 15;
int ex_ramses_horiz = 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 const char* LabelName() const
{ {

View file

@ -410,10 +410,9 @@ void TextOverlay::ComputeCinemaText()
nHeight = screentext.Size() * 10; nHeight = screentext.Size() * 10;
} }
void TextOverlay::ReadyCinemaText(uint16_t nVal) void TextOverlay::ReadyCinemaText(const char* nVal)
{ {
FStringf label("TXT_EX_CINEMA%d", nVal); FString label = nVal[0] == '$'? GStrings(nVal +1) : nVal;
label = GStrings(label);
screentext = label.Split("\n"); screentext = label.Split("\n");
ComputeCinemaText(); ComputeCinemaText();
} }

View file

@ -262,7 +262,7 @@ void GameMove(void)
sprite[i].backuploc(); sprite[i].backuploc();
} }
if (currentLevel->levelNumber == kMap20) if (currentLevel->gameflags & LEVEL_EX_COUNTDOWN)
{ {
if (lCountDown <= 0) if (lCountDown <= 0)
{ {
@ -471,7 +471,7 @@ void GameInterface::Ticker()
void LevelFinished() void LevelFinished()
{ {
NextMap = currentLevel->levelNumber == 20 ? nullptr : FindMapByLevelNum(currentLevel->levelNumber + 1); // todo: Use the map record for progression NextMap = FindNextMap(currentLevel);
EndLevel = 13; EndLevel = 13;
} }
@ -496,26 +496,6 @@ void GameInterface::app_init()
help_disabled = true; help_disabled = true;
#endif #endif
auto vol0 = MustFindVolume(0);
auto vol1 = MustFindVolume(1);
if (vol0) vol0->startmap = "LEV1";
if (vol1) vol1->startmap = "LEV0";
// Create the global level table. Parts of the engine need it, even though the game itself does not.
for (int i = 0; i <= 32; i++)
{
auto mi = AllocateMap();
mi->fileName.Format("LEV%d.MAP", i);
mi->labelName.Format("LEV%d", i);
mi->name.Format("$TXT_EX_MAP%02d", i);
mi->levelNumber = i;
mi->cluster = i? 1 : 2; // training is cluster 2
int nTrack = i;
if (nTrack != 0) nTrack--;
mi->cdSongId = (nTrack % 8) + 11;
}
InitCheats(); InitCheats();
registerosdcommands(); registerosdcommands();
if (nNetPlayerCount == -1) if (nNetPlayerCount == -1)
@ -637,7 +617,7 @@ void SerializeState(FSerializer& arc)
int loaded = 0; int loaded = 0;
if (arc.BeginObject("state")) if (arc.BeginObject("state"))
{ {
if (arc.isReading() && currentLevel->levelNumber == 20) if (arc.isReading() && (currentLevel->gameflags & LEVEL_EX_COUNTDOWN))
{ {
InitEnergyTile(); InitEnergyTile();
} }

View file

@ -188,7 +188,7 @@ public:
void Start(double starttime); void Start(double starttime);
void ComputeCinemaText(); void ComputeCinemaText();
void ReadyCinemaText(uint16_t nVal); void ReadyCinemaText(const char* nVal);
void DisplayText(); void DisplayText();
bool AdvanceCinemaText(double clock); bool AdvanceCinemaText(double clock);
void SetPalette(int pal) { currentCinemaPalette = pal; } void SetPalette(int pal) { currentCinemaPalette = pal; }

View file

@ -69,7 +69,7 @@ void GameInterface::Render()
drawtime.Reset(); drawtime.Reset();
drawtime.Clock(); drawtime.Clock();
if (currentLevel && currentLevel->levelNumber == kMap20) if (currentLevel && (currentLevel->gameflags & LEVEL_EX_COUNTDOWN))
{ {
DoEnergyTile(); DoEnergyTile();
DrawClock(); DrawClock();
@ -153,7 +153,7 @@ DEFINE_ACTION_FUNCTION(DMapScreen, SetNextLevel)
void GameInterface::LevelCompleted(MapRecord *to_map, int skill) void GameInterface::LevelCompleted(MapRecord *to_map, int skill)
{ {
Mus_Stop(); Mus_Stop();
if (currentLevel->levelNumber == 0) if (currentLevel->gameflags & LEVEL_EX_TRAINING)
{ {
gameaction = ga_mainmenu; gameaction = ga_mainmenu;
return; return;
@ -168,8 +168,8 @@ void GameInterface::LevelCompleted(MapRecord *to_map, int skill)
{ {
if (to_map->levelNumber > nBestLevel) nBestLevel = to_map->levelNumber - 1; if (to_map->levelNumber > nBestLevel) nBestLevel = to_map->levelNumber - 1;
if (to_map->levelNumber == 20) nPlayerLives[0] = 0; if (to_map->gameflags & LEVEL_EX_COUNTDOWN) nPlayerLives[0] = 0;
if (to_map->levelNumber == 0) // skip all intermission stuff when going to the training map. if (to_map->gameflags & LEVEL_EX_TRAINING)
{ {
gameaction = ga_nextlevel; gameaction = ga_nextlevel;
return; return;

View file

@ -68,7 +68,7 @@ uint8_t bIsVersion6 = true;
uint8_t LoadLevel(MapRecord* map) uint8_t LoadLevel(MapRecord* map)
{ {
if (map->levelNumber == kMap20) if (map->gameflags & LEVEL_EX_COUNTDOWN)
{ {
lCountDown = 81000; lCountDown = 81000;
nAlarmTicks = 30; nAlarmTicks = 30;
@ -116,12 +116,12 @@ uint8_t LoadLevel(MapRecord* map)
InitItems(); InitItems();
InitInput(); InitInput();
if (map->levelNumber == kMap20) { if (map->gameflags & LEVEL_EX_COUNTDOWN) {
InitEnergyTile(); InitEnergyTile();
} }
} }
if (map->levelNumber > 15) if (map->gameflags & LEVEL_EX_ALTSOUND)
{ {
nSwitchSound = 35; nSwitchSound = 35;
nStoneSound = 23; nStoneSound = 23;
@ -196,10 +196,8 @@ void InitLevel(MapRecord* map)
RefreshStatus(); RefreshStatus();
int nTrack = map->levelNumber; if (!mus_redbook && map->music.IsNotEmpty()) Mus_Play(map->labelName, map->music, true); // Allow non-CD music if defined for the current level
if (nTrack != 0) nTrack--; playCDtrack(map->cdSongId, true);
playCDtrack((nTrack % 8) + 11, true);
setLevelStarted(currentLevel); setLevelStarted(currentLevel);
} }

View file

@ -432,7 +432,7 @@ void StartRegenerate(short nSprite)
pSprite->extra = 1350; pSprite->extra = 1350;
pSprite->ang = nFirstRegenerate; pSprite->ang = nFirstRegenerate;
if (currentLevel->levelNumber <= kMap20) if (!(currentLevel->gameflags & LEVEL_EX_MULTI))
{ {
pSprite->ang /= 5; pSprite->ang /= 5;
} }

View file

@ -207,7 +207,7 @@ void MoveThings()
DoMovingSects(); DoMovingSects();
DoRegenerates(); DoRegenerates();
if (currentLevel->levelNumber == kMap20) if (currentLevel->gameflags & LEVEL_EX_COUNTDOWN)
{ {
DoFinale(); DoFinale();
if (lCountDown < 1800 && nDronePitch < 2400 && !lFinaleStart) if (lCountDown < 1800 && nDronePitch < 2400 && !lFinaleStart)

View file

@ -2254,7 +2254,7 @@ FUNCOBJECT_GOTO:
} }
} }
if (currentLevel->levelNumber <= 20 || nStat != kStatExplodeTrigger) if (!(currentLevel->gameflags & LEVEL_EX_MULTI) || nStat != kStatExplodeTrigger)
{ {
runlist_SubRunRec(sprite[nSprite].owner); runlist_SubRunRec(sprite[nSprite].owner);
runlist_SubRunRec(ObjectList[nObject].field_4); runlist_SubRunRec(ObjectList[nObject].field_4);
@ -2689,7 +2689,7 @@ void PostProcess()
} }
} }
if (currentLevel->levelNumber != kMap20) if (!(currentLevel->gameflags & LEVEL_EX_COUNTDOWN))
{ {
// esi is i // esi is i
for (i = 0; i < numsectors; i++) for (i = 0; i < numsectors; i++)

View file

@ -417,7 +417,7 @@ void RestartPlayer(short nPlayer)
plr->nAir = 100; plr->nAir = 100;
airpages = 0; airpages = 0;
if (currentLevel->levelNumber <= kMap20) if (!(currentLevel->gameflags & LEVEL_EX_MULTI))
{ {
RestoreMinAmmo(nPlayer); RestoreMinAmmo(nPlayer);
} }
@ -570,7 +570,7 @@ void StartDeathSeq(int nPlayer, int nVal)
BuildStatusAnim((3 * (nLives - 1)) + 7, 0); BuildStatusAnim((3 * (nLives - 1)) + 7, 0);
} }
if (currentLevel->levelNumber > 0) { // if not on the training level if (!(currentLevel->gameflags & LEVEL_EX_TRAINING)) { // if not on the training level
nPlayerLives[nPlayer]--; nPlayerLives[nPlayer]--;
} }
@ -679,7 +679,7 @@ void FuncPlayer(int a, int nDamage, int nRun)
{ {
int var_48 = 0; int var_48 = 0;
int var_40; int var_40;
bool mplevel = currentLevel->levelNumber > 20; bool mplevel = (currentLevel->gameflags & LEVEL_EX_MULTI);
short nPlayer = RunData[nRun].nVal; short nPlayer = RunData[nRun].nVal;
assert(nPlayer >= 0 && nPlayer < kMaxPlayers); assert(nPlayer >= 0 && nPlayer < kMaxPlayers);
@ -1033,14 +1033,7 @@ void FuncPlayer(int a, int nDamage, int nRun)
InitSpiritHead(); InitSpiritHead();
PlayerList[nPlayer].nDestVertPan = q16horiz(0); PlayerList[nPlayer].nDestVertPan = q16horiz(0);
if (currentLevel->levelNumber == 11) PlayerList[nPlayer].horizon.settarget(currentLevel->ex_ramses_horiz);
{
PlayerList[nPlayer].horizon.settarget(46);
}
else
{
PlayerList[nPlayer].horizon.settarget(11);
}
} }
} }
else else

View file

@ -64,8 +64,6 @@ short nTalkTime = 0;
void InitSpiritHead() void InitSpiritHead()
{ {
char filename[20];
nPixels = 0; nPixels = 0;
nSpiritRepeatX = sprite[nSpiritSprite].xrepeat; nSpiritRepeatX = sprite[nSpiritSprite].xrepeat;
@ -137,26 +135,15 @@ void InitSpiritHead()
fadecdaudio(); fadecdaudio();
int nTrack; int nTrack = currentLevel->ex_ramses_cdtrack;
if (currentLevel->levelNumber == 1)
{
nTrack = 3;
}
else
{
nTrack = 7;
}
playCDtrack(nTrack, false); playCDtrack(nTrack, false);
StartSwirlies(); StartSwirlies();
sprintf(filename, "LEV%d.PUP", currentLevel->levelNumber);
lNextStateChange = PlayClock; lNextStateChange = PlayClock;
lHeadStartClock = PlayClock; lHeadStartClock = PlayClock;
auto headfd = fileSystem.OpenFileReader(filename); auto headfd = fileSystem.OpenFileReader(currentLevel->ex_ramses_pup);
if (!headfd.isOpen()) if (!headfd.isOpen())
{ {
memset(cPupData, 0, sizeof(cPupData)); memset(cPupData, 0, sizeof(cPupData));

View file

@ -117,7 +117,7 @@ void GameInterface::SerializeGameState(FSerializer& arc)
parallaxtype = 2; parallaxtype = 2;
g_visibility = 1024; g_visibility = 1024;
if (currentLevel->levelNumber > 15) if (currentLevel->gameflags & LEVEL_EX_ALTSOUND)
{ {
nSwitchSound = 35; nSwitchSound = 35;
nStoneSound = 23; nStoneSound = 23;

View file

@ -724,7 +724,7 @@ void CheckAmbience(short nSector)
void UpdateCreepySounds() void UpdateCreepySounds()
{ {
if (currentLevel->levelNumber == 20 || nFreeze || !SoundEnabled()) if ((currentLevel->gameflags & LEVEL_EX_COUNTDOWN) || nFreeze || !SoundEnabled())
return; return;
spritetype* pSprite = &sprite[PlayerList[nLocalPlayer].nSprite]; spritetype* pSprite = &sprite[PlayerList[nLocalPlayer].nSprite];
nCreepyTimer--; nCreepyTimer--;

View file

@ -402,10 +402,7 @@ void DrawView(double smoothRatio, bool sceneonly)
if (bSubTitles) if (bSubTitles)
{ {
subtitleOverlay.Start(I_GetTimeNS() * (120. / 1'000'000'000)); subtitleOverlay.Start(I_GetTimeNS() * (120. / 1'000'000'000));
if (currentLevel->levelNumber == 1) subtitleOverlay.ReadyCinemaText(currentLevel->ex_ramses_text);
subtitleOverlay.ReadyCinemaText(1);
else
subtitleOverlay.ReadyCinemaText(5);
} }
inputState.ClearAllInput(); inputState.ClearAllInput();
} }

View file

@ -1,71 +0,0 @@
// Cutscene definitions for Duke
definecutscene intro
{
function ExhumedCutscenes.BuildIntro
}
definecutscene map lev5
{
intro
{
function ExhumedCutscenes.BuildCinemaBefore5
}
}
definecutscene map lev10
{
outro
{
function ExhumedCutscenes.BuildCinemaAfter10
}
}
definecutscene map lev11
{
intro
{
function ExhumedCutscenes.BuildCinemaBefore11
}
}
definecutscene map lev15
{
outro
{
function ExhumedCutscenes.BuildCinemaAfter15
}
}
definecutscene map lev20
{
intro
{
function ExhumedCutscenes.BuildCinemaBefore20
}
outro
{
function ExhumedCutscenes.BuildCinemaAfter20
}
}
/*
definecutscene gameover
{
function ExhumedCutscenes.BuildGameoverScene
}
definecutscene lose
{
function ExhumedCutscenes.BuildCinemaLose
}
definecutscene loading
{
function DukeCutscenes.BuildLoading
}
*/
definecutscene summary ExhumedCutscenes.BuildMap
//definecutscene mpsummary DukeCutscenes.BuildMPSummary

View file

@ -0,0 +1,306 @@
episode LEV1
{
name = "Exhumed"
noskillmenu
}
episode LEV0
{
name = "$TXT_EX_MAP00"
noskillmenu
}
cluster 1
{
name = "Exhumed"
gameover
{
function = ExhumedCutscenes.BuildGameoverScene
}
}
cluster 2
{
name = "$TXT_EX_MAP00"
}
cluster 3
{
name = "Multiplayer"
}
cluster 4
{
gameover
{
function = ExhumedCutscenes.BuildCinemaLose
}
}
map lev0 "$TXT_EX_MAP00"
{
cdtrack = 11
ex_training
cluster = 2
}
map lev1 "$TXT_EX_MAP01"
{
cdtrack = 11
cluster = 1
ex_ramses_cdtrack = 3
ex_ramses_pup = "lev1.pup"
ex_ramses_text = "$TXT_EX_CINEMA1"
}
map lev2 "$TXT_EX_MAP02"
{
cdtrack = 12
cluster = 1
}
map lev3 "$TXT_EX_MAP03"
{
cdtrack = 13
cluster = 1
}
map lev4 "$TXT_EX_MAP04"
{
cdtrack = 14
cluster = 1
}
map lev5 "$TXT_EX_MAP05"
{
cdtrack = 15
cluster = 1
intro
{
function = ExhumedCutscenes.BuildCinemaBefore5
}
}
map lev6 "$TXT_EX_MAP06"
{
cdtrack = 16
cluster = 1
}
map lev7 "$TXT_EX_MAP07"
{
cdtrack = 17
cluster = 1
}
map lev8 "$TXT_EX_MAP08"
{
cdtrack = 18
cluster = 1
}
map lev9 "$TXT_EX_MAP09"
{
cdtrack = 11
cluster = 1
}
map lev10 "$TXT_EX_MAP10"
{
cdtrack = 12
cluster = 1
outro
{
function = ExhumedCutscenes.BuildCinemaAfter10
}
}
map lev11 "$TXT_EX_MAP11"
{
cdtrack = 13
cluster = 1
ex_ramses_cdtrack = 7
ex_ramses_pup = "lev11.pup"
ex_ramses_text = "$TXT_EX_CINEMA5"
ex_ramses_horiz = 46
intro
{
function = ExhumedCutscenes.BuildCinemaBefore11
}
}
map lev12 "$TXT_EX_MAP12"
{
cdtrack = 14
cluster = 1
}
map lev13 "$TXT_EX_MAP13"
{
cdtrack = 15
cluster = 1
}
map lev14 "$TXT_EX_MAP14"
{
cdtrack = 16
cluster = 1
}
map lev15 "$TXT_EX_MAP15"
{
cdtrack = 17
cluster = 1
outro
{
function = ExhumedCutscenes.BuildCinemaAfter15
}
}
map lev16 "$TXT_EX_MAP16"
{
cdtrack = 18
cluster = 1
ex_altsound
}
map lev17 "$TXT_EX_MAP17"
{
cdtrack = 11
cluster = 1
ex_altsound
}
map lev18 "$TXT_EX_MAP18"
{
cdtrack = 12
cluster = 1
ex_altsound
}
map lev19 "$TXT_EX_MAP19"
{
cdtrack = 13
cluster = 1
ex_altsound
}
map lev20 "$TXT_EX_MAP20"
{
cdtrack = 14
cluster = 4
next = "-"
ex_altsound
ex_countdown
intro
{
function = ExhumedCutscenes.BuildCinemaBefore20
}
outro
{
function = ExhumedCutscenes.BuildCinemaAfter20
}
}
map lev21 "$TXT_EX_MAP21"
{
cdtrack = 15
cluster = 3
ex_multi
}
map lev22 "$TXT_EX_MAP22"
{
cdtrack = 16
cluster = 3
ex_multi
}
map lev23 "$TXT_EX_MAP23"
{
cdtrack = 17
cluster = 3
ex_multi
}
map lev24 "$TXT_EX_MAP24"
{
cdtrack = 18
cluster = 3
ex_multi
}
map lev25 "$TXT_EX_MAP25"
{
cdtrack = 11
cluster = 3
ex_multi
}
map lev26 "$TXT_EX_MAP26"
{
cdtrack = 12
cluster = 3
ex_multi
}
map lev27 "$TXT_EX_MAP27"
{
cdtrack = 13
cluster = 3
ex_multi
}
map lev28 "$TXT_EX_MAP28"
{
cdtrack = 14
cluster = 3
ex_multi
}
map lev29 "$TXT_EX_MAP29"
{
cdtrack = 15
cluster = 3
ex_multi
}
map lev30 "$TXT_EX_MAP30"
{
cdtrack = 16
cluster = 3
ex_multi
}
map lev31 "$TXT_EX_MAP31"
{
cdtrack = 17
cluster = 3
ex_multi
}
map lev32 "$TXT_EX_MAP32"
{
cdtrack = 18
cluster = 3
ex_multi
}
cutscenes
{
intro
{
function = ExhumedCutscenes.BuildIntro
}
loadscreen
{
function = DukeCutscenes.BuildLoading
}
}
gameinfo
{
summaryscreen = ExhumedCutscenes.BuildMap
}