1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-02-03 13:01:33 +02:00

EWallPart & EWallState are now enum class

This commit is contained in:
Ivan Savenko 2023-01-13 00:35:58 +02:00
parent b86704bece
commit 500cf7f15d
22 changed files with 84 additions and 101 deletions

View File

@ -46,14 +46,14 @@ std::vector<BattleHex> CBattleAI::getBrokenWallMoatHexes() const
{
std::vector<BattleHex> result;
for(int wallPart = EWallPart::BOTTOM_WALL; wallPart < EWallPart::UPPER_WALL; wallPart++)
for(EWallPart wallPart : { EWallPart::BOTTOM_WALL, EWallPart::BELOW_GATE, EWallPart::OVER_GATE, EWallPart::UPPER_WALL })
{
auto state = cb->battleGetWallState(wallPart);
if(state != EWallState::DESTROYED)
continue;
auto wallHex = cb->wallPartToBattleHex((EWallPart::EWallPart)wallPart);
auto wallHex = cb->wallPartToBattleHex((EWallPart)wallPart);
auto moatHex = wallHex.cloneInDirection(BattleHex::LEFT);
result.push_back(moatHex);
@ -364,7 +364,7 @@ BattleAction CBattleAI::useCatapult(const CStack * stack)
}
else
{
EWallPart::EWallPart wallParts[] = {
EWallPart wallParts[] = {
EWallPart::KEEP,
EWallPart::BOTTOM_TOWER,
EWallPart::UPPER_TOWER,

View File

@ -403,7 +403,7 @@ void HypotheticBattle::removeUnitBonus(uint32_t id, const std::vector<Bonus> & b
bonusTreeVersion++;
}
void HypotheticBattle::setWallState(int partOfWall, si8 state)
void HypotheticBattle::setWallState(EWallPart partOfWall, EWallState state)
{
//TODO:HypotheticBattle::setWallState
}

View File

@ -130,7 +130,7 @@ public:
void updateUnitBonus(uint32_t id, const std::vector<Bonus> & bonus) override;
void removeUnitBonus(uint32_t id, const std::vector<Bonus> & bonus) override;
void setWallState(int partOfWall, si8 state) override;
void setWallState(EWallPart partOfWall, EWallState state) override;
void addObstacle(const ObstacleChanges & changes) override;
void updateObstacle(const ObstacleChanges& changes) override;

View File

@ -28,7 +28,7 @@
#include "../../lib/CStack.h"
#include "../../lib/mapObjects/CGTownInstance.h"
std::string BattleSiegeController::getWallPieceImageName(EWallVisual::EWallVisual what, EWallState::EWallState state) const
std::string BattleSiegeController::getWallPieceImageName(EWallVisual::EWallVisual what, EWallState state) const
{
auto getImageIndex = [&]() -> int
{
@ -130,9 +130,9 @@ bool BattleSiegeController::getWallPieceExistance(EWallVisual::EWallVisual what)
{
case EWallVisual::MOAT: return town->hasBuilt(BuildingID::CITADEL) && town->town->faction->index != ETownType::TOWER;
case EWallVisual::MOAT_BANK: return town->hasBuilt(BuildingID::CITADEL) && town->town->faction->index != ETownType::TOWER && town->town->faction->index != ETownType::NECROPOLIS;
case EWallVisual::KEEP_BATTLEMENT: return town->hasBuilt(BuildingID::CITADEL) && EWallState::EWallState(owner.curInt->cb->battleGetWallState(EWallPart::KEEP)) != EWallState::DESTROYED;
case EWallVisual::UPPER_BATTLEMENT: return town->hasBuilt(BuildingID::CASTLE) && EWallState::EWallState(owner.curInt->cb->battleGetWallState(EWallPart::UPPER_TOWER)) != EWallState::DESTROYED;
case EWallVisual::BOTTOM_BATTLEMENT: return town->hasBuilt(BuildingID::CASTLE) && EWallState::EWallState(owner.curInt->cb->battleGetWallState(EWallPart::BOTTOM_TOWER)) != EWallState::DESTROYED;
case EWallVisual::KEEP_BATTLEMENT: return town->hasBuilt(BuildingID::CITADEL) && EWallState(owner.curInt->cb->battleGetWallState(EWallPart::KEEP)) != EWallState::DESTROYED;
case EWallVisual::UPPER_BATTLEMENT: return town->hasBuilt(BuildingID::CASTLE) && EWallState(owner.curInt->cb->battleGetWallState(EWallPart::UPPER_TOWER)) != EWallState::DESTROYED;
case EWallVisual::BOTTOM_BATTLEMENT: return town->hasBuilt(BuildingID::CASTLE) && EWallState(owner.curInt->cb->battleGetWallState(EWallPart::BOTTOM_TOWER)) != EWallState::DESTROYED;
default: return true;
}
}
@ -321,7 +321,7 @@ bool BattleSiegeController::isAttackableByCatapult(BattleHex hex) const
if (!owner.curInt->cb->isWallPartPotentiallyAttackable(wallPart))
return false;
auto state = owner.curInt->cb->battleGetWallState(static_cast<int>(wallPart));
auto state = owner.curInt->cb->battleGetWallState(wallPart);
return state != EWallState::DESTROYED && state != EWallState::NONE;
}
@ -354,12 +354,12 @@ void BattleSiegeController::stackIsCatapulting(const CatapultAttack & ca)
for (auto attackInfo : ca.attackedParts)
{
int wallId = attackInfo.attackedPart + EWallVisual::DESTRUCTIBLE_FIRST;
int wallId = static_cast<int>(attackInfo.attackedPart) + EWallVisual::DESTRUCTIBLE_FIRST;
//gate state changing handled separately
if (wallId == EWallVisual::GATE)
continue;
auto wallState = EWallState::EWallState(owner.curInt->cb->battleGetWallState(attackInfo.attackedPart));
auto wallState = EWallState(owner.curInt->cb->battleGetWallState(attackInfo.attackedPart));
wallPieceImages[wallId] = IImage::createFromFile(getWallPieceImageName(EWallVisual::EWallVisual(wallId), wallState));
}

View File

@ -76,7 +76,7 @@ class BattleSiegeController
std::array<std::shared_ptr<IImage>, EWallVisual::WALL_LAST + 1> wallPieceImages;
/// return URI for image for a wall piece
std::string getWallPieceImageName(EWallVisual::EWallVisual what, EWallState::EWallState state) const;
std::string getWallPieceImageName(EWallVisual::EWallVisual what, EWallState state) const;
/// returns BattleHex to which chosen wall piece is bound
BattleHex getWallPiecePosition(EWallVisual::EWallVisual what) const;

View File

@ -615,28 +615,22 @@ namespace ECommander
const int MAX_SKILL_LEVEL = 5;
}
namespace EWallPart
enum class EWallPart : int8_t
{
enum EWallPart
{
INDESTRUCTIBLE_PART_OF_GATE = -3, INDESTRUCTIBLE_PART = -2, INVALID = -1,
KEEP = 0, BOTTOM_TOWER, BOTTOM_WALL, BELOW_GATE, OVER_GATE, UPPER_WALL, UPPER_TOWER, GATE,
PARTS_COUNT /* This constant SHOULD always stay as the last item in the enum. */
};
}
INDESTRUCTIBLE_PART_OF_GATE = -3, INDESTRUCTIBLE_PART = -2, INVALID = -1,
KEEP = 0, BOTTOM_TOWER, BOTTOM_WALL, BELOW_GATE, OVER_GATE, UPPER_WALL, UPPER_TOWER, GATE,
PARTS_COUNT /* This constant SHOULD always stay as the last item in the enum. */
};
namespace EWallState
enum class EWallState : int8_t
{
enum EWallState
{
NONE = -1, //no wall
DESTROYED,
DAMAGED,
INTACT
};
}
NONE = -1, //no wall
DESTROYED,
DAMAGED,
INTACT
};
enum class EGateState : ui8
enum class EGateState : uint8_t
{
NONE,
CLOSED,

View File

@ -1827,7 +1827,7 @@ struct ELF_VISIBILITY CatapultAttack : public CPackForClient
struct AttackInfo
{
si16 destinationTile;
ui8 attackedPart;
EWallPart attackedPart;
ui8 damageDealt;
template <typename Handler> void serialize(Handler & h, const int version)

View File

@ -1707,7 +1707,7 @@ DLL_LINKAGE void CatapultAttack::applyBattle(IBattleState * battleState)
for(const auto & part : attackedParts)
{
auto newWallState = SiegeInfo::applyDamage(EWallState::EWallState(battleState->getWallState(part.attackedPart)), part.damageDealt);
auto newWallState = SiegeInfo::applyDamage(EWallState(battleState->getWallState(part.attackedPart)), part.damageDealt);
battleState->setWallState(part.attackedPart, newWallState);
}
}

View File

@ -225,7 +225,7 @@ BattleInfo * BattleInfo::setupBattle(const int3 & tile, TerrainId terrain, const
for (int b = 0; b < curB->si.wallState.size(); ++b)
{
curB->si.wallState[b] = EWallState::INTACT;
curB->si.wallState[EWallPart(b)] = EWallState::INTACT;
}
if (!town->hasBuilt(BuildingID::CITADEL))
@ -610,7 +610,7 @@ const CGTownInstance * BattleInfo::getDefendedTown() const
return town;
}
si8 BattleInfo::getWallState(int partOfWall) const
EWallState BattleInfo::getWallState(EWallPart partOfWall) const
{
return si.wallState.at(partOfWall);
}
@ -913,9 +913,9 @@ void BattleInfo::addOrUpdateUnitBonus(CStack * sta, const Bonus & value, bool fo
}
}
void BattleInfo::setWallState(int partOfWall, si8 state)
void BattleInfo::setWallState(EWallPart partOfWall, EWallState state)
{
si.wallState.at(partOfWall) = state;
si.wallState[partOfWall] = state;
}
void BattleInfo::addObstacle(const ObstacleChanges & changes)

View File

@ -87,7 +87,7 @@ public:
ui8 getTacticsSide() const override;
const CGTownInstance * getDefendedTown() const override;
si8 getWallState(int partOfWall) const override;
EWallState getWallState(EWallPart partOfWall) const override;
EGateState getGateState() const override;
uint32_t getCastSpells(ui8 side) const override;
@ -115,7 +115,7 @@ public:
void updateUnitBonus(uint32_t id, const std::vector<Bonus> & bonus) override;
void removeUnitBonus(uint32_t id, const std::vector<Bonus> & bonus) override;
void setWallState(int partOfWall, si8 state) override;
void setWallState(EWallPart partOfWall, EWallState state) override;
void addObstacle(const ObstacleChanges & changes) override;
void updateObstacle(const ObstacleChanges& changes) override;

View File

@ -89,7 +89,7 @@ const CGTownInstance * BattleProxy::getDefendedTown() const
return subject->battleGetDefendedTown();
}
si8 BattleProxy::getWallState(int partOfWall) const
EWallState BattleProxy::getWallState(EWallPart partOfWall) const
{
return subject->battleGetWallState(partOfWall);
}

View File

@ -44,7 +44,7 @@ public:
ui8 getTacticsSide() const override;
const CGTownInstance * getDefendedTown() const override;
si8 getWallState(int partOfWall) const override;
EWallState getWallState(EWallPart partOfWall) const override;
EGateState getGateState() const override;
uint32_t getCastSpells(ui8 side) const override;

View File

@ -71,7 +71,7 @@ static bool sameSideOfWall(BattleHex pos1, BattleHex pos2)
}
// parts of wall
static const std::pair<int, EWallPart::EWallPart> wallParts[] =
static const std::pair<int, EWallPart> wallParts[] =
{
std::make_pair(50, EWallPart::KEEP),
std::make_pair(183, EWallPart::BOTTOM_TOWER),
@ -89,7 +89,7 @@ static const std::pair<int, EWallPart::EWallPart> wallParts[] =
std::make_pair(165, EWallPart::INDESTRUCTIBLE_PART)
};
static EWallPart::EWallPart hexToWallPart(BattleHex hex)
static EWallPart hexToWallPart(BattleHex hex)
{
for(auto & elem : wallParts)
{
@ -100,7 +100,7 @@ static EWallPart::EWallPart hexToWallPart(BattleHex hex)
return EWallPart::INVALID; //not found!
}
static BattleHex WallPartToHex(EWallPart::EWallPart part)
static BattleHex WallPartToHex(EWallPart part)
{
for(auto & elem : wallParts)
{
@ -1109,13 +1109,13 @@ AccessibilityInfo CBattleInfoCallback::getAccesibility() const
ret[hex] = EAccessibility::UNAVAILABLE;
//TODO likely duplicated logic
static const std::pair<int, BattleHex> lockedIfNotDestroyed[] =
static const std::pair<EWallPart, BattleHex> lockedIfNotDestroyed[] =
{
//which part of wall, which hex is blocked if this part of wall is not destroyed
std::make_pair(2, BattleHex(ESiegeHex::DESTRUCTIBLE_WALL_4)),
std::make_pair(3, BattleHex(ESiegeHex::DESTRUCTIBLE_WALL_3)),
std::make_pair(4, BattleHex(ESiegeHex::DESTRUCTIBLE_WALL_2)),
std::make_pair(5, BattleHex(ESiegeHex::DESTRUCTIBLE_WALL_1))
std::make_pair(EWallPart::BOTTOM_WALL, BattleHex(ESiegeHex::DESTRUCTIBLE_WALL_4)),
std::make_pair(EWallPart::BELOW_GATE, BattleHex(ESiegeHex::DESTRUCTIBLE_WALL_3)),
std::make_pair(EWallPart::OVER_GATE, BattleHex(ESiegeHex::DESTRUCTIBLE_WALL_2)),
std::make_pair(EWallPart::UPPER_WALL, BattleHex(ESiegeHex::DESTRUCTIBLE_WALL_1))
};
for(auto & elem : lockedIfNotDestroyed)
@ -1604,19 +1604,19 @@ bool CBattleInfoCallback::battleHasDistancePenalty(const IBonusBearer * shooter,
return true;
}
BattleHex CBattleInfoCallback::wallPartToBattleHex(EWallPart::EWallPart part) const
BattleHex CBattleInfoCallback::wallPartToBattleHex(EWallPart part) const
{
RETURN_IF_NOT_BATTLE(BattleHex::INVALID);
return WallPartToHex(part);
}
EWallPart::EWallPart CBattleInfoCallback::battleHexToWallPart(BattleHex hex) const
EWallPart CBattleInfoCallback::battleHexToWallPart(BattleHex hex) const
{
RETURN_IF_NOT_BATTLE(EWallPart::INVALID);
return hexToWallPart(hex);
}
bool CBattleInfoCallback::isWallPartPotentiallyAttackable(EWallPart::EWallPart wallPart) const
bool CBattleInfoCallback::isWallPartPotentiallyAttackable(EWallPart wallPart) const
{
RETURN_IF_NOT_BATTLE(false);
return wallPart != EWallPart::INDESTRUCTIBLE_PART && wallPart != EWallPart::INDESTRUCTIBLE_PART_OF_GATE &&
@ -1632,7 +1632,7 @@ std::vector<BattleHex> CBattleInfoCallback::getAttackableBattleHexes() const
{
if(isWallPartPotentiallyAttackable(wallPartPair.second))
{
auto wallState = static_cast<EWallState::EWallState>(battleGetWallState(static_cast<int>(wallPartPair.second)));
auto wallState = static_cast<EWallState>(battleGetWallState(wallPartPair.second));
if(wallState == EWallState::INTACT || wallState == EWallState::DAMAGED)
{
attackableBattleHexes.push_back(BattleHex(wallPartPair.first));

View File

@ -110,9 +110,9 @@ public:
bool battleHasWallPenalty(const IBonusBearer * shooter, BattleHex shooterPosition, BattleHex destHex) const;
bool battleHasShootingPenalty(const battle::Unit * shooter, BattleHex destHex) const;
BattleHex wallPartToBattleHex(EWallPart::EWallPart part) const;
EWallPart::EWallPart battleHexToWallPart(BattleHex hex) const; //returns part of destructible wall / gate / keep under given hex or -1 if not found
bool isWallPartPotentiallyAttackable(EWallPart::EWallPart wallPart) const; // returns true if the wall part is potentially attackable (independent of wall state), false if not
BattleHex wallPartToBattleHex(EWallPart part) const;
EWallPart battleHexToWallPart(BattleHex hex) const; //returns part of destructible wall / gate / keep under given hex or -1 if not found
bool isWallPartPotentiallyAttackable(EWallPart wallPart) const; // returns true if the wall part is potentially attackable (independent of wall state), false if not
std::vector<BattleHex> getAttackableBattleHexes() const;
si8 battleMinSpellLevel(ui8 side) const; //calculates maximum spell level possible to be cast on battlefield - takes into account artifacts of both heroes; if no effects are set, 0 is returned

View File

@ -364,7 +364,7 @@ bool CBattleInfoEssentials::battleHasHero(ui8 side) const
return getBattle()->getSideHero(side) != nullptr;
}
si8 CBattleInfoEssentials::battleGetWallState(int partOfWall) const
EWallState CBattleInfoEssentials::battleGetWallState(EWallPart partOfWall) const
{
RETURN_IF_NOT_BATTLE(EWallState::NONE);
if(battleGetSiegeLevel() == CGTownInstance::NONE)

View File

@ -94,7 +94,7 @@ public:
// for determining state of a part of the wall; format: parameter [0] - keep, [1] - bottom tower, [2] - bottom wall,
// [3] - below gate, [4] - over gate, [5] - upper wall, [6] - uppert tower, [7] - gate; returned value: 1 - intact, 2 - damaged, 3 - destroyed; 0 - no battle
si8 battleGetWallState(int partOfWall) const;
EWallState battleGetWallState(EWallPart partOfWall) const;
EGateState battleGetGateState() const;
//helpers

View File

@ -49,7 +49,7 @@ public:
virtual ObstacleCList getAllObstacles() const = 0;
virtual const CGTownInstance * getDefendedTown() const = 0;
virtual si8 getWallState(int partOfWall) const = 0;
virtual EWallState getWallState(EWallPart partOfWall) const = 0;
virtual EGateState getGateState() const = 0;
virtual PlayerColor getSidePlayer(ui8 side) const = 0;
@ -87,7 +87,7 @@ public:
virtual void updateUnitBonus(uint32_t id, const std::vector<Bonus> & bonus) = 0;
virtual void removeUnitBonus(uint32_t id, const std::vector<Bonus> & bonus) = 0;
virtual void setWallState(int partOfWall, si8 state) = 0;
virtual void setWallState(EWallPart partOfWall, EWallState state) = 0;
virtual void addObstacle(const ObstacleChanges & changes) = 0;
virtual void updateObstacle(const ObstacleChanges & changes) = 0;

View File

@ -15,14 +15,14 @@ VCMI_LIB_NAMESPACE_BEGIN
SiegeInfo::SiegeInfo()
{
for(int i = 0; i < wallState.size(); ++i)
for(int i = 0; i < int(EWallPart::PARTS_COUNT); ++i)
{
wallState[i] = EWallState::NONE;
wallState[EWallPart(i)] = EWallState::NONE;
}
gateState = EGateState::NONE;
}
EWallState::EWallState SiegeInfo::applyDamage(EWallState::EWallState state, unsigned int value)
EWallState SiegeInfo::applyDamage(EWallState state, unsigned int value)
{
if(value == 0)
return state;

View File

@ -15,13 +15,13 @@ VCMI_LIB_NAMESPACE_BEGIN
//only for use in BattleInfo
struct DLL_LINKAGE SiegeInfo
{
std::array<si8, EWallPart::PARTS_COUNT> wallState;
std::map<EWallPart, EWallState> wallState;
EGateState gateState;
SiegeInfo();
// return EWallState decreased by value of damage points
static EWallState::EWallState applyDamage(EWallState::EWallState state, unsigned int value);
static EWallState applyDamage(EWallState state, unsigned int value);
template <typename Handler> void serialize(Handler &h, const int version)
{

View File

@ -68,7 +68,7 @@ bool Catapult::applicable(Problem & problem, const Mechanics * m) const
void Catapult::apply(ServerCallback * server, const Mechanics * m, const EffectTarget & /* eTarget */) const
{
//start with all destructible parts
static const std::set<EWallPart::EWallPart> potentialTargets =
static const std::set<EWallPart> potentialTargets =
{
EWallPart::KEEP,
EWallPart::BOTTOM_TOWER,
@ -80,9 +80,9 @@ void Catapult::apply(ServerCallback * server, const Mechanics * m, const EffectT
EWallPart::GATE
};
assert(potentialTargets.size() == EWallPart::PARTS_COUNT);
assert(potentialTargets.size() == size_t(EWallPart::PARTS_COUNT));
std::set<EWallPart::EWallPart> allowedTargets;
std::set<EWallPart> allowedTargets;
for (auto const & target : potentialTargets)
{
@ -98,16 +98,13 @@ void Catapult::apply(ServerCallback * server, const Mechanics * m, const EffectT
CatapultAttack ca;
ca.attacker = -1;
BattleUnitsChanged removeUnits;
for(int i = 0; i < targetsToAttack; i++)
{
// Hit on any existing, not destroyed targets are allowed
// Multiple hit on same target are allowed.
// Potential overshots (more hits on same targets than remaining HP) are allowed
EWallPart::EWallPart target = *RandomGeneratorUtil::nextItem(allowedTargets, *server->getRNG());
EWallPart target = *RandomGeneratorUtil::nextItem(allowedTargets, *server->getRNG());
auto state = m->battle()->battleGetWallState(target);
auto attackInfo = ca.attackedParts.begin();
for ( ; attackInfo != ca.attackedParts.end(); ++attackInfo)
@ -127,11 +124,19 @@ void Catapult::apply(ServerCallback * server, const Mechanics * m, const EffectT
{
attackInfo->damageDealt += 1;
}
}
server->apply(&ca);
BattleUnitsChanged removeUnits;
for (auto const wallPart : { EWallPart::KEEP, EWallPart::BOTTOM_TOWER, EWallPart::UPPER_TOWER })
{
//removing creatures in turrets / keep if one is destroyed
BattleHex posRemove;
auto state = m->battle()->battleGetWallState(wallPart);
switch(target)
switch(wallPart)
{
case EWallPart::KEEP:
posRemove = BattleHex::CASTLE_CENTRAL_TOWER;
@ -144,35 +149,19 @@ void Catapult::apply(ServerCallback * server, const Mechanics * m, const EffectT
break;
}
if(posRemove != BattleHex::INVALID && state - attackInfo->damageDealt <= 0) //HP enum subtraction not intuitive, consider using SiegeInfo::applyDamage
if(state == EWallState::DESTROYED) //HP enum subtraction not intuitive, consider using SiegeInfo::applyDamage
{
auto all = m->battle()->battleGetUnitsIf([=](const battle::Unit * unit)
{
return !unit->isGhost();
return !unit->isGhost() && unit->getPosition() == posRemove;
});
assert(all.size() == 0 || all.size() == 1);
for(auto & elem : all)
{
if(elem->getPosition() != posRemove)
continue;
// if tower was hit multiple times, it may have been destroyed already
bool stackWasRemovedBefore = false;
for(auto & removed : removeUnits.changedStacks)
{
if (removed.id == elem->unitId())
stackWasRemovedBefore = true;
}
if (!stackWasRemovedBefore)
removeUnits.changedStacks.emplace_back(elem->unitId(), UnitChanges::EOperation::REMOVE);
break;
}
removeUnits.changedStacks.emplace_back(elem->unitId(), UnitChanges::EOperation::REMOVE);
}
}
server->apply(&ca);
if(!removeUnits.changedStacks.empty())
server->apply(&removeUnits);
}

View File

@ -256,7 +256,7 @@ bool Obstacle::isHexAvailable(const CBattleInfoCallback * cb, const BattleHex &
if(cb->battleGetSiegeLevel() != 0)
{
EWallPart::EWallPart part = cb->battleHexToWallPart(hex);
EWallPart part = cb->battleHexToWallPart(hex);
if(part == EWallPart::INVALID || part == EWallPart::INDESTRUCTIBLE_PART_OF_GATE)
return true;//no fortification here

View File

@ -4790,7 +4790,7 @@ bool CGameHandler::makeBattleAction(BattleAction &ba)
case EActionType::CATAPULT:
{
//TODO: unify with spells::effects:Catapult
auto getCatapultHitChance = [](EWallPart::EWallPart part, const CHeroHandler::SBallisticsLevelInfo & sbi) -> int
auto getCatapultHitChance = [](EWallPart part, const CHeroHandler::SBallisticsLevelInfo & sbi) -> int
{
switch(part)
{
@ -4829,7 +4829,7 @@ bool CGameHandler::makeBattleAction(BattleAction &ba)
}
};
auto isWallPartAttackable = [this] (EWallPart::EWallPart part)
auto isWallPartAttackable = [this] (EWallPart part)
{
return (gs->curB->si.wallState[part] == EWallState::INTACT || gs->curB->si.wallState[part] == EWallState::DAMAGED);
};
@ -4851,13 +4851,13 @@ bool CGameHandler::makeBattleAction(BattleAction &ba)
}
else
{
static const std::array<EWallPart::EWallPart, 4> walls = { EWallPart::BOTTOM_WALL, EWallPart::BELOW_GATE, EWallPart::OVER_GATE, EWallPart::UPPER_WALL };
static const std::array<EWallPart::EWallPart, 3> towers= { EWallPart::BOTTOM_TOWER, EWallPart::KEEP, EWallPart::UPPER_TOWER };
static const EWallPart::EWallPart gates = EWallPart::GATE;
static const std::array<EWallPart, 4> walls = { EWallPart::BOTTOM_WALL, EWallPart::BELOW_GATE, EWallPart::OVER_GATE, EWallPart::UPPER_WALL };
static const std::array<EWallPart, 3> towers= { EWallPart::BOTTOM_TOWER, EWallPart::KEEP, EWallPart::UPPER_TOWER };
static const EWallPart gates = EWallPart::GATE;
// in H3, catapult under automatic control will attack objects in following order:
// walls, gates, towers
std::vector<EWallPart::EWallPart> potentialTargets;
std::vector<EWallPart> potentialTargets;
for (auto & part : walls )
if (isWallPartAttackable(part))
potentialTargets.push_back(part);
@ -4906,7 +4906,7 @@ bool CGameHandler::makeBattleAction(BattleAction &ba)
logGlobal->trace("Catapult attacks %d dealing %d damage", (int)attack.attackedPart, (int)attack.damageDealt);
//removing creatures in turrets / keep if one is destroyed
if (gs->curB->si.wallState[actualTarget] <= 0 && (actualTarget == EWallPart::KEEP || actualTarget == EWallPart::BOTTOM_TOWER || actualTarget == EWallPart::UPPER_TOWER))
if (gs->curB->si.wallState[actualTarget] == EWallState::DESTROYED && (actualTarget == EWallPart::KEEP || actualTarget == EWallPart::BOTTOM_TOWER || actualTarget == EWallPart::UPPER_TOWER))
{
int posRemove = -1;
switch(actualTarget)