refactor EngineController
This commit is contained in:
@@ -69,10 +69,6 @@ void ContentGfxCache::refresh() {
|
|||||||
|
|
||||||
ContentGfxCache::~ContentGfxCache() = default;
|
ContentGfxCache::~ContentGfxCache() = default;
|
||||||
|
|
||||||
const Content* ContentGfxCache::getContent() const {
|
|
||||||
return &content;
|
|
||||||
}
|
|
||||||
|
|
||||||
const model::Model& ContentGfxCache::getModel(blockid_t id) const {
|
const model::Model& ContentGfxCache::getModel(blockid_t id) const {
|
||||||
const auto& found = models.find(id);
|
const auto& found = models.find(id);
|
||||||
if (found == models.end()) {
|
if (found == models.end()) {
|
||||||
|
|||||||
@@ -38,8 +38,6 @@ public:
|
|||||||
|
|
||||||
const model::Model& getModel(blockid_t id) const;
|
const model::Model& getModel(blockid_t id) const;
|
||||||
|
|
||||||
const Content* getContent() const;
|
|
||||||
|
|
||||||
void refresh(const Block& block, const Atlas& atlas);
|
void refresh(const Block& block, const Atlas& atlas);
|
||||||
|
|
||||||
void refresh();
|
void refresh();
|
||||||
|
|||||||
@@ -101,14 +101,6 @@ Level& LevelFrontend::getLevel() {
|
|||||||
return level;
|
return level;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Level& LevelFrontend::getLevel() const {
|
|
||||||
return level;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Assets& LevelFrontend::getAssets() const {
|
|
||||||
return assets;
|
|
||||||
}
|
|
||||||
|
|
||||||
ContentGfxCache& LevelFrontend::getContentGfxCache() {
|
ContentGfxCache& LevelFrontend::getContentGfxCache() {
|
||||||
return *contentCache;
|
return *contentCache;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,8 +25,6 @@ public:
|
|||||||
~LevelFrontend();
|
~LevelFrontend();
|
||||||
|
|
||||||
Level& getLevel();
|
Level& getLevel();
|
||||||
const Level& getLevel() const;
|
|
||||||
const Assets& getAssets() const;
|
|
||||||
const ContentGfxCache& getContentGfxCache() const;
|
const ContentGfxCache& getContentGfxCache() const;
|
||||||
ContentGfxCache& getContentGfxCache();
|
ContentGfxCache& getContentGfxCache();
|
||||||
LevelController* getController() const;
|
LevelController* getController() const;
|
||||||
|
|||||||
@@ -32,13 +32,12 @@ void menus::create_version_label(gui::GUI& gui) {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool menus::call(Engine& engine, runnable func) {
|
void menus::call(Engine& engine, runnable func) {
|
||||||
if (engine.isHeadless()) {
|
if (engine.isHeadless()) {
|
||||||
throw std::runtime_error("menus::call(...) in headless mode");
|
throw std::runtime_error("menus::call(...) in headless mode");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
func();
|
func();
|
||||||
return true;
|
|
||||||
} catch (const contentpack_error& error) {
|
} catch (const contentpack_error& error) {
|
||||||
engine.setScreen(std::make_shared<MenuScreen>(engine));
|
engine.setScreen(std::make_shared<MenuScreen>(engine));
|
||||||
// could not to find or read pack
|
// could not to find or read pack
|
||||||
@@ -47,7 +46,7 @@ bool menus::call(Engine& engine, runnable func) {
|
|||||||
langs::get(L"error.pack-not-found") + L": " +
|
langs::get(L"error.pack-not-found") + L": " +
|
||||||
util::str2wstr_utf8(error.getPackId())
|
util::str2wstr_utf8(error.getPackId())
|
||||||
);
|
);
|
||||||
return false;
|
throw std::runtime_error(error);
|
||||||
} catch (const assetload::error& error) {
|
} catch (const assetload::error& error) {
|
||||||
engine.setScreen(std::make_shared<MenuScreen>(engine));
|
engine.setScreen(std::make_shared<MenuScreen>(engine));
|
||||||
guiutil::alert(
|
guiutil::alert(
|
||||||
@@ -55,11 +54,11 @@ bool menus::call(Engine& engine, runnable func) {
|
|||||||
langs::get(L"Assets Load Error", L"menu") + L":\n" +
|
langs::get(L"Assets Load Error", L"menu") + L":\n" +
|
||||||
util::str2wstr_utf8(error.what())
|
util::str2wstr_utf8(error.what())
|
||||||
);
|
);
|
||||||
return false;
|
throw std::runtime_error(error);
|
||||||
} catch (const parsing_error& error) {
|
} catch (const parsing_error& error) {
|
||||||
engine.setScreen(std::make_shared<MenuScreen>(engine));
|
engine.setScreen(std::make_shared<MenuScreen>(engine));
|
||||||
guiutil::alert(engine, util::str2wstr_utf8(error.errorLog()));
|
guiutil::alert(engine, util::str2wstr_utf8(error.errorLog()));
|
||||||
return false;
|
throw std::runtime_error(error);
|
||||||
} catch (const std::runtime_error& error) {
|
} catch (const std::runtime_error& error) {
|
||||||
engine.setScreen(std::make_shared<MenuScreen>(engine));
|
engine.setScreen(std::make_shared<MenuScreen>(engine));
|
||||||
guiutil::alert(
|
guiutil::alert(
|
||||||
@@ -67,7 +66,7 @@ bool menus::call(Engine& engine, runnable func) {
|
|||||||
langs::get(L"Content Error", L"menu") + L":\n" +
|
langs::get(L"Content Error", L"menu") + L":\n" +
|
||||||
util::str2wstr_utf8(error.what())
|
util::str2wstr_utf8(error.what())
|
||||||
);
|
);
|
||||||
return false;
|
throw std::runtime_error(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,5 +32,5 @@ namespace menus {
|
|||||||
const std::wstring& text = L""
|
const std::wstring& text = L""
|
||||||
);
|
);
|
||||||
|
|
||||||
bool call(Engine& engine, runnable func);
|
void call(Engine& engine, runnable func);
|
||||||
}
|
}
|
||||||
|
|||||||
+173
-152
@@ -1,7 +1,6 @@
|
|||||||
#include "EngineController.hpp"
|
#include "EngineController.hpp"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <filesystem>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "engine/Engine.hpp"
|
#include "engine/Engine.hpp"
|
||||||
@@ -26,12 +25,9 @@
|
|||||||
#include "world/World.hpp"
|
#include "world/World.hpp"
|
||||||
#include "LevelController.hpp"
|
#include "LevelController.hpp"
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
|
||||||
|
|
||||||
static debug::Logger logger("engine-control");
|
static debug::Logger logger("engine-control");
|
||||||
|
|
||||||
EngineController::EngineController(Engine& engine) : engine(engine) {
|
EngineController::EngineController(Engine& engine) : engine(engine) {}
|
||||||
}
|
|
||||||
|
|
||||||
void EngineController::deleteWorld(const std::string& name) {
|
void EngineController::deleteWorld(const std::string& name) {
|
||||||
io::path folder = engine.getPaths().getWorldFolderByName(name);
|
io::path folder = engine.getPaths().getWorldFolderByName(name);
|
||||||
@@ -83,65 +79,66 @@ std::shared_ptr<Task> create_converter(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void show_convert_request(
|
struct ConfirmRequest {
|
||||||
Engine& engine,
|
bool memo;
|
||||||
const Content* content,
|
std::wstring message;
|
||||||
const std::shared_ptr<ContentReport>& report,
|
std::wstring text;
|
||||||
const std::shared_ptr<WorldFiles>& worldFiles,
|
};
|
||||||
const runnable& postRunnable
|
|
||||||
) {
|
|
||||||
auto on_confirm = [&engine, worldFiles, content, report, postRunnable]() {
|
|
||||||
auto converter =
|
|
||||||
create_converter(engine, worldFiles, content, report, postRunnable);
|
|
||||||
menus::show_process_panel(
|
|
||||||
engine, converter, L"Converting world..."
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
std::wstring message = L"world.convert-block-layouts";
|
static ConfirmRequest create_convert_request(
|
||||||
|
const std::shared_ptr<ContentReport>& report
|
||||||
|
) {
|
||||||
|
ConfirmRequest request {false, L"", L""};
|
||||||
|
|
||||||
|
request.message = L"world.convert-block-layouts";
|
||||||
if (report->hasContentReorder()) {
|
if (report->hasContentReorder()) {
|
||||||
message = L"world.convert-request";
|
request.message = L"world.convert-request";
|
||||||
}
|
}
|
||||||
if (report->isUpgradeRequired()) {
|
if (report->isUpgradeRequired()) {
|
||||||
message = L"world.upgrade-request";
|
request.message = L"world.upgrade-request";
|
||||||
} else if (report->hasDataLoss()) {
|
} else if (report->hasDataLoss()) {
|
||||||
message = L"world.convert-with-loss";
|
request.message = L"world.convert-with-loss";
|
||||||
std::wstring text;
|
request.memo = true;
|
||||||
for (const auto& line : report->getDataLoss()) {
|
for (const auto& line : report->getDataLoss()) {
|
||||||
text += util::str2wstr_utf8(line) + L"\n";
|
request.text += util::str2wstr_utf8(line) + L"\n";
|
||||||
}
|
}
|
||||||
guiutil::confirm_with_memo(
|
|
||||||
engine,
|
|
||||||
langs::get(message),
|
|
||||||
text,
|
|
||||||
on_confirm,
|
|
||||||
L"",
|
|
||||||
langs::get(L"Cancel")
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
guiutil::confirm(
|
return request;
|
||||||
engine,
|
|
||||||
langs::get(message),
|
|
||||||
on_confirm,
|
|
||||||
nullptr,
|
|
||||||
L"",
|
|
||||||
langs::get(L"Cancel")
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool load_world_content(Engine& engine, const io::path& folder) {
|
static void call(Engine& engine, runnable func) {
|
||||||
|
if (engine.isHeadless()) {
|
||||||
|
func();
|
||||||
|
} else {
|
||||||
|
menus::call(engine, std::move(func));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void start(Engine& engine, std::shared_ptr<Task> task, const std::wstring& message) {
|
||||||
|
if (engine.isHeadless()) {
|
||||||
|
task->waitForEnd();
|
||||||
|
} else {
|
||||||
|
menus::show_process_panel(engine, task, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void check_world(const EnginePaths& paths, const io::path& folder) {
|
||||||
|
auto worldFile = folder / "world.json";
|
||||||
|
if (!io::exists(worldFile)) {
|
||||||
|
throw std::runtime_error(worldFile.string() + " does not exists");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const Content* load_world_content(Engine& engine, const io::path& folder) {
|
||||||
auto& paths = engine.getPaths();
|
auto& paths = engine.getPaths();
|
||||||
auto& contentControl = engine.getContentControl();
|
auto& contentControl = engine.getContentControl();
|
||||||
paths.setCurrentWorldFolder(folder);
|
paths.setCurrentWorldFolder(folder);
|
||||||
if (engine.isHeadless()) {
|
|
||||||
|
check_world(paths, folder);
|
||||||
|
call(engine, [&contentControl]() {
|
||||||
contentControl.loadContent(ContentPack::worldPacksList("world:"));
|
contentControl.loadContent(ContentPack::worldPacksList("world:"));
|
||||||
return true;
|
});
|
||||||
} else {
|
return contentControl.get();
|
||||||
return menus::call(engine, [&contentControl]() {
|
|
||||||
contentControl.loadContent(ContentPack::worldPacksList("world:"));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void load_world(
|
static void load_world(
|
||||||
@@ -149,21 +146,15 @@ static void load_world(
|
|||||||
const std::shared_ptr<WorldFiles>& worldFiles,
|
const std::shared_ptr<WorldFiles>& worldFiles,
|
||||||
int64_t localPlayer
|
int64_t localPlayer
|
||||||
) {
|
) {
|
||||||
try {
|
call(engine, [&engine, worldFiles, localPlayer] () {
|
||||||
auto& contentControl = engine.getContentControl();
|
auto& contentControl = engine.getContentControl();
|
||||||
auto content = contentControl.get();
|
auto content = contentControl.get();
|
||||||
auto& packs = contentControl.getContentPacks();
|
const auto& packs = contentControl.getContentPacks();
|
||||||
auto& settings = engine.getSettings();
|
auto& settings = engine.getSettings();
|
||||||
|
|
||||||
auto level = World::load(worldFiles, settings, *content, packs);
|
auto level = World::load(worldFiles, settings, *content, packs);
|
||||||
engine.onWorldOpen(std::move(level), localPlayer);
|
engine.onWorldOpen(std::move(level), localPlayer);
|
||||||
} catch (const world_load_error& error) {
|
});
|
||||||
guiutil::alert(
|
|
||||||
engine,
|
|
||||||
langs::get(L"Error") + L": " + util::str2wstr_utf8(error.what())
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static dv::value create_missing_content_report(
|
static dv::value create_missing_content_report(
|
||||||
@@ -180,7 +171,9 @@ static dv::value create_missing_content_report(
|
|||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EngineController::onMissingContent(const std::shared_ptr<ContentReport>& report) {
|
void EngineController::onMissingContent(
|
||||||
|
const std::shared_ptr<ContentReport>& report
|
||||||
|
) {
|
||||||
if (engine.isHeadless()) {
|
if (engine.isHeadless()) {
|
||||||
throw std::runtime_error(
|
throw std::runtime_error(
|
||||||
"missing content: " +
|
"missing content: " +
|
||||||
@@ -196,50 +189,63 @@ void EngineController::onMissingContent(const std::shared_ptr<ContentReport>& re
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void confirm(
|
||||||
|
Engine& engine, ConfirmRequest request, bool confirmed, runnable callback
|
||||||
|
) {
|
||||||
|
if (confirmed || engine.isHeadless()) {
|
||||||
|
callback();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (request.memo) {
|
||||||
|
guiutil::confirm_with_memo(
|
||||||
|
engine,
|
||||||
|
langs::get(request.message),
|
||||||
|
request.text,
|
||||||
|
callback,
|
||||||
|
L"",
|
||||||
|
langs::get(L"Cancel")
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
guiutil::confirm(
|
||||||
|
engine,
|
||||||
|
langs::get(request.message),
|
||||||
|
callback,
|
||||||
|
nullptr,
|
||||||
|
L"",
|
||||||
|
langs::get(L"Cancel")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void EngineController::openWorld(const std::string& name, bool confirmConvert) {
|
void EngineController::openWorld(const std::string& name, bool confirmConvert) {
|
||||||
const auto& paths = engine.getPaths();
|
const auto& paths = engine.getPaths();
|
||||||
|
auto& debugSettings = engine.getSettings().debug;
|
||||||
auto folder = paths.getWorldsFolder() / name;
|
auto folder = paths.getWorldsFolder() / name;
|
||||||
auto worldFile = folder / "world.json";
|
|
||||||
if (!io::exists(worldFile)) {
|
|
||||||
throw std::runtime_error(worldFile.string() + " does not exists");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!load_world_content(engine, folder)) {
|
auto content = load_world_content(engine, folder);
|
||||||
|
auto worldFiles = std::make_shared<WorldFiles>(folder, debugSettings);
|
||||||
|
auto report = World::checkIndices(worldFiles, content);
|
||||||
|
|
||||||
|
if (report == nullptr) {
|
||||||
|
load_world(engine, std::move(worldFiles), localPlayer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (report->hasMissingContent()) {
|
||||||
|
onMissingContent(report);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& contentControl = engine.getContentControl();
|
auto request = create_convert_request(report);
|
||||||
const Content* content = contentControl.get();
|
confirm(engine, std::move(request), confirmConvert, [=]() {
|
||||||
auto worldFiles = std::make_shared<WorldFiles>(
|
auto task = create_converter(
|
||||||
folder, engine.getSettings().debug);
|
engine,
|
||||||
if (auto report = World::checkIndices(worldFiles, content)) {
|
worldFiles,
|
||||||
if (report->hasMissingContent()) {
|
content,
|
||||||
onMissingContent(report);
|
report,
|
||||||
} else {
|
[=]() { openWorld(name, false); }
|
||||||
if (confirmConvert) {
|
);
|
||||||
auto task = create_converter(
|
start(engine, std::move(task), L"Converting world...");
|
||||||
engine,
|
});
|
||||||
worldFiles,
|
|
||||||
content,
|
|
||||||
report,
|
|
||||||
[=]() { openWorld(name, false); }
|
|
||||||
);
|
|
||||||
if (engine.isHeadless()) {
|
|
||||||
task->waitForEnd();
|
|
||||||
} else {
|
|
||||||
menus::show_process_panel(
|
|
||||||
engine, task, L"Converting world..."
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
show_convert_request(engine, content, report, std::move(worldFiles), [=]() {
|
|
||||||
openWorld(name, false);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
load_world(engine, std::move(worldFiles), localPlayer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint64_t str2seed(const std::string& seedstr) {
|
inline uint64_t str2seed(const std::string& seedstr) {
|
||||||
@@ -266,15 +272,11 @@ void EngineController::createWorld(
|
|||||||
EnginePaths& paths = engine.getPaths();
|
EnginePaths& paths = engine.getPaths();
|
||||||
auto folder = paths.getWorldsFolder() / name;
|
auto folder = paths.getWorldsFolder() / name;
|
||||||
|
|
||||||
if (engine.isHeadless()) {
|
call(engine, [this, &paths, folder]() {
|
||||||
engine.getContentControl().loadContent();
|
engine.getContentControl().loadContent();
|
||||||
paths.setCurrentWorldFolder(folder);
|
paths.setCurrentWorldFolder(folder);
|
||||||
} else if (!menus::call(engine, [this, &paths, folder]() {
|
});
|
||||||
engine.getContentControl().loadContent();
|
|
||||||
paths.setCurrentWorldFolder(folder);
|
|
||||||
})) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
auto& contentControl = engine.getContentControl();
|
auto& contentControl = engine.getContentControl();
|
||||||
auto level = World::create(
|
auto level = World::create(
|
||||||
name,
|
name,
|
||||||
@@ -301,6 +303,48 @@ void EngineController::reopenWorld(World* world) {
|
|||||||
openWorld(name, true);
|
openWorld(name, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void reconfig_packs_outside(
|
||||||
|
ContentControl& contentControl,
|
||||||
|
const std::vector<std::string>& packsToAdd,
|
||||||
|
const std::vector<std::string>& packsToRemove
|
||||||
|
) {
|
||||||
|
auto& manager = contentControl.scan();
|
||||||
|
|
||||||
|
auto names = PacksManager::getNames(
|
||||||
|
contentControl.getContentPacks()
|
||||||
|
);
|
||||||
|
for (const auto& id : packsToAdd) {
|
||||||
|
names.push_back(id);
|
||||||
|
}
|
||||||
|
for (const auto& id : packsToRemove) {
|
||||||
|
manager.exclude(id);
|
||||||
|
names.erase(std::find(names.begin(), names.end(), id));
|
||||||
|
}
|
||||||
|
names = manager.assemble(names);
|
||||||
|
contentControl.getContentPacks() = manager.getAll(names);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void reconfig_packs_inside(
|
||||||
|
PacksManager& manager,
|
||||||
|
std::vector<std::string>& names,
|
||||||
|
const std::vector<std::string>& packsToAdd,
|
||||||
|
const std::vector<std::string>& packsToRemove
|
||||||
|
) {
|
||||||
|
for (const auto& id : packsToAdd) {
|
||||||
|
names.push_back(id);
|
||||||
|
}
|
||||||
|
for (const auto& id : packsToRemove) {
|
||||||
|
manager.exclude(id);
|
||||||
|
const auto& found = std::find(names.begin(), names.end(), id);
|
||||||
|
if (found != names.end()) {
|
||||||
|
names.erase(found);
|
||||||
|
} else {
|
||||||
|
logger.warning()
|
||||||
|
<< "attempt to remove non-installed pack: " << id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void EngineController::reconfigPacks(
|
void EngineController::reconfigPacks(
|
||||||
LevelController* controller,
|
LevelController* controller,
|
||||||
const std::vector<std::string>& packsToAdd,
|
const std::vector<std::string>& packsToAdd,
|
||||||
@@ -308,8 +352,32 @@ void EngineController::reconfigPacks(
|
|||||||
) {
|
) {
|
||||||
auto& contentControl = engine.getContentControl();
|
auto& contentControl = engine.getContentControl();
|
||||||
auto content = contentControl.get();
|
auto content = contentControl.get();
|
||||||
bool hasIndices = false;
|
|
||||||
|
|
||||||
|
runnable removeFunc = [this, controller, packsToAdd, packsToRemove, &contentControl]() {
|
||||||
|
if (controller == nullptr) {
|
||||||
|
try {
|
||||||
|
reconfig_packs_outside(contentControl, packsToAdd, packsToRemove);
|
||||||
|
} catch (const contentpack_error& err) {
|
||||||
|
throw std::runtime_error(
|
||||||
|
std::string(err.what()) + " [" + err.getPackId() + "]"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
auto world = controller->getLevel()->getWorld();
|
||||||
|
controller->saveWorld();
|
||||||
|
|
||||||
|
auto names = PacksManager::getNames(world->getPacks());
|
||||||
|
auto& manager = contentControl.scan();
|
||||||
|
reconfig_packs_inside(manager, names, packsToAdd, packsToRemove);
|
||||||
|
|
||||||
|
auto& wfile = *world->wfile;
|
||||||
|
wfile.removeIndices(packsToRemove);
|
||||||
|
wfile.writePacks(manager.getAll(names));
|
||||||
|
reopenWorld(world);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
bool hasIndices = false;
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
if (content) {
|
if (content) {
|
||||||
for (const auto& id : packsToRemove) {
|
for (const auto& id : packsToRemove) {
|
||||||
@@ -323,53 +391,6 @@ void EngineController::reconfigPacks(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
runnable removeFunc = [this, controller, packsToAdd, packsToRemove, &contentControl]() {
|
|
||||||
auto& manager = contentControl.scan();
|
|
||||||
if (controller == nullptr) {
|
|
||||||
try {
|
|
||||||
auto names = PacksManager::getNames(
|
|
||||||
engine.getContentControl().getContentPacks()
|
|
||||||
);
|
|
||||||
for (const auto& id : packsToAdd) {
|
|
||||||
names.push_back(id);
|
|
||||||
}
|
|
||||||
for (const auto& id : packsToRemove) {
|
|
||||||
manager.exclude(id);
|
|
||||||
names.erase(std::find(names.begin(), names.end(), id));
|
|
||||||
}
|
|
||||||
names = manager.assemble(names);
|
|
||||||
engine.getContentControl().getContentPacks() = manager.getAll(names);
|
|
||||||
} catch (const contentpack_error& err) {
|
|
||||||
throw std::runtime_error(
|
|
||||||
std::string(err.what()) + " [" + err.getPackId() + "]"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
auto world = controller->getLevel()->getWorld();
|
|
||||||
auto& wfile = *world->wfile;
|
|
||||||
controller->saveWorld();
|
|
||||||
|
|
||||||
auto names = PacksManager::getNames(world->getPacks());
|
|
||||||
for (const auto& id : packsToAdd) {
|
|
||||||
names.push_back(id);
|
|
||||||
}
|
|
||||||
for (const auto& id : packsToRemove) {
|
|
||||||
manager.exclude(id);
|
|
||||||
const auto& found = std::find(names.begin(), names.end(), id);
|
|
||||||
if (found != names.end()) {
|
|
||||||
names.erase(found);
|
|
||||||
} else {
|
|
||||||
logger.warning()
|
|
||||||
<< "attempt to remove non-installed pack: " << id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
wfile.removeIndices(packsToRemove);
|
|
||||||
wfile.writePacks(manager.getAll(names));
|
|
||||||
reopenWorld(world);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (hasIndices && !engine.isHeadless()) {
|
if (hasIndices && !engine.isHeadless()) {
|
||||||
guiutil::confirm(
|
guiutil::confirm(
|
||||||
engine,
|
engine,
|
||||||
|
|||||||
Reference in New Issue
Block a user