- 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;
}
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
@ -592,6 +625,10 @@ MapFlagHandlers[] =
{ "forcenoeog", MITYPE_SETFLAG, LEVEL_FORCENOEOG, 0, -1 },
{ "rrra_hulkspawn", MITYPE_SETFLAGG,LEVEL_RR_HULKSPAWN, 0, GAMEFLAG_RRRA },
{ "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}
};

View file

@ -36,6 +36,12 @@ 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,
};
// These get filled in by the map definition parsers of the front ends.
@ -151,6 +157,10 @@ struct MapRecord
// game specific stuff
int rr_startsound = 0;
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
{

View file

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

View file

@ -262,7 +262,7 @@ void GameMove(void)
sprite[i].backuploc();
}
if (currentLevel->levelNumber == kMap20)
if (currentLevel->gameflags & LEVEL_EX_COUNTDOWN)
{
if (lCountDown <= 0)
{
@ -471,7 +471,7 @@ void GameInterface::Ticker()
void LevelFinished()
{
NextMap = currentLevel->levelNumber == 20 ? nullptr : FindMapByLevelNum(currentLevel->levelNumber + 1); // todo: Use the map record for progression
NextMap = FindNextMap(currentLevel);
EndLevel = 13;
}
@ -496,26 +496,6 @@ void GameInterface::app_init()
help_disabled = true;
#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();
registerosdcommands();
if (nNetPlayerCount == -1)
@ -637,7 +617,7 @@ void SerializeState(FSerializer& arc)
int loaded = 0;
if (arc.BeginObject("state"))
{
if (arc.isReading() && currentLevel->levelNumber == 20)
if (arc.isReading() && (currentLevel->gameflags & LEVEL_EX_COUNTDOWN))
{
InitEnergyTile();
}

View file

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

View file

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

View file

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

View file

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

View file

@ -207,7 +207,7 @@ void MoveThings()
DoMovingSects();
DoRegenerates();
if (currentLevel->levelNumber == kMap20)
if (currentLevel->gameflags & LEVEL_EX_COUNTDOWN)
{
DoFinale();
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(ObjectList[nObject].field_4);
@ -2689,7 +2689,7 @@ void PostProcess()
}
}
if (currentLevel->levelNumber != kMap20)
if (!(currentLevel->gameflags & LEVEL_EX_COUNTDOWN))
{
// esi is i
for (i = 0; i < numsectors; i++)

View file

@ -417,7 +417,7 @@ void RestartPlayer(short nPlayer)
plr->nAir = 100;
airpages = 0;
if (currentLevel->levelNumber <= kMap20)
if (!(currentLevel->gameflags & LEVEL_EX_MULTI))
{
RestoreMinAmmo(nPlayer);
}
@ -570,7 +570,7 @@ void StartDeathSeq(int nPlayer, int nVal)
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]--;
}
@ -679,7 +679,7 @@ void FuncPlayer(int a, int nDamage, int nRun)
{
int var_48 = 0;
int var_40;
bool mplevel = currentLevel->levelNumber > 20;
bool mplevel = (currentLevel->gameflags & LEVEL_EX_MULTI);
short nPlayer = RunData[nRun].nVal;
assert(nPlayer >= 0 && nPlayer < kMaxPlayers);
@ -1033,14 +1033,7 @@ void FuncPlayer(int a, int nDamage, int nRun)
InitSpiritHead();
PlayerList[nPlayer].nDestVertPan = q16horiz(0);
if (currentLevel->levelNumber == 11)
{
PlayerList[nPlayer].horizon.settarget(46);
}
else
{
PlayerList[nPlayer].horizon.settarget(11);
}
PlayerList[nPlayer].horizon.settarget(currentLevel->ex_ramses_horiz);
}
}
else

View file

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

View file

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

View file

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

View file

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