瀏覽代碼

fixed patch obstacle placement inside walls

AlexVinS 9 年之前
父節點
當前提交
cffc4b2ab5
共有 2 個文件被更改,包括 32 次插入23 次删除
  1. 31 23
      lib/spells/BattleSpellMechanics.cpp
  2. 1 0
      lib/spells/BattleSpellMechanics.h

+ 31 - 23
lib/spells/BattleSpellMechanics.cpp

@@ -405,34 +405,42 @@ ESpellCastProblem::ESpellCastProblem ObstacleMechanics::canBeCast(const CBattleI
 
 
 	auto tilesThatMustBeClear = owner->rangeInHexes(ctx.destination, ctx.schoolLvl, side, &hexesOutsideBattlefield);
 	auto tilesThatMustBeClear = owner->rangeInHexes(ctx.destination, ctx.schoolLvl, side, &hexesOutsideBattlefield);
 
 
-	if(ctx.ti.clearAffected)
-	{
-		for(BattleHex hex : tilesThatMustBeClear)
-		{
-			if(cb->battleGetStackByPos(hex, true) || !!cb->battleGetObstacleOnPos(hex, false) || !hex.isAvailable())
-			{
-				return ESpellCastProblem::NO_APPROPRIATE_TARGET;
-			}
+	for(const BattleHex & hex : tilesThatMustBeClear)
+		if(!isHexAviable(cb, hex, ctx.ti.clearAffected))
+			return ESpellCastProblem::NO_APPROPRIATE_TARGET;
 
 
-			if(nullptr != cb->battleGetDefendedTown() && CGTownInstance::NONE != cb->battleGetDefendedTown()->fortLevel())
-			{
-                EWallPart::EWallPart part = cb->battleHexToWallPart(hex);
+	if(hexesOutsideBattlefield)
+		return ESpellCastProblem::NO_APPROPRIATE_TARGET;
 
 
-                if(part != EWallPart::INVALID)
-				{
-					if(cb->battleGetWallState(part) != EWallState::DESTROYED && cb->battleGetWallState(part) != EWallState::NONE)
-						return ESpellCastProblem::NO_APPROPRIATE_TARGET;
-				}
-			}
-		}
-	}
+	return ESpellCastProblem::OK;
+}
 
 
-	if(hexesOutsideBattlefield)
+bool ObstacleMechanics::isHexAviable(const CBattleInfoCallback * cb, const BattleHex & hex, const bool mustBeClear)
+{
+	if(!hex.isAvailable())
+		return false;
+
+	if(!mustBeClear)
+		return true;
+
+	if(cb->battleGetStackByPos(hex, true) || !!cb->battleGetObstacleOnPos(hex, false))
+		return false;
+
+	if(nullptr != cb->battleGetDefendedTown() && CGTownInstance::NONE != cb->battleGetDefendedTown()->fortLevel())
 	{
 	{
-		return ESpellCastProblem::NO_APPROPRIATE_TARGET;
+		EWallPart::EWallPart part = cb->battleHexToWallPart(hex);
+
+		if(part != EWallPart::INVALID)
+		{
+			if(static_cast<int>(part) < 0)
+				return false;//indestuctible part, cant be checked by battleGetWallState
+
+			if(cb->battleGetWallState(part) != EWallState::DESTROYED && cb->battleGetWallState(part) != EWallState::NONE)
+				return false;
+		}
 	}
 	}
 
 
-	return ESpellCastProblem::OK;
+	return true;
 }
 }
 
 
 void ObstacleMechanics::placeObstacle(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, const BattleHex & pos) const
 void ObstacleMechanics::placeObstacle(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, const BattleHex & pos) const
@@ -461,7 +469,7 @@ void PatchObstacleMechanics::applyBattleEffects(const SpellCastEnvironment * env
 	for(int i = 0; i < GameConstants::BFIELD_SIZE; i += 1)
 	for(int i = 0; i < GameConstants::BFIELD_SIZE; i += 1)
 	{
 	{
 		BattleHex hex = i;
 		BattleHex hex = i;
-		if(hex.getX() > 0 && hex.getX() < 16 && !(parameters.cb->battleGetStackByPos(hex, false)) && !(parameters.cb->battleGetObstacleOnPos(hex, false)))
+		if(isHexAviable(parameters.cb, hex, true))
 			availableTiles.push_back(hex);
 			availableTiles.push_back(hex);
 	}
 	}
 	RandomGeneratorUtil::randomShuffle(availableTiles, env->getRandomGenerator());
 	RandomGeneratorUtil::randomShuffle(availableTiles, env->getRandomGenerator());

+ 1 - 0
lib/spells/BattleSpellMechanics.h

@@ -104,6 +104,7 @@ public:
 	ObstacleMechanics(CSpell * s): SpecialSpellMechanics(s){};
 	ObstacleMechanics(CSpell * s): SpecialSpellMechanics(s){};
 	ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const override;
 	ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const override;
 protected:
 protected:
+	static bool isHexAviable(const CBattleInfoCallback * cb, const BattleHex & hex, const bool mustBeClear);
 	void placeObstacle(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, const BattleHex & pos) const;
 	void placeObstacle(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, const BattleHex & pos) const;
 	virtual void setupObstacle(SpellCreatedObstacle * obstacle) const = 0;
 	virtual void setupObstacle(SpellCreatedObstacle * obstacle) const = 0;
 };
 };