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

CGameHandler: slightly rework obstacle caster

This commit is contained in:
Konstantin 2023-03-30 15:04:05 +03:00
parent 25956e3f37
commit d5e2933bee

View File

@ -5238,50 +5238,47 @@ bool CGameHandler::handleDamageFromObstacle(const CStack * curStack, bool stackI
bool movementStopped = false; bool movementStopped = false;
for(auto & obstacle : getAllAffectedObstaclesByStack(curStack, passed)) for(auto & obstacle : getAllAffectedObstaclesByStack(curStack, passed))
{ {
//helper info //helper info
const SpellCreatedObstacle * spellObstacle = dynamic_cast<const SpellCreatedObstacle *>(obstacle.get()); const SpellCreatedObstacle * spellObstacle = dynamic_cast<const SpellCreatedObstacle *>(obstacle.get());
const ui8 side = curStack->side;
if(!spellObstacle) if(spellObstacle)
COMPLAIN_RET("Invalid obstacle instance"); {
auto revealObstacles = [&](const SpellCreatedObstacle & spellObstacle) -> void
if(spellObstacle->triggersEffects())
{ {
auto revealObstacles = [&](const SpellCreatedObstacle & spellObstacle) -> void // For the hidden spell created obstacles, e.g. QuickSand, it should be revealed after taking damage
{ auto operation = ObstacleChanges::EOperation::UPDATE;
// For the hidden spell created obstacles, e.g. QuickSand, it should be revealed after taking damage if (spellObstacle.removeOnTrigger)
auto operation = ObstacleChanges::EOperation::UPDATE; operation = ObstacleChanges::EOperation::REMOVE;
if (spellObstacle.removeOnTrigger)
operation = ObstacleChanges::EOperation::REMOVE;
SpellCreatedObstacle changedObstacle; SpellCreatedObstacle changedObstacle;
changedObstacle.uniqueID = spellObstacle.uniqueID; changedObstacle.uniqueID = spellObstacle.uniqueID;
changedObstacle.revealed = true; changedObstacle.revealed = true;
BattleObstaclesChanged bocp; BattleObstaclesChanged bocp;
bocp.changes.emplace_back(spellObstacle.uniqueID, operation); bocp.changes.emplace_back(spellObstacle.uniqueID, operation);
changedObstacle.toInfo(bocp.changes.back(), operation); changedObstacle.toInfo(bocp.changes.back(), operation);
sendAndApply(&bocp); sendAndApply(&bocp);
}; };
auto shouldReveal = !spellObstacle->hidden || !gs->curB->battleIsObstacleVisibleForSide(*obstacle, (BattlePerspective::BattlePerspective)side); const auto side = curStack->side;
const auto * hero = gs->curB->battleGetFightingHero(spellObstacle->casterSide); auto shouldReveal = !spellObstacle->hidden || !gs->curB->battleIsObstacleVisibleForSide(*obstacle, (BattlePerspective::BattlePerspective)side);
auto caster = spells::ObstacleCasterProxy(gs->curB->sides.at(spellObstacle->casterSide).color, hero, *spellObstacle); const auto * hero = gs->curB->battleGetFightingHero(spellObstacle->casterSide);
const auto * sp = SpellID(spellObstacle->ID).toSpell(); auto caster = spells::ObstacleCasterProxy(gs->curB->getSidePlayer(spellObstacle->casterSide), hero, *spellObstacle);
if(sp) const auto * sp = SpellID(spellObstacle->ID).toSpell();
if(obstacle->triggersEffects() && sp)
{
auto cast = spells::BattleCast(gs->curB, &caster, spells::Mode::PASSIVE, sp);
spells::detail::ProblemImpl ignored;
auto target = spells::Target(1, spells::Destination(curStack));
if(sp->battleMechanics(&cast)->canBeCastAt(target, ignored)) // Obstacles should not be revealed by immune creatures
{ {
auto cast = spells::BattleCast(gs->curB, &caster, spells::Mode::PASSIVE, sp); if(shouldReveal) { //hidden obstacle triggers effects after revealed
spells::detail::ProblemImpl ignored; revealObstacles(*spellObstacle);
auto target = spells::Target(1, spells::Destination(curStack)); cast.cast(spellEnv, target);
if(sp->battleMechanics(&cast)->canBeCastAt(target, ignored)) // Obstacles should not be revealed by immune creatures
{
if(shouldReveal) { //hidden obstacle triggers effects after revealed
revealObstacles(*spellObstacle);
cast.cast(spellEnv, target);
}
} }
} }
else if(shouldReveal) }
revealObstacles(*spellObstacle); else if(shouldReveal)
revealObstacles(*spellObstacle);
} }
if(!curStack->alive()) if(!curStack->alive())