فهرست منبع

Move REMOVE_OBSTACLE-related code from callback to where it should be.

AlexVinS 9 سال پیش
والد
کامیت
40e6e0c143

+ 6 - 39
lib/CBattleCallback.cpp

@@ -1776,47 +1776,14 @@ ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleCanCastThisSpell
 		return ESpellCastProblem::INVALID;
 	}
 	const PlayerColor player = caster->getOwner();
-	ESpellCastProblem::ESpellCastProblem moreGeneralProblem = battleCanCastThisSpell(caster, spell, mode);
-	if(moreGeneralProblem != ESpellCastProblem::OK)
-		return moreGeneralProblem;
 
-	if(spell->getTargetType() == CSpell::OBSTACLE)
-	{
-		if(spell->id == SpellID::REMOVE_OBSTACLE)
-		{
-			if(auto obstacle = battleGetObstacleOnPos(dest, false))
-			{
-				switch (obstacle->obstacleType)
-				{
-				case CObstacleInstance::ABSOLUTE_OBSTACLE: //cliff-like obstacles can't be removed
-				case CObstacleInstance::MOAT:
-					return ESpellCastProblem::NO_APPROPRIATE_TARGET;
-				case CObstacleInstance::USUAL:
-					return ESpellCastProblem::OK;
-
-// 				//TODO FIRE_WALL only for ADVANCED level casters
-// 				case CObstacleInstance::FIRE_WALL:
-// 					return
-// 				//TODO other magic obstacles for EXPERT
-// 				case CObstacleInstance::QUICKSAND:
-// 				case CObstacleInstance::LAND_MINE:
-// 				case CObstacleInstance::FORCE_FIELD:
-// 					return
-				default:
-//					assert(0);
-					return ESpellCastProblem::OK;
-				}
-			}
-		}
-		//isObstacleOnTile(dest)
-		//
-		//
-		//TODO
-		//assert that it's remove obstacle
-		//rules whether we can remove spell-created obstacle
-		return ESpellCastProblem::NO_APPROPRIATE_TARGET;
-	}
+	ESpellCastProblem::ESpellCastProblem problem = battleCanCastThisSpell(caster, spell, mode);
+	if(problem != ESpellCastProblem::OK)
+		return problem;
 
+	problem = spell->canBeCastAt(this, caster, mode, dest);
+	if(problem != ESpellCastProblem::OK)
+		return problem;
 
 	//get dead stack if we cast resurrection or animate dead
 	const CStack *deadStack = getStackIf([dest](const CStack *s) { return !s->alive() && s->coversPos(dest); });

+ 32 - 1
lib/spells/BattleSpellMechanics.cpp

@@ -465,7 +465,6 @@ void ObstacleMechanics::applyBattleEffects(const SpellCastEnvironment * env, con
 	}
 }
 
-
 ///WallMechanics
 std::vector<BattleHex> WallMechanics::rangeInHexes(BattleHex centralHex, ui8 schoolLvl, ui8 side, bool * outDroppedHexes) const
 {
@@ -516,6 +515,38 @@ void RemoveObstacleMechanics::applyBattleEffects(const SpellCastEnvironment * en
 		env->complain("There's no obstacle to remove!");
 }
 
+ESpellCastProblem::ESpellCastProblem RemoveObstacleMechanics::canBeCast(const SpellTargetingContext & ctx) const
+{
+	ESpellCastProblem::ESpellCastProblem res = ESpellCastProblem::NO_APPROPRIATE_TARGET;
+
+	if(auto obstacle = ctx.cb->battleGetObstacleOnPos(ctx.destination, false))
+	{
+		switch (obstacle->obstacleType)
+		{
+		case CObstacleInstance::ABSOLUTE_OBSTACLE: //cliff-like obstacles can't be removed
+		case CObstacleInstance::MOAT:
+			break;
+		case CObstacleInstance::USUAL:
+			res = ESpellCastProblem::OK;
+			break;
+		case CObstacleInstance::FIRE_WALL:
+			if(ctx.schoolLvl >= 2)
+				res = ESpellCastProblem::OK;
+			break;
+		case CObstacleInstance::QUICKSAND:
+		case CObstacleInstance::LAND_MINE:
+		case CObstacleInstance::FORCE_FIELD:
+			if(ctx.schoolLvl >= 3)
+				res = ESpellCastProblem::OK;
+			break;
+		default:
+			break;
+		}
+	}
+	return res;
+}
+
+///RisingSpellMechanics
 HealingSpellMechanics::EHealLevel RisingSpellMechanics::getHealLevel(int effectLevel) const
 {
 	//this may be even distinct class

+ 1 - 0
lib/spells/BattleSpellMechanics.h

@@ -110,6 +110,7 @@ class DLL_LINKAGE RemoveObstacleMechanics : public DefaultSpellMechanics
 {
 public:
 	RemoveObstacleMechanics(CSpell * s): DefaultSpellMechanics(s){};
+	ESpellCastProblem::ESpellCastProblem canBeCast(const SpellTargetingContext & ctx) const override;
 protected:
 	void applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
 };

+ 1 - 1
lib/spells/CDefaultSpellMechanics.cpp

@@ -747,7 +747,7 @@ ESpellCastProblem::ESpellCastProblem DefaultSpellMechanics::canBeCast(const CBat
 	return ESpellCastProblem::OK;
 }
 
-ESpellCastProblem DefaultSpellMechanics::canBeCast(const SpellTargetingContext & ctx) const
+ESpellCastProblem::ESpellCastProblem DefaultSpellMechanics::canBeCast(const SpellTargetingContext & ctx) const
 {
 	//no problems by default, this method is for spell-specific problems
 	//common problems handled by CSpell

+ 2 - 3
lib/spells/CSpellHandler.cpp

@@ -310,12 +310,11 @@ ESpellCastProblem::ESpellCastProblem CSpell::canBeCastAt(const CBattleInfoCallba
 
 	//todo: CSpell::canBeCastAt check common problems
 
-	SpellTargetingContext ctx(this, cb, mode, caster, , destination);
+	ISpellMechanics::SpellTargetingContext ctx(this, cb, mode, caster, caster->getSpellSchoolLevel(this), destination);
 
-	return mechanics->canBeCast(cb, caster, mode, destination);
+	return mechanics->canBeCast(ctx);
 }
 
-
 ESpellCastProblem::ESpellCastProblem CSpell::isImmuneAt(const CBattleInfoCallback * cb, const ISpellCaster * caster, ECastingMode::ECastingMode mode, BattleHex destination) const
 {
 	// Get all stacks at destination hex. only alive if not rising spell