diff --git a/Mods/WoG/config/wog/artifacts.json b/Mods/WoG/config/wog/artifacts.json new file mode 100644 index 000000000..c714fbc64 --- /dev/null +++ b/Mods/WoG/config/wog/artifacts.json @@ -0,0 +1,309 @@ +{ + "art144": + { + "index" : 144, + "type" : ["HERO"] + }, + "art145": + { + "index" : 145, + "type" : ["HERO"] + }, + "axeOfSmashing": //TODO: move growing bonuses to this config, someday + { + "bonuses" : [ + { + "subtype" : "primSkill.attack", + "type" : "PRIMARY_SKILL", + "val" : 6, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 146, + "type" : ["COMMANDER"], + "growing": + { + "bonusesPerLevel": + [ + { + "level": 6, + "bonus": + { + "type" : "PRIMARY_SKILL", + "subtype" : "primSkill.attack", + "val" : 1 + } + } + ] + } + }, + "mithrilMail": + { + "bonuses" : [ + { + "type" : "STACK_HEALTH", + "val" : 12, + "valueType" : "PERCENT_TO_ALL" + } + ], + "index" : 147, + "type" : ["COMMANDER"], + "growing": + { + "bonusesPerLevel": + [ + { + "level": 1, + "bonus": + { + "type" : "STACK_HEALTH", + "val" : 1 + } + } + ] + } + }, + "swordOfSharpness": + { + "bonuses" : [ + { + "subtype" : 0, + "type" : "CREATURE_DAMAGE", + "val" : 12, + "valueType" : "PERCENT_TO_ALL" + } + ], + "index" : 148, + "type" : ["COMMANDER"], + "growing": + { + "bonusesPerLevel": + [ + { + "level": 1, + "bonus": + { + "type" : "CREATURE_DAMAGE", + "val" : 1 + } + } + ] + } + }, + "helmOfImmortality": //TODO: implement + { + "index" : 149, + "type" : ["COMMANDER"] + }, + "pendantOfSorcery": + { + "bonuses" : [ + { + "type" : "CASTS", + "val" : 1, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 150, + "type" : ["COMMANDER"], + "growing": + { + "bonusesPerLevel": + [ + { + "level": 10, + "bonus": + { + "type" : "CREATURE_ENCHANT_POWER", + "val" : 1 + } + } + ] + } + }, + "bootsOfHaste": + { + "bonuses" : [ + { + "type" : "STACKS_SPEED", + "val" : 1, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 151, + "type" : ["COMMANDER"], + "growing": + { + "bonusesPerLevel": + [ + { + "level": 10, + "bonus": + { + "type" : "STACKS_SPEED", + "val" : 1 + } + } + ] + } + }, + "bowOfSeeking": + { + "index" : 152, + "type" : ["COMMANDER"], + "growing": + { + "thresholdBonuses": + [ + { + "level": 5, + "bonus": + { + "type" : "SHOOTER" + } + }, + { + "level": 25, + "bonus": + { + "type" : "NO_WALL_PENALTY" + } + }, + { + "level": 50, + "bonus": + { + "type" : "NO_DISTANCE_PENALTY" + } + } + ] + } + }, + "dragonEyeRing": //TODO: implement + { + "index" : 153, + "type" : ["COMMANDER"], + }, + "hardenedShield": + { + "bonuses" : [ + { + "subtype" : "primSkill.attack", + "type" : "PRIMARY_SKILL", + "val" : 6, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 154, + "type" : ["COMMANDER"], + "growing": + { + "bonusesPerLevel": + [ + { + "level": 6, + "bonus": + { + "type" : "PRIMARY_SKILL", + "subtype" : "primSkill.defence", + "val" : 1 + } + } + ] + } + }, + "slavasRingOfPower": //TODO: implement if possible + { + "index" : 155, + "type" : ["COMMANDER"] + }, + "warlordsBanner": + { + "bonuses" : [ + { + "type" : "STACK_HEALTH", + "val" : 2, + "valueType" : "BASE_NUMBER" + } + ], + "index" : 156, + "type" : ["CREATURE"] + }, + "crimsonShieldOfRetribution": //TODO: implement + { + "index" : 157, + "type" : ["HERO"] + }, + "barbarianLordsAxeOfFerocity": //TODO: implement + { + "index" : 158, + "type" : ["HERO"], + "components": + [ + "ogresClubOfHavoc", + "targOfTheRampagingOgre", + "crownOfTheSupremeMagi", + "tunicOfTheCyclopsKing" + ] + }, + "dragonheart": + { + "index" : 159, + "type" : ["HERO"] + }, + "gateKey": + { + "index" : 160, + "type" : ["HERO"] + }, + "art161": + { + "index" : 161, + "type" : ["HERO"] + }, + "art162": + { + "index" : 162, + "type" : ["HERO"] + }, + "art163": + { + "index" : 163, + "type" : ["HERO"] + }, + "art164": + { + "index" : 164, + "type" : ["HERO"] + }, + "art165": + { + "index" : 165, + "type" : ["HERO"] + }, + "art166": + { + "index" : 166, + "type" : ["HERO"] + }, + "art167": + { + "index" : 167, + "type" : ["HERO"] + }, + "art168": + { + "index" : 168, + "type" : ["HERO"] + }, + "art169": + { + "index" : 169, + "type" : ["HERO"] + }, + "art170": + { + "index" : 170, + "type" : ["HERO"] + } +} diff --git a/Mods/WoG/mod.json b/Mods/WoG/mod.json index d7d33c647..17b4944fb 100644 --- a/Mods/WoG/mod.json +++ b/Mods/WoG/mod.json @@ -40,6 +40,11 @@ "name" : "In The Wake of Gods", "description" : "Unnofficial addon for Heroes of Might and Magic III", + "artifacts" : + [ + "config/wog/artifacts.json" + ], + "creatures" : [ "config/wog/creatures.json" diff --git a/config/artifacts.json b/config/artifacts.json index e184386c9..56a2904b6 100644 --- a/config/artifacts.json +++ b/config/artifacts.json @@ -2332,312 +2332,5 @@ ], "index" : 143, "type" : ["CREATURE"] - }, - "art144": - { - "index" : 144, - "type" : ["HERO"] - }, - "art145": - { - "index" : 145, - "type" : ["HERO"] - }, - "axeOfSmashing": //TODO: move growing bonuses to this config, someday - { - "bonuses" : [ - { - "subtype" : "primSkill.attack", - "type" : "PRIMARY_SKILL", - "val" : 6, - "valueType" : "BASE_NUMBER" - } - ], - "index" : 146, - "type" : ["COMMANDER"], - "growing": - { - "bonusesPerLevel": - [ - { - "level": 6, - "bonus": - { - "type" : "PRIMARY_SKILL", - "subtype" : "primSkill.attack", - "val" : 1 - } - } - ] - } - }, - "mithrilMail": - { - "bonuses" : [ - { - "type" : "STACK_HEALTH", - "val" : 12, - "valueType" : "PERCENT_TO_ALL" - } - ], - "index" : 147, - "type" : ["COMMANDER"], - "growing": - { - "bonusesPerLevel": - [ - { - "level": 1, - "bonus": - { - "type" : "STACK_HEALTH", - "val" : 1 - } - } - ] - } - }, - "swordOfSharpness": - { - "bonuses" : [ - { - "subtype" : 0, - "type" : "CREATURE_DAMAGE", - "val" : 12, - "valueType" : "PERCENT_TO_ALL" - } - ], - "index" : 148, - "type" : ["COMMANDER"], - "growing": - { - "bonusesPerLevel": - [ - { - "level": 1, - "bonus": - { - "type" : "CREATURE_DAMAGE", - "val" : 1 - } - } - ] - } - }, - "helmOfImmortality": //TODO: implement - { - "index" : 149, - "type" : ["COMMANDER"] - }, - "pendantOfSorcery": - { - "bonuses" : [ - { - "type" : "CASTS", - "val" : 1, - "valueType" : "BASE_NUMBER" - } - ], - "index" : 150, - "type" : ["COMMANDER"], - "growing": - { - "bonusesPerLevel": - [ - { - "level": 10, - "bonus": - { - "type" : "CREATURE_ENCHANT_POWER", - "val" : 1 - } - } - ] - } - }, - "bootsOfHaste": - { - "bonuses" : [ - { - "type" : "STACKS_SPEED", - "val" : 1, - "valueType" : "BASE_NUMBER" - } - ], - "index" : 151, - "type" : ["COMMANDER"], - "growing": - { - "bonusesPerLevel": - [ - { - "level": 10, - "bonus": - { - "type" : "STACKS_SPEED", - "val" : 1 - } - } - ] - } - }, - "bowOfSeeking": - { - "index" : 152, - "type" : ["COMMANDER"], - "growing": - { - "thresholdBonuses": - [ - { - "level": 5, - "bonus": - { - "type" : "SHOOTER" - } - }, - { - "level": 25, - "bonus": - { - "type" : "NO_WALL_PENALTY" - } - }, - { - "level": 50, - "bonus": - { - "type" : "NO_DISTANCE_PENALTY" - } - } - ] - } - }, - "dragonEyeRing": //TODO: implement - { - "index" : 153, - "type" : ["COMMANDER"], - }, - "hardenedShield": - { - "bonuses" : [ - { - "subtype" : "primSkill.attack", - "type" : "PRIMARY_SKILL", - "val" : 6, - "valueType" : "BASE_NUMBER" - } - ], - "index" : 154, - "type" : ["COMMANDER"], - "growing": - { - "bonusesPerLevel": - [ - { - "level": 6, - "bonus": - { - "type" : "PRIMARY_SKILL", - "subtype" : "primSkill.defence", - "val" : 1 - } - } - ] - } - }, - "slavasRingOfPower": //TODO: implement if possible - { - "index" : 155, - "type" : ["COMMANDER"] - }, - "warlordsBanner": - { - "bonuses" : [ - { - "type" : "STACK_HEALTH", - "val" : 2, - "valueType" : "BASE_NUMBER" - } - ], - "index" : 156, - "type" : ["CREATURE"] - }, - "crimsonShieldOfRetribution": //TODO: implement - { - "index" : 157, - "type" : ["HERO"] - }, - "barbarianLordsAxeOfFerocity": //TODO: implement - { - "index" : 158, - "type" : ["HERO"], - "components": - [ - "ogresClubOfHavoc", - "targOfTheRampagingOgre", - "crownOfTheSupremeMagi", - "tunicOfTheCyclopsKing" - ] - }, - "dragonheart": - { - "index" : 159, - "type" : ["HERO"] - }, - "gateKey": - { - "index" : 160, - "type" : ["HERO"] - }, - "art161": - { - "index" : 161, - "type" : ["HERO"] - }, - "art162": - { - "index" : 162, - "type" : ["HERO"] - }, - "art163": - { - "index" : 163, - "type" : ["HERO"] - }, - "art164": - { - "index" : 164, - "type" : ["HERO"] - }, - "art165": - { - "index" : 165, - "type" : ["HERO"] - }, - "art166": - { - "index" : 166, - "type" : ["HERO"] - }, - "art167": - { - "index" : 167, - "type" : ["HERO"] - }, - "art168": - { - "index" : 168, - "type" : ["HERO"] - }, - "art169": - { - "index" : 169, - "type" : ["HERO"] - }, - "art170": - { - "index" : 170, - "type" : ["HERO"] } } diff --git a/lib/CCreatureHandler.cpp b/lib/CCreatureHandler.cpp index c31fedb11..1471575cc 100644 --- a/lib/CCreatureHandler.cpp +++ b/lib/CCreatureHandler.cpp @@ -482,7 +482,7 @@ void CCreatureHandler::loadAnimationInfo(std::vector &h3Data) parser.endLine(); // header parser.endLine(); - for(int dd=0; ddmodh->settings.data["textData"]["creature"].Float(); ++dd) { while (parser.isNextEntryEmpty() && parser.endLine()) // skip empty lines ; diff --git a/lib/CGeneralTextHandler.cpp b/lib/CGeneralTextHandler.cpp index 5c34a869c..81339d194 100644 --- a/lib/CGeneralTextHandler.cpp +++ b/lib/CGeneralTextHandler.cpp @@ -4,6 +4,8 @@ #include "filesystem/CResourceLoader.h" #include "filesystem/CInputStream.h" #include "GameConstants.h" +#include "CModHandler.h" +#include "VCMI_Lib.h" // #include //needed? @@ -307,6 +309,7 @@ CGeneralTextHandler::CGeneralTextHandler() while (parser.endLine() && !text.empty()); } } + if (VLC->modh->modules.STACK_EXP) { CLegacyConfigParser parser("DATA/ZCREXP.TXT"); parser.endLine();//header diff --git a/lib/CHeroHandler.cpp b/lib/CHeroHandler.cpp index 566700f6f..4b9fd55ea 100644 --- a/lib/CHeroHandler.cpp +++ b/lib/CHeroHandler.cpp @@ -123,7 +123,7 @@ CHeroClass *CHeroClassHandler::loadFromJson(const JsonNode & node) std::vector CHeroClassHandler::loadLegacyData(size_t dataSize) { - heroClasses.resize(GameConstants::F_NUMBER * 2); + heroClasses.resize(dataSize); std::vector h3Data; h3Data.reserve(dataSize); diff --git a/lib/CModHandler.cpp b/lib/CModHandler.cpp index dfdf762d7..5dbac8964 100644 --- a/lib/CModHandler.cpp +++ b/lib/CModHandler.cpp @@ -182,10 +182,10 @@ void CIdentifierStorage::finalize() assert(errorsFound == false); } -CContentHandler::ContentTypeHandler::ContentTypeHandler(IHandlerBase * handler, size_t size, std::string objectName): +CContentHandler::ContentTypeHandler::ContentTypeHandler(IHandlerBase * handler, std::string objectName): handler(handler), objectName(objectName), - originalData(handler->loadLegacyData(size)) + originalData(handler->loadLegacyData(VLC->modh->settings.data["textData"][objectName].Float())) { BOOST_FOREACH(auto & node, originalData) { @@ -262,11 +262,11 @@ void CContentHandler::ContentTypeHandler::loadMod(std::string modName) CContentHandler::CContentHandler() { - handlers.insert(std::make_pair("heroClasses", ContentTypeHandler(&VLC->heroh->classes, GameConstants::F_NUMBER * 2, "heroClass"))); - handlers.insert(std::make_pair("artifacts", ContentTypeHandler(VLC->arth, GameConstants::ARTIFACTS_QUANTITY, "artifact"))); - handlers.insert(std::make_pair("creatures", ContentTypeHandler(VLC->creh, GameConstants::CREATURES_COUNT, "creature"))); - handlers.insert(std::make_pair("factions", ContentTypeHandler(VLC->townh, GameConstants::F_NUMBER, "faction"))); - handlers.insert(std::make_pair("heroes", ContentTypeHandler(VLC->heroh, GameConstants::HEROES_QUANTITY, "hero"))); + handlers.insert(std::make_pair("heroClasses", ContentTypeHandler(&VLC->heroh->classes, "heroClass"))); + handlers.insert(std::make_pair("artifacts", ContentTypeHandler(VLC->arth, "artifact"))); + handlers.insert(std::make_pair("creatures", ContentTypeHandler(VLC->creh, "creature"))); + handlers.insert(std::make_pair("factions", ContentTypeHandler(VLC->townh, "faction"))); + handlers.insert(std::make_pair("heroes", ContentTypeHandler(VLC->heroh, "hero"))); //TODO: spells, bonuses, something else? } @@ -297,13 +297,12 @@ CModHandler::CModHandler() for(int i=0; ierrorStream() << "Selected configuration: "; + logGlobal->errorStream() << settings.data; } // currentList is passed by value to get current list of depending mods @@ -514,6 +516,8 @@ void CModHandler::handleData(Handler handler, const JsonNode & source, std::stri void CModHandler::loadGameContent() { + loadConfigFromFile("defaultMods.json"); + CStopWatch timer, totalTime; CContentHandler content; diff --git a/lib/CModHandler.h b/lib/CModHandler.h index 3db7e431d..7e7a5706a 100644 --- a/lib/CModHandler.h +++ b/lib/CModHandler.h @@ -88,7 +88,7 @@ class CContentHandler std::map modData; public: - ContentTypeHandler(IHandlerBase * handler, size_t size, std::string objectName); + ContentTypeHandler(IHandlerBase * handler, std::string objectName); /// local version of methods in ContentHandler void preloadModData(std::string modName, std::vector fileList); @@ -177,6 +177,8 @@ public: struct DLL_LINKAGE hardcodedFeatures { + JsonNode data; + int CREEP_SIZE; // neutral stacks won't grow beyond this number int WEEKLY_GROWTH; //percent int NEUTRAL_STACK_EXP; @@ -186,7 +188,7 @@ public: template void serialize(Handler &h, const int version) { - h & CREEP_SIZE & WEEKLY_GROWTH & NEUTRAL_STACK_EXP; + h & data & CREEP_SIZE & WEEKLY_GROWTH & NEUTRAL_STACK_EXP; h & DWELLINGS_ACCUMULATE_CREATURES & ALL_CREATURES_GET_DOUBLE_MONTHS; } } settings; diff --git a/lib/JsonNode.cpp b/lib/JsonNode.cpp index 3e14efb96..6da3c2eba 100644 --- a/lib/JsonNode.cpp +++ b/lib/JsonNode.cpp @@ -15,6 +15,7 @@ #include "HeroBonus.h" #include "filesystem/CResourceLoader.h" +#include "filesystem/ISimpleResourceLoader.h" #include "VCMI_Lib.h" //for identifier resolution #include "CModHandler.h" @@ -387,6 +388,8 @@ void JsonWriter::writeNode(const JsonNode &node) writeContainer(node.Struct().begin(), node.Struct().end()); out << prefix << "}"; } + if (!node.meta.empty()) // write metainf as comment + out << " //" << node.meta; } JsonWriter::JsonWriter(std::ostream &output, const JsonNode &node): @@ -1603,3 +1606,24 @@ JsonNode JsonUtils::assembleFromFiles(std::vector files) } return result; } + +JsonNode JsonUtils::assembleFromFiles(std::string filename) +{ + JsonNode result; + + auto & configList = CResourceHandler::get()->getResourcesWithName(ResourceID(filename, EResType::TEXT)); + + BOOST_FOREACH(auto & entry, configList) + { + // FIXME: some way to make this code more readable + auto stream = entry.getLoader()->load(entry.getResourceName()); + std::unique_ptr textData(new ui8[stream->getSize()]); + stream->read(textData.get(), stream->getSize()); + + JsonNode section((char*)textData.get(), stream->getSize()); + //for debug + //section.setMeta(entry.getLoader()->getOrigin()); + merge(result, section); + } + return result; +} diff --git a/lib/JsonNode.h b/lib/JsonNode.h index 0658480a8..af4bd5dee 100644 --- a/lib/JsonNode.h +++ b/lib/JsonNode.h @@ -165,6 +165,9 @@ namespace JsonUtils */ DLL_LINKAGE JsonNode assembleFromFiles(std::vector files); + /// This version loads all files with same name (overriden by mods) + DLL_LINKAGE JsonNode assembleFromFiles(std::string filename); + /** * @brief removes all nodes that are identical to default entry in schema * @param node - JsonNode to minimize