mirror of
https://github.com/vcmi/vcmi.git
synced 2025-03-31 22:05:10 +02:00
Fix 0001331
This commit is contained in:
parent
257a1b024d
commit
11b3426bea
@ -20,7 +20,7 @@
|
|||||||
#include "../CGameInfoCallback.h"
|
#include "../CGameInfoCallback.h"
|
||||||
|
|
||||||
///SummonBoatMechanics
|
///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);
|
const int schoolLevel = parameters.caster->getSpellSchoolLevel(owner);
|
||||||
//check if spell works at all
|
//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.addTxt(MetaString::GENERAL_TXT, 336); //%s tried to summon a boat, but failed.
|
||||||
iw.text.addReplacement(parameters.caster->name);
|
iw.text.addReplacement(parameters.caster->name);
|
||||||
env->sendAndApply(&iw);
|
env->sendAndApply(&iw);
|
||||||
return true;
|
return ESpellCastResult::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
//try to find unoccupied boat to summon
|
//try to find unoccupied boat to summon
|
||||||
@ -41,7 +41,7 @@ bool SummonBoatMechanics::applyAdventureEffects(const SpellCastEnvironment * env
|
|||||||
if(summonPos.x < 0)
|
if(summonPos.x < 0)
|
||||||
{
|
{
|
||||||
env->complain("There is no water tile available!");
|
env->complain("There is no water tile available!");
|
||||||
return false;
|
return ESpellCastResult::ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(const CGObjectInstance * obj : env->getMap()->objects)
|
for(const CGObjectInstance * obj : env->getMap()->objects)
|
||||||
@ -84,11 +84,11 @@ bool SummonBoatMechanics::applyAdventureEffects(const SpellCastEnvironment * env
|
|||||||
no.pos = summonPos + int3(1,0,0);;
|
no.pos = summonPos + int3(1,0,0);;
|
||||||
env->sendAndApply(&no);
|
env->sendAndApply(&no);
|
||||||
}
|
}
|
||||||
return true;
|
return ESpellCastResult::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
///ScuttleBoatMechanics
|
///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);
|
const int schoolLevel = parameters.caster->getSpellSchoolLevel(owner);
|
||||||
//check if spell works at all
|
//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.addTxt(MetaString::GENERAL_TXT, 337); //%s tried to scuttle the boat, but failed
|
||||||
iw.text.addReplacement(parameters.caster->name);
|
iw.text.addReplacement(parameters.caster->name);
|
||||||
env->sendAndApply(&iw);
|
env->sendAndApply(&iw);
|
||||||
return true;
|
return ESpellCastResult::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!env->getMap()->isInTheMap(parameters.pos))
|
if(!env->getMap()->isInTheMap(parameters.pos))
|
||||||
{
|
{
|
||||||
env->complain("Invalid dst tile for scuttle!");
|
env->complain("Invalid dst tile for scuttle!");
|
||||||
return false;
|
return ESpellCastResult::ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: test range, visibility
|
//TODO: test range, visibility
|
||||||
@ -113,22 +113,22 @@ bool ScuttleBoatMechanics::applyAdventureEffects(const SpellCastEnvironment* env
|
|||||||
if(!t->visitableObjects.size() || t->visitableObjects.back()->ID != Obj::BOAT)
|
if(!t->visitableObjects.size() || t->visitableObjects.back()->ID != Obj::BOAT)
|
||||||
{
|
{
|
||||||
env->complain("There is no boat to scuttle!");
|
env->complain("There is no boat to scuttle!");
|
||||||
return false;
|
return ESpellCastResult::ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
RemoveObject ro;
|
RemoveObject ro;
|
||||||
ro.id = t->visitableObjects.back()->id;
|
ro.id = t->visitableObjects.back()->id;
|
||||||
env->sendAndApply(&ro);
|
env->sendAndApply(&ro);
|
||||||
return true;
|
return ESpellCastResult::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
///DimensionDoorMechanics
|
///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))
|
if(!env->getMap()->isInTheMap(parameters.pos))
|
||||||
{
|
{
|
||||||
env->complain("Destination is out of map!");
|
env->complain("Destination is out of map!");
|
||||||
return false;
|
return ESpellCastResult::ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
const TerrainTile * dest = env->getCb()->getTile(parameters.pos);
|
const TerrainTile * dest = env->getCb()->getTile(parameters.pos);
|
||||||
@ -137,19 +137,19 @@ bool DimensionDoorMechanics::applyAdventureEffects(const SpellCastEnvironment* e
|
|||||||
if(nullptr == dest)
|
if(nullptr == dest)
|
||||||
{
|
{
|
||||||
env->complain("Destination tile doesn't exist!");
|
env->complain("Destination tile doesn't exist!");
|
||||||
return false;
|
return ESpellCastResult::ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(nullptr == curr)
|
if(nullptr == curr)
|
||||||
{
|
{
|
||||||
env->complain("Source tile doesn't exist!");
|
env->complain("Source tile doesn't exist!");
|
||||||
return false;
|
return ESpellCastResult::ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(parameters.caster->movement <= 0)
|
if(parameters.caster->movement <= 0)
|
||||||
{
|
{
|
||||||
env->complain("Hero needs movement points to cast Dimension Door!");
|
env->complain("Hero needs movement points to cast Dimension Door!");
|
||||||
return false;
|
return ESpellCastResult::ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int schoolLevel = parameters.caster->getSpellSchoolLevel(owner);
|
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.addTxt(MetaString::GENERAL_TXT, 338); //%s is not skilled enough to cast this spell again today.
|
||||||
iw.text.addReplacement(parameters.caster->name);
|
iw.text.addReplacement(parameters.caster->name);
|
||||||
env->sendAndApply(&iw);
|
env->sendAndApply(&iw);
|
||||||
return true;
|
return ESpellCastResult::CANCEL;
|
||||||
}
|
}
|
||||||
|
|
||||||
GiveBonus gb;
|
GiveBonus gb;
|
||||||
@ -183,23 +183,23 @@ bool DimensionDoorMechanics::applyAdventureEffects(const SpellCastEnvironment* e
|
|||||||
smp.val = std::max<ui32>(0, parameters.caster->movement - 300);
|
smp.val = std::max<ui32>(0, parameters.caster->movement - 300);
|
||||||
env->sendAndApply(&smp);
|
env->sendAndApply(&smp);
|
||||||
}
|
}
|
||||||
return true;
|
return ESpellCastResult::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
///TownPortalMechanics
|
///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))
|
if (!env->getMap()->isInTheMap(parameters.pos))
|
||||||
{
|
{
|
||||||
env->complain("Destination tile not present!");
|
env->complain("Destination tile not present!");
|
||||||
return false;
|
return ESpellCastResult::ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
TerrainTile tile = env->getMap()->getTile(parameters.pos);
|
TerrainTile tile = env->getMap()->getTile(parameters.pos);
|
||||||
if (tile.visitableObjects.empty() || tile.visitableObjects.back()->ID != Obj::TOWN)
|
if (tile.visitableObjects.empty() || tile.visitableObjects.back()->ID != Obj::TOWN)
|
||||||
{
|
{
|
||||||
env->complain("Town not found for Town Portal!");
|
env->complain("Town not found for Town Portal!");
|
||||||
return false;
|
return ESpellCastResult::ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGTownInstance * town = static_cast<CGTownInstance*>(tile.visitableObjects.back());
|
CGTownInstance * town = static_cast<CGTownInstance*>(tile.visitableObjects.back());
|
||||||
@ -209,13 +209,13 @@ bool TownPortalMechanics::applyAdventureEffects(const SpellCastEnvironment * env
|
|||||||
if(relations == PlayerRelations::ENEMIES)
|
if(relations == PlayerRelations::ENEMIES)
|
||||||
{
|
{
|
||||||
env->complain("Can't teleport to enemy!");
|
env->complain("Can't teleport to enemy!");
|
||||||
return false;
|
return ESpellCastResult::ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (town->visitingHero)
|
if (town->visitingHero)
|
||||||
{
|
{
|
||||||
env->complain("Can't teleport to occupied town!");
|
env->complain("Can't teleport to occupied town!");
|
||||||
return false;
|
return ESpellCastResult::ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parameters.caster->getSpellSchoolLevel(owner) < 2)
|
if (parameters.caster->getSpellSchoolLevel(owner) < 2)
|
||||||
@ -234,7 +234,7 @@ bool TownPortalMechanics::applyAdventureEffects(const SpellCastEnvironment * env
|
|||||||
if (town->id != nearest)
|
if (town->id != nearest)
|
||||||
{
|
{
|
||||||
env->complain("This hero can only teleport to nearest town!");
|
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)
|
if(parameters.caster->movement < movementCost)
|
||||||
{
|
{
|
||||||
env->complain("This hero has not enough movement points!");
|
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))
|
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<ui32>(0, parameters.caster->movement - movementCost);
|
smp.val = std::max<ui32>(0, parameters.caster->movement - movementCost);
|
||||||
env->sendAndApply(&smp);
|
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;
|
ShowWorldViewEx pack;
|
||||||
|
|
||||||
@ -275,7 +275,7 @@ bool ViewMechanics::applyAdventureEffects(const SpellCastEnvironment * env, Adve
|
|||||||
|
|
||||||
env->sendAndApply(&pack);
|
env->sendAndApply(&pack);
|
||||||
|
|
||||||
return true;
|
return ESpellCastResult::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ViewAirMechanics::filterObject(const CGObjectInstance * obj, const int spellLevel) const
|
bool ViewAirMechanics::filterObject(const CGObjectInstance * obj, const int spellLevel) const
|
||||||
|
@ -20,7 +20,7 @@ class DLL_LINKAGE SummonBoatMechanics : public DefaultSpellMechanics
|
|||||||
public:
|
public:
|
||||||
SummonBoatMechanics(CSpell * s): DefaultSpellMechanics(s){};
|
SummonBoatMechanics(CSpell * s): DefaultSpellMechanics(s){};
|
||||||
protected:
|
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
|
class DLL_LINKAGE ScuttleBoatMechanics : public DefaultSpellMechanics
|
||||||
@ -28,7 +28,7 @@ class DLL_LINKAGE ScuttleBoatMechanics : public DefaultSpellMechanics
|
|||||||
public:
|
public:
|
||||||
ScuttleBoatMechanics(CSpell * s): DefaultSpellMechanics(s){};
|
ScuttleBoatMechanics(CSpell * s): DefaultSpellMechanics(s){};
|
||||||
protected:
|
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
|
class DLL_LINKAGE DimensionDoorMechanics : public DefaultSpellMechanics
|
||||||
@ -36,7 +36,7 @@ class DLL_LINKAGE DimensionDoorMechanics : public DefaultSpellMechanics
|
|||||||
public:
|
public:
|
||||||
DimensionDoorMechanics(CSpell * s): DefaultSpellMechanics(s){};
|
DimensionDoorMechanics(CSpell * s): DefaultSpellMechanics(s){};
|
||||||
protected:
|
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
|
class DLL_LINKAGE TownPortalMechanics : public DefaultSpellMechanics
|
||||||
@ -44,7 +44,7 @@ class DLL_LINKAGE TownPortalMechanics : public DefaultSpellMechanics
|
|||||||
public:
|
public:
|
||||||
TownPortalMechanics(CSpell * s): DefaultSpellMechanics(s){};
|
TownPortalMechanics(CSpell * s): DefaultSpellMechanics(s){};
|
||||||
protected:
|
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
|
class DLL_LINKAGE ViewMechanics : public DefaultSpellMechanics
|
||||||
@ -52,7 +52,7 @@ class DLL_LINKAGE ViewMechanics : public DefaultSpellMechanics
|
|||||||
public:
|
public:
|
||||||
ViewMechanics(CSpell * s): DefaultSpellMechanics(s){};
|
ViewMechanics(CSpell * s): DefaultSpellMechanics(s){};
|
||||||
protected:
|
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;
|
virtual bool filterObject(const CGObjectInstance * obj, const int spellLevel) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -176,7 +176,9 @@ bool DefaultSpellMechanics::adventureCast(const SpellCastEnvironment * env, Adve
|
|||||||
env->sendAndApply(&asc);
|
env->sendAndApply(&asc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(applyAdventureEffects(env, parameters))
|
switch(applyAdventureEffects(env, parameters))
|
||||||
|
{
|
||||||
|
case ESpellCastResult::OK:
|
||||||
{
|
{
|
||||||
SetMana sm;
|
SetMana sm;
|
||||||
sm.hid = caster->id;
|
sm.hid = caster->id;
|
||||||
@ -185,10 +187,14 @@ bool DefaultSpellMechanics::adventureCast(const SpellCastEnvironment * env, Adve
|
|||||||
env->sendAndApply(&sm);
|
env->sendAndApply(&sm);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case ESpellCastResult::CANCEL:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DefaultSpellMechanics::applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const
|
ESpellCastResult DefaultSpellMechanics::applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const
|
||||||
{
|
{
|
||||||
if(owner->hasEffects())
|
if(owner->hasEffects())
|
||||||
{
|
{
|
||||||
@ -206,13 +212,13 @@ bool DefaultSpellMechanics::applyAdventureEffects(const SpellCastEnvironment * e
|
|||||||
env->sendAndApply(&gb);
|
env->sendAndApply(&gb);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return ESpellCastResult::OK;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//There is no generic algorithm of adventure cast
|
//There is no generic algorithm of adventure cast
|
||||||
env->complain("Unimplemented adventure spell");
|
env->complain("Unimplemented adventure spell");
|
||||||
return false;
|
return ESpellCastResult::ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,6 +25,13 @@ struct SpellCastContext
|
|||||||
StacksInjured & si;
|
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
|
class DLL_LINKAGE DefaultSpellMechanics : public ISpellMechanics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -50,7 +57,7 @@ protected:
|
|||||||
ui32 calculateHealedHP(const CGHeroInstance * caster, const CStack * stack, const CStack * sacrificedStack) const;
|
ui32 calculateHealedHP(const CGHeroInstance * caster, const CStack * stack, const CStack * sacrificedStack) const;
|
||||||
|
|
||||||
///actual adventure cast implementation
|
///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;
|
void doDispell(BattleInfo * battle, const BattleSpellCast * packet, const CSelector & selector) const;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user