1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-28 08:48:48 +02:00

vcmi: add getTrigger method to obstacles

Fixes advanced remove obstacle spell
This commit is contained in:
Konstantin 2023-03-31 00:49:51 +03:00
parent 82a6d94fd0
commit d8a237ba46
8 changed files with 25 additions and 33 deletions

View File

@ -312,23 +312,22 @@ BattleAction CBattleAI::goTowardsNearest(const CStack * stack, std::vector<Battl
{
std::set<BattleHex> obstacleHexes;
auto insertAffected = [](const CObstacleInstance* spellObst, std::set<BattleHex> obstacleHexes) {
auto affectedHexes = spellObst->getAffectedTiles();
auto insertAffected = [](const CObstacleInstance & spellObst, std::set<BattleHex> obstacleHexes) {
auto affectedHexes = spellObst.getAffectedTiles();
obstacleHexes.insert(affectedHexes.cbegin(), affectedHexes.cend());
};
const auto & obstacles = hb.battleGetAllObstacles();
for (const auto & obst: obstacles) {
const auto * spellObst = dynamic_cast<const SpellCreatedObstacle*>(obst.get());
if(spellObst && spellObst->trigger)
if(obst->triggersEffects())
{
auto triggerAbility = VLC->spells()->getById(SpellID(spellObst->ID));
auto triggerAbility = VLC->spells()->getById(obst->getTrigger());
auto triggerIsNegative = triggerAbility->isNegative() || triggerAbility->isDamage();
if(triggerIsNegative)
insertAffected(spellObst, obstacleHexes);
insertAffected(*obst, obstacleHexes);
}
}
// Flying stack doesn't go hex by hex, so we can't backtrack using predecessors.

View File

@ -61,7 +61,6 @@
"type":"core:moat",
"hidden" : false,
"trap" : true,
"trigger" : true,
"triggerAbility" : "core:castleMoatTrigger",
"dispellable" : false,
"removeOnTrigger" : false,
@ -159,7 +158,6 @@
"type":"core:moat",
"hidden" : false,
"trap" : true,
"trigger" : true,
"triggerAbility" : "core:rampartMoatTrigger",
"dispellable" : false,
"removeOnTrigger" : false,
@ -216,7 +214,6 @@
"type":"core:moat",
"hidden" : true,
"trap" : false,
"trigger" : true,
"triggerAbility" : "core:landMineTrigger",
"dispellable" : true,
"removeOnTrigger" : true,
@ -309,7 +306,6 @@
"type":"core:moat",
"hidden" : false,
"trap" : true,
"trigger" : true,
"triggerAbility" : "core:infernoMoatTrigger",
"dispellable" : false,
"removeOnTrigger" : false,
@ -405,9 +401,8 @@
"battleEffects":{
"moat":{
"type":"core:moat",
"hidden" : true,
"trap" : false,
"trigger" : true,
"hidden" : false,
"trap" : true,
"triggerAbility" : "core:necropolisMoatTrigger",
"dispellable" : false,
"removeOnTrigger" : false,
@ -505,7 +500,6 @@
"type":"core:moat",
"hidden" : false,
"trap" : true,
"trigger" : true,
"triggerAbility" : "core:dungeonMoatTrigger",
"dispellable" : false,
"removeOnTrigger" : false,
@ -603,7 +597,6 @@
"type":"core:moat",
"hidden" : false,
"trap" : true,
"trigger" : true,
"triggerAbility" : "core:strongholdMoatTrigger",
"dispellable" : false,
"removeOnTrigger" : false,
@ -701,7 +694,6 @@
"type":"core:moat",
"hidden" : false,
"trap" : true,
"trigger" : true,
"triggerAbility" : "core:fortressMoatTrigger",
"dispellable" : false,
"removeOnTrigger" : false,

View File

@ -15,7 +15,6 @@
"hidden" : true,
"passable" : true,
"trap" : true,
"trigger" : false,
"patchCount" : 4,
"turnsRemaining" : -1,
"attacker" :{
@ -127,7 +126,6 @@
"hidden" : true,
"passable" : true,
"trap" : false,
"trigger" : true,
"triggerAbility" : "core:landMineTrigger",
"removeOnTrigger" : true,
"patchCount" : 4,
@ -194,7 +192,6 @@
"hidden" : false,
"passable" : false,
"trap" : false,
"trigger" : false,
"turnsRemaining" : 2,
"attacker" :{
"range" : [[""]],
@ -319,7 +316,6 @@
"hidden" : false,
"passable" : true,
"trap" : false,
"trigger" : true,
"triggerAbility" : "core:fireWallTrigger",
"turnsRemaining" : 2,
"attacker" :{

View File

@ -98,7 +98,12 @@ bool CObstacleInstance::blocksTiles() const
bool CObstacleInstance::triggersEffects() const
{
return false;
return getTrigger() != SpellID::NONE;
}
SpellID CObstacleInstance::getTrigger() const
{
return SpellID::NONE;
}
void CObstacleInstance::serializeJson(JsonSerializeFormat & handler)
@ -172,7 +177,7 @@ bool SpellCreatedObstacle::stopsMovement() const
return trap;
}
bool SpellCreatedObstacle::triggersEffects() const
SpellID SpellCreatedObstacle::getTrigger() const
{
return trigger;
}
@ -203,7 +208,7 @@ void SpellCreatedObstacle::serializeJson(JsonSerializeFormat & handler)
handler.serializeBool("hidden", hidden);
handler.serializeBool("revealed", revealed);
handler.serializeBool("passable", passable);
handler.serializeBool("trigger", trigger);
handler.serializeId("trigger", trigger, SpellID::NONE);
handler.serializeBool("trap", trap);
handler.serializeBool("removeOnTrigger", removeOnTrigger);
handler.serializeBool("nativeVisible", nativeVisible);

View File

@ -16,6 +16,7 @@ VCMI_LIB_NAMESPACE_BEGIN
class ObstacleInfo;
class ObstacleChanges;
class JsonSerializeFormat;
class SpellID;
struct DLL_LINKAGE CObstacleInstance
{
@ -42,6 +43,7 @@ struct DLL_LINKAGE CObstacleInstance
virtual bool blocksTiles() const;
virtual bool stopsMovement() const; //if unit stepping onto obstacle, can't continue movement (in general, doesn't checks for the side)
virtual bool triggersEffects() const;
virtual SpellID getTrigger() const;
virtual std::vector<BattleHex> getAffectedTiles() const;
virtual bool visibleForSide(ui8 side, bool hasNativeStack) const; //0 attacker
@ -76,12 +78,12 @@ struct DLL_LINKAGE SpellCreatedObstacle : CObstacleInstance
int32_t minimalDamage; //How many damage should it do regardless of power and level of caster
si8 casterSide; //0 - obstacle created by attacker; 1 - by defender
SpellID trigger;
bool hidden;
bool passable;
bool trigger;
bool trap;
bool removeOnTrigger;
bool revealed;
bool nativeVisible; //Should native terrain creatures reveal obstacle
@ -100,7 +102,7 @@ struct DLL_LINKAGE SpellCreatedObstacle : CObstacleInstance
bool blocksTiles() const override;
bool stopsMovement() const override;
bool triggersEffects() const override;
SpellID getTrigger() const override;
void battleTurnPassed() override;

View File

@ -51,7 +51,6 @@ static void serializeMoatHexes(JsonSerializeFormat & handler, const std::string
void Moat::serializeJsonEffect(JsonSerializeFormat & handler)
{
handler.serializeBool("hidden", hidden);
handler.serializeBool("trigger", trigger);
handler.serializeBool("trap", trap);
handler.serializeBool("removeOnTrigger", removeOnTrigger);
handler.serializeBool("dispellable", dispellable);
@ -147,7 +146,7 @@ void Moat::placeObstacles(ServerCallback * server, const Mechanics * m, const Ef
obstacle.uniqueID = obstacleIdToGive++;
obstacle.pos = destination.at(0);
obstacle.obstacleType = dispellable ? CObstacleInstance::SPELL_CREATED : CObstacleInstance::MOAT;
obstacle.ID = triggerAbility;
obstacle.ID = m->getSpellIndex();
obstacle.turnsRemaining = -1; //Moat cannot be expired
obstacle.casterSpellPower = m->getEffectPower();
@ -156,7 +155,7 @@ void Moat::placeObstacles(ServerCallback * server, const Mechanics * m, const Ef
obstacle.minimalDamage = moatDamage; // Minimal moat damage
obstacle.hidden = hidden;
obstacle.passable = true; //Moats always passable
obstacle.trigger = trigger;
obstacle.trigger = triggerAbility;
obstacle.trap = trap;
obstacle.removeOnTrigger = removeOnTrigger;
obstacle.nativeVisible = false; //Moats is invisible for native terrain

View File

@ -212,7 +212,6 @@ void Obstacle::serializeJsonEffect(JsonSerializeFormat & handler)
{
handler.serializeBool("hidden", hidden);
handler.serializeBool("passable", passable);
handler.serializeBool("trigger", trigger);
handler.serializeBool("trap", trap);
handler.serializeBool("removeOnTrigger", removeOnTrigger);
handler.serializeBool("hideNative", hideNative);
@ -289,7 +288,7 @@ void Obstacle::placeObstacles(ServerCallback * server, const Mechanics * m, cons
obstacle.uniqueID = obstacleIdToGive++;
obstacle.pos = destination.hexValue;
obstacle.obstacleType = CObstacleInstance::SPELL_CREATED;
obstacle.ID = triggerAbility;
obstacle.ID = m->getSpellIndex();
obstacle.turnsRemaining = turnsRemaining;
obstacle.casterSpellPower = m->getEffectPower();
@ -299,7 +298,7 @@ void Obstacle::placeObstacles(ServerCallback * server, const Mechanics * m, cons
obstacle.nativeVisible = !hideNative;
obstacle.hidden = hidden;
obstacle.passable = passable;
obstacle.trigger = trigger;
obstacle.trigger = triggerAbility;
obstacle.trap = trap;
obstacle.removeOnTrigger = removeOnTrigger;

View File

@ -5263,7 +5263,7 @@ bool CGameHandler::handleDamageFromObstacle(const CStack * curStack, bool stackI
auto shouldReveal = !spellObstacle->hidden || !gs->curB->battleIsObstacleVisibleForSide(*obstacle, (BattlePerspective::BattlePerspective)side);
const auto * hero = gs->curB->battleGetFightingHero(spellObstacle->casterSide);
auto caster = spells::ObstacleCasterProxy(gs->curB->getSidePlayer(spellObstacle->casterSide), hero, *spellObstacle);
const auto * sp = SpellID(spellObstacle->ID).toSpell();
const auto * sp = obstacle->getTrigger().toSpell();
if(obstacle->triggersEffects() && sp)
{
auto cast = spells::BattleCast(gs->curB, &caster, spells::Mode::PASSIVE, sp);