Explorar o código

Add isMeleeAttacker to Unit

Andrej Dudenhefner hai 1 mes
pai
achega
3b72a74161

+ 8 - 6
lib/battle/CBattleInfoCallback.cpp

@@ -280,8 +280,11 @@ std::vector<PossiblePlayerBattleAction> CBattleInfoCallback::getClientActionsFor
 		if(stack->hasBonusOfType(BonusType::RETURN_AFTER_STRIKE))
 			allowedActionList.push_back(PossiblePlayerBattleAction::ATTACK_AND_RETURN);
 
-		allowedActionList.push_back(PossiblePlayerBattleAction::ATTACK); //all active stacks can attack
-		allowedActionList.push_back(PossiblePlayerBattleAction::WALK_AND_ATTACK); //not all stacks can always walk, but we will check this elsewhere
+		if (stack->isMeleeAttacker()) //not all stacks can actually attack or walk and attack, check this elsewhere
+		{
+			allowedActionList.push_back(PossiblePlayerBattleAction::ATTACK);
+			allowedActionList.push_back(PossiblePlayerBattleAction::WALK_AND_ATTACK);
+		}
 
 		if(stack->canMove() && stack->getMovementRange(0)) //probably no reason to try move war machines or bound stacks
 			allowedActionList.push_back(PossiblePlayerBattleAction::MOVE_STACK);
@@ -683,6 +686,9 @@ bool CBattleInfoCallback::battleCanAttack(const battle::Unit * stack, const batt
 	if(!battleMatchOwner(stack, target))
 		return false;
 
+	if (!stack->isMeleeAttacker())
+		return false;
+
 	if (stack->getPosition() != dest)
 	{
 		for (const auto & obstacle : battleGetAllObstacles())
@@ -695,10 +701,6 @@ bool CBattleInfoCallback::battleCanAttack(const battle::Unit * stack, const batt
 		}
 	}
 
-	auto id = stack->unitType()->getId();
-	if (id == CreatureID::FIRST_AID_TENT || id == CreatureID::CATAPULT)
-		return false;
-
 	return target->alive();
 }
 

+ 16 - 0
lib/battle/CUnitState.cpp

@@ -545,6 +545,22 @@ bool CUnitState::isShooter() const
 	return shots.total() > 0;
 }
 
+bool CUnitState::isMeleeAttacker() const
+{
+	//exclude non melee attackers
+	static const std::set<CreatureID> nonMeleeAttackers{
+		CreatureID::FIRST_AID_TENT,
+		CreatureID::CATAPULT,
+		CreatureID::BALLISTA,
+		CreatureID::AMMO_CART,
+		CreatureID::ARROW_TOWERS
+	};
+	if (vstd::contains(nonMeleeAttackers, creatureId()))
+		return false;
+
+	return true;
+}
+
 int32_t CUnitState::getKilled() const
 {
 	int32_t res = unitBaseAmount() - health.getCount() + health.getResurrected();

+ 1 - 0
lib/battle/CUnitState.h

@@ -205,6 +205,7 @@ public:
 	bool canShootBlocked() const override;
 	bool canShoot() const override;
 	bool isShooter() const override;
+	bool isMeleeAttacker() const override;
 
 	int32_t getKilled() const override;
 	int32_t getCount() const override;

+ 1 - 0
lib/battle/Unit.h

@@ -97,6 +97,7 @@ public:
 	virtual bool canShootBlocked() const = 0;
 	virtual bool canShoot() const = 0;
 	virtual bool isShooter() const = 0;
+	virtual bool isMeleeAttacker() const = 0;
 
 	/// returns initial size of this unit
 	virtual int32_t getCount() const = 0;