- adapted map transition in Duke/RR.

There's still some issues which will be taken care of by adding map flags.
This commit is contained in:
Christoph Oelckers 2021-05-02 10:35:43 +02:00
parent e9385ed4e8
commit 1798380f23
9 changed files with 53 additions and 77 deletions

View file

@ -280,6 +280,7 @@ void DeferedStartGame(MapRecord* map, int skill, bool nostopsound)
static MapRecord* levelwarp_common(FCommandLine& argv, const char *cmdname, const char *t2)
{
int numparm = g_gameType & (GAMEFLAG_SW | GAMEFLAG_PSEXHUMED) ? 1 : 2; // Handle games with episodic and non-episodic level order.
if (numparm == 2 && argv.argc() == 2) numparm = 1;
if (argv.argc() <= numparm)
{
if (numparm == 2) Printf(PRINT_BOLD, "%s <e> <m>: %s episode 'e' and map 'm'\n", cmdname, t2);
@ -294,7 +295,7 @@ static MapRecord* levelwarp_common(FCommandLine& argv, const char *cmdname, cons
Printf(PRINT_BOLD, "Invalid level! Numbers must be > 0\n");
return nullptr;
}
auto map = FindMapByLevelNum(numparm == 1 ? m : makelevelnum(e, m));
auto map = FindMapByIndex(e, m);
if (!map)
{
if (numparm == 2) Printf(PRINT_BOLD, "Level E%s L%s not found!\n", argv[1], argv[2]);

View file

@ -1527,8 +1527,8 @@ DEFINE_FIELD_X(MapRecord, MapRecord, cdSongId)
DEFINE_FIELD_X(MapRecord, MapRecord, flags)
DEFINE_FIELD_X(MapRecord, MapRecord, levelNumber)
DEFINE_FIELD_X(MapRecord, MapRecord, cluster)
DEFINE_FIELD_X(MapRecord, MapRecord, nextLevel)
DEFINE_FIELD_X(MapRecord, MapRecord, nextSecret)
DEFINE_FIELD_X(MapRecord, MapRecord, NextMap)
DEFINE_FIELD_X(MapRecord, MapRecord, NextSecret)
//native readonly String messages[MAX_MESSAGES];
DEFINE_FIELD_X(MapRecord, MapRecord, Author)
DEFINE_FIELD_X(MapRecord, MapRecord, InterBackground)

View file

@ -195,7 +195,7 @@ MapRecord* FindNextMap(MapRecord* thismap)
MapRecord* next = nullptr;
if (!thismap->NextMap.Compare("-")) return nullptr; // '-' means to forcibly end the game here.
if (thismap->NextMap.IsNotEmpty()) next = FindMapByName(thismap->NextMap);
if (!next) next = FindMapByLevelNum(thismap->levelNumber);
if (!next) next = FindMapByLevelNum(thismap->levelNumber + 1);
return next;
}
@ -208,28 +208,6 @@ MapRecord* FindNextSecretMap(MapRecord* thismap)
}
// return a map whose cluster and map number matches.
// if there's only one map with the given level number return that.
MapRecord* FindMapByClusterAndLevelNum(int cluster, int num)
{
MapRecord* mr = nullptr;
int mapfound = 0;
for (auto& map : mapList)
{
if (map->levelNumber == num)
{
if (map->cluster == cluster) return map.Data();
else
{
mr = map.Data();
mapfound++;
}
}
}
if (mapfound == 1) return mr;
return nullptr;
}
bool SetMusicForMap(const char* mapname, const char* music, bool namehack)
{
static const char* specials[] = { "intro", "briefing", "loading" };
@ -256,7 +234,7 @@ bool SetMusicForMap(const char* mapname, const char* music, bool namehack)
if (numMatches != 4 || toupper(b1) != 'E' || toupper(b2) != 'L')
return false;
index = FindMapByLevelNum(makelevelnum(ep - 1, lev - 1));
index = FindMapByIndexOnly(ep, lev);
}
if (index != nullptr)

View file

@ -143,8 +143,6 @@ struct MapRecord
FVector4 skyrotatevector;
// The rest is only used by Blood
int nextLevel = -1;
int nextSecret = -1;
FString messages[MAX_MESSAGES];
int8_t fog = -1, weather = -1; // Blood defines these but they aren't used.
@ -207,7 +205,6 @@ 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* FindMapByClusterAndLevelNum(int clst, int num);
MapRecord *FindNextMap(MapRecord *thismap);
MapRecord* FindNextSecretMap(MapRecord* thismap);
MapRecord* SetupUserMap(const char* boardfilename, const char *defaultmusic = nullptr);
@ -243,17 +240,6 @@ constexpr inline int makelevelnum(int vol, int map)
return vol * 1000 + map;
}
constexpr inline int volfromlevelnum(int num)
{
return num >= 0 ? num / 1000 : 0;
}
constexpr inline int mapfromlevelnum(int num)
{
return num >= 0 ? num % 1000 : -1;
}
enum
{
RRENDSLOT = 127

View file

@ -48,11 +48,12 @@ Modifications for JonoF's port by Jonathon Fowler (jf@jonof.id.au)
#include "conlabeldef.h"
#include "gi.h"
extern TArray<TPointer<MapRecord>> mapList;
BEGIN_DUKE_NS
enum { VERSIONCHECK = 41 };
//---------------------------------------------------------------------------
//
// definitions needed by the parser.
@ -88,7 +89,8 @@ public:
struct TempMusic
{
int levnum;
int volnum;
int levlnum;
FString music;
};
@ -1016,7 +1018,8 @@ int ConCompiler::parsecommand()
if (k >= 0)
{
tempMusic.Reserve(1);
tempMusic.Last().levnum = makelevelnum(k, i);
tempMusic.Last().volnum = k + 1;
tempMusic.Last().levlnum = i + 1;
tempMusic.Last().music = parsebuffer.Data();
}
else
@ -1701,8 +1704,7 @@ int ConCompiler::parsecommand()
textptr++, i++;
}
parsebuffer.Push(0);
auto levnum = makelevelnum(j, k);
auto map = FindMapByLevelNum(levnum);
auto map = FindMapByIndexOnly(j + 1, k + 1);
if (!map) map = AllocateMap();
map->SetFileName(parsebuffer.Data());
if (k == 0)
@ -1724,7 +1726,9 @@ int ConCompiler::parsecommand()
(((*(textptr + 0) - '0') * 10 + (*(textptr + 1) - '0')) * 60) +
(((*(textptr + 3) - '0') * 10 + (*(textptr + 4) - '0')));
map->levelNumber = levnum;
SetLevelNum(map, makelevelnum(j + 1, k + 1));
map->mapindex = k + 1;
map->cluster = j + 1;
textptr += 5;
@ -3144,7 +3148,7 @@ void ConCompiler::setmusic()
{
for (auto& tm : tempMusic)
{
auto map = FindMapByLevelNum(tm.levnum);
auto map = FindMapByIndexOnly(tm.volnum, tm.levlnum);
if (map) map->music = tm.music;
}
tempMusic.Clear();
@ -3230,30 +3234,30 @@ void loadcons()
void FixMapinfo()
{
// todo: export this to proper map definition features.
// RR must link the last map of E1 to the first map of E2.
for (auto& map : mapList)
{
if (isRR() && map->cluster == 1)
{
auto nextmap = FindMapByIndexOnly(map->cluster + 1, 1);
if (nextmap) map->NextMap = nextmap->labelName;
}
}
if (isWorldTour())
{
// fix broken secret exit in WT's super secret map.
// fix broken secret exit in WT's super secret map.
// This cannot be done from an RMAPINFO definition because the conditions are too specific and must not override custom maps.
int num = fileSystem.CheckNumForName("e1l7.map");
int file = fileSystem.GetFileContainer(num);
if (file <= fileSystem.GetMaxIwadNum())
{
auto maprec = FindMapByName("e1l7");
if (maprec) maprec->nextLevel = makelevelnum(0, 4);
if (maprec) maprec->NextMap = "e1l5";
}
}
else if (isRR())
{
if (true)
{
// RR goes directly to the second episode after E1L7 to continue the game.
auto maprec1 = FindMapByLevelNum(makelevelnum(0, 6)); // E1L7 must exist
auto maprec2 = FindMapByLevelNum(makelevelnum(0, 7)); // E1L8 must not exist
if (maprec1 && !maprec2)
{
maprec1->nextLevel = makelevelnum(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.

View file

@ -3442,7 +3442,7 @@ int ParseState::parse(void)
insptr++; // skip command
volnume = GetGameVarID(*insptr++, g_ac, g_p);
levnume = GetGameVarID(*insptr++, g_ac, g_p);
auto level = FindMapByLevelNum(makelevelnum(volnume - 1, levnume - 1));
auto level = FindMapByIndex(volnume, levnume);
if (level != nullptr)
ChangeLevel(level, -1);
break;
@ -3559,7 +3559,7 @@ int ParseState::parse(void)
{
insptr++;
int music_select = *insptr++;
auto level = FindMapByLevelNum(makelevelnum(currentLevel->cluster, music_select));
auto level = FindMapByIndex(currentLevel->cluster, music_select+1); // this was 0-based in EDuke 2.0...
if (level) S_PlayLevelMusic(level);
break;
}

View file

@ -140,7 +140,7 @@ void resetplayerstats(int snum)
p->jetpack_on = 0;
p->holoduke_on = nullptr;
p->angle.olook_ang = p->angle.look_ang = buildlook(512 - ((currentLevel->levelNumber & 1) << 10));
p->angle.olook_ang = p->angle.look_ang = buildlook(512 - (((~currentLevel->levelNumber) & 1) << 10));
p->angle.orotscrnang = p->angle.rotscrnang = buildlook(0);
p->newOwner =nullptr;
@ -916,14 +916,21 @@ void enterlevel(MapRecord *mi, int gamemode)
for (int i = connecthead; i >= 0; i = connectpoint2[i])
{
bool clearweapon = false;
int pn = sector[ps[i].GetActor()->s->sectnum].floorpicnum;
if (pn == TILE_HURTRAIL || pn == TILE_FLOORSLIME || pn == TILE_FLOORPLASMA)
{
resetweapons(i);
resetinventory(i);
clearweapon = true;
}
if (clearweapon || (isRRRA() && currentLevel->mapindex == 3 && currentLevel->cluster == 1)
|| (!isRRRA() && currentLevel->mapindex == 2 && currentLevel->cluster == 2))
{
resetweapons(i);
ps[i].gotweapon.Clear(PISTOL_WEAPON);
ps[i].ammo_amount[PISTOL_WEAPON] = 0;
ps[i].curr_weapon = KNEE_WEAPON;
ps[i].kickback_pic = 0;
ps[i].okickback_pic = ps[i].kickback_pic = 0;
}
}
@ -932,7 +939,7 @@ void enterlevel(MapRecord *mi, int gamemode)
everyothertime = 0;
global_random = 0;
ud.last_level = currentLevel->levelNumber;
ud.last_level = 1;
ps[myconnectindex].over_shoulder_on = 0;
clearfrags();
resettimevars(); // Here we go
@ -991,7 +998,7 @@ void GameInterface::NewGame(MapRecord* map, int skill, bool)
bool setnextmap(bool checksecretexit)
{
MapRecord* map = nullptr;;
int from_bonus = 0;
MapRecord* from_bonus = nullptr;
if (ud.eog)
{
@ -1000,15 +1007,14 @@ bool setnextmap(bool checksecretexit)
{
if (ud.secretlevel > 0)
{
int newlevnum = makelevelnum(volfromlevelnum(currentLevel->levelNumber), ud.secretlevel-1);
map = FindMapByLevelNum(newlevnum);
map = FindMapByIndex(currentLevel->cluster, ud.secretlevel);
if (map)
{
from_bonus = currentLevel->levelNumber + 1;
from_bonus = FindNextMap(currentLevel);
}
}
}
else if (ud.from_bonus && currentLevel->nextLevel == -1) // if the current level has an explicit link, use that instead of ud.from_bonus.
else if (ud.from_bonus && currentLevel->NextMap.IsEmpty()) // if the current level has an explicit link, use that instead of ud.from_bonus.
{
map = FindMapByLevelNum(ud.from_bonus);
}
@ -1027,7 +1033,7 @@ bool setnextmap(bool checksecretexit)
{
I_Error("Trying to open non-existent %s", map->fileName.GetChars());
}
ud.from_bonus = from_bonus;
ud.from_bonus = from_bonus? from_bonus->levelNumber : 0;
}
CompleteLevel(map);
return false;

View file

@ -7044,7 +7044,7 @@ void MultiPlayLimits(void)
MapRecord *next = nullptr;
// do not increment if level is 23 thru 28 (should be done smarter.)
if (currentLevel->levelNumber <= 22)
next = FindMapByLevelNum(currentLevel->levelNumber + 1);
next = FindNextMap(currentLevel);
ChangeLevel(next, -1);
}
}
@ -7202,7 +7202,7 @@ domovethings(void)
MapRecord *map = nullptr;
if (FinishAnim == ANIM_SUMO)
{
map = FindMapByLevelNum(currentLevel->levelNumber+1);
map = FindNextMap(currentLevel);
}
ChangeLevel(map, -1);
}

View file

@ -66,9 +66,10 @@ struct MapRecord native
native readonly int levelNumber;
native readonly int cluster;
native readonly String InterBackground;
// The rest is only used by Blood
native readonly int nextLevel;
native readonly int nextSecret;
native readonly String nextMap;
native readonly String nextSecret;
//native readonly String messages[MAX_MESSAGES];
native readonly String author;