1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-01-12 02:28:11 +02:00

Casting DD or TP will now spend mana before hero movement (and any side

effects such as visiting objects)
This commit is contained in:
Ivan Savenko 2024-04-10 18:42:31 +03:00
parent 8353bca34f
commit 6c45353aa7
2 changed files with 45 additions and 15 deletions

View File

@ -119,29 +119,31 @@ ESpellCastResult AdventureSpellMechanics::applyAdventureEffects(SpellCastEnviron
ESpellCastResult AdventureSpellMechanics::beginCast(SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const
{
return ESpellCastResult::OK;
return ESpellCastResult::OK;
}
void AdventureSpellMechanics::endCast(SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const
{
// no-op, only for implementation in derived classes
}
void AdventureSpellMechanics::performCast(SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const
{
const auto level = parameters.caster->getSpellSchoolLevel(owner);
const auto cost = owner->getCost(level);
AdvmapSpellCast asc;
asc.casterID = ObjectInstanceID(parameters.caster->getCasterUnitId());
asc.spellID = owner->id;
env->apply(&asc);
ESpellCastResult result = applyAdventureEffects(env, parameters);
endCast(env, parameters, result);
}
void AdventureSpellMechanics::endCast(SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters, const ESpellCastResult result) const
{
const auto level = parameters.caster->getSpellSchoolLevel(owner);
const auto cost = owner->getCost(level);
switch(result)
{
case ESpellCastResult::OK:
parameters.caster->spendMana(env, cost);
endCast(env, parameters);
break;
default:
break;
@ -427,10 +429,17 @@ ESpellCastResult DimensionDoorMechanics::applyAdventureEffects(SpellCastEnvironm
smp.val = 0;
env->apply(&smp);
return ESpellCastResult::OK;
}
void DimensionDoorMechanics::endCast(SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const
{
int3 casterPosition = parameters.caster->getHeroCaster()->getSightCenter();
const TerrainTile * dest = env->getCb()->getTile(parameters.pos);
const TerrainTile * curr = env->getCb()->getTile(casterPosition);
if(dest->isClear(curr))
env->moveHero(ObjectInstanceID(parameters.caster->getCasterUnitId()), parameters.caster->getHeroCaster()->convertFromVisitablePos(parameters.pos), true);
return ESpellCastResult::OK;
}
///TownPortalMechanics
@ -526,6 +535,26 @@ ESpellCastResult TownPortalMechanics::applyAdventureEffects(SpellCastEnvironment
return ESpellCastResult::ERROR;
}
return ESpellCastResult::OK;
}
void TownPortalMechanics::endCast(SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const
{
const int moveCost = movementCost(parameters);
const CGTownInstance * destination = nullptr;
if(parameters.caster->getSpellSchoolLevel(owner) < 2)
{
std::vector <const CGTownInstance*> pool = getPossibleTowns(env, parameters);
destination = findNearestTown(env, parameters, pool);
}
else
{
const TerrainTile & tile = env->getMap()->getTile(parameters.pos);
auto * const topObj = tile.topVisitableObj(false);
destination = dynamic_cast<const CGTownInstance*>(topObj);
}
if(env->moveHero(ObjectInstanceID(parameters.caster->getCasterUnitId()), parameters.caster->getHeroCaster()->convertFromVisitablePos(destination->visitablePos()), true))
{
SetMovePoints smp;
@ -533,7 +562,6 @@ ESpellCastResult TownPortalMechanics::applyAdventureEffects(SpellCastEnvironment
smp.val = std::max<ui32>(0, parameters.caster->getHeroCaster()->movementPointsRemaining() - moveCost);
env->apply(&smp);
}
return ESpellCastResult::OK;
}
ESpellCastResult TownPortalMechanics::beginCast(SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const

View File

@ -18,10 +18,10 @@ class CGTownInstance;
enum class ESpellCastResult
{
OK,
CANCEL,//cast failed but it is not an error
OK, // cast successful
CANCEL, // cast failed but it is not an error, no mana has been spent
PENDING,
ERROR//internal error occurred
ERROR// error occured, for example invalid request from player
};
class AdventureSpellMechanics : public IAdventureSpellMechanics
@ -37,11 +37,11 @@ protected:
///actual adventure cast implementation
virtual ESpellCastResult applyAdventureEffects(SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const;
virtual ESpellCastResult beginCast(SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const;
virtual void endCast(SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const;
virtual bool canBeCastImpl(spells::Problem & problem, const CGameInfoCallback * cb, const spells::Caster * caster) const;
virtual bool canBeCastAtImpl(spells::Problem & problem, const CGameInfoCallback * cb, const spells::Caster * caster, const int3 & pos) const;
void performCast(SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const;
void endCast(SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters, const ESpellCastResult result) const;
};
class SummonBoatMechanics final : public AdventureSpellMechanics
@ -73,6 +73,7 @@ protected:
bool canBeCastAtImpl(spells::Problem & problem, const CGameInfoCallback * cb, const spells::Caster * caster, const int3 & pos) const override;
ESpellCastResult applyAdventureEffects(SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const override;
void endCast(SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const override;
};
class TownPortalMechanics final : public AdventureSpellMechanics
@ -82,6 +83,7 @@ public:
protected:
ESpellCastResult applyAdventureEffects(SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const override;
ESpellCastResult beginCast(SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const override;
void endCast(SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const override;
private:
const CGTownInstance * findNearestTown(SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters, const std::vector <const CGTownInstance*> & pool) const;
int32_t movementCost(const AdventureSpellCastParameters & parameters) const;