From 1798380f238fc70e11489deec7e0c02fc122f7f6 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 2 May 2021 10:35:43 +0200 Subject: [PATCH] - adapted map transition in Duke/RR. There's still some issues which will be taken care of by adding map flags. --- source/core/cheats.cpp | 3 +- source/core/gamecontrol.cpp | 4 +-- source/core/mapinfo.cpp | 26 ++---------------- source/core/mapinfo.h | 14 ---------- source/games/duke/src/gamedef.cpp | 44 ++++++++++++++++-------------- source/games/duke/src/gameexec.cpp | 4 +-- source/games/duke/src/premap.cpp | 24 ++++++++++------ source/games/sw/src/player.cpp | 4 +-- wadsrc/static/zscript/razebase.zs | 7 +++-- 9 files changed, 53 insertions(+), 77 deletions(-) diff --git a/source/core/cheats.cpp b/source/core/cheats.cpp index 6cd00d6cd..d422e5c20 100644 --- a/source/core/cheats.cpp +++ b/source/core/cheats.cpp @@ -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 : %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]); diff --git a/source/core/gamecontrol.cpp b/source/core/gamecontrol.cpp index 01d630e8a..f1e362e82 100644 --- a/source/core/gamecontrol.cpp +++ b/source/core/gamecontrol.cpp @@ -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) diff --git a/source/core/mapinfo.cpp b/source/core/mapinfo.cpp index 253d1a092..1a8a606db 100644 --- a/source/core/mapinfo.cpp +++ b/source/core/mapinfo.cpp @@ -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) diff --git a/source/core/mapinfo.h b/source/core/mapinfo.h index 76d44a95a..765354d19 100644 --- a/source/core/mapinfo.h +++ b/source/core/mapinfo.h @@ -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 diff --git a/source/games/duke/src/gamedef.cpp b/source/games/duke/src/gamedef.cpp index f61e1cee4..962148442 100644 --- a/source/games/duke/src/gamedef.cpp +++ b/source/games/duke/src/gamedef.cpp @@ -48,11 +48,12 @@ Modifications for JonoF's port by Jonathon Fowler (jf@jonof.id.au) #include "conlabeldef.h" #include "gi.h" +extern TArray> 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. diff --git a/source/games/duke/src/gameexec.cpp b/source/games/duke/src/gameexec.cpp index 28e867304..5e8677bc7 100644 --- a/source/games/duke/src/gameexec.cpp +++ b/source/games/duke/src/gameexec.cpp @@ -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; } diff --git a/source/games/duke/src/premap.cpp b/source/games/duke/src/premap.cpp index f09f18878..f31d71946 100644 --- a/source/games/duke/src/premap.cpp +++ b/source/games/duke/src/premap.cpp @@ -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; diff --git a/source/games/sw/src/player.cpp b/source/games/sw/src/player.cpp index 90367ccdb..84e4e34bf 100644 --- a/source/games/sw/src/player.cpp +++ b/source/games/sw/src/player.cpp @@ -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); } diff --git a/wadsrc/static/zscript/razebase.zs b/wadsrc/static/zscript/razebase.zs index 2e6129596..67098cc3c 100644 --- a/wadsrc/static/zscript/razebase.zs +++ b/wadsrc/static/zscript/razebase.zs @@ -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;