mirror of
https://github.com/odamex/odamex
synced 2026-08-19 02:23:09 -04:00
Implement new nextmap logic for the enhanced lastmap
This commit is contained in:
parent
5f8ea94caa
commit
74701da267
6 changed files with 42 additions and 33 deletions
|
|
@ -20,9 +20,9 @@
|
|||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef __C_MAPLIST__
|
||||
#define __C_MAPLIST__
|
||||
#pragma once
|
||||
|
||||
#include <nonstd/expected.hpp>
|
||||
|
||||
// Maplist statuses
|
||||
enum maplist_status_t
|
||||
|
|
@ -50,11 +50,13 @@ inline auto format_as(maplist_status_t eStatus)
|
|||
}
|
||||
|
||||
struct maplist_lastmaps_t {
|
||||
std::vector<std::pair<OLumpName, OLumpName>> entries;
|
||||
std::vector<std::pair<std::string, std::string>> entries;
|
||||
|
||||
bool empty() const {
|
||||
return entries.empty();
|
||||
}
|
||||
|
||||
static nonstd::expected<maplist_lastmaps_t, std::string> parse(const std::string& lastmaps);
|
||||
};
|
||||
|
||||
// Map list entry structure
|
||||
|
|
@ -90,5 +92,3 @@ inline auto format_as(const maplist_lastmaps_t& lastmaps)
|
|||
// Query result
|
||||
typedef std::pair<size_t, maplist_entry_t*> maplist_qrow_t;
|
||||
typedef std::vector<maplist_qrow_t> maplist_qrows_t;
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -368,7 +368,7 @@ StringTokens TokenizeString(const std::string& str, const std::string& delim) {
|
|||
while (delimPos != std::string::npos) {
|
||||
delimPos = str.find(delim, prevDelim);
|
||||
tokens.push_back(str.substr(prevDelim, delimPos - prevDelim));
|
||||
prevDelim = delimPos + 1;
|
||||
prevDelim = delimPos + delim.length();
|
||||
}
|
||||
|
||||
return tokens;
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include "c_console.h"
|
||||
#include "c_dispatch.h"
|
||||
#include "c_maplist.h"
|
||||
#include "d_event.h"
|
||||
#include "d_main.h"
|
||||
#include "g_game.h"
|
||||
|
|
@ -46,7 +47,7 @@
|
|||
#include "w_ident.h"
|
||||
|
||||
level_locals_t level; // info about current level
|
||||
std::string forcedlastmap; // forced last map for the current wad
|
||||
maplist_lastmaps_t forcedlastmaps; // forced last map for the current wad
|
||||
|
||||
level_pwad_info_t g_EmptyLevel;
|
||||
cluster_info_t g_EmptyCluster;
|
||||
|
|
@ -394,7 +395,7 @@ const char *ParseString2(const char *data);
|
|||
// Takes a string of random wads and patches, which is sorted through and
|
||||
// trampolined to the implementation of G_LoadWad.
|
||||
//
|
||||
bool G_LoadWadString(const std::string& str, const std::string& mapname, const std::string& lastmap)
|
||||
bool G_LoadWadString(const std::string& str, const std::string& mapname, const maplist_lastmaps_t& lastmaps)
|
||||
{
|
||||
const std::vector<std::string>& wad_exts = M_FileTypeExts(OFILE_WAD);
|
||||
const std::vector<std::string>& deh_exts = M_FileTypeExts(OFILE_DEH);
|
||||
|
|
@ -452,7 +453,7 @@ bool G_LoadWadString(const std::string& str, const std::string& mapname, const s
|
|||
continue;
|
||||
}
|
||||
|
||||
forcedlastmap = StdStringToUpper(lastmap);
|
||||
forcedlastmaps = lastmaps;
|
||||
return G_LoadWad(newwadfiles, newpatchfiles, mapname);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "cmdlib.h"
|
||||
#include "c_maplist.h"
|
||||
#include "m_fixed.h"
|
||||
#include "m_resfile.h"
|
||||
#include "olumpname.h"
|
||||
|
|
@ -489,7 +490,7 @@ void P_RemoveDefereds();
|
|||
|
||||
bool G_LoadWad(const OWantFiles& newwadfiles, const OWantFiles& newpatchfiles,
|
||||
const std::string& mapname = "");
|
||||
bool G_LoadWadString(const std::string& str, const std::string& mapname = "", const std::string& lastmap = "");
|
||||
bool G_LoadWadString(const std::string& str, const std::string& mapname = "", const maplist_lastmaps_t& lastmaps = {});
|
||||
|
||||
LevelInfos& getLevelInfos();
|
||||
ClusterInfos& getClusterInfos();
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ EXTERN_CVAR (sv_teamsinplay)
|
|||
EXTERN_CVAR(g_resetinvonexit)
|
||||
|
||||
extern int mapchange;
|
||||
extern std::string forcedlastmap;
|
||||
extern maplist_lastmaps_t forcedlastmaps;
|
||||
|
||||
// [AM] Stores the reset snapshot
|
||||
FLZOMemFile *reset_snapshot = NULL;
|
||||
|
|
@ -165,16 +165,20 @@ BEGIN_COMMAND (wad) // denis - changes wads
|
|||
}
|
||||
|
||||
std::string lastmap = argv[argc-1];
|
||||
maplist_lastmaps_t lastmaps;
|
||||
if (lastmap.rfind("lastmap=", 0) == 0)
|
||||
{
|
||||
lastmap = lastmap.substr(8);
|
||||
auto lastmap_result = maplist_lastmaps_t::parse(lastmap.substr(8));
|
||||
if (!lastmap_result) {
|
||||
PrintFmt(PRINT_HIGH, "Failed to parse lastmap: {}\n", lastmap_result.error());
|
||||
return;
|
||||
}
|
||||
lastmaps = lastmap_result.value();
|
||||
argc--;
|
||||
}
|
||||
else
|
||||
lastmap = "";
|
||||
|
||||
std::string wadstr = C_EscapeWadList(VectorArgs(argc, argv));
|
||||
G_LoadWadString(wadstr, "", lastmap);
|
||||
G_LoadWadString(wadstr, "", lastmaps);
|
||||
}
|
||||
END_COMMAND (wad)
|
||||
|
||||
|
|
@ -184,7 +188,12 @@ EXTERN_CVAR(sv_shufflemaplist)
|
|||
|
||||
bool isLastMap()
|
||||
{
|
||||
return level.nextmap == "" || level.mapname == forcedlastmap;
|
||||
return level.nextmap.empty() ||
|
||||
std::any_of(
|
||||
forcedlastmaps.entries.begin(), forcedlastmaps.entries.end(),
|
||||
[&](const auto& entry) {
|
||||
return entry.first == level.mapname && (entry.second.empty() || entry.second == level.nextmap);
|
||||
});
|
||||
}
|
||||
|
||||
// Returns the next map, assuming there is no maplist.
|
||||
|
|
@ -193,7 +202,7 @@ OLumpName G_NextMap()
|
|||
{
|
||||
OLumpName next = level.nextmap;
|
||||
|
||||
if (gamestate == GS_STARTUP || (sv_gametype != GM_COOP && forcedlastmap.empty()) || next.empty())
|
||||
if (gamestate == GS_STARTUP || (sv_gametype != GM_COOP && forcedlastmaps.empty()) || next.empty())
|
||||
{
|
||||
// if not coop, and lastmap is not specified, stay on same level
|
||||
// [ML] 1/25/10: OR if next is empty
|
||||
|
|
@ -207,9 +216,9 @@ OLumpName G_NextMap()
|
|||
|
||||
// NES - exiting a Doom 1 episode moves to the next episode,
|
||||
// rather than always going back to E1M1
|
||||
if (level.nextmap == "" || level.mapname == forcedlastmap ||
|
||||
(next.substr(0, 7) == "EndGame") ||
|
||||
(gamemode == retail_chex && (level.nextmap == "E1M6")))
|
||||
if (isLastMap() ||
|
||||
(next.substr(0, 7) == "EndGame") ||
|
||||
(gamemode == retail_chex && (level.nextmap == "E1M6")))
|
||||
{
|
||||
if (gameinfo.flags & GI_MAPxx || gamemode == shareware ||
|
||||
(((gamemode == registered && level.cluster == 3) ||
|
||||
|
|
@ -247,7 +256,7 @@ void G_ChangeMap()
|
|||
else
|
||||
{
|
||||
size_t next_index;
|
||||
if ((!forcedlastmap.empty() && !isLastMap()) || !Maplist::instance().get_next_index(next_index))
|
||||
if ((!forcedlastmaps.empty() && !isLastMap()) || !Maplist::instance().get_next_index(next_index))
|
||||
{
|
||||
// We don't have a maplist, so grab the next 'natural' map lump.
|
||||
G_DeferedInitNew(G_NextMap());
|
||||
|
|
@ -258,7 +267,7 @@ void G_ChangeMap()
|
|||
Maplist::instance().get_map_by_index(next_index, maplist_entry);
|
||||
|
||||
std::string wadstr = C_EscapeWadList(maplist_entry.wads);
|
||||
G_LoadWadString(wadstr, maplist_entry.map, maplist_entry.lastmap);
|
||||
G_LoadWadString(wadstr, maplist_entry.map, maplist_entry.lastmaps);
|
||||
|
||||
// Set the new map as the current map
|
||||
Maplist::instance().set_index(next_index);
|
||||
|
|
@ -284,7 +293,7 @@ void G_ChangeMap(size_t index) {
|
|||
}
|
||||
|
||||
std::string wadstr = C_EscapeWadList(maplist_entry.wads);
|
||||
G_LoadWadString(wadstr, maplist_entry.map, maplist_entry.lastmap);
|
||||
G_LoadWadString(wadstr, maplist_entry.map, maplist_entry.lastmaps);
|
||||
|
||||
// Set the new map as the current map
|
||||
Maplist::instance().set_index(index);
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@
|
|||
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <nonstd/expected.hpp>
|
||||
|
||||
#include "c_maplist.h"
|
||||
#include "sv_maplist.h"
|
||||
|
|
@ -641,21 +640,20 @@ void Maplist_Disconnect(player_t &player) {
|
|||
|
||||
//////// CONSOLE COMMANDS ////////
|
||||
|
||||
// TODO: since this is needed for the wad command too, move this to c_maplist.h or smth and make it a static method
|
||||
nonstd::expected<maplist_lastmaps_t, std::string> ParseLastmaps(const std::string& lastmaps) {
|
||||
nonstd::expected<maplist_lastmaps_t, std::string> maplist_lastmaps_t::parse(const std::string& lastmaps) {
|
||||
StringTokens entries = TokenizeString(lastmaps, ",");
|
||||
maplist_lastmaps_t result;
|
||||
for (const auto& entry : entries) {
|
||||
if (entry.empty()) {
|
||||
return nonstd::make_unexpected("Empty lastmap entry found.");
|
||||
return nonstd::make_unexpected(fmt::format("Empty lastmap entry found in {}", lastmaps));
|
||||
}
|
||||
StringTokens maps = TokenizeString(entry, "->");
|
||||
if (maps.size() == 1)
|
||||
result.entries.push_back({ entry, "" });
|
||||
StringTokens maps = TokenizeString(StdStringToUpper(entry), "->");
|
||||
if (maps.size() == 1 && maps[0].find("->") == std::string::npos)
|
||||
result.entries.push_back({ maps[0], "" });
|
||||
else if (maps.size() == 2)
|
||||
result.entries.push_back({ maps[0], maps[1] });
|
||||
else {
|
||||
return nonstd::make_unexpected(fmt::format("Invalid lastmap entry: {}", entry));
|
||||
return nonstd::make_unexpected(fmt::format("Invalid lastmap entry: {} in {}", entry, lastmaps));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
|
@ -701,7 +699,7 @@ BEGIN_COMMAND (addmap) {
|
|||
std::string lastmap = argv[argc-1];
|
||||
if (lastmap.rfind("lastmap=", 0) == 0)
|
||||
{
|
||||
auto lastmap_result = ParseLastmaps(lastmap.substr(8));
|
||||
auto lastmap_result = maplist_lastmaps_t::parse(lastmap.substr(8));
|
||||
if (!lastmap_result) {
|
||||
PrintFmt(PRINT_HIGH, "Failed to parse lastmap: {}\n", lastmap_result.error());
|
||||
return;
|
||||
|
|
@ -740,7 +738,7 @@ BEGIN_COMMAND(insertmap) {
|
|||
std::string lastmap = argv[argc-1];
|
||||
if (lastmap.rfind("lastmap=", 0) == 0)
|
||||
{
|
||||
auto lastmap_result = ParseLastmaps(lastmap.substr(8));
|
||||
auto lastmap_result = maplist_lastmaps_t::parse(lastmap.substr(8));
|
||||
if (!lastmap_result) {
|
||||
PrintFmt(PRINT_HIGH, "Failed to parse lastmap: {}\n", lastmap_result.error());
|
||||
return;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue