2
0
Эх сурвалжийг харах

UI now shows spell range from config

Ivan Savenko 3 сар өмнө
parent
commit
5ada2d19e1

+ 10 - 0
client/PlayerLocalState.cpp

@@ -91,6 +91,16 @@ void PlayerLocalState::verifyPath(const CGHeroInstance * h)
 	setPath(h, getPath(h).endPos());
 }
 
+SpellID PlayerLocalState::getCurrentSpell() const
+{
+	return currentSpell;
+}
+
+void PlayerLocalState::setCurrentSpell(SpellID castedSpell)
+{
+	currentSpell = castedSpell;
+}
+
 const CGHeroInstance * PlayerLocalState::getCurrentHero() const
 {
 	if(currentSelection && currentSelection->ID == Obj::HERO)

+ 7 - 0
client/PlayerLocalState.h

@@ -49,6 +49,8 @@ class PlayerLocalState
 
 	PlayerSpellbookSetting spellbookSettings;
 
+	SpellID currentSpell;
+
 	void syncronizeState();
 public:
 
@@ -89,6 +91,11 @@ public:
 	const CGTownInstance * getCurrentTown() const;
 	const CArmedInstance * getCurrentArmy() const;
 
+	// returns currently cast spell, if any
+	SpellID getCurrentSpell() const;
+
+	void setCurrentSpell(SpellID castedSpell);
+
 	void serialize(JsonNode & dest) const;
 	void deserialize(const JsonNode & source);
 

+ 2 - 8
client/adventureMap/AdventureMapInterface.cpp

@@ -515,7 +515,6 @@ void AdventureMapInterface::onTileLeftClicked(const int3 &targetPosition)
 	if(spellBeingCasted)
 	{
 		assert(shortcuts->optionSpellcasting());
-		assert(spellBeingCasted->id == SpellID::SCUTTLE_BOAT || spellBeingCasted->id == SpellID::DIMENSION_DOOR);
 
 		if(isValidAdventureSpellTarget(targetPosition))
 			performSpellcasting(targetPosition);
@@ -839,11 +838,8 @@ void AdventureMapInterface::onTileRightClicked(const int3 &mapPos)
 
 void AdventureMapInterface::enterCastingMode(const CSpell * sp)
 {
-	assert(sp->id == SpellID::SCUTTLE_BOAT || sp->id == SpellID::DIMENSION_DOOR);
 	spellBeingCasted = sp;
-	Settings config = settings.write["session"]["showSpellRange"];
-	config->Bool() = true;
-
+	GAME->interface()->localState->setCurrentSpell(sp->id);
 	setState(EAdventureState::CASTING_SPELL);
 }
 
@@ -852,9 +848,7 @@ void AdventureMapInterface::exitCastingMode()
 	assert(spellBeingCasted);
 	spellBeingCasted = nullptr;
 	setState(EAdventureState::MAKING_TURN);
-
-	Settings config = settings.write["session"]["showSpellRange"];
-	config->Bool() = false;
+	GAME->interface()->localState->setCurrentSpell(SpellID::NONE);
 }
 
 void AdventureMapInterface::hotkeyAbortCastingMode()

+ 9 - 8
client/mapView/MapRendererContext.cpp

@@ -19,14 +19,16 @@
 #include "../GameInstance.h"
 
 #include "../../lib/Point.h"
+#include "../../lib/battle/CPlayerBattleCallback.h"
+#include "../../lib/battle/IBattleState.h"
 #include "../../lib/callback/CCallback.h"
 #include "../../lib/mapObjects/CGHeroInstance.h"
 #include "../../lib/mapObjects/MiscObjects.h"
-#include "../../lib/spells/CSpellHandler.h"
 #include "../../lib/mapping/CMap.h"
 #include "../../lib/pathfinder/CGPathNode.h"
-#include "../../lib/battle/CPlayerBattleCallback.h"
-#include "../../lib/battle/IBattleState.h"
+#include "../../lib/spells/CSpellHandler.h"
+#include "../../lib/spells/ISpellMechanics.h"
+#include "../../lib/spells/Problem.h"
 
 MapRendererBaseContext::MapRendererBaseContext(const MapRendererContextState & viewState)
 	: viewState(viewState)
@@ -367,15 +369,14 @@ bool MapRendererAdventureContext::showTextOverlay() const
 
 bool MapRendererAdventureContext::showSpellRange(const int3 & position) const
 {
-	if (!settingSpellRange)
-		return false;
-
 	auto hero = GAME->interface()->localState->getCurrentHero();
+	auto spell = GAME->interface()->localState->getCurrentSpell();
 
-	if (!hero)
+	if (!hero || !spell.hasValue())
 		return false;
 
-	return !isInScreenRange(hero->getSightCenter(), position);
+	spells::detail::ProblemImpl problem;;
+	return !spell.toSpell()->getAdventureMechanics().isTargetInRange(problem, GAME->interface()->cb.get(), hero, position);
 }
 
 MapRendererAdventureTransitionContext::MapRendererAdventureTransitionContext(const MapRendererContextState & viewState)

+ 0 - 1
client/mapView/MapRendererContext.h

@@ -72,7 +72,6 @@ public:
 	bool settingShowGrid = false;
 	bool settingShowVisitable = false;
 	bool settingShowBlocked = false;
-	bool settingSpellRange= false;
 	bool settingTextOverlay = false;
 	bool settingsAdventureObjectAnimation = true;
 	bool settingsAdventureTerrainAnimation = true;

+ 0 - 1
client/mapView/MapViewController.cpp

@@ -233,7 +233,6 @@ void MapViewController::updateState()
 		adventureContext->settingShowGrid = settings["gameTweaks"]["showGrid"].Bool();
 		adventureContext->settingShowVisitable = settings["session"]["showVisitable"].Bool();
 		adventureContext->settingShowBlocked = settings["session"]["showBlocked"].Bool();
-		adventureContext->settingSpellRange = settings["session"]["showSpellRange"].Bool();
 		adventureContext->settingTextOverlay = (ENGINE->isKeyboardAltDown() || ENGINE->input().getNumTouchFingers() == 2) && settings["general"]["enableOverlay"].Bool();
 	}
 }

+ 0 - 6
lib/spells/CSpellHandler.cpp

@@ -536,12 +536,6 @@ CSpell::TargetInfo::TargetInfo(const CSpell * spell, const int level, spells::Mo
 	clearAffected = levelInfo.clearAffected;
 }
 
-bool DLL_LINKAGE isInScreenRange(const int3 & center, const int3 & pos)
-{
-	int3 diff = pos - center;
-	return diff.x >= -9 && diff.x <= 9 && diff.y >= -8 && diff.y <= 8;
-}
-
 ///CSpellHandler
 std::vector<JsonNode> CSpellHandler::loadLegacyData()
 {

+ 0 - 2
lib/spells/CSpellHandler.h

@@ -290,8 +290,6 @@ private:
 	std::unique_ptr<IAdventureSpellMechanics> adventureMechanics;//(!) do not serialize
 };
 
-bool DLL_LINKAGE isInScreenRange(const int3 &center, const int3 &pos); //for spells like Dimension Door
-
 class DLL_LINKAGE CSpellHandler: public CHandlerBase<SpellID, spells::Spell, CSpell, spells::Service>
 {
 	std::vector<int> spellRangeInHexes(std::string rng) const;

+ 1 - 0
lib/spells/ISpellMechanics.h

@@ -354,6 +354,7 @@ public:
 
 	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 isTargetInRange(spells::Problem & problem, const IGameInfoCallback * cb, const spells::Caster * caster, const int3 & pos) const = 0;
 
 	virtual bool adventureCast(SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const = 0;
 

+ 4 - 10
lib/spells/adventure/AdventureSpellEffect.cpp

@@ -24,23 +24,17 @@ AdventureSpellRangedEffect::AdventureSpellRangedEffect(const JsonNode & config)
 {
 }
 
-bool AdventureSpellRangedEffect::isTargetInRange(const int3 & pos, const int3 & center) const
-{
-	int3 diff = pos - center;
-	return diff.x >= -rangeX && diff.x <= rangeX && diff.y >= -rangeY && diff.y <= rangeY;
-}
-
-bool AdventureSpellRangedEffect::canBeCastAtImpl(spells::Problem & problem, const IGameInfoCallback * cb, const spells::Caster * caster, const int3 & pos) const
+bool AdventureSpellRangedEffect::isTargetInRange(spells::Problem & problem, const IGameInfoCallback * cb, const spells::Caster * caster, const int3 & pos) const
 {
 	if(!cb->isInTheMap(pos))
 		return false;
 
 	if(caster->getHeroCaster())
 	{
-		int3 casterPosition = caster->getHeroCaster()->getSightCenter();
+		int3 center = caster->getHeroCaster()->getSightCenter();
 
-		if(!isTargetInRange(casterPosition, pos))
-			return false;
+		int3 diff = pos - center;
+		return diff.x >= -rangeX && diff.x <= rangeX && diff.y >= -rangeY && diff.y <= rangeY;
 	}
 
 	if(!ignoreFow && !cb->isVisibleFor(pos, caster->getCasterOwner()))

+ 2 - 2
lib/spells/adventure/AdventureSpellEffect.h

@@ -34,6 +34,7 @@ public:
 	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 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;};
 };
 
 class AdventureSpellEffect final : public IAdventureSpellEffect
@@ -48,11 +49,10 @@ class AdventureSpellRangedEffect : public IAdventureSpellEffect
 	int rangeY;
 	bool ignoreFow;
 
-	bool isTargetInRange(const int3 & pos, const int3 & center) const;
 public:
 	AdventureSpellRangedEffect(const JsonNode & config);
 
-	bool canBeCastAtImpl(spells::Problem & problem, const IGameInfoCallback * cb, const spells::Caster * caster, const int3 & pos) const override;
+	bool isTargetInRange(spells::Problem & problem, const IGameInfoCallback * cb, const spells::Caster * caster, const int3 & pos) const override;
 };
 
 VCMI_LIB_NAMESPACE_END

+ 5 - 0
lib/spells/adventure/AdventureSpellMechanics.cpp

@@ -125,6 +125,11 @@ bool AdventureSpellMechanics::canBeCastAt(spells::Problem & problem, const IGame
 	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);
+}
+
 bool AdventureSpellMechanics::adventureCast(SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const
 {
 	spells::detail::ProblemImpl problem;

+ 1 - 0
lib/spells/adventure/AdventureSpellMechanics.h

@@ -36,6 +36,7 @@ public:
 
 	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 isTargetInRange(spells::Problem & problem, const IGameInfoCallback * cb, const spells::Caster * caster, const int3 & pos) const final;
 	bool adventureCast(SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const final;
 
 	void giveBonuses(SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const;

+ 1 - 1
lib/spells/adventure/DimensionDoorEffect.cpp

@@ -46,7 +46,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
 {
-	if (!AdventureSpellRangedEffect::canBeCastAtImpl(problem, cb, caster, pos))
+	if (!isTargetInRange(problem, cb, caster, pos))
 		return false;
 
 	int3 casterPosition = caster->getHeroCaster()->getSightCenter();

+ 1 - 1
lib/spells/adventure/RemoveObjectEffect.cpp

@@ -40,7 +40,7 @@ RemoveObjectEffect::RemoveObjectEffect(const CSpell * s, const JsonNode & config
 
 bool RemoveObjectEffect::canBeCastAtImpl(spells::Problem & problem, const IGameInfoCallback * cb, const spells::Caster * caster, const int3 & pos) const
 {
-	if (!AdventureSpellRangedEffect::canBeCastAtImpl(problem, cb, caster, pos))
+	if (!isTargetInRange(problem, cb, caster, pos))
 		return false;
 
 	const TerrainTile * t = cb->getTile(pos);

+ 1 - 0
lib/spells/adventure/RemoveObjectEffect.h

@@ -19,6 +19,7 @@ class RemoveObjectEffect final : public AdventureSpellRangedEffect
 	const CSpell * owner;
 	std::vector<MapObjectID> removedObjects;
 	MetaString failMessage;
+	ImagePath cursorPath;
 
 public:
 	RemoveObjectEffect(const CSpell * s, const JsonNode & config);