From ecae600563e4e7e4298a603677449d4a69d1b5d5 Mon Sep 17 00:00:00 2001 From: Konstantin Date: Wed, 29 Mar 2023 17:23:12 +0300 Subject: [PATCH] effects: Moat now includes battlefield bonus This is an implementation which works exactly like in H3 --- config/spells/moats.json | 56 +++++++++++++++++++++++++++++++++++++ lib/spells/effects/Moat.cpp | 54 +++++++++++++++++++++++++++++++++++ lib/spells/effects/Moat.h | 4 ++- 3 files changed, 113 insertions(+), 1 deletion(-) diff --git a/config/spells/moats.json b/config/spells/moats.json index ed12f7df3..3bcc27bb7 100644 --- a/config/spells/moats.json +++ b/config/spells/moats.json @@ -68,6 +68,14 @@ "moatDamage" : 70, "moatHexes" : [[11, 28, 44, 61, 77, 111, 129, 146, 164, 181]], "defender" :{ + }, + "bonus" :{ + "primarySkill" : { + "val" : -3, + "type" : "PRIMARY_SKILL", + "subtype" : "primSkill.defence", + "valueType" : "ADDITIVE_VALUE" + } } } }, @@ -158,6 +166,14 @@ "moatDamage" : 70, "moatHexes" : [[11, 28, 44, 61, 77, 111, 129, 146, 164, 181]], "defender" :{ + }, + "bonus" :{ + "primarySkill" : { + "val" : -3, + "type" : "PRIMARY_SKILL", + "subtype" : "primSkill.defence", + "valueType" : "ADDITIVE_VALUE" + } } } }, @@ -300,6 +316,14 @@ "moatDamage" : 90, "moatHexes" : [[11, 28, 44, 61, 77, 111, 129, 146, 164, 181]], "defender" :{ + }, + "bonus" :{ + "primarySkill" : { + "val" : -3, + "type" : "PRIMARY_SKILL", + "subtype" : "primSkill.defence", + "valueType" : "ADDITIVE_VALUE" + } } } }, @@ -390,6 +414,14 @@ "moatDamage" : 70, "moatHexes" : [[11, 28, 44, 61, 77, 111, 129, 146, 164, 181]], "defender" :{ + }, + "bonus" :{ + "primarySkill" : { + "val" : -3, + "type" : "PRIMARY_SKILL", + "subtype" : "primSkill.defence", + "valueType" : "ADDITIVE_VALUE" + } } } }, @@ -480,6 +512,14 @@ "moatDamage" : 90, "moatHexes" : [[11, 28, 44, 61, 77, 111, 129, 146, 164, 181]], "defender" :{ + }, + "bonus" :{ + "primarySkill" : { + "val" : -3, + "type" : "PRIMARY_SKILL", + "subtype" : "primSkill.defence", + "valueType" : "ADDITIVE_VALUE" + } } } }, @@ -570,6 +610,14 @@ "moatDamage" : 70, "moatHexes" : [[11, 28, 44, 61, 77, 111, 129, 146, 164, 181]], "defender" :{ + }, + "bonus" :{ + "primarySkill" : { + "val" : -3, + "type" : "PRIMARY_SKILL", + "subtype" : "primSkill.defence", + "valueType" : "ADDITIVE_VALUE" + } } } }, @@ -660,6 +708,14 @@ "moatDamage" : 90, "moatHexes" : [[10, 11, 27, 28, 43, 44, 60, 61, 76, 77, 94, 110, 111, 128, 129, 145, 146, 163, 164, 180, 181]], "defender" :{ + }, + "bonus" :{ + "primarySkill" : { + "val" : -3, + "type" : "PRIMARY_SKILL", + "subtype" : "primSkill.defence", + "valueType" : "ADDITIVE_VALUE" + } } } }, diff --git a/lib/spells/effects/Moat.cpp b/lib/spells/effects/Moat.cpp index fa8ed948d..76612ab3b 100644 --- a/lib/spells/effects/Moat.cpp +++ b/lib/spells/effects/Moat.cpp @@ -59,6 +59,51 @@ void Moat::serializeJsonEffect(JsonSerializeFormat & handler) serializeMoatHexes(handler, "moatHexes", moatHexes); handler.serializeId("triggerAbility", triggerAbility, SpellID::NONE); handler.serializeStruct("defender", sideOptions); //Moats are defender only + + assert(!handler.saving); + { + auto guard = handler.enterStruct("bonus"); + const JsonNode & data = handler.getCurrent(); + + for(const auto & p : data.Struct()) + { + //TODO: support JsonSerializeFormat in Bonus + auto guard = handler.enterStruct(p.first); + const JsonNode & bonusNode = handler.getCurrent(); + auto b = JsonUtils::parseBonus(bonusNode); + bonus.push_back(b); + } + } +} + +void Moat::convertBonus(const Mechanics * m, std::vector & converted) const +{ + + for(const auto & b : bonus) + { + Bonus nb(*b); + + //Moat battlefield effect is always permanent + nb.duration = Bonus::ONE_BATTLE; + + if(m->battle()->battleGetDefendedTown() && m->battle()->battleGetSiegeLevel() >= CGTownInstance::CITADEL) + { + nb.sid = Bonus::getSid32(m->battle()->battleGetDefendedTown()->town->faction->getIndex(), BuildingID::CITADEL); + nb.source = Bonus::TOWN_STRUCTURE; + } + else + { + nb.sid = m->getSpellIndex(); //for all + nb.source = Bonus::SPELL_EFFECT;//for all + } + std::set flatMoatHexes; + + for(const auto & moatPatch : moatHexes) + flatMoatHexes.insert(moatPatch.begin(), moatPatch.end()); + + nb.limiter = std::make_shared(std::move(flatMoatHexes)); + converted.push_back(nb); + } } void Moat::apply(ServerCallback * server, const Mechanics * m, const EffectTarget & target) const @@ -69,6 +114,15 @@ void Moat::apply(ServerCallback * server, const Mechanics * m, const EffectTarge { EffectTarget moat; placeObstacles(server, m, moat); + + std::vector converted; + convertBonus(m, converted); + for(auto & b : converted) + { + GiveBonus gb(GiveBonus::ETarget::BATTLE); + gb.bonus = b; + server->apply(&gb); + } } } diff --git a/lib/spells/effects/Moat.h b/lib/spells/effects/Moat.h index c4e45668c..536cf4bfd 100644 --- a/lib/spells/effects/Moat.h +++ b/lib/spells/effects/Moat.h @@ -23,7 +23,8 @@ class Moat : public Obstacle { private: ObstacleSideOptions sideOptions; //Defender only - std::vector> moatHexes; + std::vector> moatHexes; //Determine number of moat patches and hexes + std::vector> bonus; //For battle-wide bonuses bool dispellable; //For Tower landmines int moatDamage; // Minimal moat damage public: @@ -31,6 +32,7 @@ public: protected: void serializeJsonEffect(JsonSerializeFormat & handler) override; void placeObstacles(ServerCallback * server, const Mechanics * m, const EffectTarget & target) const override; + void convertBonus(const Mechanics * m, std::vector & converted) const; }; }