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);
if(wallState == EWallState::INTACT || wallState == EWallState::DAMAGED)
if(wallState == EWallState::REINFORCED || wallState == EWallState::INTACT || wallState == EWallState::DAMAGED)
{
targetHex = cb->wallPartToBattleHex(wallPart);
break;
}
}

View File

@ -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::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));
}
}

View File

@ -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

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -1632,8 +1632,8 @@ std::vector<BattleHex> CBattleInfoCallback::getAttackableBattleHexes() const
{
if(isWallPartPotentiallyAttackable(wallPartPair.second))
{
auto wallState = static_cast<EWallState>(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));
}

View File

@ -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:

View File

@ -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);