From 11b3426beab3a3d1229c738cf24ab54be9cf3761 Mon Sep 17 00:00:00 2001 From: AlexVinS Date: Mon, 13 Apr 2015 06:12:23 +0300 Subject: [PATCH] Fix 0001331 --- lib/spells/AdventureSpellMechanics.cpp | 52 +++++++++++++------------- lib/spells/AdventureSpellMechanics.h | 10 ++--- lib/spells/CDefaultSpellMechanics.cpp | 26 ++++++++----- lib/spells/CDefaultSpellMechanics.h | 9 ++++- 4 files changed, 55 insertions(+), 42 deletions(-) diff --git a/lib/spells/AdventureSpellMechanics.cpp b/lib/spells/AdventureSpellMechanics.cpp index 4089c0d25..a3db3ef0f 100644 --- a/lib/spells/AdventureSpellMechanics.cpp +++ b/lib/spells/AdventureSpellMechanics.cpp @@ -20,7 +20,7 @@ #include "../CGameInfoCallback.h" ///SummonBoatMechanics -bool SummonBoatMechanics::applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const +ESpellCastResult SummonBoatMechanics::applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const { const int schoolLevel = parameters.caster->getSpellSchoolLevel(owner); //check if spell works at all @@ -31,7 +31,7 @@ bool SummonBoatMechanics::applyAdventureEffects(const SpellCastEnvironment * env iw.text.addTxt(MetaString::GENERAL_TXT, 336); //%s tried to summon a boat, but failed. iw.text.addReplacement(parameters.caster->name); env->sendAndApply(&iw); - return true; + return ESpellCastResult::OK; } //try to find unoccupied boat to summon @@ -41,7 +41,7 @@ bool SummonBoatMechanics::applyAdventureEffects(const SpellCastEnvironment * env if(summonPos.x < 0) { env->complain("There is no water tile available!"); - return false; + return ESpellCastResult::ERROR; } for(const CGObjectInstance * obj : env->getMap()->objects) @@ -84,11 +84,11 @@ bool SummonBoatMechanics::applyAdventureEffects(const SpellCastEnvironment * env no.pos = summonPos + int3(1,0,0);; env->sendAndApply(&no); } - return true; + return ESpellCastResult::OK; } ///ScuttleBoatMechanics -bool ScuttleBoatMechanics::applyAdventureEffects(const SpellCastEnvironment* env, AdventureSpellCastParameters& parameters) const +ESpellCastResult ScuttleBoatMechanics::applyAdventureEffects(const SpellCastEnvironment* env, AdventureSpellCastParameters& parameters) const { const int schoolLevel = parameters.caster->getSpellSchoolLevel(owner); //check if spell works at all @@ -99,13 +99,13 @@ bool ScuttleBoatMechanics::applyAdventureEffects(const SpellCastEnvironment* env iw.text.addTxt(MetaString::GENERAL_TXT, 337); //%s tried to scuttle the boat, but failed iw.text.addReplacement(parameters.caster->name); env->sendAndApply(&iw); - return true; + return ESpellCastResult::OK; } if(!env->getMap()->isInTheMap(parameters.pos)) { env->complain("Invalid dst tile for scuttle!"); - return false; + return ESpellCastResult::ERROR; } //TODO: test range, visibility @@ -113,22 +113,22 @@ bool ScuttleBoatMechanics::applyAdventureEffects(const SpellCastEnvironment* env if(!t->visitableObjects.size() || t->visitableObjects.back()->ID != Obj::BOAT) { env->complain("There is no boat to scuttle!"); - return false; + return ESpellCastResult::ERROR; } RemoveObject ro; ro.id = t->visitableObjects.back()->id; env->sendAndApply(&ro); - return true; + return ESpellCastResult::OK; } ///DimensionDoorMechanics -bool DimensionDoorMechanics::applyAdventureEffects(const SpellCastEnvironment* env, AdventureSpellCastParameters& parameters) const +ESpellCastResult DimensionDoorMechanics::applyAdventureEffects(const SpellCastEnvironment* env, AdventureSpellCastParameters& parameters) const { if(!env->getMap()->isInTheMap(parameters.pos)) { env->complain("Destination is out of map!"); - return false; + return ESpellCastResult::ERROR; } const TerrainTile * dest = env->getCb()->getTile(parameters.pos); @@ -137,19 +137,19 @@ bool DimensionDoorMechanics::applyAdventureEffects(const SpellCastEnvironment* e if(nullptr == dest) { env->complain("Destination tile doesn't exist!"); - return false; + return ESpellCastResult::ERROR; } if(nullptr == curr) { env->complain("Source tile doesn't exist!"); - return false; + return ESpellCastResult::ERROR; } if(parameters.caster->movement <= 0) { env->complain("Hero needs movement points to cast Dimension Door!"); - return false; + return ESpellCastResult::ERROR; } const int schoolLevel = parameters.caster->getSpellSchoolLevel(owner); @@ -161,7 +161,7 @@ bool DimensionDoorMechanics::applyAdventureEffects(const SpellCastEnvironment* e iw.text.addTxt(MetaString::GENERAL_TXT, 338); //%s is not skilled enough to cast this spell again today. iw.text.addReplacement(parameters.caster->name); env->sendAndApply(&iw); - return true; + return ESpellCastResult::CANCEL; } GiveBonus gb; @@ -183,23 +183,23 @@ bool DimensionDoorMechanics::applyAdventureEffects(const SpellCastEnvironment* e smp.val = std::max(0, parameters.caster->movement - 300); env->sendAndApply(&smp); } - return true; + return ESpellCastResult::OK; } ///TownPortalMechanics -bool TownPortalMechanics::applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters& parameters) const +ESpellCastResult TownPortalMechanics::applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters& parameters) const { if (!env->getMap()->isInTheMap(parameters.pos)) { env->complain("Destination tile not present!"); - return false; + return ESpellCastResult::ERROR; } TerrainTile tile = env->getMap()->getTile(parameters.pos); if (tile.visitableObjects.empty() || tile.visitableObjects.back()->ID != Obj::TOWN) { env->complain("Town not found for Town Portal!"); - return false; + return ESpellCastResult::ERROR; } CGTownInstance * town = static_cast(tile.visitableObjects.back()); @@ -209,13 +209,13 @@ bool TownPortalMechanics::applyAdventureEffects(const SpellCastEnvironment * env if(relations == PlayerRelations::ENEMIES) { env->complain("Can't teleport to enemy!"); - return false; + return ESpellCastResult::ERROR; } if (town->visitingHero) { env->complain("Can't teleport to occupied town!"); - return false; + return ESpellCastResult::ERROR; } if (parameters.caster->getSpellSchoolLevel(owner) < 2) @@ -234,7 +234,7 @@ bool TownPortalMechanics::applyAdventureEffects(const SpellCastEnvironment * env if (town->id != nearest) { env->complain("This hero can only teleport to nearest town!"); - return false; + return ESpellCastResult::ERROR; } } @@ -244,7 +244,7 @@ bool TownPortalMechanics::applyAdventureEffects(const SpellCastEnvironment * env if(parameters.caster->movement < movementCost) { env->complain("This hero has not enough movement points!"); - return false; + return ESpellCastResult::ERROR; } if(env->moveHero(parameters.caster->id, town->visitablePos() + parameters.caster->getVisitableOffset() ,1)) @@ -254,10 +254,10 @@ bool TownPortalMechanics::applyAdventureEffects(const SpellCastEnvironment * env smp.val = std::max(0, parameters.caster->movement - movementCost); env->sendAndApply(&smp); } - return true; + return ESpellCastResult::OK; } -bool ViewMechanics::applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const +ESpellCastResult ViewMechanics::applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const { ShowWorldViewEx pack; @@ -275,7 +275,7 @@ bool ViewMechanics::applyAdventureEffects(const SpellCastEnvironment * env, Adve env->sendAndApply(&pack); - return true; + return ESpellCastResult::OK; } bool ViewAirMechanics::filterObject(const CGObjectInstance * obj, const int spellLevel) const diff --git a/lib/spells/AdventureSpellMechanics.h b/lib/spells/AdventureSpellMechanics.h index 42d7a9b1e..c198290a8 100644 --- a/lib/spells/AdventureSpellMechanics.h +++ b/lib/spells/AdventureSpellMechanics.h @@ -20,7 +20,7 @@ class DLL_LINKAGE SummonBoatMechanics : public DefaultSpellMechanics public: SummonBoatMechanics(CSpell * s): DefaultSpellMechanics(s){}; protected: - bool applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const override; + ESpellCastResult applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const override; }; class DLL_LINKAGE ScuttleBoatMechanics : public DefaultSpellMechanics @@ -28,7 +28,7 @@ class DLL_LINKAGE ScuttleBoatMechanics : public DefaultSpellMechanics public: ScuttleBoatMechanics(CSpell * s): DefaultSpellMechanics(s){}; protected: - bool applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const override; + ESpellCastResult applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const override; }; class DLL_LINKAGE DimensionDoorMechanics : public DefaultSpellMechanics @@ -36,7 +36,7 @@ class DLL_LINKAGE DimensionDoorMechanics : public DefaultSpellMechanics public: DimensionDoorMechanics(CSpell * s): DefaultSpellMechanics(s){}; protected: - bool applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const override; + ESpellCastResult applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const override; }; class DLL_LINKAGE TownPortalMechanics : public DefaultSpellMechanics @@ -44,7 +44,7 @@ class DLL_LINKAGE TownPortalMechanics : public DefaultSpellMechanics public: TownPortalMechanics(CSpell * s): DefaultSpellMechanics(s){}; protected: - bool applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const override; + ESpellCastResult applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const override; }; class DLL_LINKAGE ViewMechanics : public DefaultSpellMechanics @@ -52,7 +52,7 @@ class DLL_LINKAGE ViewMechanics : public DefaultSpellMechanics public: ViewMechanics(CSpell * s): DefaultSpellMechanics(s){}; protected: - bool applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const override; + ESpellCastResult applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const override; virtual bool filterObject(const CGObjectInstance * obj, const int spellLevel) const = 0; }; diff --git a/lib/spells/CDefaultSpellMechanics.cpp b/lib/spells/CDefaultSpellMechanics.cpp index 1872922df..2d07af6f1 100644 --- a/lib/spells/CDefaultSpellMechanics.cpp +++ b/lib/spells/CDefaultSpellMechanics.cpp @@ -175,20 +175,26 @@ bool DefaultSpellMechanics::adventureCast(const SpellCastEnvironment * env, Adve asc.spellID = owner->id; env->sendAndApply(&asc); } - - if(applyAdventureEffects(env, parameters)) + + switch(applyAdventureEffects(env, parameters)) { - SetMana sm; - sm.hid = caster->id; - sm.absolute = false; - sm.val = -cost; - env->sendAndApply(&sm); + case ESpellCastResult::OK: + { + SetMana sm; + sm.hid = caster->id; + sm.absolute = false; + sm.val = -cost; + env->sendAndApply(&sm); + return true; + } + break; + case ESpellCastResult::CANCEL: return true; } return false; } -bool DefaultSpellMechanics::applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const +ESpellCastResult DefaultSpellMechanics::applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const { if(owner->hasEffects()) { @@ -206,13 +212,13 @@ bool DefaultSpellMechanics::applyAdventureEffects(const SpellCastEnvironment * e env->sendAndApply(&gb); } - return true; + return ESpellCastResult::OK; } else { //There is no generic algorithm of adventure cast env->complain("Unimplemented adventure spell"); - return false; + return ESpellCastResult::ERROR; } } diff --git a/lib/spells/CDefaultSpellMechanics.h b/lib/spells/CDefaultSpellMechanics.h index 6d59c6b77..98256bfbd 100644 --- a/lib/spells/CDefaultSpellMechanics.h +++ b/lib/spells/CDefaultSpellMechanics.h @@ -25,6 +25,13 @@ struct SpellCastContext StacksInjured & si; }; +enum class ESpellCastResult +{ + OK, + CANCEL,//cast failed but it is not an error + ERROR//internal error occurred +}; + class DLL_LINKAGE DefaultSpellMechanics : public ISpellMechanics { public: @@ -50,7 +57,7 @@ protected: ui32 calculateHealedHP(const CGHeroInstance * caster, const CStack * stack, const CStack * sacrificedStack) const; ///actual adventure cast implementation - virtual bool applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const; + virtual ESpellCastResult applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const; void doDispell(BattleInfo * battle, const BattleSpellCast * packet, const CSelector & selector) const; };