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:
parent
82a6d94fd0
commit
d8a237ba46
@ -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.
|
||||
|
@ -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,
|
||||
|
@ -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" :{
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user