From 3b010d9596c195218ecd871e423e629a0fbcb16a Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Sun, 15 Oct 2023 16:50:24 +0300 Subject: [PATCH] Renamed MetaIdentifier to VariantIdentifier --- cmake_modules/VCMI_lib.cmake | 2 +- lib/JsonNode.cpp | 129 ++++++++++++++++-- lib/bonuses/Bonus.h | 6 +- .../{MetaIdentifier.h => VariantIdentifier.h} | 24 ++-- 4 files changed, 135 insertions(+), 26 deletions(-) rename lib/constants/{MetaIdentifier.h => VariantIdentifier.h} (69%) diff --git a/cmake_modules/VCMI_lib.cmake b/cmake_modules/VCMI_lib.cmake index d019bc146..0cf3914ab 100644 --- a/cmake_modules/VCMI_lib.cmake +++ b/cmake_modules/VCMI_lib.cmake @@ -374,7 +374,7 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE) ${MAIN_LIB_DIR}/constants/EntityIdentifiers.h ${MAIN_LIB_DIR}/constants/Enumerations.h ${MAIN_LIB_DIR}/constants/IdentifierBase.h - ${MAIN_LIB_DIR}/constants/MetaIdentifier.h + ${MAIN_LIB_DIR}/constants/VariantIdentifier.h ${MAIN_LIB_DIR}/constants/NumericConstants.h ${MAIN_LIB_DIR}/constants/StringConstants.h diff --git a/lib/JsonNode.cpp b/lib/JsonNode.cpp index ed74ec600..5cf575c84 100644 --- a/lib/JsonNode.cpp +++ b/lib/JsonNode.cpp @@ -425,6 +425,14 @@ static void loadBonusSubtype(TBonusSubtype & subtype, BonusType type, const Json return; } + if (node.isNumber()) // Compatibility code for 1.3 or older + { + VLC->identifiers()->requestIdentifier( "bonusSubtype", node, [&subtype](int32_t identifier) + { + subtype = BonusSubtypeID(identifier); + }); + } + if (!node.isString()) { logMod->warn("Bonus subtype must be string!"); @@ -432,16 +440,114 @@ static void loadBonusSubtype(TBonusSubtype & subtype, BonusType type, const Json return; } - VLC->identifiers()->requestIdentifier(node, [&subtype, node](int32_t identifier) + switch (type) { - assert(0); //TODO - subtype = BonusSubtypeID(identifier); - }); + case BonusType::MAGIC_SCHOOL_SKILL: + case BonusType::SPELL_DAMAGE: + case BonusType::SPELLS_OF_SCHOOL: + case BonusType::SPELL_DAMAGE_REDUCTION: + { + VLC->identifiers()->requestIdentifier( "spellSchool", node, [&subtype](int32_t identifier) + { + subtype = SpellSchool(identifier); + }); + break; + } + case BonusType::NO_TERRAIN_PENALTY: + { + VLC->identifiers()->requestIdentifier( "terrain", node, [&subtype](int32_t identifier) + { + subtype = TerrainId(identifier); + }); + break; + } + case BonusType::PRIMARY_SKILL: + { + VLC->identifiers()->requestIdentifier( "primarySkill", node, [&subtype](int32_t identifier) + { + subtype = PrimarySkill(identifier); + }); + break; + } + case BonusType::IMPROVED_NECROMANCY: + case BonusType::HERO_GRANTS_ATTACKS: + case BonusType::BONUS_DAMAGE_CHANCE: + case BonusType::BONUS_DAMAGE_PERCENTAGE: + case BonusType::SPECIAL_UPGRADE: + case BonusType::HATE: + case BonusType::SUMMON_GUARDIANS: + { + VLC->identifiers()->requestIdentifier( "creature", node, [&subtype](int32_t identifier) + { + subtype = CreatureID(identifier); + }); + break; + } + case BonusType::SPECIAL_SPELL_LEV: + case BonusType::SPECIFIC_SPELL_DAMAGE: + case BonusType::SPELL: + case BonusType::OPENING_BATTLE_SPELL: + case BonusType::SPELL_LIKE_ATTACK: + case BonusType::CATAPULT: + case BonusType::CATAPULT_EXTRA_SHOTS: + case BonusType::HEALER: + case BonusType::SPELLCASTER: + case BonusType::ENCHANTER: + case BonusType::SPELL_AFTER_ATTACK: + case BonusType::SPELL_BEFORE_ATTACK: + case BonusType::SPECIFIC_SPELL_POWER: + case BonusType::ENCHANTED: + case BonusType::MORE_DAMAGE_FROM_SPELL: + { + VLC->identifiers()->requestIdentifier( "spell", node, [&subtype](int32_t identifier) + { + subtype = SpellID(identifier); + }); + break; + } + case BonusType::GENERATE_RESOURCE: + { + VLC->identifiers()->requestIdentifier( "resource", node, [&subtype](int32_t identifier) + { + subtype = GameResID(identifier); + }); + break; + } + case BonusType::MOVEMENT: + case BonusType::WATER_WALKING: + case BonusType::FLYING_MOVEMENT: + case BonusType::SPECIAL_PECULIAR_ENCHANT: + case BonusType::NEGATE_ALL_NATURAL_IMMUNITIES: + case BonusType::CREATURE_DAMAGE: + case BonusType::FLYING: + case BonusType::GENERAL_DAMAGE_REDUCTION: + case BonusType::PERCENTAGE_DAMAGE_BOOST: + case BonusType::SOUL_STEAL: + case BonusType::TRANSMUTATION: + case BonusType::DESTRUCTION: + case BonusType::DEATH_STARE: + case BonusType::REBIRTH: + case BonusType::VISIONS: + case BonusType::SPELLS_OF_LEVEL: // spell level + case BonusType::CREATURE_GROWTH: // creature level + { + VLC->identifiers()->requestIdentifier( "bonusSubtype", node, [&subtype](int32_t identifier) + { + subtype = BonusSubtypeID(identifier); + }); + break; + } + default: + for(const auto & i : bonusNameMap) + if(i.second == type) + logMod->warn("Bonus type %s does not supports subtypes!", i.first ); + subtype = TBonusSubtype(); + } } static void loadBonusSourceInstance(TBonusSourceID & sourceInstance, BonusSource sourceType, const JsonNode & node) { - assert(0); + assert(0);//TODO } std::shared_ptr JsonUtils::parseBonus(const JsonVector & ability_vec) @@ -895,7 +1001,8 @@ bool JsonUtils::parseBonus(const JsonNode &ability, Bonus *b) if (!value->isNull()) b->source = static_cast(parseByMap(bonusSourceMap, value, "source type ")); - loadBonusSourceInstance(b->sid, b->source, ability["sourceID"]); + if (!ability["sourceID"].isNull()) + loadBonusSourceInstance(b->sid, b->source, ability["sourceID"]); value = &ability["targetSourceType"]; if (!value->isNull()) @@ -960,20 +1067,24 @@ CSelector JsonUtils::parseSelector(const JsonNode & ability) ret = ret.And(base.Not()); } + BonusType type = BonusType::NONE; + // Actual selector parser value = &ability["type"]; if(value->isString()) { auto it = bonusNameMap.find(value->String()); if(it != bonusNameMap.end()) + { + type = it->second; ret = ret.And(Selector::type()(it->second)); + } } value = &ability["subtype"]; - if(!value->isNull()) + if(!value->isNull() && type != BonusType::NONE) { TBonusSubtype subtype; - assert(0); //TODO - loadBonusSubtype(subtype, BonusType::NONE, ability); + loadBonusSubtype(subtype, type, ability); ret = ret.And(Selector::subtype()(subtype)); } value = &ability["sourceType"]; diff --git a/lib/bonuses/Bonus.h b/lib/bonuses/Bonus.h index 4abbe9cc9..47273f73d 100644 --- a/lib/bonuses/Bonus.h +++ b/lib/bonuses/Bonus.h @@ -11,7 +11,7 @@ #include "BonusEnum.h" #include "BonusSubtypeID.h" -#include "../constants/MetaIdentifier.h" +#include "../constants/VariantIdentifier.h" #include "../constants/EntityIdentifiers.h" VCMI_LIB_NAMESPACE_BEGIN @@ -25,8 +25,8 @@ class IUpdater; class BonusList; class CSelector; -using TBonusSubtype = MetaIdentifier; -using TBonusSourceID = MetaIdentifier; +using TBonusSubtype = VariantIdentifier; +using TBonusSourceID = VariantIdentifier; using TBonusListPtr = std::shared_ptr; using TConstBonusListPtr = std::shared_ptr; using TLimiterPtr = std::shared_ptr; diff --git a/lib/constants/MetaIdentifier.h b/lib/constants/VariantIdentifier.h similarity index 69% rename from lib/constants/MetaIdentifier.h rename to lib/constants/VariantIdentifier.h index d882f9e0d..6b0394f65 100644 --- a/lib/constants/MetaIdentifier.h +++ b/lib/constants/VariantIdentifier.h @@ -1,5 +1,5 @@ /* - * MetaIdentifier.h, part of VCMI engine + * VariantIdentifier.h, part of VCMI engine * * Authors: listed in file AUTHORS in main folder * @@ -15,37 +15,35 @@ VCMI_LIB_NAMESPACE_BEGIN /// This class represents field that may contain value of multiple different identifer types template -class DLL_LINKAGE MetaIdentifier +class DLL_LINKAGE VariantIdentifier { std::variant value; public: - MetaIdentifier() + VariantIdentifier() {} template - MetaIdentifier(const IdentifierType & identifier) + VariantIdentifier(const IdentifierType & identifier) : value(identifier) {} int32_t getNum() const { - std::optional result; + int32_t result; std::visit([&result] (const auto& v) { result = v.getNum(); }, value); - assert(result.has_value()); - return result.value_or(-1); + return result; } std::string toString() const { - std::optional result; + std::string result; std::visit([&result] (const auto& v) { result = v.encode(v.getNum()); }, value); - assert(result.has_value()); - return result.value_or(""); + return result; } template @@ -65,15 +63,15 @@ public: h & value; } - bool operator == (const MetaIdentifier & other) const + bool operator == (const VariantIdentifier & other) const { return value == other.value; } - bool operator != (const MetaIdentifier & other) const + bool operator != (const VariantIdentifier & other) const { return value != other.value; } - bool operator < (const MetaIdentifier & other) const + bool operator < (const VariantIdentifier & other) const { return value < other.value; }