1
0
mirror of https://github.com/luanti-org/luanti.git synced 2025-11-09 19:45:21 +01:00

Fix singleplayer with --gameid and new world

This commit is contained in:
sfan5
2025-11-05 13:23:48 +01:00
parent e82495d98c
commit b6bfc494e6
3 changed files with 42 additions and 45 deletions

View File

@@ -274,6 +274,15 @@ void ClientLauncher::init_args(GameStartData &start_data, const Settings &cmd_ar
if (cmd_args.exists("name"))
start_data.name = cmd_args.get("name");
// If a world was commanded, select it
if (!start_data.world_path.empty()) {
auto &spec = start_data.world_spec;
spec.path = start_data.world_path;
spec.gameid = getWorldGameId(spec.path, true);
spec.name = _("[--world parameter]");
}
random_input = g_settings->getBool("random_input")
|| cmd_args.getFlag("random-input");
}
@@ -413,17 +422,8 @@ bool ClientLauncher::launch_game(std::string &error_message,
}
}
// If a world was commanded, append and select it
// This is provieded by "get_world_from_cmdline()", main.cpp
if (!start_data.world_path.empty()) {
auto &spec = start_data.world_spec;
spec.path = start_data.world_path;
spec.gameid = getWorldGameId(spec.path, true);
spec.name = _("[--world parameter]");
}
/* Show the GUI menu
/*
* Show the GUI menu
*/
std::string server_name, server_description;
if (!skip_main_menu) {
@@ -440,7 +440,7 @@ bool ClientLauncher::launch_game(std::string &error_message,
main_menu(&menudata);
// Skip further loading if there was an exit signal.
if (*porting::signal_handler_killstatus())
if (!m_rendering_engine->run() || *porting::signal_handler_killstatus())
return false;
if (!menudata.script_data.errormessage.empty()) {
@@ -461,6 +461,7 @@ bool ClientLauncher::launch_game(std::string &error_message,
int world_index = menudata.selected_world;
if (world_index >= 0 && world_index < (int)worldspecs.size()) {
start_data.world_spec = worldspecs[world_index];
start_data.world_path = start_data.world_spec.path;
}
start_data.name = menudata.name;
@@ -477,9 +478,6 @@ bool ClientLauncher::launch_game(std::string &error_message,
start_data.address.empty() && !start_data.name.empty();
}
if (!m_rendering_engine->run())
return false;
if (!start_data.isSinglePlayer() && start_data.name.empty()) {
error_message = gettext("Please choose a name!");
errorstream << error_message << std::endl;
@@ -502,12 +500,9 @@ bool ClientLauncher::launch_game(std::string &error_message,
return false;
}
auto &worldspec = start_data.world_spec;
infostream << "Selected world: " << worldspec.name
<< " [" << worldspec.path << "]" << std::endl;
// For singleplayer and local server
if (start_data.address.empty()) {
// For singleplayer and local server
auto &worldspec = start_data.world_spec;
if (worldspec.path.empty()) {
error_message = gettext("No world selected and no address "
"provided. Nothing to do.");
@@ -515,26 +510,30 @@ bool ClientLauncher::launch_game(std::string &error_message,
return false;
}
if (!fs::PathExists(worldspec.path)) {
error_message = gettext("Provided world path doesn't exist: ")
+ worldspec.path;
errorstream << error_message << std::endl;
return false;
infostream << "Selected world: " << worldspec.name
<< " [" << worldspec.path << "]" << std::endl;
// Figure out which game we'll be using
// Note that start_data.game_spec contains the gameid from the command line
bool world_exists = getWorldExists(worldspec.path);
if (world_exists) {
auto world_game = findWorldSubgame(worldspec.path);
if (world_game.isValid())
start_data.game_spec = world_game;
}
// Load gamespec for required game
start_data.game_spec = findWorldSubgame(worldspec.path);
if (!start_data.game_spec.isValid()) {
error_message = gettext("Could not find or load game: ")
if (world_exists) {
error_message = gettext("Could not find or load game: ")
+ worldspec.gameid;
} else {
error_message = gettext("World does not exist and no game selected to create one.");
}
errorstream << error_message << std::endl;
return false;
}
return true;
}
start_data.world_path = start_data.world_spec.path;
return true;
}

View File

@@ -237,9 +237,11 @@ std::vector<SubgameSpec> getAvailableGames()
bool getWorldExists(const std::string &world_path)
{
if (world_path.empty())
return false;
// Note: very old worlds are valid without a world.mt
return (fs::PathExists(world_path + DIR_DELIM + "map_meta.txt") ||
fs::PathExists(world_path + DIR_DELIM + "world.mt"));
return (fs::IsFile(world_path + DIR_DELIM + "map_meta.txt") ||
fs::IsFile(world_path + DIR_DELIM + "world.mt"));
}
//! Try to get the displayed name of a world

View File

@@ -1041,8 +1041,7 @@ static bool get_game_from_cmdline(GameParams *game_params, const Settings &cmd_a
errorstream << "Game \"" << gameid << "\" not found" << std::endl;
return false;
}
dstream << _("Using game specified by --gameid on the command line")
<< std::endl;
infostream << "Using commanded gameid [" << commanded_gamespec.id << "]" << std::endl;
game_params->game_spec = commanded_gamespec;
return true;
}
@@ -1052,18 +1051,19 @@ static bool get_game_from_cmdline(GameParams *game_params, const Settings &cmd_a
static bool determine_subgame(GameParams *game_params)
{
SubgameSpec gamespec;
if (!game_params->is_dedicated_server) {
// ClientLauncher has its own logic to choose a game
return true;
}
SubgameSpec gamespec;
assert(!game_params->world_path.empty()); // Pre-condition
// If world doesn't exist
if (!game_params->world_path.empty()
&& !getWorldExists(game_params->world_path)) {
if (!getWorldExists(game_params->world_path)) {
// Try to take gamespec from command line
if (game_params->game_spec.isValid()) {
gamespec = game_params->game_spec;
infostream << "Using commanded gameid [" << gamespec.id << "]" << std::endl;
} else if (game_params->is_dedicated_server) {
} else {
auto games = getAvailableGameIds();
// If there's exactly one obvious choice then do the right thing
if (games.size() > 1)
@@ -1094,16 +1094,12 @@ static bool determine_subgame(GameParams *game_params)
<< world_gameid << "]" << std::endl;
}
} else {
// If world contains an embedded game, use it;
// Otherwise find world from local system.
gamespec = findWorldSubgame(game_params->world_path);
infostream << "Using world gameid [" << gamespec.id << "]" << std::endl;
}
}
if (!gamespec.isValid()) {
if (!game_params->is_dedicated_server)
return true; // not an error, this would prevent the main menu from running
errorstream << "Game [" << gamespec.id << "] could not be found."
<< std::endl;
return false;