2
0
Эх сурвалжийг харах

vcmi: add getTrigger method to obstacles

Fixes advanced remove obstacle spell
Konstantin 2 жил өмнө
parent
commit
d8a237ba46

+ 5 - 6
AI/BattleAI/BattleAI.cpp

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

+ 2 - 10
config/spells/moats.json

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

+ 0 - 4
config/spells/other.json

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

+ 8 - 3
lib/battle/CObstacleInstance.cpp

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

+ 5 - 3
lib/battle/CObstacleInstance.h

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

+ 2 - 3
lib/spells/effects/Moat.cpp

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

+ 2 - 3
lib/spells/effects/Obstacle.cpp

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

+ 1 - 1
server/CGameHandler.cpp

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