From 1d7f004658bfe28da1282e49cbd86b99aa94bcfa Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Fri, 13 Jan 2023 01:09:24 +0200 Subject: [PATCH] Implemented reinforced walls in towns with Castle --- AI/BattleAI/BattleAI.cpp | 3 +-- client/battle/BattleSiegeController.cpp | 21 ++++++++++++++------- lib/GameConstants.h | 3 ++- lib/NetPacksLib.cpp | 2 +- lib/battle/BattleInfo.cpp | 21 ++++++++++++--------- lib/battle/CBattleInfoCallback.cpp | 4 ++-- lib/battle/SiegeInfo.cpp | 2 ++ server/CGameHandler.cpp | 2 +- 8 files changed, 35 insertions(+), 23 deletions(-) diff --git a/AI/BattleAI/BattleAI.cpp b/AI/BattleAI/BattleAI.cpp index 0ae8a183d..a0ccfb6f9 100644 --- a/AI/BattleAI/BattleAI.cpp +++ b/AI/BattleAI/BattleAI.cpp @@ -378,10 +378,9 @@ BattleAction CBattleAI::useCatapult(const CStack * stack) { auto wallState = cb->battleGetWallState(wallPart); - if(wallState == EWallState::INTACT || wallState == EWallState::DAMAGED) + if(wallState == EWallState::REINFORCED || wallState == EWallState::INTACT || wallState == EWallState::DAMAGED) { targetHex = cb->wallPartToBattleHex(wallPart); - break; } } diff --git a/client/battle/BattleSiegeController.cpp b/client/battle/BattleSiegeController.cpp index 0f6a76f7f..0b0acf36c 100644 --- a/client/battle/BattleSiegeController.cpp +++ b/client/battle/BattleSiegeController.cpp @@ -32,18 +32,25 @@ std::string BattleSiegeController::getWallPieceImageName(EWallVisual::EWallVisua { auto getImageIndex = [&]() -> int { + bool isTower = (what == EWallVisual::KEEP || what == EWallVisual::BOTTOM_TOWER || what == EWallVisual::UPPER_TOWER); + switch (state) { - case EWallState::INTACT : + case EWallState::REINFORCED : return 1; + case EWallState::INTACT : + if (town->hasBuilt(BuildingID::CASTLE)) + return 2; // reinforced walls were damaged + else + return 1; case EWallState::DAMAGED : // towers don't have separate image here - INTACT and DAMAGED is 1, DESTROYED is 2 - if(what == EWallVisual::KEEP || what == EWallVisual::BOTTOM_TOWER || what == EWallVisual::UPPER_TOWER) + if (isTower) return 1; else return 2; case EWallState::DESTROYED : - if (what == EWallVisual::KEEP || what == EWallVisual::BOTTOM_TOWER || what == EWallVisual::UPPER_TOWER) + if (isTower) return 2; else return 3; @@ -130,9 +137,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(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; + case EWallVisual::KEEP_BATTLEMENT: return town->hasBuilt(BuildingID::CITADEL) && owner.curInt->cb->battleGetWallState(EWallPart::KEEP) != EWallState::DESTROYED; + case EWallVisual::UPPER_BATTLEMENT: return town->hasBuilt(BuildingID::CASTLE) && owner.curInt->cb->battleGetWallState(EWallPart::UPPER_TOWER) != EWallState::DESTROYED; + case EWallVisual::BOTTOM_BATTLEMENT: return town->hasBuilt(BuildingID::CASTLE) && owner.curInt->cb->battleGetWallState(EWallPart::BOTTOM_TOWER) != EWallState::DESTROYED; default: return true; } } @@ -177,7 +184,7 @@ BattleSiegeController::BattleSiegeController(BattleInterface & owner, const CGTo if ( !getWallPieceExistance(EWallVisual::EWallVisual(g)) ) continue; - wallPieceImages[g] = IImage::createFromFile(getWallPieceImageName(EWallVisual::EWallVisual(g), EWallState::INTACT)); + wallPieceImages[g] = IImage::createFromFile(getWallPieceImageName(EWallVisual::EWallVisual(g), EWallState::REINFORCED)); } } diff --git a/lib/GameConstants.h b/lib/GameConstants.h index 5d50073bc..1574619de 100644 --- a/lib/GameConstants.h +++ b/lib/GameConstants.h @@ -627,7 +627,8 @@ enum class EWallState : int8_t NONE = -1, //no wall DESTROYED, DAMAGED, - INTACT + INTACT, + REINFORCED, // walls in towns with castle }; enum class EGateState : uint8_t diff --git a/lib/NetPacksLib.cpp b/lib/NetPacksLib.cpp index 0be775aa8..665304f99 100644 --- a/lib/NetPacksLib.cpp +++ b/lib/NetPacksLib.cpp @@ -1707,7 +1707,7 @@ DLL_LINKAGE void CatapultAttack::applyBattle(IBattleState * battleState) for(const auto & part : attackedParts) { - auto newWallState = SiegeInfo::applyDamage(EWallState(battleState->getWallState(part.attackedPart)), part.damageDealt); + auto newWallState = SiegeInfo::applyDamage(battleState->getWallState(part.attackedPart), part.damageDealt); battleState->setWallState(part.attackedPart, newWallState); } } diff --git a/lib/battle/BattleInfo.cpp b/lib/battle/BattleInfo.cpp index 74024b8a4..10ee785da 100644 --- a/lib/battle/BattleInfo.cpp +++ b/lib/battle/BattleInfo.cpp @@ -223,20 +223,23 @@ BattleInfo * BattleInfo::setupBattle(const int3 & tile, TerrainId terrain, const { curB->si.gateState = EGateState::CLOSED; - for (int b = 0; b < curB->si.wallState.size(); ++b) + curB->si.wallState[EWallPart::GATE] = EWallState::INTACT; + + for (auto const wall : {EWallPart::BOTTOM_WALL, EWallPart::BELOW_GATE, EWallPart::OVER_GATE, EWallPart::UPPER_WALL} ) { - curB->si.wallState[EWallPart(b)] = EWallState::INTACT; + if (town->hasBuilt(BuildingID::CASTLE)) + curB->si.wallState[wall] = EWallState::REINFORCED; + else + curB->si.wallState[wall] = EWallState::INTACT; } - if (!town->hasBuilt(BuildingID::CITADEL)) - { - curB->si.wallState[EWallPart::KEEP] = EWallState::NONE; - } + if (town->hasBuilt(BuildingID::CITADEL)) + curB->si.wallState[EWallPart::KEEP] = EWallState::INTACT; - if (!town->hasBuilt(BuildingID::CASTLE)) + if (town->hasBuilt(BuildingID::CASTLE)) { - curB->si.wallState[EWallPart::UPPER_TOWER] = EWallState::NONE; - curB->si.wallState[EWallPart::BOTTOM_TOWER] = EWallState::NONE; + curB->si.wallState[EWallPart::UPPER_TOWER] = EWallState::INTACT; + curB->si.wallState[EWallPart::BOTTOM_TOWER] = EWallState::INTACT; } } diff --git a/lib/battle/CBattleInfoCallback.cpp b/lib/battle/CBattleInfoCallback.cpp index 05ce607bb..e0ffd90d3 100644 --- a/lib/battle/CBattleInfoCallback.cpp +++ b/lib/battle/CBattleInfoCallback.cpp @@ -1632,8 +1632,8 @@ std::vector CBattleInfoCallback::getAttackableBattleHexes() const { if(isWallPartPotentiallyAttackable(wallPartPair.second)) { - auto wallState = static_cast(battleGetWallState(wallPartPair.second)); - if(wallState == EWallState::INTACT || wallState == EWallState::DAMAGED) + auto wallState = battleGetWallState(wallPartPair.second); + if(wallState == EWallState::REINFORCED || wallState == EWallState::INTACT || wallState == EWallState::DAMAGED) { attackableBattleHexes.push_back(BattleHex(wallPartPair.first)); } diff --git a/lib/battle/SiegeInfo.cpp b/lib/battle/SiegeInfo.cpp index c11a5a6d9..4666671e3 100644 --- a/lib/battle/SiegeInfo.cpp +++ b/lib/battle/SiegeInfo.cpp @@ -29,6 +29,8 @@ EWallState SiegeInfo::applyDamage(EWallState state, unsigned int value) switch(applyDamage(state, value - 1)) { + case EWallState::REINFORCED: + return EWallState::INTACT; case EWallState::INTACT: return EWallState::DAMAGED; case EWallState::DAMAGED: diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index 985f7bbd7..4934e3315 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -4831,7 +4831,7 @@ bool CGameHandler::makeBattleAction(BattleAction &ba) auto isWallPartAttackable = [this] (EWallPart part) { - return (gs->curB->si.wallState[part] == EWallState::INTACT || gs->curB->si.wallState[part] == EWallState::DAMAGED); + return (gs->curB->si.wallState[part] == EWallState::REINFORCED || gs->curB->si.wallState[part] == EWallState::INTACT || gs->curB->si.wallState[part] == EWallState::DAMAGED); }; CHeroHandler::SBallisticsLevelInfo stackBallisticsParameters = getBallisticsInfo(stack);