mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-06 09:09:40 +02:00
Adventure spell API refactoring to ease use by AI
This commit is contained in:
@@ -47,6 +47,7 @@
|
|||||||
#include "../../lib/mapObjects/CGTownInstance.h"
|
#include "../../lib/mapObjects/CGTownInstance.h"
|
||||||
#include "../../lib/pathfinder/CGPathNode.h"
|
#include "../../lib/pathfinder/CGPathNode.h"
|
||||||
#include "../../lib/pathfinder/TurnInfo.h"
|
#include "../../lib/pathfinder/TurnInfo.h"
|
||||||
|
#include "../../lib/spells/adventure/AdventureSpellEffect.h"
|
||||||
#include "../../lib/spells/ISpellMechanics.h"
|
#include "../../lib/spells/ISpellMechanics.h"
|
||||||
#include "../../lib/spells/Problem.h"
|
#include "../../lib/spells/Problem.h"
|
||||||
|
|
||||||
@@ -612,13 +613,15 @@ void AdventureMapInterface::onTileHovered(const int3 &targetPosition)
|
|||||||
|
|
||||||
if(spellBeingCasted)
|
if(spellBeingCasted)
|
||||||
{
|
{
|
||||||
|
const auto * hero = GAME->interface()->localState->getCurrentHero();
|
||||||
|
const auto * spellEffect = spellBeingCasted->getAdventureMechanics().getEffectAs<AdventureSpellRangedEffect>(hero);
|
||||||
spells::detail::ProblemImpl problem;
|
spells::detail::ProblemImpl problem;
|
||||||
|
|
||||||
if(isValidAdventureSpellTarget(targetPosition))
|
if(spellEffect && spellEffect->canBeCastAtImpl(problem, GAME->interface()->cb.get(), hero, targetPosition))
|
||||||
ENGINE->cursor().set(spellBeingCasted->getAdventureMechanics().getCursorForTarget(GAME->interface()->cb.get(), GAME->interface()->localState->getCurrentHero(), targetPosition));
|
ENGINE->cursor().set(spellEffect->getCursorForTarget(GAME->interface()->cb.get(), hero, targetPosition));
|
||||||
else
|
else
|
||||||
ENGINE->cursor().set(Cursor::Map::POINTER);
|
ENGINE->cursor().set(Cursor::Map::POINTER);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
#include "../../lib/pathfinder/CGPathNode.h"
|
#include "../../lib/pathfinder/CGPathNode.h"
|
||||||
#include "../../lib/spells/CSpellHandler.h"
|
#include "../../lib/spells/CSpellHandler.h"
|
||||||
#include "../../lib/spells/ISpellMechanics.h"
|
#include "../../lib/spells/ISpellMechanics.h"
|
||||||
#include "../../lib/spells/Problem.h"
|
#include "../../lib/spells/adventure/AdventureSpellEffect.h"
|
||||||
|
|
||||||
MapRendererBaseContext::MapRendererBaseContext(const MapRendererContextState & viewState)
|
MapRendererBaseContext::MapRendererBaseContext(const MapRendererContextState & viewState)
|
||||||
: viewState(viewState)
|
: viewState(viewState)
|
||||||
@@ -375,8 +375,8 @@ bool MapRendererAdventureContext::showSpellRange(const int3 & position) const
|
|||||||
if (!hero || !spell.hasValue())
|
if (!hero || !spell.hasValue())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
spells::detail::ProblemImpl problem;;
|
const auto * spellEffect = spell.toSpell()->getAdventureMechanics().getEffectAs<AdventureSpellRangedEffect>(hero);
|
||||||
return !spell.toSpell()->getAdventureMechanics().isTargetInRange(problem, GAME->interface()->cb.get(), hero, position);
|
return !spellEffect->isTargetInRange(GAME->interface()->cb.get(), hero, position);
|
||||||
}
|
}
|
||||||
|
|
||||||
MapRendererAdventureTransitionContext::MapRendererAdventureTransitionContext(const MapRendererContextState & viewState)
|
MapRendererAdventureTransitionContext::MapRendererAdventureTransitionContext(const MapRendererContextState & viewState)
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ class JsonNode;
|
|||||||
class CStack;
|
class CStack;
|
||||||
class CGObjectInstance;
|
class CGObjectInstance;
|
||||||
class CGHeroInstance;
|
class CGHeroInstance;
|
||||||
|
class IAdventureSpellEffect;
|
||||||
|
|
||||||
namespace spells
|
namespace spells
|
||||||
{
|
{
|
||||||
@@ -354,13 +355,18 @@ public:
|
|||||||
|
|
||||||
virtual bool canBeCast(spells::Problem & problem, const IGameInfoCallback * cb, const spells::Caster * caster) const = 0;
|
virtual bool canBeCast(spells::Problem & problem, const IGameInfoCallback * cb, const spells::Caster * caster) const = 0;
|
||||||
virtual bool canBeCastAt(spells::Problem & problem, const IGameInfoCallback * cb, const spells::Caster * caster, const int3 & pos) const = 0;
|
virtual bool canBeCastAt(spells::Problem & problem, const IGameInfoCallback * cb, const spells::Caster * caster, const int3 & pos) const = 0;
|
||||||
virtual bool isTargetInRange(spells::Problem & problem, const IGameInfoCallback * cb, const spells::Caster * caster, const int3 & pos) const = 0;
|
|
||||||
virtual std::string getCursorForTarget(const IGameInfoCallback * cb, const spells::Caster * caster, const int3 & pos) const = 0;
|
|
||||||
|
|
||||||
virtual bool adventureCast(SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const = 0;
|
virtual bool adventureCast(SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const = 0;
|
||||||
|
|
||||||
static std::unique_ptr<IAdventureSpellMechanics> createMechanics(const CSpell * s);
|
static std::unique_ptr<IAdventureSpellMechanics> createMechanics(const CSpell * s);
|
||||||
|
|
||||||
|
template<typename EffectType>
|
||||||
|
const EffectType * getEffectAs(const spells::Caster * caster) const
|
||||||
|
{
|
||||||
|
return dynamic_cast<const EffectType *>(getEffect(caster));
|
||||||
|
}
|
||||||
protected:
|
protected:
|
||||||
|
virtual const IAdventureSpellEffect * getEffect(const spells::Caster * caster) const = 0;
|
||||||
|
|
||||||
const CSpell * owner;
|
const CSpell * owner;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ AdventureSpellRangedEffect::AdventureSpellRangedEffect(const JsonNode & config)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AdventureSpellRangedEffect::isTargetInRange(spells::Problem & problem, const IGameInfoCallback * cb, const spells::Caster * caster, const int3 & pos) const
|
bool AdventureSpellRangedEffect::isTargetInRange(const IGameInfoCallback * cb, const spells::Caster * caster, const int3 & pos) const
|
||||||
{
|
{
|
||||||
if(!cb->isInTheMap(pos))
|
if(!cb->isInTheMap(pos))
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ public:
|
|||||||
virtual void endCast(SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const {};
|
virtual void endCast(SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const {};
|
||||||
virtual bool canBeCastImpl(spells::Problem & problem, const IGameInfoCallback * cb, const spells::Caster * caster) const {return true;};
|
virtual bool canBeCastImpl(spells::Problem & problem, const IGameInfoCallback * cb, const spells::Caster * caster) const {return true;};
|
||||||
virtual bool canBeCastAtImpl(spells::Problem & problem, const IGameInfoCallback * cb, const spells::Caster * caster, const int3 & pos) const {return true;};
|
virtual bool canBeCastAtImpl(spells::Problem & problem, const IGameInfoCallback * cb, const spells::Caster * caster, const int3 & pos) const {return true;};
|
||||||
virtual bool isTargetInRange(spells::Problem & problem, const IGameInfoCallback * cb, const spells::Caster * caster, const int3 & pos) const {return true;};
|
|
||||||
virtual std::string getCursorForTarget(const IGameInfoCallback * cb, const spells::Caster * caster, const int3 & pos) const {return {};};
|
virtual std::string getCursorForTarget(const IGameInfoCallback * cb, const spells::Caster * caster, const int3 & pos) const {return {};};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -53,8 +52,9 @@ class AdventureSpellRangedEffect : public IAdventureSpellEffect
|
|||||||
public:
|
public:
|
||||||
AdventureSpellRangedEffect(const JsonNode & config);
|
AdventureSpellRangedEffect(const JsonNode & config);
|
||||||
|
|
||||||
bool isTargetInRange(spells::Problem & problem, const IGameInfoCallback * cb, const spells::Caster * caster, const int3 & pos) const final;
|
DLL_LINKAGE bool isTargetInRange(const IGameInfoCallback * cb, const spells::Caster * caster, const int3 & pos) const;
|
||||||
std::string getCursorForTarget(const IGameInfoCallback * cb, const spells::Caster * caster, const int3 & pos) const override = 0; //must be implemented in derived
|
std::string getCursorForTarget(const IGameInfoCallback * cb, const spells::Caster * caster, const int3 & pos) const override = 0; //must be implemented in derived classes
|
||||||
|
bool canBeCastAtImpl(spells::Problem & problem, const IGameInfoCallback * cb, const spells::Caster * caster, const int3 & pos) const override = 0; //must be implemented in derived classes
|
||||||
};
|
};
|
||||||
|
|
||||||
VCMI_LIB_NAMESPACE_END
|
VCMI_LIB_NAMESPACE_END
|
||||||
|
|||||||
@@ -79,6 +79,11 @@ const AdventureSpellMechanics::LevelOptions & AdventureSpellMechanics::getLevel(
|
|||||||
return levelOptions.at(schoolLevel);
|
return levelOptions.at(schoolLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const IAdventureSpellEffect * AdventureSpellMechanics::getEffect(const spells::Caster * caster) const
|
||||||
|
{
|
||||||
|
return getLevel(caster).effect.get();
|
||||||
|
}
|
||||||
|
|
||||||
bool AdventureSpellMechanics::canBeCast(spells::Problem & problem, const IGameInfoCallback * cb, const spells::Caster * caster) const
|
bool AdventureSpellMechanics::canBeCast(spells::Problem & problem, const IGameInfoCallback * cb, const spells::Caster * caster) const
|
||||||
{
|
{
|
||||||
if(!owner->isAdventure())
|
if(!owner->isAdventure())
|
||||||
@@ -125,16 +130,6 @@ bool AdventureSpellMechanics::canBeCastAt(spells::Problem & problem, const IGame
|
|||||||
return canBeCast(problem, cb, caster) && getLevel(caster).effect->canBeCastAtImpl(problem, cb, caster, pos);
|
return canBeCast(problem, cb, caster) && getLevel(caster).effect->canBeCastAtImpl(problem, cb, caster, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AdventureSpellMechanics::isTargetInRange(spells::Problem & problem, const IGameInfoCallback * cb, const spells::Caster * caster, const int3 & pos) const
|
|
||||||
{
|
|
||||||
return getLevel(caster).effect->isTargetInRange(problem, cb, caster, pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string AdventureSpellMechanics::getCursorForTarget(const IGameInfoCallback * cb, const spells::Caster * caster, const int3 & pos) const
|
|
||||||
{
|
|
||||||
return getLevel(caster).effect->getCursorForTarget(cb, caster, pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AdventureSpellMechanics::adventureCast(SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const
|
bool AdventureSpellMechanics::adventureCast(SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const
|
||||||
{
|
{
|
||||||
spells::detail::ProblemImpl problem;
|
spells::detail::ProblemImpl problem;
|
||||||
|
|||||||
@@ -28,19 +28,17 @@ class AdventureSpellMechanics final : public IAdventureSpellMechanics, boost::no
|
|||||||
|
|
||||||
std::array<LevelOptions, GameConstants::SPELL_SCHOOL_LEVELS> levelOptions;
|
std::array<LevelOptions, GameConstants::SPELL_SCHOOL_LEVELS> levelOptions;
|
||||||
|
|
||||||
|
const LevelOptions & getLevel(const spells::Caster * caster) const;
|
||||||
|
void giveBonuses(SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AdventureSpellMechanics(const CSpell * s);
|
AdventureSpellMechanics(const CSpell * s);
|
||||||
~AdventureSpellMechanics();
|
~AdventureSpellMechanics();
|
||||||
|
|
||||||
const LevelOptions & getLevel(const spells::Caster * caster) const;
|
|
||||||
|
|
||||||
bool canBeCast(spells::Problem & problem, const IGameInfoCallback * cb, const spells::Caster * caster) const final;
|
bool canBeCast(spells::Problem & problem, const IGameInfoCallback * cb, const spells::Caster * caster) const final;
|
||||||
bool canBeCastAt(spells::Problem & problem, const IGameInfoCallback * cb, const spells::Caster * caster, const int3 & pos) const final;
|
bool canBeCastAt(spells::Problem & problem, const IGameInfoCallback * cb, const spells::Caster * caster, const int3 & pos) const final;
|
||||||
bool isTargetInRange(spells::Problem & problem, const IGameInfoCallback * cb, const spells::Caster * caster, const int3 & pos) const final;
|
|
||||||
std::string getCursorForTarget(const IGameInfoCallback * cb, const spells::Caster * caster, const int3 & pos) const final;
|
|
||||||
bool adventureCast(SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const final;
|
bool adventureCast(SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const final;
|
||||||
|
const IAdventureSpellEffect * getEffect(const spells::Caster * caster) const final;
|
||||||
void giveBonuses(SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const;
|
|
||||||
void performCast(SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const;
|
void performCast(SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ bool DimensionDoorEffect::canBeCastImpl(spells::Problem & problem, const IGameIn
|
|||||||
|
|
||||||
bool DimensionDoorEffect::canBeCastAtImpl(spells::Problem & problem, const IGameInfoCallback * cb, const spells::Caster * caster, const int3 & pos) const
|
bool DimensionDoorEffect::canBeCastAtImpl(spells::Problem & problem, const IGameInfoCallback * cb, const spells::Caster * caster, const int3 & pos) const
|
||||||
{
|
{
|
||||||
if (!isTargetInRange(problem, cb, caster, pos))
|
if (!isTargetInRange(cb, caster, pos))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
int3 casterPosition = caster->getHeroCaster()->getSightCenter();
|
int3 casterPosition = caster->getHeroCaster()->getSightCenter();
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ std::string RemoveObjectEffect::getCursorForTarget(const IGameInfoCallback * cb,
|
|||||||
|
|
||||||
bool RemoveObjectEffect::canBeCastAtImpl(spells::Problem & problem, const IGameInfoCallback * cb, const spells::Caster * caster, const int3 & pos) const
|
bool RemoveObjectEffect::canBeCastAtImpl(spells::Problem & problem, const IGameInfoCallback * cb, const spells::Caster * caster, const int3 & pos) const
|
||||||
{
|
{
|
||||||
if (!isTargetInRange(problem, cb, caster, pos))
|
if (!isTargetInRange(cb, caster, pos))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const TerrainTile * t = cb->getTile(pos);
|
const TerrainTile * t = cb->getTile(pos);
|
||||||
|
|||||||
Reference in New Issue
Block a user