瀏覽代碼

Factored spell action selection for location target.

AlexVinS 9 年之前
父節點
當前提交
5d329b40a4
共有 3 個文件被更改,包括 32 次插入26 次删除
  1. 4 25
      client/battle/CBattleInterface.cpp
  2. 27 0
      lib/spells/BattleSpellMechanics.cpp
  3. 1 1
      lib/spells/BattleSpellMechanics.h

+ 4 - 25
client/battle/CBattleInterface.cpp

@@ -2099,31 +2099,11 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
 					notLegal = true;
 				break;
 			case FREE_LOCATION:
+				legalAction = true;
+				if(!isCastingPossibleHere(sactive, shere, myNumber))
 				{
-					ui8 side = curInt->cb->battleGetMySide();
-					auto hero = curInt->cb->battleGetMyHero();
-					assert(!creatureCasting); //we assume hero casts this spell
-					assert(hero);
-
-					legalAction = true;
-					bool hexesOutsideBattlefield = false;
-					//todo: move to spell mechanics
-					auto tilesThatMustBeClear = sp->rangeInHexes(myNumber, hero->getSpellSchoolLevel(sp), side, &hexesOutsideBattlefield);
-					for(BattleHex hex : tilesThatMustBeClear)
-					{
-						if(curInt->cb->battleGetStackByPos(hex, true)  ||  !!curInt->cb->battleGetObstacleOnPos(hex, false)
-						 || !hex.isAvailable())
-						{
-							legalAction = false;
-							notLegal = true;
-						}
-					}
-
-					if(hexesOutsideBattlefield)
-					{
-						legalAction = false;
-						notLegal = true;
-					}
+					legalAction = false;
+					notLegal = true;
 				}
 				break;
 			case CATAPULT:
@@ -2288,7 +2268,6 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
 				isCastingPossible = true;
 				break;
 			case FREE_LOCATION:
-				//cursorFrame = ECursor::SPELLBOOK;
 				consoleMsg = boost::str(boost::format(CGI->generaltexth->allTexts[26]) % sp->name); //Cast %s
 				isCastingPossible = true;
 				break;

+ 27 - 0
lib/spells/BattleSpellMechanics.cpp

@@ -371,6 +371,33 @@ ESpellCastProblem::ESpellCastProblem HypnotizeMechanics::isImmuneByStack(const I
 }
 
 ///ObstacleMechanics
+ESpellCastProblem::ESpellCastProblem ObstacleMechanics::canBeCast(const SpellTargetingContext & ctx) const
+{
+	if(ctx.ti.clearAffected)
+	{
+		ui8 side = ctx.cb->playerToSide(ctx.caster->getOwner());
+
+		bool hexesOutsideBattlefield = false;
+
+		auto tilesThatMustBeClear = owner->rangeInHexes(ctx.destination, ctx.caster->getSpellSchoolLevel(owner), side, &hexesOutsideBattlefield);
+
+		for(BattleHex hex : tilesThatMustBeClear)
+		{
+			if(ctx.cb->battleGetStackByPos(hex, true) || !!ctx.cb->battleGetObstacleOnPos(hex, false) || !hex.isAvailable())
+			{
+				return ESpellCastProblem::NO_APPROPRIATE_TARGET;
+			}
+		}
+
+		if(hexesOutsideBattlefield)
+		{
+			return ESpellCastProblem::NO_APPROPRIATE_TARGET;
+		}
+	}
+
+	return ESpellCastProblem::OK;
+}
+
 void ObstacleMechanics::applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const
 {
 	auto placeObstacle = [&, this](const BattleHex & pos)

+ 1 - 1
lib/spells/BattleSpellMechanics.h

@@ -96,7 +96,7 @@ class DLL_LINKAGE ObstacleMechanics : public DefaultSpellMechanics
 {
 public:
 	ObstacleMechanics(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;
 };