diff --git a/client/CMusicHandler.cpp b/client/CMusicHandler.cpp index 57a3c5aad..0b74e73ca 100644 --- a/client/CMusicHandler.cpp +++ b/client/CMusicHandler.cpp @@ -75,7 +75,7 @@ void CSoundHandler::onVolumeChange(const JsonNode &volumeNode) CSoundHandler::CSoundHandler(): listener(settings.listen["general"]["sound"]), - ambientConfig(JsonNode(ResourcePath("config/ambientSounds.json"))) + ambientConfig(JsonPath::builtin("config/ambientSounds.json")) { listener(std::bind(&CSoundHandler::onVolumeChange, this, _1)); diff --git a/client/adventureMap/AdventureMapWidget.cpp b/client/adventureMap/AdventureMapWidget.cpp index 1af8cdb8d..ebff69812 100644 --- a/client/adventureMap/AdventureMapWidget.cpp +++ b/client/adventureMap/AdventureMapWidget.cpp @@ -56,7 +56,7 @@ AdventureMapWidget::AdventureMapWidget( std::shared_ptr s for (const auto & entry : shortcuts->getShortcuts()) addShortcut(entry.shortcut, entry.callback); - const JsonNode config(ResourcePath("config/widgets/adventureMap.json")); + const JsonNode config(JsonPath::builtin("config/widgets/adventureMap.json")); for(const auto & entry : config["options"]["imagesPlayerColored"].Vector()) { diff --git a/client/adventureMap/TurnTimerWidget.cpp b/client/adventureMap/TurnTimerWidget.cpp index 2550ef23d..1530713d1 100644 --- a/client/adventureMap/TurnTimerWidget.cpp +++ b/client/adventureMap/TurnTimerWidget.cpp @@ -47,7 +47,7 @@ TurnTimerWidget::TurnTimerWidget(): recActions &= ~DEACTIVATE; - const JsonNode config(ResourcePath("config/widgets/turnTimer.json")); + const JsonNode config(JsonPath::builtin("config/widgets/turnTimer.json")); build(config); diff --git a/client/battle/BattleEffectsController.cpp b/client/battle/BattleEffectsController.cpp index eb3d2e419..178b15196 100644 --- a/client/battle/BattleEffectsController.cpp +++ b/client/battle/BattleEffectsController.cpp @@ -132,7 +132,7 @@ void BattleEffectsController::collectRenderableObjects(BattleRenderer & renderer void BattleEffectsController::loadColorMuxers() { - const JsonNode config(ResourcePath("config/battleEffects.json")); + const JsonNode config(JsonPath::builtin("config/battleEffects.json")); for(auto & muxer : config["colorMuxers"].Struct()) { diff --git a/client/battle/BattleWindow.cpp b/client/battle/BattleWindow.cpp index 4e62ea056..7595df164 100644 --- a/client/battle/BattleWindow.cpp +++ b/client/battle/BattleWindow.cpp @@ -51,7 +51,7 @@ BattleWindow::BattleWindow(BattleInterface & owner): REGISTER_BUILDER("battleConsole", &BattleWindow::buildBattleConsole); - const JsonNode config(ResourcePath("config/widgets/BattleWindow2.json")); + const JsonNode config(JsonPath::builtin("config/widgets/BattleWindow2.json")); addShortcut(EShortcut::GLOBAL_OPTIONS, std::bind(&BattleWindow::bOptionsf, this)); addShortcut(EShortcut::BATTLE_SURRENDER, std::bind(&BattleWindow::bSurrenderf, this)); diff --git a/client/gui/InterfaceObjectConfigurable.cpp b/client/gui/InterfaceObjectConfigurable.cpp index e3d9a8a34..d27d97b45 100644 --- a/client/gui/InterfaceObjectConfigurable.cpp +++ b/client/gui/InterfaceObjectConfigurable.cpp @@ -110,7 +110,7 @@ void InterfaceObjectConfigurable::build(const JsonNode &config) { if (!config["library"].isNull()) { - const JsonNode library(ResourcePath(config["library"].String())); + const JsonNode library(JsonPath::fromJson(config["library"])); loadCustomBuilders(library); } diff --git a/client/lobby/OptionsTab.cpp b/client/lobby/OptionsTab.cpp index 48f675425..78c5c141a 100644 --- a/client/lobby/OptionsTab.cpp +++ b/client/lobby/OptionsTab.cpp @@ -137,7 +137,7 @@ OptionsTab::OptionsTab() : humanPlayers(0) } }); - const JsonNode config(ResourcePath("config/widgets/optionsTab.json")); + const JsonNode config(JsonPath::builtin("config/widgets/optionsTab.json")); build(config); //set timers combo box callbacks diff --git a/client/lobby/RandomMapTab.cpp b/client/lobby/RandomMapTab.cpp index f116104bc..aaaacea86 100644 --- a/client/lobby/RandomMapTab.cpp +++ b/client/lobby/RandomMapTab.cpp @@ -118,7 +118,7 @@ RandomMapTab::RandomMapTab(): }); } - const JsonNode config(ResourcePath("config/widgets/randomMapTab.json")); + const JsonNode config(JsonPath::builtin("config/widgets/randomMapTab.json")); build(config); //set combo box callbacks @@ -388,7 +388,7 @@ std::vector RandomMapTab::getPossibleMapSizes() TeamAlignmentsWidget::TeamAlignmentsWidget(RandomMapTab & randomMapTab): InterfaceObjectConfigurable() { - const JsonNode config(ResourcePath("config/widgets/randomMapTeamsWidget.json")); + const JsonNode config(JsonPath::builtin("config/widgets/randomMapTeamsWidget.json")); variables = config["variables"]; int humanPlayers = randomMapTab.obtainMapGenOptions().getPlayerCount(); diff --git a/client/mainmenu/CMainMenu.cpp b/client/mainmenu/CMainMenu.cpp index bd6edd96a..3f0a121bf 100644 --- a/client/mainmenu/CMainMenu.cpp +++ b/client/mainmenu/CMainMenu.cpp @@ -262,7 +262,8 @@ CMenuEntry::CMenuEntry(CMenuScreen * parent, const JsonNode & config) } CMainMenuConfig::CMainMenuConfig() - : campaignSets(JsonNode(ResourcePath("config/campaignSets.json"))), config(JsonNode(ResourcePath("config/mainmenu.json"))) + : campaignSets(JsonPath::builtin("config/campaignSets.json")) + , config(JsonPath::builtin("config/mainmenu.json")) { } diff --git a/client/render/Graphics.cpp b/client/render/Graphics.cpp index c23751484..cf5c23ce9 100644 --- a/client/render/Graphics.cpp +++ b/client/render/Graphics.cpp @@ -105,7 +105,7 @@ void Graphics::initializeBattleGraphics() if(!CResourceHandler::get(mod)->existsResource(ResourcePath("config/battles_graphics.json"))) continue; - const JsonNode config(mod, ResourcePath("config/battles_graphics.json")); + const JsonNode config(mod, JsonPath::builtin("config/battles_graphics.json")); //initialization of AC->def name mapping if(!config["ac_mapping"].isNull()) @@ -204,7 +204,7 @@ void Graphics::blueToPlayersAdv(SDL_Surface * sur, PlayerColor player) void Graphics::loadFonts() { - const JsonNode config(ResourcePath("config/fonts.json")); + const JsonNode config(JsonPath::builtin("config/fonts.json")); const JsonVector & bmpConf = config["bitmap"].Vector(); const JsonNode & ttfConf = config["trueType"]; @@ -228,7 +228,7 @@ void Graphics::loadFonts() void Graphics::loadErmuToPicture() { //loading ERMU to picture - const JsonNode config(ResourcePath("config/ERMU_to_picture.json")); + const JsonNode config(JsonPath::builtin("config/ERMU_to_picture.json")); int etp_idx = 0; for(const JsonNode &etp : config["ERMU_to_picture"].Vector()) { int idx = 0; diff --git a/client/windows/settings/AdventureOptionsTab.cpp b/client/windows/settings/AdventureOptionsTab.cpp index d48b8dcc1..90db19c93 100644 --- a/client/windows/settings/AdventureOptionsTab.cpp +++ b/client/windows/settings/AdventureOptionsTab.cpp @@ -44,7 +44,7 @@ AdventureOptionsTab::AdventureOptionsTab() addConditional("desktop", true); #endif - const JsonNode config(ResourcePath("config/widgets/settings/adventureOptionsTab.json")); + const JsonNode config(JsonPath::builtin("config/widgets/settings/adventureOptionsTab.json")); addCallback("playerHeroSpeedChanged", [this](int value) { auto targetLabel = widget("heroSpeedValueLabel"); diff --git a/client/windows/settings/BattleOptionsTab.cpp b/client/windows/settings/BattleOptionsTab.cpp index 0b95198bd..35abf73cb 100644 --- a/client/windows/settings/BattleOptionsTab.cpp +++ b/client/windows/settings/BattleOptionsTab.cpp @@ -23,7 +23,7 @@ BattleOptionsTab::BattleOptionsTab(BattleInterface * owner) OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; setRedrawParent(true); - const JsonNode config(ResourcePath("config/widgets/settings/battleOptionsTab.json")); + const JsonNode config(JsonPath::builtin("config/widgets/settings/battleOptionsTab.json")); addCallback("viewGridChanged", [this, owner](bool value) { viewGridChangedCallback(value, owner); diff --git a/client/windows/settings/GeneralOptionsTab.cpp b/client/windows/settings/GeneralOptionsTab.cpp index 6ed20cabf..2851873bc 100644 --- a/client/windows/settings/GeneralOptionsTab.cpp +++ b/client/windows/settings/GeneralOptionsTab.cpp @@ -105,7 +105,7 @@ GeneralOptionsTab::GeneralOptionsTab() addConditional("desktop", true); #endif - const JsonNode config(ResourcePath("config/widgets/settings/generalOptionsTab.json")); + const JsonNode config(JsonPath::builtin("config/widgets/settings/generalOptionsTab.json")); addCallback("spellbookAnimationChanged", [](bool value) { setBoolSetting("video", "spellbookAnimation", value); diff --git a/client/windows/settings/OtherOptionsTab.cpp b/client/windows/settings/OtherOptionsTab.cpp index aa5e5325a..c2709b6a6 100644 --- a/client/windows/settings/OtherOptionsTab.cpp +++ b/client/windows/settings/OtherOptionsTab.cpp @@ -26,7 +26,7 @@ OtherOptionsTab::OtherOptionsTab() : InterfaceObjectConfigurable() { OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; - const JsonNode config(ResourcePath("config/widgets/settings/otherOptionsTab.json")); + const JsonNode config(JsonPath::builtin("config/widgets/settings/otherOptionsTab.json")); addCallback("availableCreaturesAsDwellingLabelChanged", [](bool value) { return setBoolSetting("gameTweaks", "availableCreaturesAsDwellingLabel", value); diff --git a/client/windows/settings/SettingsMainWindow.cpp b/client/windows/settings/SettingsMainWindow.cpp index 2dfa11577..3ced217de 100644 --- a/client/windows/settings/SettingsMainWindow.cpp +++ b/client/windows/settings/SettingsMainWindow.cpp @@ -35,7 +35,7 @@ SettingsMainWindow::SettingsMainWindow(BattleInterface * parentBattleUi) : Inter { OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; - const JsonNode config(ResourcePath("config/widgets/settings/settingsMainContainer.json")); + const JsonNode config(JsonPath::builtin("config/widgets/settings/settingsMainContainer.json")); addCallback("activateSettingsTab", [this](int tabId) { openTab(tabId); }); addCallback("loadGame", [this](int) { loadGameButtonCallback(); }); addCallback("saveGame", [this](int) { saveGameButtonCallback(); }); diff --git a/launcher/modManager/cmodmanager.cpp b/launcher/modManager/cmodmanager.cpp index dc7144a14..82ec45d56 100644 --- a/launcher/modManager/cmodmanager.cpp +++ b/launcher/modManager/cmodmanager.cpp @@ -84,7 +84,7 @@ void CModManager::loadMods() for(auto modname : installedMods) { - ResourcePath resID(CModInfo::getModFile(modname)); + auto resID = CModInfo::getModFile(modname); if(CResourceHandler::get()->existsResource(resID)) { boost::filesystem::path name = *CResourceHandler::get()->getResourceName(resID); diff --git a/lib/CArtHandler.cpp b/lib/CArtHandler.cpp index 9b8664301..5eeebb5e4 100644 --- a/lib/CArtHandler.cpp +++ b/lib/CArtHandler.cpp @@ -332,8 +332,8 @@ std::vector CArtHandler::loadLegacyData() static std::map classes = {{'S',"SPECIAL"}, {'T',"TREASURE"},{'N',"MINOR"},{'J',"MAJOR"},{'R',"RELIC"},}; - CLegacyConfigParser parser("DATA/ARTRAITS.TXT"); - CLegacyConfigParser events("DATA/ARTEVENT.TXT"); + CLegacyConfigParser parser(TextPath::builtin("DATA/ARTRAITS.TXT")); + CLegacyConfigParser events(TextPath::builtin("DATA/ARTEVENT.TXT")); parser.endLine(); // header parser.endLine(); diff --git a/lib/CBonusTypeHandler.cpp b/lib/CBonusTypeHandler.cpp index 8de2163d9..f583288a4 100644 --- a/lib/CBonusTypeHandler.cpp +++ b/lib/CBonusTypeHandler.cpp @@ -196,7 +196,7 @@ ImagePath CBonusTypeHandler::bonusToGraphics(const std::shared_ptr & bonu void CBonusTypeHandler::load() { - const JsonNode gameConf(ResourcePath("config/gameConfig.json")); + const JsonNode gameConf(JsonPath::builtin("config/gameConfig.json")); const JsonNode config(JsonUtils::assembleFromFiles(gameConf["bonuses"].convertTo>())); load(config); } diff --git a/lib/CConfigHandler.cpp b/lib/CConfigHandler.cpp index 6aa7321e8..fd3a2fe85 100644 --- a/lib/CConfigHandler.cpp +++ b/lib/CConfigHandler.cpp @@ -55,12 +55,12 @@ SettingsStorage::SettingsStorage(): void SettingsStorage::init() { - std::string confName = "config/settings.json"; + JsonPath confName = JsonPath::builtin("config/settings.json"); - JsonUtils::assembleFromFiles(confName).swap(config); + JsonUtils::assembleFromFiles(confName.getOriginalName()).swap(config); // Probably new install. Create config file to save settings to - if (!CResourceHandler::get("local")->existsResource(ResourcePath(confName))) + if (!CResourceHandler::get("local")->existsResource(confName)) CResourceHandler::get("local")->createResource(confName); JsonUtils::maximize(config, "vcmi:settings"); diff --git a/lib/CCreatureHandler.cpp b/lib/CCreatureHandler.cpp index 872804635..10b293f0a 100644 --- a/lib/CCreatureHandler.cpp +++ b/lib/CCreatureHandler.cpp @@ -415,7 +415,7 @@ const CCreature * CCreatureHandler::getCreature(const std::string & scope, const void CCreatureHandler::loadCommanders() { - ResourcePath configResource("config/commanders.json"); + auto configResource = JsonPath::builtin("config/commanders.json"); std::string modSource = VLC->modh->findResourceOrigin(configResource); JsonNode data(configResource); @@ -507,7 +507,7 @@ std::vector CCreatureHandler::loadLegacyData() std::vector h3Data; h3Data.reserve(dataSize); - CLegacyConfigParser parser("DATA/CRTRAITS.TXT"); + CLegacyConfigParser parser(TextPath::builtin("DATA/CRTRAITS.TXT")); parser.endLine(); // header @@ -698,7 +698,7 @@ void CCreatureHandler::loadCrExpMod() } } - CLegacyConfigParser expBonParser("DATA/CREXPMOD.TXT"); + CLegacyConfigParser expBonParser(TextPath::builtin("DATA/CREXPMOD.TXT")); expBonParser.endLine(); //header @@ -745,7 +745,7 @@ void CCreatureHandler::loadCrExpBon(CBonusSystemNode & globalEffects) globalEffects.addNewBonus(b); }; - CLegacyConfigParser parser("DATA/CREXPBON.TXT"); + CLegacyConfigParser parser(TextPath::builtin("DATA/CREXPBON.TXT")); Bonus b; //prototype with some default properties b.source = BonusSource::STACK_EXPERIENCE; @@ -804,7 +804,7 @@ void CCreatureHandler::loadCrExpBon(CBonusSystemNode & globalEffects) void CCreatureHandler::loadAnimationInfo(std::vector &h3Data) const { - CLegacyConfigParser parser("DATA/CRANIM.TXT"); + CLegacyConfigParser parser(TextPath::builtin("DATA/CRANIM.TXT")); parser.endLine(); // header parser.endLine(); diff --git a/lib/CGeneralTextHandler.cpp b/lib/CGeneralTextHandler.cpp index 624a0b08b..e11a3e903 100644 --- a/lib/CGeneralTextHandler.cpp +++ b/lib/CGeneralTextHandler.cpp @@ -119,9 +119,8 @@ protected: } }; -CLegacyConfigParser::CLegacyConfigParser(std::string URI) +CLegacyConfigParser::CLegacyConfigParser(const TextPath & resource) { - ResourcePath resource(URI, EResType::TEXT); auto input = CResourceHandler::get()->load(resource); std::string modName = VLC->modh->findResourceOrigin(resource); std::string language = VLC->modh->getModLanguage(modName); @@ -250,7 +249,7 @@ bool CLegacyConfigParser::endLine() void CGeneralTextHandler::readToVector(const std::string & sourceID, const std::string & sourceName) { - CLegacyConfigParser parser(sourceName); + CLegacyConfigParser parser(TextPath::builtin(sourceName)); size_t index = 0; do { @@ -434,7 +433,7 @@ CGeneralTextHandler::CGeneralTextHandler(): readToVector("vcmi.quickExchange", QE_MOD_COMMANDS); { - CLegacyConfigParser parser("DATA/RANDTVRN.TXT"); + CLegacyConfigParser parser(TextPath::builtin("DATA/RANDTVRN.TXT")); parser.endLine(); size_t index = 0; do @@ -449,7 +448,7 @@ CGeneralTextHandler::CGeneralTextHandler(): while (parser.endLine()); } { - CLegacyConfigParser parser("DATA/GENRLTXT.TXT"); + CLegacyConfigParser parser(TextPath::builtin("DATA/GENRLTXT.TXT")); parser.endLine(); size_t index = 0; do @@ -460,7 +459,7 @@ CGeneralTextHandler::CGeneralTextHandler(): while (parser.endLine()); } { - CLegacyConfigParser parser("DATA/HELP.TXT"); + CLegacyConfigParser parser(TextPath::builtin("DATA/HELP.TXT")); size_t index = 0; do { @@ -473,7 +472,7 @@ CGeneralTextHandler::CGeneralTextHandler(): while (parser.endLine()); } { - CLegacyConfigParser parser("DATA/PLCOLORS.TXT"); + CLegacyConfigParser parser(TextPath::builtin("DATA/PLCOLORS.TXT")); size_t index = 0; do { @@ -487,7 +486,7 @@ CGeneralTextHandler::CGeneralTextHandler(): while (parser.endLine()); } { - CLegacyConfigParser parser("DATA/SEERHUT.TXT"); + CLegacyConfigParser parser(TextPath::builtin("DATA/SEERHUT.TXT")); //skip header parser.endLine(); @@ -531,7 +530,7 @@ CGeneralTextHandler::CGeneralTextHandler(): } } { - CLegacyConfigParser parser("DATA/CAMPTEXT.TXT"); + CLegacyConfigParser parser(TextPath::builtin("DATA/CAMPTEXT.TXT")); //skip header parser.endLine(); diff --git a/lib/CGeneralTextHandler.h b/lib/CGeneralTextHandler.h index 83a7ee7b4..6bbbc98c1 100644 --- a/lib/CGeneralTextHandler.h +++ b/lib/CGeneralTextHandler.h @@ -9,6 +9,8 @@ */ #pragma once +#include "filesystem/ResourcePath.h" + VCMI_LIB_NAMESPACE_BEGIN class CInputStream; @@ -56,7 +58,7 @@ public: /// end current line bool endLine(); - explicit CLegacyConfigParser(std::string URI); + explicit CLegacyConfigParser(const TextPath & URI); }; class CGeneralTextHandler; diff --git a/lib/CHeroHandler.cpp b/lib/CHeroHandler.cpp index 280d09105..dceb58b47 100644 --- a/lib/CHeroHandler.cpp +++ b/lib/CHeroHandler.cpp @@ -320,7 +320,7 @@ std::vector CHeroClassHandler::loadLegacyData() std::vector h3Data; h3Data.reserve(dataSize); - CLegacyConfigParser parser("DATA/HCTRAITS.TXT"); + CLegacyConfigParser parser(TextPath::builtin("DATA/HCTRAITS.TXT")); parser.endLine(); // header parser.endLine(); @@ -681,9 +681,9 @@ std::vector CHeroHandler::loadLegacyData() std::vector h3Data; h3Data.reserve(dataSize); - CLegacyConfigParser specParser("DATA/HEROSPEC.TXT"); - CLegacyConfigParser bioParser("DATA/HEROBIOS.TXT"); - CLegacyConfigParser parser("DATA/HOTRAITS.TXT"); + CLegacyConfigParser specParser(TextPath::builtin("DATA/HEROSPEC.TXT")); + CLegacyConfigParser bioParser(TextPath::builtin("DATA/HEROBIOS.TXT")); + CLegacyConfigParser parser(TextPath::builtin("DATA/HOTRAITS.TXT")); parser.endLine(); //ignore header parser.endLine(); diff --git a/lib/CSkillHandler.cpp b/lib/CSkillHandler.cpp index dcd5d6725..355a44198 100644 --- a/lib/CSkillHandler.cpp +++ b/lib/CSkillHandler.cpp @@ -146,7 +146,7 @@ void CSkill::serializeJson(JsonSerializeFormat & handler) ///CSkillHandler std::vector CSkillHandler::loadLegacyData() { - CLegacyConfigParser parser("DATA/SSTRAITS.TXT"); + CLegacyConfigParser parser(TextPath::builtin("DATA/SSTRAITS.TXT")); //skip header parser.endLine(); diff --git a/lib/CTownHandler.cpp b/lib/CTownHandler.cpp index 3d4e1388c..8015ceb52 100644 --- a/lib/CTownHandler.cpp +++ b/lib/CTownHandler.cpp @@ -330,7 +330,7 @@ std::vector CTownHandler::loadLegacyData() return dest[town]["town"]["buildings"][EBuildingType::names[building]]; }; - CLegacyConfigParser parser("DATA/BUILDING.TXT"); + CLegacyConfigParser parser(TextPath::builtin("DATA/BUILDING.TXT")); parser.endLine(); // header parser.endLine(); @@ -382,7 +382,7 @@ std::vector CTownHandler::loadLegacyData() } } { - CLegacyConfigParser parser("DATA/BLDGNEUT.TXT"); + CLegacyConfigParser parser(TextPath::builtin("DATA/BLDGNEUT.TXT")); for(int building=0; building<15; building++) { @@ -420,7 +420,7 @@ std::vector CTownHandler::loadLegacyData() } } { - CLegacyConfigParser parser("DATA/BLDGSPEC.TXT"); + CLegacyConfigParser parser(TextPath::builtin("DATA/BLDGSPEC.TXT")); for(int town=0; town CTownHandler::loadLegacyData() } } { - CLegacyConfigParser parser("DATA/DWELLING.TXT"); + CLegacyConfigParser parser(TextPath::builtin("DATA/DWELLING.TXT")); for(int town=0; town CTownHandler::loadLegacyData() } } { - CLegacyConfigParser typeParser("DATA/TOWNTYPE.TXT"); - CLegacyConfigParser nameParser("DATA/TOWNNAME.TXT"); + CLegacyConfigParser typeParser(TextPath::builtin("DATA/TOWNTYPE.TXT")); + CLegacyConfigParser nameParser(TextPath::builtin("DATA/TOWNNAME.TXT")); size_t townID=0; do { @@ -1148,9 +1148,7 @@ void CTownHandler::loadObject(std::string scope, std::string name, const JsonNod void CTownHandler::loadRandomFaction() { - static const ResourcePath randomFactionPath("config/factions/random.json"); - - JsonNode randomFactionJson(randomFactionPath); + JsonNode randomFactionJson(JsonPath::builtin("config/factions/random.json")); randomFactionJson.setMeta(ModScope::scopeBuiltin(), true); loadBuildings(randomTown, randomFactionJson["random"]["town"]["buildings"]); } diff --git a/lib/JsonNode.cpp b/lib/JsonNode.cpp index 66a1596ac..a09d193ab 100644 --- a/lib/JsonNode.cpp +++ b/lib/JsonNode.cpp @@ -80,7 +80,7 @@ JsonNode::JsonNode(const char *data, size_t datasize): *this = parser.parse(""); } -JsonNode::JsonNode(ResourcePath && fileURI): +JsonNode::JsonNode(const JsonPath & fileURI): type(JsonType::DATA_NULL) { auto file = CResourceHandler::get()->load(fileURI)->readAll(); @@ -89,16 +89,7 @@ JsonNode::JsonNode(ResourcePath && fileURI): *this = parser.parse(fileURI.getName()); } -JsonNode::JsonNode(const ResourcePath & fileURI): - type(JsonType::DATA_NULL) -{ - auto file = CResourceHandler::get()->load(fileURI)->readAll(); - - JsonParser parser(reinterpret_cast(file.first.get()), file.second); - *this = parser.parse(fileURI.getName()); -} - -JsonNode::JsonNode(const std::string & idx, const ResourcePath & fileURI): +JsonNode::JsonNode(const std::string & idx, const JsonPath & fileURI): type(JsonType::DATA_NULL) { auto file = CResourceHandler::get(idx)->load(fileURI)->readAll(); @@ -107,7 +98,7 @@ type(JsonType::DATA_NULL) *this = parser.parse(fileURI.getName()); } -JsonNode::JsonNode(ResourcePath && fileURI, bool &isValidSyntax): +JsonNode::JsonNode(const JsonPath & fileURI, bool &isValidSyntax): type(JsonType::DATA_NULL) { auto file = CResourceHandler::get()->load(fileURI)->readAll(); @@ -1253,11 +1244,11 @@ const JsonNode & getSchemaByName(const std::string & name) if (vstd::contains(loadedSchemas, name)) return loadedSchemas[name]; - std::string filename = "config/schemas/" + name; + auto filename = JsonPath::builtin("config/schemas/" + name); - if (CResourceHandler::get()->existsResource(ResourcePath(filename))) + if (CResourceHandler::get()->existsResource(filename)) { - loadedSchemas[name] = JsonNode(ResourcePath(filename)); + loadedSchemas[name] = JsonNode(filename); return loadedSchemas[name]; } @@ -1444,10 +1435,10 @@ JsonNode JsonUtils::assembleFromFiles(const std::vector & files, bo isValid = true; JsonNode result; - for(const std::string & file : files) + for(const auto & file : files) { bool isValidFile = false; - JsonNode section(ResourcePath(file, EResType::TEXT), isValidFile); + JsonNode section(JsonPath::builtinTODO(file), isValidFile); merge(result, section); isValid |= isValidFile; } @@ -1457,7 +1448,7 @@ JsonNode JsonUtils::assembleFromFiles(const std::vector & files, bo JsonNode JsonUtils::assembleFromFiles(const std::string & filename) { JsonNode result; - ResourcePath resID(filename, EResType::TEXT); + JsonPath resID(filename); for(auto & loader : CResourceHandler::get()->getResourcesWithName(resID)) { diff --git a/lib/JsonNode.h b/lib/JsonNode.h index bdae6ea58..97833d7ff 100644 --- a/lib/JsonNode.h +++ b/lib/JsonNode.h @@ -9,6 +9,7 @@ */ #pragma once #include "GameConstants.h" +#include "filesystem/ResourcePath.h" VCMI_LIB_NAMESPACE_BEGIN @@ -18,7 +19,6 @@ using JsonVector = std::vector; struct Bonus; class CSelector; -class ResourcePath; class CAddInfo; class ILimiter; @@ -61,10 +61,9 @@ public: //Create tree from Json-formatted input explicit JsonNode(const char * data, size_t datasize); //Create tree from JSON file - explicit JsonNode(ResourcePath && fileURI); - explicit JsonNode(const ResourcePath & fileURI); - explicit JsonNode(const std::string& idx, const ResourcePath & fileURI); - explicit JsonNode(ResourcePath && fileURI, bool & isValidSyntax); + explicit JsonNode(const JsonPath & fileURI); + explicit JsonNode(const std::string & modName, const JsonPath & fileURI); + explicit JsonNode(const JsonPath & fileURI, bool & isValidSyntax); //Copy c-tor JsonNode(const JsonNode ©); diff --git a/lib/TerrainHandler.cpp b/lib/TerrainHandler.cpp index 6bd09d3c6..0c8ce487f 100644 --- a/lib/TerrainHandler.cpp +++ b/lib/TerrainHandler.cpp @@ -127,7 +127,7 @@ std::vector TerrainTypeHandler::loadLegacyData() objects.resize(dataSize); - CLegacyConfigParser terrainParser("DATA/TERRNAME.TXT"); + CLegacyConfigParser terrainParser(TextPath::builtin("DATA/TERRNAME.TXT")); std::vector result; do diff --git a/lib/battle/BattleInfo.cpp b/lib/battle/BattleInfo.cpp index ba7f0d5c3..d4e306c58 100644 --- a/lib/battle/BattleInfo.cpp +++ b/lib/battle/BattleInfo.cpp @@ -348,7 +348,7 @@ BattleInfo * BattleInfo::setupBattle(const int3 & tile, TerrainId terrain, const std::vector> creBankFormations[2]; std::vector commanderField; std::vector commanderBank; - const JsonNode config(ResourcePath("config/battleStartpos.json")); + const JsonNode config(JsonPath::builtin("config/battleStartpos.json")); const JsonVector &positions = config["battle_positions"].Vector(); CGH::readBattlePositions(positions[0]["levels"], looseFormations[0]); diff --git a/lib/campaign/CampaignHandler.cpp b/lib/campaign/CampaignHandler.cpp index 133e99a62..e2bb31f38 100644 --- a/lib/campaign/CampaignHandler.cpp +++ b/lib/campaign/CampaignHandler.cpp @@ -592,7 +592,7 @@ std::vector< std::vector > CampaignHandler::getFile(std::unique_ptr campDescriptions; if(campDescriptions.empty()) //read once { - const JsonNode config(ResourcePath("config/campaign_regions.json")); + const JsonNode config(JsonPath::builtin("config/campaign_regions.json")); for(const JsonNode & campaign : config["campaign_regions"].Vector()) campDescriptions.push_back(CampaignRegions::fromJson(campaign)); } diff --git a/lib/filesystem/AdapterLoaders.cpp b/lib/filesystem/AdapterLoaders.cpp index c15b1b4a8..c95ac4c77 100644 --- a/lib/filesystem/AdapterLoaders.cpp +++ b/lib/filesystem/AdapterLoaders.cpp @@ -128,9 +128,9 @@ std::unordered_set CFilesystemList::getFilteredFiles(std::function return ret; } -bool CFilesystemList::createResource(std::string filename, bool update) +bool CFilesystemList::createResource(const ResourcePath & filename, bool update) { - logGlobal->trace("Creating %s", filename); + logGlobal->trace("Creating %s", filename.getOriginalName()); for (auto & loader : boost::adaptors::reverse(loaders)) { if (writeableLoaders.count(loader.get()) != 0 // writeable, diff --git a/lib/filesystem/AdapterLoaders.h b/lib/filesystem/AdapterLoaders.h index c54c24d50..23bf6d6a6 100644 --- a/lib/filesystem/AdapterLoaders.h +++ b/lib/filesystem/AdapterLoaders.h @@ -75,7 +75,7 @@ public: std::set getResourceNames(const ResourcePath & resourceName) const override; void updateFilteredFiles(std::function filter) const override; std::unordered_set getFilteredFiles(std::function filter) const override; - bool createResource(std::string filename, bool update = false) override; + bool createResource(const ResourcePath & filename, bool update = false) override; std::vector getResourcesWithName(const ResourcePath & resourceName) const override; /** diff --git a/lib/filesystem/CFilesystemLoader.cpp b/lib/filesystem/CFilesystemLoader.cpp index c90df4dd0..8298ae15c 100644 --- a/lib/filesystem/CFilesystemLoader.cpp +++ b/lib/filesystem/CFilesystemLoader.cpp @@ -68,9 +68,9 @@ std::unordered_set CFilesystemLoader::getFilteredFiles(std::functi return foundID; } -bool CFilesystemLoader::createResource(std::string filename, bool update) +bool CFilesystemLoader::createResource(const ResourcePath & resID, bool update) { - ResourcePath resID(filename); + std::string filename = resID.getOriginalName(); if (fileList.find(resID) != fileList.end()) return true; diff --git a/lib/filesystem/CFilesystemLoader.h b/lib/filesystem/CFilesystemLoader.h index 9d7687865..301adc361 100644 --- a/lib/filesystem/CFilesystemLoader.h +++ b/lib/filesystem/CFilesystemLoader.h @@ -37,7 +37,7 @@ public: std::unique_ptr load(const ResourcePath & resourceName) const override; bool existsResource(const ResourcePath & resourceName) const override; std::string getMountPoint() const override; - bool createResource(std::string filename, bool update = false) override; + bool createResource(const ResourcePath & filename, bool update = false) override; std::optional getResourceName(const ResourcePath & resourceName) const override; void updateFilteredFiles(std::function filter) const override; std::unordered_set getFilteredFiles(std::function filter) const override; diff --git a/lib/filesystem/ISimpleResourceLoader.h b/lib/filesystem/ISimpleResourceLoader.h index 33272b1a9..b9b9c3f94 100644 --- a/lib/filesystem/ISimpleResourceLoader.h +++ b/lib/filesystem/ISimpleResourceLoader.h @@ -90,7 +90,7 @@ public: * * @return true if new file was created, false on error or if file already exists */ - virtual bool createResource(std::string filename, bool update = false) + virtual bool createResource(const ResourcePath & filename, bool update = false) { return false; } diff --git a/lib/filesystem/ResourcePath.h b/lib/filesystem/ResourcePath.h index 6ccfa1d8e..fe2094ba5 100644 --- a/lib/filesystem/ResourcePath.h +++ b/lib/filesystem/ResourcePath.h @@ -19,7 +19,8 @@ class JsonSerializeFormat; * * Supported file extensions: * - * Text: .txt .json + * Text: .txt + * Json: .json * Animation: .def * Mask: .msk .msg * Campaign: .h3c @@ -36,6 +37,7 @@ class JsonSerializeFormat; enum class EResType { TEXT, + JSON, ANIMATION, MASK, CAMPAIGN, @@ -167,6 +169,8 @@ public: using AnimationPath = ResourcePathTempl; using ImagePath = ResourcePathTempl; +using TextPath = ResourcePathTempl; +using JsonPath = ResourcePathTempl; namespace EResTypeHelper { diff --git a/lib/gameState/CGameState.cpp b/lib/gameState/CGameState.cpp index 18fd60bb3..a998d1c0e 100644 --- a/lib/gameState/CGameState.cpp +++ b/lib/gameState/CGameState.cpp @@ -804,7 +804,7 @@ void CGameState::removeHeroPlaceholders() void CGameState::initStartingResources() { logGlobal->debug("\tSetting up resources"); - const JsonNode config(ResourcePath("config/startres.json")); + const JsonNode config(JsonPath::builtin("config/startres.json")); const JsonVector &vector = config["difficulty"].Vector(); const JsonNode &level = vector[scenarioOps->difficulty]; diff --git a/lib/mapObjectConstructors/CObjectClassesHandler.cpp b/lib/mapObjectConstructors/CObjectClassesHandler.cpp index ffa63e29b..ead7a1f40 100644 --- a/lib/mapObjectConstructors/CObjectClassesHandler.cpp +++ b/lib/mapObjectConstructors/CObjectClassesHandler.cpp @@ -112,7 +112,7 @@ std::vector CObjectClassesHandler::loadLegacyData() { size_t dataSize = VLC->settings()->getInteger(EGameSettings::TEXTS_OBJECT); - CLegacyConfigParser parser("Data/Objects.txt"); + CLegacyConfigParser parser(TextPath::builtin("Data/Objects.txt")); auto totalNumber = static_cast(parser.readNumber()); // first line contains number of objects to read and nothing else parser.endLine(); @@ -132,7 +132,7 @@ std::vector CObjectClassesHandler::loadLegacyData() std::vector ret(dataSize);// create storage for 256 objects assert(dataSize == 256); - CLegacyConfigParser namesParser("Data/ObjNames.txt"); + CLegacyConfigParser namesParser(TextPath::builtin("Data/ObjNames.txt")); for (size_t i=0; i<256; i++) { ret[i]["name"].String() = namesParser.readString(); @@ -142,7 +142,7 @@ std::vector CObjectClassesHandler::loadLegacyData() JsonNode cregen1; JsonNode cregen4; - CLegacyConfigParser cregen1Parser("data/crgen1"); + CLegacyConfigParser cregen1Parser(TextPath::builtin("data/crgen1")); do { JsonNode subObject; @@ -151,7 +151,7 @@ std::vector CObjectClassesHandler::loadLegacyData() } while(cregen1Parser.endLine()); - CLegacyConfigParser cregen4Parser("data/crgen4"); + CLegacyConfigParser cregen4Parser(TextPath::builtin("data/crgen4")); do { JsonNode subObject; diff --git a/lib/mapObjects/CObjectHandler.cpp b/lib/mapObjects/CObjectHandler.cpp index 614877f31..492974869 100644 --- a/lib/mapObjects/CObjectHandler.cpp +++ b/lib/mapObjects/CObjectHandler.cpp @@ -19,7 +19,7 @@ VCMI_LIB_NAMESPACE_BEGIN CObjectHandler::CObjectHandler() { logGlobal->trace("\t\tReading resources prices "); - const JsonNode config2(ResourcePath("config/resources.json")); + const JsonNode config2(JsonPath::builtin("config/resources.json")); for(const JsonNode &price : config2["resources_prices"].Vector()) { resVals.push_back(static_cast(price.Float())); diff --git a/lib/mapping/CMapService.cpp b/lib/mapping/CMapService.cpp index c17db6fc2..8b52b0a72 100644 --- a/lib/mapping/CMapService.cpp +++ b/lib/mapping/CMapService.cpp @@ -154,9 +154,9 @@ std::unique_ptr CMapService::getMapLoader(std::unique_ptrexistsResource(ResourcePath(path))) { - return JsonNode(ResourcePath(path, EResType::TEXT)); + return JsonNode(path); } // Probably new install. Create initial configuration CResourceHandler::get("local")->createResource(path); @@ -200,9 +200,9 @@ void CModHandler::loadOneMod(std::string modName, const std::string & parent, co return; } - if(CResourceHandler::get("initial")->existsResource(ResourcePath(CModInfo::getModFile(modFullName)))) + if(CResourceHandler::get("initial")->existsResource(CModInfo::getModFile(modFullName))) { - CModInfo mod(modFullName, modSettings[modName], JsonNode(ResourcePath(CModInfo::getModFile(modFullName)))); + CModInfo mod(modFullName, modSettings[modName], JsonNode(CModInfo::getModFile(modFullName))); if (!parent.empty()) // this is submod, add parent to dependencies mod.dependencies.insert(parent); @@ -224,11 +224,11 @@ void CModHandler::loadMods(bool onlyEssential) } else { - modConfig = loadModSettings("config/modSettings.json"); + modConfig = loadModSettings(JsonPath::builtin("config/modSettings.json")); loadMods("", "", modConfig["activeMods"], true); } - coreMod = std::make_unique(ModScope::scopeBuiltin(), modConfig[ModScope::scopeBuiltin()], JsonNode(ResourcePath("config/gameConfig.json"))); + coreMod = std::make_unique(ModScope::scopeBuiltin(), modConfig[ModScope::scopeBuiltin()], JsonNode(JsonPath::builtin("config/gameConfig.json"))); coreMod->name = "Original game files"; } @@ -283,7 +283,7 @@ static ui32 calculateModChecksum(const std::string & modName, ISimpleResourceLoa // FIXME: remove workaround for core mod if (modName != ModScope::scopeBuiltin()) { - ResourcePath modConfFile(CModInfo::getModFile(modName), EResType::TEXT); + auto modConfFile = CModInfo::getModFile(modName); ui32 configChecksum = CResourceHandler::get("initial")->load(modConfFile)->calculateCRC32(); modChecksum.process_bytes(reinterpret_cast(&configChecksum), sizeof(configChecksum)); } diff --git a/lib/modding/CModInfo.cpp b/lib/modding/CModInfo.cpp index 7fb5fd48a..1901e8923 100644 --- a/lib/modding/CModInfo.cpp +++ b/lib/modding/CModInfo.cpp @@ -75,9 +75,9 @@ std::string CModInfo::getModDir(const std::string & name) return "MODS/" + boost::algorithm::replace_all_copy(name, ".", "/MODS/"); } -std::string CModInfo::getModFile(const std::string & name) +JsonPath CModInfo::getModFile(const std::string & name) { - return getModDir(name) + "/mod.json"; + return JsonPath::builtinTODO(getModDir(name) + "/mod.json"); } void CModInfo::updateChecksum(ui32 newChecksum) @@ -152,7 +152,7 @@ bool CModInfo::checkModGameplayAffecting() const "obstacles" }; - ResourcePath modFileResource(CModInfo::getModFile(identifier)); + JsonPath modFileResource(CModInfo::getModFile(identifier)); if(CResourceHandler::get("initial")->existsResource(modFileResource)) { diff --git a/lib/modding/CModInfo.h b/lib/modding/CModInfo.h index 72e60f01a..6e8a5012d 100644 --- a/lib/modding/CModInfo.h +++ b/lib/modding/CModInfo.h @@ -69,7 +69,7 @@ public: void setEnabled(bool on); static std::string getModDir(const std::string & name); - static std::string getModFile(const std::string & name); + static JsonPath getModFile(const std::string & name); /// return true if this mod can affect gameplay, e.g. adds or modifies any game objects bool checkModGameplayAffecting() const; diff --git a/lib/rmg/CMapGenerator.cpp b/lib/rmg/CMapGenerator.cpp index d18e7b5c4..30dcd24fe 100644 --- a/lib/rmg/CMapGenerator.cpp +++ b/lib/rmg/CMapGenerator.cpp @@ -51,8 +51,7 @@ int CMapGenerator::getRandomSeed() const void CMapGenerator::loadConfig() { - static const ResourcePath path("config/randomMap.json"); - JsonNode randomMapJson(path); + JsonNode randomMapJson(JsonPath::builtin("config/randomMap.json")); config.shipyardGuard = randomMapJson["waterZone"]["shipyard"]["value"].Integer(); for(auto & treasure : randomMapJson["waterZone"]["treasure"].Vector()) diff --git a/lib/spells/CSpellHandler.cpp b/lib/spells/CSpellHandler.cpp index fdb16c975..d5ac49775 100644 --- a/lib/spells/CSpellHandler.cpp +++ b/lib/spells/CSpellHandler.cpp @@ -561,7 +561,7 @@ std::vector CSpellHandler::loadLegacyData() using namespace SpellConfig; std::vector legacyData; - CLegacyConfigParser parser("DATA/SPTRAITS.TXT"); + CLegacyConfigParser parser(TextPath::builtin("DATA/SPTRAITS.TXT")); auto readSchool = [&](JsonMap & schools, const std::string & name) { diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index b60723b28..701c27ab7 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -1717,12 +1717,13 @@ void CGameHandler::save(const std::string & filename) logGlobal->info("Saving to %s", filename); const auto stem = FileInfo::GetPathStem(filename); const auto savefname = stem.to_string() + ".vsgm1"; - CResourceHandler::get("local")->createResource(savefname); + ResourcePath savePath(stem.to_string(), EResType::SAVEGAME); + CResourceHandler::get("local")->createResource(savePath); try { { - CSaveFile save(*CResourceHandler::get("local")->getResourceName(ResourcePath(stem.to_string(), EResType::SAVEGAME))); + CSaveFile save(*CResourceHandler::get("local")->getResourceName(savePath)); saveCommonState(save); logGlobal->info("Saving server state"); save << *this; diff --git a/test/map/CMapEditManagerTest.cpp b/test/map/CMapEditManagerTest.cpp index 048c2f5bd..aefffdbc2 100644 --- a/test/map/CMapEditManagerTest.cpp +++ b/test/map/CMapEditManagerTest.cpp @@ -120,7 +120,7 @@ TEST(MapManager, DrawTerrain_View) // Validate edit manager auto editManager = map->getEditManager(); CRandomGenerator gen; - const JsonNode viewNode(ResourcePath("test/terrainViewMappings", EResType::TEXT)); + const JsonNode viewNode(JsonPath::builtin("test/terrainViewMappings")); const auto & mappingsNode = viewNode["mappings"].Vector(); for (const auto & node : mappingsNode) { diff --git a/test/map/CMapFormatTest.cpp b/test/map/CMapFormatTest.cpp index 030cfd20a..f1b1a4d77 100644 --- a/test/map/CMapFormatTest.cpp +++ b/test/map/CMapFormatTest.cpp @@ -153,14 +153,14 @@ TEST(MapFormat, Objects) { static const std::string MAP_DATA_PATH = "test/ObjectPropertyTest/"; - const JsonNode initialHeader(ResourcePath(MAP_DATA_PATH + CMapFormatJson::HEADER_FILE_NAME)); - const JsonNode expectedHeader(ResourcePath(MAP_DATA_PATH + CMapFormatJson::HEADER_FILE_NAME));//same as initial for now + const JsonNode initialHeader(JsonPath::builtin(MAP_DATA_PATH + CMapFormatJson::HEADER_FILE_NAME)); + const JsonNode expectedHeader(JsonPath::builtin(MAP_DATA_PATH + CMapFormatJson::HEADER_FILE_NAME));//same as initial for now - const JsonNode initialObjects(ResourcePath(MAP_DATA_PATH + CMapFormatJson::OBJECTS_FILE_NAME)); - const JsonNode expectedObjects(ResourcePath(MAP_DATA_PATH + "objects.ex.json")); + const JsonNode initialObjects(JsonPath::builtin(MAP_DATA_PATH + CMapFormatJson::OBJECTS_FILE_NAME)); + const JsonNode expectedObjects(JsonPath::builtin(MAP_DATA_PATH + "objects.ex.json")); - const JsonNode expectedSurface(ResourcePath(MAP_DATA_PATH + "surface_terrain.json")); - const JsonNode expectedUnderground(ResourcePath(MAP_DATA_PATH + "underground_terrain.json")); + const JsonNode expectedSurface(JsonPath::builtin(MAP_DATA_PATH + "surface_terrain.json")); + const JsonNode expectedUnderground(JsonPath::builtin(MAP_DATA_PATH + "underground_terrain.json")); std::unique_ptr originalMap = loadOriginal(initialHeader, initialObjects, expectedSurface, expectedUnderground); @@ -192,11 +192,11 @@ TEST(MapFormat, Terrain) { static const std::string MAP_DATA_PATH = "test/TerrainTest/"; - const JsonNode expectedHeader(ResourcePath(MAP_DATA_PATH + CMapFormatJson::HEADER_FILE_NAME)); - const JsonNode expectedObjects(ResourcePath(MAP_DATA_PATH + CMapFormatJson::OBJECTS_FILE_NAME)); + const JsonNode expectedHeader(JsonPath::builtin(MAP_DATA_PATH + CMapFormatJson::HEADER_FILE_NAME)); + const JsonNode expectedObjects(JsonPath::builtin(MAP_DATA_PATH + CMapFormatJson::OBJECTS_FILE_NAME)); - const JsonNode expectedSurface(ResourcePath(MAP_DATA_PATH + "surface_terrain.json")); - const JsonNode expectedUnderground(ResourcePath(MAP_DATA_PATH + "underground_terrain.json")); + const JsonNode expectedSurface(JsonPath::builtin(MAP_DATA_PATH + "surface_terrain.json")); + const JsonNode expectedUnderground(JsonPath::builtin(MAP_DATA_PATH + "underground_terrain.json")); std::unique_ptr originalMap = loadOriginal(expectedHeader, expectedObjects, expectedSurface, expectedUnderground); diff --git a/test/mock/mock_MapService.cpp b/test/mock/mock_MapService.cpp index 8e0c83591..d9883c9d6 100644 --- a/test/mock/mock_MapService.cpp +++ b/test/mock/mock_MapService.cpp @@ -23,15 +23,15 @@ MapServiceMock::MapServiceMock(const std::string & path, MapListener * mapListen CZipSaver saver(io, "_"); - const JsonNode header(ResourcePath(path+CMapFormatJson::HEADER_FILE_NAME)); - const JsonNode objects(ResourcePath(path+CMapFormatJson::OBJECTS_FILE_NAME)); - const JsonNode surface(ResourcePath(path+"surface_terrain.json")); + const JsonNode header(JsonPath::builtin(path+CMapFormatJson::HEADER_FILE_NAME)); + const JsonNode objects(JsonPath::builtin(path+CMapFormatJson::OBJECTS_FILE_NAME)); + const JsonNode surface(JsonPath::builtin(path+"surface_terrain.json")); addToArchive(saver, header, CMapFormatJson::HEADER_FILE_NAME); addToArchive(saver, objects, CMapFormatJson::OBJECTS_FILE_NAME); addToArchive(saver, surface, "surface_terrain.json"); - ResourcePath undergroundPath(path+"underground_terrain.json"); + auto undergroundPath = JsonPath::builtin(path+"underground_terrain.json"); if(CResourceHandler::get()->existsResource(undergroundPath)) {