1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Implemented reinforced walls in towns with Castle

This commit is contained in:
Ivan Savenko 2023-01-13 01:09:24 +02:00
parent 500cf7f15d
commit 1d7f004658
8 changed files with 35 additions and 23 deletions

View File

@ -378,10 +378,9 @@ BattleAction CBattleAI::useCatapult(const CStack * stack)
{ {
auto wallState = cb->battleGetWallState(wallPart); 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); targetHex = cb->wallPartToBattleHex(wallPart);
break; break;
} }
} }

View File

@ -32,18 +32,25 @@ std::string BattleSiegeController::getWallPieceImageName(EWallVisual::EWallVisua
{ {
auto getImageIndex = [&]() -> int auto getImageIndex = [&]() -> int
{ {
bool isTower = (what == EWallVisual::KEEP || what == EWallVisual::BOTTOM_TOWER || what == EWallVisual::UPPER_TOWER);
switch (state) switch (state)
{ {
case EWallState::REINFORCED :
return 1;
case EWallState::INTACT : case EWallState::INTACT :
if (town->hasBuilt(BuildingID::CASTLE))
return 2; // reinforced walls were damaged
else
return 1; return 1;
case EWallState::DAMAGED : case EWallState::DAMAGED :
// towers don't have separate image here - INTACT and DAMAGED is 1, DESTROYED is 2 // 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; return 1;
else else
return 2; return 2;
case EWallState::DESTROYED : case EWallState::DESTROYED :
if (what == EWallVisual::KEEP || what == EWallVisual::BOTTOM_TOWER || what == EWallVisual::UPPER_TOWER) if (isTower)
return 2; return 2;
else else
return 3; 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: 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::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::KEEP_BATTLEMENT: return town->hasBuilt(BuildingID::CITADEL) && 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::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) && EWallState(owner.curInt->cb->battleGetWallState(EWallPart::BOTTOM_TOWER)) != EWallState::DESTROYED; case EWallVisual::BOTTOM_BATTLEMENT: return town->hasBuilt(BuildingID::CASTLE) && owner.curInt->cb->battleGetWallState(EWallPart::BOTTOM_TOWER) != EWallState::DESTROYED;
default: return true; default: return true;
} }
} }
@ -177,7 +184,7 @@ BattleSiegeController::BattleSiegeController(BattleInterface & owner, const CGTo
if ( !getWallPieceExistance(EWallVisual::EWallVisual(g)) ) if ( !getWallPieceExistance(EWallVisual::EWallVisual(g)) )
continue; continue;
wallPieceImages[g] = IImage::createFromFile(getWallPieceImageName(EWallVisual::EWallVisual(g), EWallState::INTACT)); wallPieceImages[g] = IImage::createFromFile(getWallPieceImageName(EWallVisual::EWallVisual(g), EWallState::REINFORCED));
} }
} }

View File

@ -627,7 +627,8 @@ enum class EWallState : int8_t
NONE = -1, //no wall NONE = -1, //no wall
DESTROYED, DESTROYED,
DAMAGED, DAMAGED,
INTACT INTACT,
REINFORCED, // walls in towns with castle
}; };
enum class EGateState : uint8_t enum class EGateState : uint8_t

View File

@ -1707,7 +1707,7 @@ DLL_LINKAGE void CatapultAttack::applyBattle(IBattleState * battleState)
for(const auto & part : attackedParts) 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); battleState->setWallState(part.attackedPart, newWallState);
} }
} }

View File

@ -223,20 +223,23 @@ BattleInfo * BattleInfo::setupBattle(const int3 & tile, TerrainId terrain, const
{ {
curB->si.gateState = EGateState::CLOSED; 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)) if (town->hasBuilt(BuildingID::CITADEL))
{ curB->si.wallState[EWallPart::KEEP] = EWallState::INTACT;
curB->si.wallState[EWallPart::KEEP] = EWallState::NONE;
}
if (!town->hasBuilt(BuildingID::CASTLE)) if (town->hasBuilt(BuildingID::CASTLE))
{ {
curB->si.wallState[EWallPart::UPPER_TOWER] = EWallState::NONE; curB->si.wallState[EWallPart::UPPER_TOWER] = EWallState::INTACT;
curB->si.wallState[EWallPart::BOTTOM_TOWER] = EWallState::NONE; curB->si.wallState[EWallPart::BOTTOM_TOWER] = EWallState::INTACT;
} }
} }

View File

@ -1632,8 +1632,8 @@ std::vector<BattleHex> CBattleInfoCallback::getAttackableBattleHexes() const
{ {
if(isWallPartPotentiallyAttackable(wallPartPair.second)) if(isWallPartPotentiallyAttackable(wallPartPair.second))
{ {
auto wallState = static_cast<EWallState>(battleGetWallState(wallPartPair.second)); auto wallState = battleGetWallState(wallPartPair.second);
if(wallState == EWallState::INTACT || wallState == EWallState::DAMAGED) if(wallState == EWallState::REINFORCED || wallState == EWallState::INTACT || wallState == EWallState::DAMAGED)
{ {
attackableBattleHexes.push_back(BattleHex(wallPartPair.first)); attackableBattleHexes.push_back(BattleHex(wallPartPair.first));
} }

View File

@ -29,6 +29,8 @@ EWallState SiegeInfo::applyDamage(EWallState state, unsigned int value)
switch(applyDamage(state, value - 1)) switch(applyDamage(state, value - 1))
{ {
case EWallState::REINFORCED:
return EWallState::INTACT;
case EWallState::INTACT: case EWallState::INTACT:
return EWallState::DAMAGED; return EWallState::DAMAGED;
case EWallState::DAMAGED: case EWallState::DAMAGED:

View File

@ -4831,7 +4831,7 @@ bool CGameHandler::makeBattleAction(BattleAction &ba)
auto isWallPartAttackable = [this] (EWallPart part) 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); CHeroHandler::SBallisticsLevelInfo stackBallisticsParameters = getBallisticsInfo(stack);