mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-23 22:37:55 +02:00
Merge pull request #6296 from mrhaandi/fix-unit-surrounded
Fix violated assert(direction != BattleHex::NONE)
This commit is contained in:
@@ -653,10 +653,11 @@ bool BattleActionsController::actionIsLegal(PossiblePlayerBattleAction action, c
|
|||||||
case PossiblePlayerBattleAction::WALK_AND_ATTACK:
|
case PossiblePlayerBattleAction::WALK_AND_ATTACK:
|
||||||
case PossiblePlayerBattleAction::ATTACK_AND_RETURN:
|
case PossiblePlayerBattleAction::ATTACK_AND_RETURN:
|
||||||
{
|
{
|
||||||
if (owner.fieldController->isTileAttackable(targetHex)) // move isTileAttackable to be part of battleCanAttack?
|
auto activeStack = owner.stacksController->getActiveStack();
|
||||||
|
if (targetStack && targetStack != activeStack && owner.fieldController->isTileAttackable(targetHex)) // move isTileAttackable to be part of battleCanAttack?
|
||||||
{
|
{
|
||||||
BattleHex attackFromHex = owner.fieldController->fromWhichHexAttack(targetHex);
|
BattleHex attackFromHex = owner.fieldController->fromWhichHexAttack(targetHex);
|
||||||
if(owner.getBattle()->battleCanAttack(owner.stacksController->getActiveStack(), targetStack, attackFromHex))
|
if(owner.getBattle()->battleCanAttack(activeStack, targetStack, attackFromHex))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -819,7 +819,7 @@ bool BattleFieldController::isTileAttackable(const BattleHex & number) const
|
|||||||
|
|
||||||
for (auto & elem : occupiableHexes)
|
for (auto & elem : occupiableHexes)
|
||||||
{
|
{
|
||||||
if (BattleHex::mutualPosition(elem, number) != BattleHex::EDir::NONE || elem == number)
|
if (BattleHex::mutualPosition(elem, number) != BattleHex::EDir::NONE)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -280,8 +280,11 @@ std::vector<PossiblePlayerBattleAction> CBattleInfoCallback::getClientActionsFor
|
|||||||
if(stack->hasBonusOfType(BonusType::RETURN_AFTER_STRIKE))
|
if(stack->hasBonusOfType(BonusType::RETURN_AFTER_STRIKE))
|
||||||
allowedActionList.push_back(PossiblePlayerBattleAction::ATTACK_AND_RETURN);
|
allowedActionList.push_back(PossiblePlayerBattleAction::ATTACK_AND_RETURN);
|
||||||
|
|
||||||
allowedActionList.push_back(PossiblePlayerBattleAction::ATTACK); //all active stacks can attack
|
if (stack->isMeleeAttacker()) //not all stacks can actually attack or walk and attack, check this elsewhere
|
||||||
allowedActionList.push_back(PossiblePlayerBattleAction::WALK_AND_ATTACK); //not all stacks can always walk, but we will 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
|
if(stack->canMove() && stack->getMovementRange(0)) //probably no reason to try move war machines or bound stacks
|
||||||
allowedActionList.push_back(PossiblePlayerBattleAction::MOVE_STACK);
|
allowedActionList.push_back(PossiblePlayerBattleAction::MOVE_STACK);
|
||||||
@@ -683,6 +686,9 @@ bool CBattleInfoCallback::battleCanAttack(const battle::Unit * stack, const batt
|
|||||||
if(!battleMatchOwner(stack, target))
|
if(!battleMatchOwner(stack, target))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (!stack->isMeleeAttacker())
|
||||||
|
return false;
|
||||||
|
|
||||||
if (stack->getPosition() != dest)
|
if (stack->getPosition() != dest)
|
||||||
{
|
{
|
||||||
for (const auto & obstacle : battleGetAllObstacles())
|
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();
|
return target->alive();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,16 @@ bool Unit::isTurret() const
|
|||||||
return creatureIndex() == CreatureID::ARROW_TOWERS;
|
return creatureIndex() == CreatureID::ARROW_TOWERS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Unit::isMeleeAttacker() const
|
||||||
|
{
|
||||||
|
//exclude war machines
|
||||||
|
if (hasBonusOfType(BonusType::SIEGE_WEAPON))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
//TODO consider that a mod may introduce a melee war machine. Possibly a new bonus type NO_MELEE_ATTACK is needed.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
std::string Unit::getDescription() const
|
std::string Unit::getDescription() const
|
||||||
{
|
{
|
||||||
boost::format fmt("Unit %d of side %d");
|
boost::format fmt("Unit %d of side %d");
|
||||||
|
|||||||
@@ -97,6 +97,7 @@ public:
|
|||||||
virtual bool canShootBlocked() const = 0;
|
virtual bool canShootBlocked() const = 0;
|
||||||
virtual bool canShoot() const = 0;
|
virtual bool canShoot() const = 0;
|
||||||
virtual bool isShooter() const = 0;
|
virtual bool isShooter() const = 0;
|
||||||
|
bool isMeleeAttacker() const;
|
||||||
|
|
||||||
/// returns initial size of this unit
|
/// returns initial size of this unit
|
||||||
virtual int32_t getCount() const = 0;
|
virtual int32_t getCount() const = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user