From ca0dd9cc7346e26f6ec9310c12b3a3d4f5ad6db4 Mon Sep 17 00:00:00 2001 From: Opuszek Date: Fri, 15 Aug 2025 17:34:47 +0200 Subject: [PATCH 1/2] Fixes crashes on trying to evaluate attacks of two double-wide melee units --- lib/CStack.cpp | 41 ++++++----------------------------------- 1 file changed, 6 insertions(+), 35 deletions(-) diff --git a/lib/CStack.cpp b/lib/CStack.cpp index d53f7936b..a922eac23 100644 --- a/lib/CStack.cpp +++ b/lib/CStack.cpp @@ -246,7 +246,6 @@ void CStack::prepareAttacked(BattleStackAttacked & bsa, vstd::RNG & rand, const BattleHexArray CStack::meleeAttackHexes(const battle::Unit * attacker, const battle::Unit * defender, BattleHex attackerPos, BattleHex defenderPos) { - int mask = 0; BattleHexArray res; if (!attackerPos.isValid()) @@ -254,43 +253,15 @@ BattleHexArray CStack::meleeAttackHexes(const battle::Unit * attacker, const bat if (!defenderPos.isValid()) defenderPos = defender->getPosition(); - BattleHex otherAttackerPos = attackerPos.toInt() + (attacker->unitSide() == BattleSide::ATTACKER ? -1 : 1); - BattleHex otherDefenderPos = defenderPos.toInt() + (defender->unitSide() == BattleSide::ATTACKER ? -1 : 1); + BattleHexArray attackableHxs = attacker->doubleWide() ? attackerPos.getNeighbouringTilesDoubleWide(attacker->unitSide()) : attackerPos.getNeighbouringTiles(); - if(BattleHex::mutualPosition(attackerPos, defenderPos) >= 0) //front <=> front + if (std::find(attackableHxs.begin(), attackableHxs.end(), defenderPos) != attackableHxs.end()) + res.insert(defenderPos); + if (defender->doubleWide()) { - if((mask & 1) == 0) - { - mask |= 1; - res.insert(defenderPos); - } - } - if (attacker->doubleWide() //back <=> front - && BattleHex::mutualPosition(otherAttackerPos, defenderPos) >= 0) - { - if((mask & 1) == 0) - { - mask |= 1; - res.insert(defenderPos); - } - } - if (defender->doubleWide()//front <=> back - && BattleHex::mutualPosition(attackerPos, otherDefenderPos) >= 0) - { - if((mask & 2) == 0) - { - mask |= 2; + BattleHex otherDefenderPos = defenderPos.toInt() + (defender->unitSide() == BattleSide::ATTACKER ? -1 : 1); + if (std::find(attackableHxs.begin(), attackableHxs.end(), otherDefenderPos) != attackableHxs.end()) res.insert(otherDefenderPos); - } - } - if (defender->doubleWide() && attacker->doubleWide()//back <=> back - && BattleHex::mutualPosition(otherAttackerPos, otherDefenderPos) >= 0) - { - if((mask & 2) == 0) - { - mask |= 2; - res.insert(otherDefenderPos); - } } return res; From fb172792c1146a3f458d93cb36e3e4c13fd4ba13 Mon Sep 17 00:00:00 2001 From: Opuszek Date: Tue, 19 Aug 2025 09:11:43 +0200 Subject: [PATCH 2/2] Fixes --- lib/CStack.cpp | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/lib/CStack.cpp b/lib/CStack.cpp index a922eac23..038858c07 100644 --- a/lib/CStack.cpp +++ b/lib/CStack.cpp @@ -253,15 +253,24 @@ BattleHexArray CStack::meleeAttackHexes(const battle::Unit * attacker, const bat if (!defenderPos.isValid()) defenderPos = defender->getPosition(); - BattleHexArray attackableHxs = attacker->doubleWide() ? attackerPos.getNeighbouringTilesDoubleWide(attacker->unitSide()) : attackerPos.getNeighbouringTiles(); + BattleHexArray defenderHexes = defender->getHexes(defenderPos); + BattleHexArray attackerHexes = attacker->getHexes(attackerPos); - if (std::find(attackableHxs.begin(), attackableHxs.end(), defenderPos) != attackableHxs.end()) - res.insert(defenderPos); - if (defender->doubleWide()) + for (BattleHex defenderHex : defenderHexes) { - BattleHex otherDefenderPos = defenderPos.toInt() + (defender->unitSide() == BattleSide::ATTACKER ? -1 : 1); - if (std::find(attackableHxs.begin(), attackableHxs.end(), otherDefenderPos) != attackableHxs.end()) - res.insert(otherDefenderPos); + if (attackerHexes.contains(defenderHex)) + { + logGlobal->debug("CStack::meleeAttackHexes: defender and attacker positions overlap"); + return res; + } + } + + const BattleHexArray attackableHxs = attacker->getSurroundingHexes(attackerPos); + + for (BattleHex defenderHex : defenderHexes) + { + if (attackableHxs.contains(defenderHex)) + res.insert(defenderHex); } return res;