mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-24 08:32:34 +02:00
vcmi: add getTrigger method to obstacles
Fixes advanced remove obstacle spell
This commit is contained in:
parent
82a6d94fd0
commit
d8a237ba46
@ -312,23 +312,22 @@ BattleAction CBattleAI::goTowardsNearest(const CStack * stack, std::vector<Battl
|
|||||||
{
|
{
|
||||||
std::set<BattleHex> obstacleHexes;
|
std::set<BattleHex> obstacleHexes;
|
||||||
|
|
||||||
auto insertAffected = [](const CObstacleInstance* spellObst, std::set<BattleHex> obstacleHexes) {
|
auto insertAffected = [](const CObstacleInstance & spellObst, std::set<BattleHex> obstacleHexes) {
|
||||||
auto affectedHexes = spellObst->getAffectedTiles();
|
auto affectedHexes = spellObst.getAffectedTiles();
|
||||||
obstacleHexes.insert(affectedHexes.cbegin(), affectedHexes.cend());
|
obstacleHexes.insert(affectedHexes.cbegin(), affectedHexes.cend());
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto & obstacles = hb.battleGetAllObstacles();
|
const auto & obstacles = hb.battleGetAllObstacles();
|
||||||
|
|
||||||
for (const auto & obst: obstacles) {
|
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();
|
auto triggerIsNegative = triggerAbility->isNegative() || triggerAbility->isDamage();
|
||||||
|
|
||||||
if(triggerIsNegative)
|
if(triggerIsNegative)
|
||||||
insertAffected(spellObst, obstacleHexes);
|
insertAffected(*obst, obstacleHexes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Flying stack doesn't go hex by hex, so we can't backtrack using predecessors.
|
// Flying stack doesn't go hex by hex, so we can't backtrack using predecessors.
|
||||||
|
@ -61,7 +61,6 @@
|
|||||||
"type":"core:moat",
|
"type":"core:moat",
|
||||||
"hidden" : false,
|
"hidden" : false,
|
||||||
"trap" : true,
|
"trap" : true,
|
||||||
"trigger" : true,
|
|
||||||
"triggerAbility" : "core:castleMoatTrigger",
|
"triggerAbility" : "core:castleMoatTrigger",
|
||||||
"dispellable" : false,
|
"dispellable" : false,
|
||||||
"removeOnTrigger" : false,
|
"removeOnTrigger" : false,
|
||||||
@ -159,7 +158,6 @@
|
|||||||
"type":"core:moat",
|
"type":"core:moat",
|
||||||
"hidden" : false,
|
"hidden" : false,
|
||||||
"trap" : true,
|
"trap" : true,
|
||||||
"trigger" : true,
|
|
||||||
"triggerAbility" : "core:rampartMoatTrigger",
|
"triggerAbility" : "core:rampartMoatTrigger",
|
||||||
"dispellable" : false,
|
"dispellable" : false,
|
||||||
"removeOnTrigger" : false,
|
"removeOnTrigger" : false,
|
||||||
@ -216,7 +214,6 @@
|
|||||||
"type":"core:moat",
|
"type":"core:moat",
|
||||||
"hidden" : true,
|
"hidden" : true,
|
||||||
"trap" : false,
|
"trap" : false,
|
||||||
"trigger" : true,
|
|
||||||
"triggerAbility" : "core:landMineTrigger",
|
"triggerAbility" : "core:landMineTrigger",
|
||||||
"dispellable" : true,
|
"dispellable" : true,
|
||||||
"removeOnTrigger" : true,
|
"removeOnTrigger" : true,
|
||||||
@ -309,7 +306,6 @@
|
|||||||
"type":"core:moat",
|
"type":"core:moat",
|
||||||
"hidden" : false,
|
"hidden" : false,
|
||||||
"trap" : true,
|
"trap" : true,
|
||||||
"trigger" : true,
|
|
||||||
"triggerAbility" : "core:infernoMoatTrigger",
|
"triggerAbility" : "core:infernoMoatTrigger",
|
||||||
"dispellable" : false,
|
"dispellable" : false,
|
||||||
"removeOnTrigger" : false,
|
"removeOnTrigger" : false,
|
||||||
@ -405,9 +401,8 @@
|
|||||||
"battleEffects":{
|
"battleEffects":{
|
||||||
"moat":{
|
"moat":{
|
||||||
"type":"core:moat",
|
"type":"core:moat",
|
||||||
"hidden" : true,
|
"hidden" : false,
|
||||||
"trap" : false,
|
"trap" : true,
|
||||||
"trigger" : true,
|
|
||||||
"triggerAbility" : "core:necropolisMoatTrigger",
|
"triggerAbility" : "core:necropolisMoatTrigger",
|
||||||
"dispellable" : false,
|
"dispellable" : false,
|
||||||
"removeOnTrigger" : false,
|
"removeOnTrigger" : false,
|
||||||
@ -505,7 +500,6 @@
|
|||||||
"type":"core:moat",
|
"type":"core:moat",
|
||||||
"hidden" : false,
|
"hidden" : false,
|
||||||
"trap" : true,
|
"trap" : true,
|
||||||
"trigger" : true,
|
|
||||||
"triggerAbility" : "core:dungeonMoatTrigger",
|
"triggerAbility" : "core:dungeonMoatTrigger",
|
||||||
"dispellable" : false,
|
"dispellable" : false,
|
||||||
"removeOnTrigger" : false,
|
"removeOnTrigger" : false,
|
||||||
@ -603,7 +597,6 @@
|
|||||||
"type":"core:moat",
|
"type":"core:moat",
|
||||||
"hidden" : false,
|
"hidden" : false,
|
||||||
"trap" : true,
|
"trap" : true,
|
||||||
"trigger" : true,
|
|
||||||
"triggerAbility" : "core:strongholdMoatTrigger",
|
"triggerAbility" : "core:strongholdMoatTrigger",
|
||||||
"dispellable" : false,
|
"dispellable" : false,
|
||||||
"removeOnTrigger" : false,
|
"removeOnTrigger" : false,
|
||||||
@ -701,7 +694,6 @@
|
|||||||
"type":"core:moat",
|
"type":"core:moat",
|
||||||
"hidden" : false,
|
"hidden" : false,
|
||||||
"trap" : true,
|
"trap" : true,
|
||||||
"trigger" : true,
|
|
||||||
"triggerAbility" : "core:fortressMoatTrigger",
|
"triggerAbility" : "core:fortressMoatTrigger",
|
||||||
"dispellable" : false,
|
"dispellable" : false,
|
||||||
"removeOnTrigger" : false,
|
"removeOnTrigger" : false,
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
"hidden" : true,
|
"hidden" : true,
|
||||||
"passable" : true,
|
"passable" : true,
|
||||||
"trap" : true,
|
"trap" : true,
|
||||||
"trigger" : false,
|
|
||||||
"patchCount" : 4,
|
"patchCount" : 4,
|
||||||
"turnsRemaining" : -1,
|
"turnsRemaining" : -1,
|
||||||
"attacker" :{
|
"attacker" :{
|
||||||
@ -127,7 +126,6 @@
|
|||||||
"hidden" : true,
|
"hidden" : true,
|
||||||
"passable" : true,
|
"passable" : true,
|
||||||
"trap" : false,
|
"trap" : false,
|
||||||
"trigger" : true,
|
|
||||||
"triggerAbility" : "core:landMineTrigger",
|
"triggerAbility" : "core:landMineTrigger",
|
||||||
"removeOnTrigger" : true,
|
"removeOnTrigger" : true,
|
||||||
"patchCount" : 4,
|
"patchCount" : 4,
|
||||||
@ -194,7 +192,6 @@
|
|||||||
"hidden" : false,
|
"hidden" : false,
|
||||||
"passable" : false,
|
"passable" : false,
|
||||||
"trap" : false,
|
"trap" : false,
|
||||||
"trigger" : false,
|
|
||||||
"turnsRemaining" : 2,
|
"turnsRemaining" : 2,
|
||||||
"attacker" :{
|
"attacker" :{
|
||||||
"range" : [[""]],
|
"range" : [[""]],
|
||||||
@ -319,7 +316,6 @@
|
|||||||
"hidden" : false,
|
"hidden" : false,
|
||||||
"passable" : true,
|
"passable" : true,
|
||||||
"trap" : false,
|
"trap" : false,
|
||||||
"trigger" : true,
|
|
||||||
"triggerAbility" : "core:fireWallTrigger",
|
"triggerAbility" : "core:fireWallTrigger",
|
||||||
"turnsRemaining" : 2,
|
"turnsRemaining" : 2,
|
||||||
"attacker" :{
|
"attacker" :{
|
||||||
|
@ -98,7 +98,12 @@ bool CObstacleInstance::blocksTiles() const
|
|||||||
|
|
||||||
bool CObstacleInstance::triggersEffects() const
|
bool CObstacleInstance::triggersEffects() const
|
||||||
{
|
{
|
||||||
return false;
|
return getTrigger() != SpellID::NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
SpellID CObstacleInstance::getTrigger() const
|
||||||
|
{
|
||||||
|
return SpellID::NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CObstacleInstance::serializeJson(JsonSerializeFormat & handler)
|
void CObstacleInstance::serializeJson(JsonSerializeFormat & handler)
|
||||||
@ -172,7 +177,7 @@ bool SpellCreatedObstacle::stopsMovement() const
|
|||||||
return trap;
|
return trap;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SpellCreatedObstacle::triggersEffects() const
|
SpellID SpellCreatedObstacle::getTrigger() const
|
||||||
{
|
{
|
||||||
return trigger;
|
return trigger;
|
||||||
}
|
}
|
||||||
@ -203,7 +208,7 @@ void SpellCreatedObstacle::serializeJson(JsonSerializeFormat & handler)
|
|||||||
handler.serializeBool("hidden", hidden);
|
handler.serializeBool("hidden", hidden);
|
||||||
handler.serializeBool("revealed", revealed);
|
handler.serializeBool("revealed", revealed);
|
||||||
handler.serializeBool("passable", passable);
|
handler.serializeBool("passable", passable);
|
||||||
handler.serializeBool("trigger", trigger);
|
handler.serializeId("trigger", trigger, SpellID::NONE);
|
||||||
handler.serializeBool("trap", trap);
|
handler.serializeBool("trap", trap);
|
||||||
handler.serializeBool("removeOnTrigger", removeOnTrigger);
|
handler.serializeBool("removeOnTrigger", removeOnTrigger);
|
||||||
handler.serializeBool("nativeVisible", nativeVisible);
|
handler.serializeBool("nativeVisible", nativeVisible);
|
||||||
|
@ -16,6 +16,7 @@ VCMI_LIB_NAMESPACE_BEGIN
|
|||||||
class ObstacleInfo;
|
class ObstacleInfo;
|
||||||
class ObstacleChanges;
|
class ObstacleChanges;
|
||||||
class JsonSerializeFormat;
|
class JsonSerializeFormat;
|
||||||
|
class SpellID;
|
||||||
|
|
||||||
struct DLL_LINKAGE CObstacleInstance
|
struct DLL_LINKAGE CObstacleInstance
|
||||||
{
|
{
|
||||||
@ -42,6 +43,7 @@ struct DLL_LINKAGE CObstacleInstance
|
|||||||
virtual bool blocksTiles() const;
|
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 stopsMovement() const; //if unit stepping onto obstacle, can't continue movement (in general, doesn't checks for the side)
|
||||||
virtual bool triggersEffects() const;
|
virtual bool triggersEffects() const;
|
||||||
|
virtual SpellID getTrigger() const;
|
||||||
|
|
||||||
virtual std::vector<BattleHex> getAffectedTiles() const;
|
virtual std::vector<BattleHex> getAffectedTiles() const;
|
||||||
virtual bool visibleForSide(ui8 side, bool hasNativeStack) const; //0 attacker
|
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
|
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
|
si8 casterSide; //0 - obstacle created by attacker; 1 - by defender
|
||||||
|
|
||||||
|
SpellID trigger;
|
||||||
|
|
||||||
bool hidden;
|
bool hidden;
|
||||||
bool passable;
|
bool passable;
|
||||||
bool trigger;
|
|
||||||
bool trap;
|
bool trap;
|
||||||
bool removeOnTrigger;
|
bool removeOnTrigger;
|
||||||
|
|
||||||
bool revealed;
|
bool revealed;
|
||||||
bool nativeVisible; //Should native terrain creatures reveal obstacle
|
bool nativeVisible; //Should native terrain creatures reveal obstacle
|
||||||
|
|
||||||
@ -100,7 +102,7 @@ struct DLL_LINKAGE SpellCreatedObstacle : CObstacleInstance
|
|||||||
|
|
||||||
bool blocksTiles() const override;
|
bool blocksTiles() const override;
|
||||||
bool stopsMovement() const override;
|
bool stopsMovement() const override;
|
||||||
bool triggersEffects() const override;
|
SpellID getTrigger() const override;
|
||||||
|
|
||||||
void battleTurnPassed() override;
|
void battleTurnPassed() override;
|
||||||
|
|
||||||
|
@ -51,7 +51,6 @@ static void serializeMoatHexes(JsonSerializeFormat & handler, const std::string
|
|||||||
void Moat::serializeJsonEffect(JsonSerializeFormat & handler)
|
void Moat::serializeJsonEffect(JsonSerializeFormat & handler)
|
||||||
{
|
{
|
||||||
handler.serializeBool("hidden", hidden);
|
handler.serializeBool("hidden", hidden);
|
||||||
handler.serializeBool("trigger", trigger);
|
|
||||||
handler.serializeBool("trap", trap);
|
handler.serializeBool("trap", trap);
|
||||||
handler.serializeBool("removeOnTrigger", removeOnTrigger);
|
handler.serializeBool("removeOnTrigger", removeOnTrigger);
|
||||||
handler.serializeBool("dispellable", dispellable);
|
handler.serializeBool("dispellable", dispellable);
|
||||||
@ -147,7 +146,7 @@ void Moat::placeObstacles(ServerCallback * server, const Mechanics * m, const Ef
|
|||||||
obstacle.uniqueID = obstacleIdToGive++;
|
obstacle.uniqueID = obstacleIdToGive++;
|
||||||
obstacle.pos = destination.at(0);
|
obstacle.pos = destination.at(0);
|
||||||
obstacle.obstacleType = dispellable ? CObstacleInstance::SPELL_CREATED : CObstacleInstance::MOAT;
|
obstacle.obstacleType = dispellable ? CObstacleInstance::SPELL_CREATED : CObstacleInstance::MOAT;
|
||||||
obstacle.ID = triggerAbility;
|
obstacle.ID = m->getSpellIndex();
|
||||||
|
|
||||||
obstacle.turnsRemaining = -1; //Moat cannot be expired
|
obstacle.turnsRemaining = -1; //Moat cannot be expired
|
||||||
obstacle.casterSpellPower = m->getEffectPower();
|
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.minimalDamage = moatDamage; // Minimal moat damage
|
||||||
obstacle.hidden = hidden;
|
obstacle.hidden = hidden;
|
||||||
obstacle.passable = true; //Moats always passable
|
obstacle.passable = true; //Moats always passable
|
||||||
obstacle.trigger = trigger;
|
obstacle.trigger = triggerAbility;
|
||||||
obstacle.trap = trap;
|
obstacle.trap = trap;
|
||||||
obstacle.removeOnTrigger = removeOnTrigger;
|
obstacle.removeOnTrigger = removeOnTrigger;
|
||||||
obstacle.nativeVisible = false; //Moats is invisible for native terrain
|
obstacle.nativeVisible = false; //Moats is invisible for native terrain
|
||||||
|
@ -212,7 +212,6 @@ void Obstacle::serializeJsonEffect(JsonSerializeFormat & handler)
|
|||||||
{
|
{
|
||||||
handler.serializeBool("hidden", hidden);
|
handler.serializeBool("hidden", hidden);
|
||||||
handler.serializeBool("passable", passable);
|
handler.serializeBool("passable", passable);
|
||||||
handler.serializeBool("trigger", trigger);
|
|
||||||
handler.serializeBool("trap", trap);
|
handler.serializeBool("trap", trap);
|
||||||
handler.serializeBool("removeOnTrigger", removeOnTrigger);
|
handler.serializeBool("removeOnTrigger", removeOnTrigger);
|
||||||
handler.serializeBool("hideNative", hideNative);
|
handler.serializeBool("hideNative", hideNative);
|
||||||
@ -289,7 +288,7 @@ void Obstacle::placeObstacles(ServerCallback * server, const Mechanics * m, cons
|
|||||||
obstacle.uniqueID = obstacleIdToGive++;
|
obstacle.uniqueID = obstacleIdToGive++;
|
||||||
obstacle.pos = destination.hexValue;
|
obstacle.pos = destination.hexValue;
|
||||||
obstacle.obstacleType = CObstacleInstance::SPELL_CREATED;
|
obstacle.obstacleType = CObstacleInstance::SPELL_CREATED;
|
||||||
obstacle.ID = triggerAbility;
|
obstacle.ID = m->getSpellIndex();
|
||||||
|
|
||||||
obstacle.turnsRemaining = turnsRemaining;
|
obstacle.turnsRemaining = turnsRemaining;
|
||||||
obstacle.casterSpellPower = m->getEffectPower();
|
obstacle.casterSpellPower = m->getEffectPower();
|
||||||
@ -299,7 +298,7 @@ void Obstacle::placeObstacles(ServerCallback * server, const Mechanics * m, cons
|
|||||||
obstacle.nativeVisible = !hideNative;
|
obstacle.nativeVisible = !hideNative;
|
||||||
obstacle.hidden = hidden;
|
obstacle.hidden = hidden;
|
||||||
obstacle.passable = passable;
|
obstacle.passable = passable;
|
||||||
obstacle.trigger = trigger;
|
obstacle.trigger = triggerAbility;
|
||||||
obstacle.trap = trap;
|
obstacle.trap = trap;
|
||||||
obstacle.removeOnTrigger = removeOnTrigger;
|
obstacle.removeOnTrigger = removeOnTrigger;
|
||||||
|
|
||||||
|
@ -5263,7 +5263,7 @@ bool CGameHandler::handleDamageFromObstacle(const CStack * curStack, bool stackI
|
|||||||
auto shouldReveal = !spellObstacle->hidden || !gs->curB->battleIsObstacleVisibleForSide(*obstacle, (BattlePerspective::BattlePerspective)side);
|
auto shouldReveal = !spellObstacle->hidden || !gs->curB->battleIsObstacleVisibleForSide(*obstacle, (BattlePerspective::BattlePerspective)side);
|
||||||
const auto * hero = gs->curB->battleGetFightingHero(spellObstacle->casterSide);
|
const auto * hero = gs->curB->battleGetFightingHero(spellObstacle->casterSide);
|
||||||
auto caster = spells::ObstacleCasterProxy(gs->curB->getSidePlayer(spellObstacle->casterSide), hero, *spellObstacle);
|
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)
|
if(obstacle->triggersEffects() && sp)
|
||||||
{
|
{
|
||||||
auto cast = spells::BattleCast(gs->curB, &caster, spells::Mode::PASSIVE, sp);
|
auto cast = spells::BattleCast(gs->curB, &caster, spells::Mode::PASSIVE, sp);
|
||||||
|
Loading…
Reference in New Issue
Block a user