Jelajahi Sumber

Fixed https://bugs.vcmi.eu/view.php?id=2864

AlexVinS 7 tahun lalu
induk
melakukan
c94daf6faa

+ 1 - 6
lib/spells/CSpellHandler.cpp

@@ -580,12 +580,7 @@ CSpell::TargetInfo::TargetInfo(const CSpell * spell, const int level, spells::Mo
 	clearAffected = levelInfo.clearAffected;
 	clearTarget = levelInfo.clearTarget;
 
-	if(mode == spells::Mode::ENCHANTER)
-	{
-		smart = true; //FIXME: not sure about that, this makes all spells smart in this mode
-		massive = true;
-	}
-	else if(mode == spells::Mode::CREATURE_ACTIVE)
+	if(mode == spells::Mode::CREATURE_ACTIVE)
 	{
 		massive = false;//FIXME: find better solution for Commander spells
 	}

+ 37 - 7
lib/spells/ISpellMechanics.cpp

@@ -162,7 +162,9 @@ BattleCast::BattleCast(const CBattleInfoCallback * cb, const Caster * caster_, c
 	effectLevel(),
 	effectPower(),
 	effectDuration(),
-	effectValue()
+	effectValue(),
+	smart(boost::logic::indeterminate),
+	massive(boost::logic::indeterminate)
 {
 
 }
@@ -176,7 +178,9 @@ BattleCast::BattleCast(const BattleCast & orig, const Caster * caster_)
 	effectLevel(orig.effectLevel),
 	effectPower(orig.effectPower),
 	effectDuration(orig.effectDuration),
-	effectValue(orig.effectValue)
+	effectValue(orig.effectValue),
+	smart(true),
+	massive(false)
 {
 }
 
@@ -233,6 +237,16 @@ BattleCast::OptionalValue64 BattleCast::getEffectValue() const
 	return effectValue;
 }
 
+boost::logic::tribool BattleCast::isSmart() const
+{
+	return smart;
+}
+
+boost::logic::tribool BattleCast::isMassive() const
+{
+	return massive;
+}
+
 void BattleCast::setSpellLevel(BattleCast::Value value)
 {
 	spellLvl = boost::make_optional(value);
@@ -455,7 +469,9 @@ Mechanics::~Mechanics() = default;
 BaseMechanics::BaseMechanics(const IBattleCast * event)
 	: Mechanics(),
 	owner(event->getSpell()),
-	mode(event->getMode())
+	mode(event->getMode()),
+	smart(event->isSmart()),
+	massive(event->isMassive())
 {
 	cb = event->getBattle();
 	caster = event->getCaster();
@@ -612,14 +628,28 @@ int32_t BaseMechanics::getSpellLevel() const
 
 bool BaseMechanics::isSmart() const
 {
-	const CSpell::TargetInfo targetInfo(owner, getRangeLevel(), mode);
-	return targetInfo.smart;
+	if(boost::logic::indeterminate(smart))
+	{
+		const CSpell::TargetInfo targetInfo(owner, getRangeLevel(), mode);
+		return targetInfo.smart;
+	}
+	else
+	{
+		return smart;
+	}
 }
 
 bool BaseMechanics::isMassive() const
 {
-	const CSpell::TargetInfo targetInfo(owner, getRangeLevel(), mode);
-	return targetInfo.massive;
+	if(boost::logic::indeterminate(massive))
+	{
+		const CSpell::TargetInfo targetInfo(owner, getRangeLevel(), mode);
+		return targetInfo.massive;
+	}
+	else
+	{
+		return massive;
+	}
 }
 
 bool BaseMechanics::requiresClearTiles() const

+ 13 - 2
lib/spells/ISpellMechanics.h

@@ -74,7 +74,6 @@ private:
 	IBattleState * battleState;
 };
 
-
 class DLL_LINKAGE IBattleCast
 {
 public:
@@ -96,6 +95,9 @@ public:
 	virtual OptionalValue getEffectDuration() const = 0;
 
 	virtual OptionalValue64 getEffectValue() const = 0;
+
+	virtual boost::logic::tribool isSmart() const = 0;
+	virtual boost::logic::tribool isMassive() const = 0;
 };
 
 ///all parameters of particular cast event
@@ -104,6 +106,9 @@ class DLL_LINKAGE BattleCast : public IBattleCast
 public:
 	Target target;
 
+	boost::logic::tribool smart;
+	boost::logic::tribool massive;
+
 	//normal constructor
 	BattleCast(const CBattleInfoCallback * cb, const Caster * caster_, const Mode mode_, const CSpell * spell_);
 
@@ -126,6 +131,9 @@ public:
 
 	OptionalValue64 getEffectValue() const override;
 
+	boost::logic::tribool isSmart() const override;
+	boost::logic::tribool isMassive() const override;
+
 	void setSpellLevel(Value value);
 	void setEffectLevel(Value value);
 	void setRangeLevel(Value value);
@@ -306,8 +314,8 @@ public:
 protected:
 	const CSpell * owner;
 	Mode mode;
-private:
 
+private:
     IBattleCast::Value rangeLevel;
 	IBattleCast::Value effectLevel;
 
@@ -318,6 +326,9 @@ private:
 
 	///raw damage/heal amount
 	IBattleCast::Value64 effectValue;
+
+	boost::logic::tribool smart;
+	boost::logic::tribool massive;
 };
 
 class DLL_LINKAGE IReceptiveCheck

+ 3 - 0
server/CGameHandler.cpp

@@ -4818,6 +4818,8 @@ void CGameHandler::stackTurnTrigger(const CStack *st)
 				});
 				spells::BattleCast parameters(gs->curB, st, spells::Mode::ENCHANTER, spell);
 				parameters.setSpellLevel(bonus->val);
+				parameters.massive = true;
+				parameters.smart = true;
 				//todo: recheck effect level
 				if(parameters.castIfPossible(spellEnv))
 				{
@@ -5985,6 +5987,7 @@ void CGameHandler::runBattle()
 				spells::BattleCast parameters(gs->curB, h, spells::Mode::PASSIVE, spell);
 				parameters.setSpellLevel(3);
 				parameters.setEffectDuration(b->val);
+				parameters.massive = true;
 				parameters.castIfPossible(spellEnv);
 			}
 		}