use fs_game w/ mod support

This commit is contained in:
m 2022-12-22 11:07:51 -06:00
parent a43b6c571b
commit 0c2c90e786
4 changed files with 54 additions and 15 deletions

View File

@ -28,7 +28,7 @@ namespace command
std::unordered_map<std::string, std::function<void(params&)>> handlers; std::unordered_map<std::string, std::function<void(params&)>> handlers;
std::unordered_map<std::string, std::function<void(int, params_sv&)>> handlers_sv; std::unordered_map<std::string, std::function<void(int, params_sv&)>> handlers_sv;
std::string saved_fs_game; std::optional<std::string> saved_fs_game;
void main_handler() void main_handler()
{ {
@ -563,10 +563,10 @@ namespace command
const auto new_mod_path = fs_game->current.string; const auto new_mod_path = fs_game->current.string;
// check if the last saved fs_game value isn't empty and if it doesn't equal the new fs_game // check if the last saved fs_game value isn't empty and if it doesn't equal the new fs_game
if (!saved_fs_game.empty() && saved_fs_game != new_mod_path) if (saved_fs_game.has_value() && saved_fs_game != new_mod_path)
{ {
// unregister path to be used as a fs directory // unregister path to be used as a fs directory
filesystem::unregister_path(saved_fs_game); filesystem::unregister_path(saved_fs_game.value());
} }
if (new_mod_path && !new_mod_path[0]) if (new_mod_path && !new_mod_path[0])

View File

@ -17,7 +17,7 @@
namespace mods namespace mods
{ {
std::string mod_path{}; std::optional<std::string> mod_path;
namespace namespace
{ {
@ -51,6 +51,13 @@ namespace mods
void full_restart(const std::string& arg) void full_restart(const std::string& arg)
{ {
if (game::environment::is_mp())
{
// vid_restart works on multiplayer, but not on singleplayer
command::execute("vid_restart");
return;
}
auto mode = game::environment::is_mp() ? " -multiplayer "s : " -singleplayer "s; auto mode = game::environment::is_mp() ? " -multiplayer "s : " -singleplayer "s;
utils::nt::relaunch_self(mode.append(arg), true); utils::nt::relaunch_self(mode.append(arg), true);
@ -63,6 +70,38 @@ namespace mods
return utils::io::file_exists(path + "/mod.ff") || utils::io::file_exists(path + "/zone/mod.ff"); return utils::io::file_exists(path + "/mod.ff") || utils::io::file_exists(path + "/zone/mod.ff");
} }
void set_filesystem_data(const std::string& path)
{
if (mod_path.has_value())
{
filesystem::unregister_path(mod_path.value());
}
if (!game::environment::is_sp())
{
// modify fs_game on mp/dedi because its not set when we obviously vid_restart (sp does a full relaunch with command line arguments)
game::Dvar_SetFromStringByNameFromSource("fs_game", path.data(),
game::DVAR_SOURCE_INTERNAL);
}
}
void set_mod(const std::string& path)
{
set_filesystem_data(path);
mod_path = path;
}
void clear_mod()
{
set_filesystem_data("");
mod_path.reset();
}
std::optional<std::string> get_mod()
{
return mod_path;
}
class component final : public component_interface class component final : public component_interface
{ {
public: public:
@ -98,24 +137,23 @@ namespace mods
} }
console::info("Loading mod %s\n", path); console::info("Loading mod %s\n", path);
set_mod(path);
if (mod_requires_restart(mod_path) || mod_requires_restart(path)) if ((mod_path.has_value() && mod_requires_restart(mod_path.value())) ||
mod_requires_restart(path))
{ {
console::info("Restarting...\n"); console::info("Restarting...\n");
full_restart("+set fs_game \""s + path + "\""); full_restart("+set fs_game \""s + path + "\"");
} }
else else
{ {
filesystem::unregister_path(mod_path);
filesystem::register_path(path);
mod_path = path;
restart(); restart();
} }
}); });
command::add("unloadmod", [](const command::params& params) command::add("unloadmod", [](const command::params& params)
{ {
if (mod_path.empty()) if (!mod_path.has_value())
{ {
console::info("No mod loaded\n"); console::info("No mod loaded\n");
return; return;
@ -128,17 +166,17 @@ namespace mods
return; return;
} }
console::info("Unloading mod %s\n", mod_path.data()); console::info("Unloading mod %s\n", mod_path.value().data());
if (mod_requires_restart(mod_path)) if (mod_requires_restart(mod_path.value()))
{ {
console::info("Restarting...\n"); console::info("Restarting...\n");
clear_mod();
full_restart(""); full_restart("");
} }
else else
{ {
filesystem::unregister_path(mod_path); clear_mod();
mod_path.clear();
restart(); restart();
} }
}); });

View File

@ -2,5 +2,5 @@
namespace mods namespace mods
{ {
extern std::string mod_path; std::optional<std::string> get_mod();
} }

View File

@ -268,7 +268,8 @@ namespace ui_scripting
game_type["getloadedmod"] = [](const game&) game_type["getloadedmod"] = [](const game&)
{ {
return mods::mod_path; const auto& path = mods::get_mod();
return path.value_or("");
}; };
if (::game::environment::is_sp()) if (::game::environment::is_sp())