diff --git a/client/CPlayerInterface.cpp b/client/CPlayerInterface.cpp index e37f16969..4959a0c69 100644 --- a/client/CPlayerInterface.cpp +++ b/client/CPlayerInterface.cpp @@ -707,7 +707,7 @@ void CPlayerInterface::battleStart(const CCreatureSet *army1, const CCreatureSet BATTLE_EVENT_POSSIBLE_RETURN; } -void CPlayerInterface::battleUnitsChanged(const std::vector & units, const std::vector & customEffects) +void CPlayerInterface::battleUnitsChanged(const std::vector & units) { EVENT_HANDLER_CALLED_BY_CLIENT; BATTLE_EVENT_POSSIBLE_RETURN; @@ -747,8 +747,6 @@ void CPlayerInterface::battleUnitsChanged(const std::vector & units break; } } - - battleInt->effectsController->displayCustomEffects(customEffects); } void CPlayerInterface::battleObstaclesChanged(const std::vector & obstacles) @@ -962,15 +960,12 @@ void CPlayerInterface::battleStacksAttacked(const std::vector & bsa, bool ranged) override; void battleStartBefore(const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2) override; //called by engine just before battle starts; side=0 - left, side=1 - right void battleStart(const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool side) override; //called by engine when battle starts; side=0 - left, side=1 - right - void battleUnitsChanged(const std::vector & units, const std::vector & customEffects) override; + void battleUnitsChanged(const std::vector & units) override; void battleObstaclesChanged(const std::vector & obstacles) override; void battleCatapultAttacked(const CatapultAttack & ca) override; //called when catapult makes an attack void battleGateStateChanged(const EGateState state) override; diff --git a/client/NetPacksClient.cpp b/client/NetPacksClient.cpp index 237a48dc8..68ddf3789 100644 --- a/client/NetPacksClient.cpp +++ b/client/NetPacksClient.cpp @@ -782,7 +782,7 @@ void BattleResultsApplied::applyCl(CClient *cl) void BattleUnitsChanged::applyCl(CClient * cl) { - callBattleInterfaceIfPresentForBothSides(cl, &IBattleEventsReceiver::battleUnitsChanged, changedStacks, customEffects); + callBattleInterfaceIfPresentForBothSides(cl, &IBattleEventsReceiver::battleUnitsChanged, changedStacks); } void BattleObstaclesChanged::applyCl(CClient *cl) diff --git a/client/battle/BattleConstants.h b/client/battle/BattleConstants.h index 2ee86901c..c6b5d06b3 100644 --- a/client/battle/BattleConstants.h +++ b/client/battle/BattleConstants.h @@ -9,6 +9,27 @@ */ #pragma once +enum class EBattleEffect +{ + // list of battle effects that have hardcoded triggers + MAGIC_MIRROR = 3, + FIRE_SHIELD = 11, + FEAR = 15, + GOOD_LUCK = 18, + GOOD_MORALE = 20, + BAD_MORALE = 30, + BAD_LUCK = 48, + RESURRECT = 50, + DRAIN_LIFE = 52, + POISON = 67, + DEATH_BLOW = 73, + REGENERATION = 74, + MANA_DRAIN = 77, + RESISTANCE = 78, + + INVALID = -1, +}; + enum class EAnimationEvents { OPENING = 0, // TODO battle opening sound is playing ACTION = 1, // there are any ongoing animations @@ -22,27 +43,6 @@ enum class EAnimationEvents { COUNT }; -namespace EBattleEffect -{ - enum EBattleEffect - { - // list of battle effects that have hardcoded triggers - FEAR = 15, - GOOD_LUCK = 18, - GOOD_MORALE = 20, - BAD_MORALE = 30, - BAD_LUCK = 48, - RESURRECT = 50, - DRAIN_LIFE = 52, - POISON = 67, - DEATH_BLOW = 73, - REGENERATION = 74, - MANA_DRAIN = 77, - - INVALID = -1, - }; -} - enum class EHeroAnimType { HOLDING = 0, diff --git a/client/battle/BattleEffectsController.cpp b/client/battle/BattleEffectsController.cpp index dc1881ec7..5b7624084 100644 --- a/client/battle/BattleEffectsController.cpp +++ b/client/battle/BattleEffectsController.cpp @@ -35,31 +35,20 @@ BattleEffectsController::BattleEffectsController(BattleInterface & owner): owner(owner) {} -void BattleEffectsController::displayEffect(EBattleEffect::EBattleEffect effect, const BattleHex & destTile) +void BattleEffectsController::displayEffect(EBattleEffect effect, const BattleHex & destTile) { displayEffect(effect, soundBase::invalid, destTile); } -void BattleEffectsController::displayEffect(EBattleEffect::EBattleEffect effect, uint32_t soundID, const BattleHex & destTile) +void BattleEffectsController::displayEffect(EBattleEffect effect, uint32_t soundID, const BattleHex & destTile) { - std::string customAnim = graphics->battleACToDef[effect][0]; + size_t effectID = static_cast(effect); + + std::string customAnim = graphics->battleACToDef[effectID][0]; owner.stacksController->addNewAnim(new PointEffectAnimation(owner, soundBase::stringsList()[soundID], customAnim, destTile)); } -void BattleEffectsController::displayCustomEffects(const std::vector & customEffects) -{ - for(const CustomEffectInfo & one : customEffects) - { - const CStack * s = owner.curInt->cb->battleGetStackByID(one.stack, false); - - assert(s); - assert(one.effect != 0); - - displayEffect(EBattleEffect::EBattleEffect(one.effect), soundBase::soundID(one.sound), s->getPosition()); - } -} - void BattleEffectsController::battleTriggerEffect(const BattleTriggerEffect & bte) { assert(owner.getAnimationCondition(EAnimationEvents::ACTION) == false); diff --git a/client/battle/BattleEffectsController.h b/client/battle/BattleEffectsController.h index aa1372842..a5c6f086e 100644 --- a/client/battle/BattleEffectsController.h +++ b/client/battle/BattleEffectsController.h @@ -15,7 +15,6 @@ VCMI_LIB_NAMESPACE_BEGIN class BattleAction; -struct CustomEffectInfo; struct BattleTriggerEffect; VCMI_LIB_NAMESPACE_END @@ -49,11 +48,9 @@ public: void startAction(const BattleAction* action); - void displayCustomEffects(const std::vector & customEffects); - //displays custom effect on the battlefield - void displayEffect(EBattleEffect::EBattleEffect effect, const BattleHex & destTile); - void displayEffect(EBattleEffect::EBattleEffect effect, uint32_t soundID, const BattleHex & destTile); + void displayEffect(EBattleEffect effect, const BattleHex & destTile); + void displayEffect(EBattleEffect effect, uint32_t soundID, const BattleHex & destTile); void battleTriggerEffect(const BattleTriggerEffect & bte); diff --git a/client/battle/BattleInterface.cpp b/client/battle/BattleInterface.cpp index b960fae5e..c83a19dea 100644 --- a/client/battle/BattleInterface.cpp +++ b/client/battle/BattleInterface.cpp @@ -550,17 +550,22 @@ void BattleInterface::spellCast(const BattleSpellCast * sc) } } - //queuing additional animation (magic mirror / resistance) - for(auto & elem : sc->customEffects) + for(auto & elem : sc->reflectedCres) { - auto stack = curInt->cb->battleGetStackByID(elem.stack, false); + auto stack = curInt->cb->battleGetStackByID(elem, false); assert(stack); - if(stack) - { - executeOnAnimationCondition(EAnimationEvents::HIT, true, [=](){ - effectsController->displayEffect(EBattleEffect::EBattleEffect(elem.effect), stack->getPosition()); - }); - } + executeOnAnimationCondition(EAnimationEvents::HIT, true, [=](){ + effectsController->displayEffect(EBattleEffect::MAGIC_MIRROR, stack->getPosition()); + }); + } + + for(auto & elem : sc->resistedCres) + { + auto stack = curInt->cb->battleGetStackByID(elem, false); + assert(stack); + executeOnAnimationCondition(EAnimationEvents::HIT, true, [=](){ + effectsController->displayEffect(EBattleEffect::RESISTANCE, stack->getPosition()); + }); } //mana absorption diff --git a/client/battle/BattleInterface.h b/client/battle/BattleInterface.h index 4a64a6794..1c3ae65a2 100644 --- a/client/battle/BattleInterface.h +++ b/client/battle/BattleInterface.h @@ -29,7 +29,6 @@ struct CatapultAttack; struct BattleTriggerEffect; struct BattleHex; struct InfoAboutHero; -struct CustomEffectInfo; VCMI_LIB_NAMESPACE_END @@ -62,14 +61,13 @@ struct StackAttackedInfo int64_t damageDealt; uint32_t amountKilled; - - EBattleEffect::EBattleEffect battleEffect; SpellID spellEffect; bool indirectAttack; //if true, stack was attacked indirectly - spell or ranged attack bool killed; //if true, stack has been killed bool rebirth; //if true, play rebirth animation after all bool cloneKilled; + bool fireShield; }; struct StackAttackInfo @@ -78,7 +76,6 @@ struct StackAttackInfo const CStack *defender; std::vector< const CStack *> secondaryDefender; - //EBattleEffect::EBattleEffect battleEffect; SpellID spellEffect; BattleHex tile; diff --git a/client/battle/BattleStacksController.cpp b/client/battle/BattleStacksController.cpp index a02fee59d..4bf6871ba 100644 --- a/client/battle/BattleStacksController.cpp +++ b/client/battle/BattleStacksController.cpp @@ -444,8 +444,8 @@ void BattleStacksController::stacksAreAttacked(std::vector at else addNewAnim(new HittedAnimation(owner, attackedInfo.defender)); - if (attackedInfo.battleEffect != EBattleEffect::INVALID) - owner.effectsController->displayEffect(EBattleEffect::EBattleEffect(attackedInfo.battleEffect), attackedInfo.defender->getPosition()); + if (attackedInfo.fireShield) + owner.effectsController->displayEffect(EBattleEffect::FIRE_SHIELD, attackedInfo.attacker->getPosition()); if (attackedInfo.spellEffect != SpellID::NONE) owner.displaySpellEffect(attackedInfo.spellEffect, attackedInfo.defender->getPosition()); diff --git a/lib/CGameInterface.cpp b/lib/CGameInterface.cpp index 3eba7affb..56c576acc 100644 --- a/lib/CGameInterface.cpp +++ b/lib/CGameInterface.cpp @@ -225,9 +225,9 @@ void CAdventureAI::battleEnd(const BattleResult * br) battleAI.reset(); } -void CAdventureAI::battleUnitsChanged(const std::vector & units, const std::vector & customEffects) +void CAdventureAI::battleUnitsChanged(const std::vector & units) { - battleAI->battleUnitsChanged(units, customEffects); + battleAI->battleUnitsChanged(units); } BattleAction CAdventureAI::activeStack(const CStack * stack) diff --git a/lib/CGameInterface.h b/lib/CGameInterface.h index 787ba00b2..30b2e8174 100644 --- a/lib/CGameInterface.h +++ b/lib/CGameInterface.h @@ -164,7 +164,7 @@ public: virtual void battleAttack(const BattleAttack *ba) override; virtual void battleSpellCast(const BattleSpellCast *sc) override; virtual void battleEnd(const BattleResult *br) override; - virtual void battleUnitsChanged(const std::vector & units, const std::vector & customEffects) override; + virtual void battleUnitsChanged(const std::vector & units) override; virtual void saveGame(BinarySerializer & h, const int version) override; virtual void loadGame(BinaryDeserializer & h, const int version) override; diff --git a/lib/IGameEventsReceiver.h b/lib/IGameEventsReceiver.h index b3df62051..1388bb6ec 100644 --- a/lib/IGameEventsReceiver.h +++ b/lib/IGameEventsReceiver.h @@ -49,7 +49,6 @@ struct CObstacleInstance; struct CPackForServer; class EVictoryLossCheckResult; struct MetaString; -struct CustomEffectInfo; class ObstacleChanges; class UnitChanges; @@ -70,7 +69,7 @@ public: virtual void battleTriggerEffect(const BattleTriggerEffect & bte){}; //called for various one-shot effects virtual void battleStartBefore(const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2) {}; //called just before battle start virtual void battleStart(const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool side){}; //called by engine when battle starts; side=0 - left, side=1 - right - virtual void battleUnitsChanged(const std::vector & units, const std::vector & customEffects){}; + virtual void battleUnitsChanged(const std::vector & units){}; virtual void battleObstaclesChanged(const std::vector & obstacles){}; virtual void battleCatapultAttacked(const CatapultAttack & ca){}; //called when catapult makes an attack virtual void battleGateStateChanged(const EGateState state){}; diff --git a/lib/NetPacks.h b/lib/NetPacks.h index 92487c206..5a8a94eda 100644 --- a/lib/NetPacks.h +++ b/lib/NetPacks.h @@ -1557,12 +1557,10 @@ struct BattleUnitsChanged : public CPackForClient void applyCl(CClient *cl); std::vector changedStacks; - std::vector customEffects; template void serialize(Handler & h, const int version) { h & changedStacks; - h & customEffects; } }; @@ -1575,7 +1573,6 @@ struct BattleStackAttacked damageAmount(0), newState(), flags(0), - effect(0), spellID(SpellID::NONE) {}; @@ -1586,9 +1583,8 @@ struct BattleStackAttacked ui32 killedAmount; int64_t damageAmount; UnitChanges newState; - enum EFlags {KILLED = 1, EFFECT = 2/*deprecated */, SECONDARY = 4, REBIRTH = 8, CLONE_KILLED = 16, SPELL_EFFECT = 32 /*, BONUS_EFFECT = 64 */}; + enum EFlags {KILLED = 1, SECONDARY = 2, REBIRTH = 4, CLONE_KILLED = 8, SPELL_EFFECT = 16, FIRE_SHIELD = 32, }; ui32 flags; //uses EFlags (above) - ui32 effect; //set only if flag EFFECT is set SpellID spellID; //only if flag SPELL_EFFECT is set bool killed() const//if target stack was killed @@ -1599,10 +1595,6 @@ struct BattleStackAttacked { return flags & CLONE_KILLED; } - bool isEffect() const//if stack has been attacked by a spell - { - return flags & EFFECT; - } bool isSecondary() const//if stack was not a primary target (receives no spell effects) { return flags & SECONDARY; @@ -1616,6 +1608,10 @@ struct BattleStackAttacked { return flags & REBIRTH; } + bool fireShield() const + { + return flags & FIRE_SHIELD; + } template void serialize(Handler &h, const int version) { h & stackAttacked; @@ -1624,7 +1620,6 @@ struct BattleStackAttacked h & flags; h & killedAmount; h & damageAmount; - h & effect; h & spellID; } bool operator<(const BattleStackAttacked &b) const @@ -1737,8 +1732,9 @@ struct BattleSpellCast : public CPackForClient SpellID spellID; //id of spell ui8 manaGained; //mana channeling ability BattleHex tile; //destination tile (may not be set in some global/mass spells - std::vector customEffects; std::set affectedCres; //ids of creatures affected by this spell, generally used if spell does not set any effect (like dispel or cure) + std::set resistedCres; // creatures that resisted the spell (e.g. Dwarves) + std::set reflectedCres; // creatures that reflected the spell (e.g. Magic Mirror spell) si32 casterStack;// -1 if not cated by creature, >=0 caster stack ID bool castByHero; //if true - spell has been cast by hero, otherwise by a creature @@ -1748,8 +1744,9 @@ struct BattleSpellCast : public CPackForClient h & spellID; h & manaGained; h & tile; - h & customEffects; h & affectedCres; + h & resistedCres; + h & reflectedCres; h & casterStack; h & castByHero; h & activeCast; diff --git a/lib/NetPacksBase.h b/lib/NetPacksBase.h index d14cf0eb4..3222087d9 100644 --- a/lib/NetPacksBase.h +++ b/lib/NetPacksBase.h @@ -250,27 +250,6 @@ struct ArtifactLocation } }; -///custom effect (resistance, reflection, etc) -struct CustomEffectInfo -{ - CustomEffectInfo() - :effect(0), - sound(0), - stack(0) - { - } - /// WoG AC format - ui32 effect; - ui32 sound; - ui32 stack; - template void serialize(Handler & h, const int version) - { - h & effect; - h & sound; - h & stack; - } -}; - class EntityChanges { public: diff --git a/lib/spells/BattleSpellMechanics.cpp b/lib/spells/BattleSpellMechanics.cpp index c6ca1f3ba..4e702af69 100644 --- a/lib/spells/BattleSpellMechanics.cpp +++ b/lib/spells/BattleSpellMechanics.cpp @@ -401,12 +401,12 @@ void BattleSpellMechanics::beforeCast(BattleSpellCast & sc, vstd::RNG & rng, con { if(caster->getCasterUnitId() >= 0) { - addCustomEffect(sc, caster->getCasterUnitId(), 3); + sc.reflectedCres.insert(caster->getCasterUnitId()); } } for(auto unit : resisted) - addCustomEffect(sc, unit, 78); + sc.resistedCres.insert(unit->unitId()); } void BattleSpellMechanics::castEval(ServerCallback * server, const Target & target) @@ -430,19 +430,6 @@ void BattleSpellMechanics::castEval(ServerCallback * server, const Target & targ p.first->apply(server, this, p.second); } -void BattleSpellMechanics::addCustomEffect(BattleSpellCast & sc, const battle::Unit * target, ui32 effect) -{ - addCustomEffect(sc, target->unitId(), effect); -} - -void BattleSpellMechanics::addCustomEffect(BattleSpellCast & sc, ui32 targetId, ui32 effect) -{ - CustomEffectInfo customEffect; - customEffect.effect = effect; - customEffect.stack = targetId; - sc.customEffects.push_back(customEffect); -} - std::set BattleSpellMechanics::collectTargets() const { std::set result; diff --git a/lib/spells/BattleSpellMechanics.h b/lib/spells/BattleSpellMechanics.h index 3742f1b23..fabbca52d 100644 --- a/lib/spells/BattleSpellMechanics.h +++ b/lib/spells/BattleSpellMechanics.h @@ -57,9 +57,6 @@ private: void beforeCast(BattleSpellCast & sc, vstd::RNG & rng, const Target & target); - void addCustomEffect(BattleSpellCast & sc, const battle::Unit * target, ui32 effect); - void addCustomEffect(BattleSpellCast & sc, ui32 targetId, ui32 effect); - std::set collectTargets() const; static void doRemoveEffects(ServerCallback * server, const std::vector & targets, const CSelector & selector); diff --git a/lib/spells/effects/Damage.cpp b/lib/spells/effects/Damage.cpp index 88b0d1848..9941be671 100644 --- a/lib/spells/effects/Damage.cpp +++ b/lib/spells/effects/Damage.cpp @@ -33,7 +33,6 @@ VCMI_REGISTER_SPELL_EFFECT(Damage, EFFECT_NAME); Damage::Damage() : UnitEffect(), - customEffectId(-1), killByPercentage(false), killByCount(false) { @@ -74,12 +73,6 @@ void Damage::apply(ServerCallback * server, const Mechanics * m, const EffectTar damageToDisplay += bsa.damageAmount; killed += bsa.killedAmount; } - if(customEffectId >= 0) - { - bsa.effect = 82; - bsa.flags |= BattleStackAttacked::EFFECT; - } - stacksInjured.stacks.push_back(bsa); } targetIndex++; @@ -116,7 +109,6 @@ bool Damage::isReceptive(const Mechanics * m, const battle::Unit * unit) const void Damage::serializeJsonUnitEffect(JsonSerializeFormat & handler) { - handler.serializeInt("customEffectId", customEffectId, -1); handler.serializeBool("killByPercentage", killByPercentage); handler.serializeBool("killByCount", killByCount); } diff --git a/lib/spells/effects/Damage.h b/lib/spells/effects/Damage.h index 699d5005d..34beeebea 100644 --- a/lib/spells/effects/Damage.h +++ b/lib/spells/effects/Damage.h @@ -39,7 +39,6 @@ protected: virtual void describeEffect(std::vector & log, const Mechanics * m, const battle::Unit * firstTarget, uint32_t kills, int64_t damage, bool multiple) const; private: - int32_t customEffectId; bool killByPercentage; bool killByCount; }; diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index de1ed6459..477d1ecf3 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -1182,10 +1182,9 @@ void CGameHandler::makeAttack(const CStack * attacker, const CStack * defender, BattleStackAttacked bsa; + bsa.flags |= BattleStackAttacked::FIRE_SHIELD; bsa.stackAttacked = attacker->ID; //invert - bsa.attackerID = uint32_t(-1); - bsa.flags |= BattleStackAttacked::EFFECT; - bsa.effect = 11; + bsa.attackerID = defender->ID; bsa.damageAmount = totalDamage; attacker->prepareAttacked(bsa, getRandomGenerator());