浏览代码

get rid of CBattleInfoCallback::battleStackIsImmune

AlexVinS 11 年之前
父节点
当前提交
e4b726151d
共有 5 个文件被更改,包括 40 次插入38 次删除
  1. 1 1
      AI/BattleAI/BattleAI.cpp
  2. 4 26
      lib/CBattleCallback.cpp
  3. 0 4
      lib/CBattleCallback.h
  4. 33 5
      lib/CSpellHandler.cpp
  5. 2 2
      server/CGameHandler.cpp

+ 1 - 1
AI/BattleAI/BattleAI.cpp

@@ -461,7 +461,7 @@ void CBattleAI::attemptCastingSpell()
 				auto stacksSuffering = cb->getAffectedCreatures(ps.spell, skillLevel, playerID, ps.dest);
 				vstd::erase_if(stacksSuffering, [&](const CStack * s) -> bool
 				{
-					return  ESpellCastProblem::OK != cb->battleStackIsImmune(hero, ps.spell, ECastingMode::HERO_CASTING, s);
+					return  ESpellCastProblem::OK !=  ps.spell->isImmuneByStack(hero, ECastingMode::HERO_CASTING, s);
 				});
 
 				if(stacksSuffering.empty())

+ 4 - 26
lib/CBattleCallback.cpp

@@ -1582,7 +1582,7 @@ ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleIsImmune(const C
 		
 		for(auto s : stacks)
 		{
-			ESpellCastProblem::ESpellCastProblem res = battleStackIsImmune(caster,spell,mode,s);
+			ESpellCastProblem::ESpellCastProblem res = spell->isImmuneByStack(caster,mode,s);
 			
 			if(res == ESpellCastProblem::OK)
 			{
@@ -1619,28 +1619,6 @@ ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleIsImmune(const C
 	return ESpellCastProblem::OK;
 }
 
-ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleStackIsImmune(const CGHeroInstance * caster, const CSpell * spell, ECastingMode::ECastingMode mode, const CStack * subject) const
-{
-	const auto immuneResult = spell->isImmuneByStack(caster, mode, subject);
-	
-	if (ESpellCastProblem::NOT_DECIDED != immuneResult) 
-		return immuneResult;
-
-	//TODO: move to spellhandler
-	if(spell->id == SpellID::HYPNOTIZE && caster) //do not resist hypnotize casted after attack, for example
-	{
-		//TODO: what with other creatures casting hypnotize, Faerie Dragons style?
-		ui64 subjectHealth = (subject->count - 1) * subject->MaxHealth() + subject->firstHPleft;
-		//apply 'damage' bonus for hypnotize, including hero specialty
-		ui64 maxHealth = spell->calculateBonus (caster->getPrimSkillLevel(PrimarySkill::SPELL_POWER)
-			* spell->power + spell->getPower(caster->getSpellSchoolLevel(spell)), caster, subject);
-		if (subjectHealth > maxHealth)
-			return ESpellCastProblem::STACK_IMMUNE_TO_SPELL;
-	}	
-		
-	return ESpellCastProblem::OK;
-}
-
 ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleCanCastThisSpell( PlayerColor player, const CSpell * spell, ECastingMode::ECastingMode mode ) const
 {
 	RETURN_IF_NOT_BATTLE(ESpellCastProblem::INVALID);
@@ -1683,7 +1661,7 @@ ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleCanCastThisSpell
 		auto stacks = spell->isNegative() ? battleAliveStacks(!side) : battleAliveStacks();
 		for(auto stack : stacks)
 		{
-			if( ESpellCastProblem::OK == battleStackIsImmune(castingHero, spell, mode, stack))
+			if(ESpellCastProblem::OK == spell->isImmuneByStack(castingHero, mode, stack))
 			{
 				allStacksImmune = false;
 				break;
@@ -1727,7 +1705,7 @@ ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleCanCastThisSpell
 
             for(const CStack * stack : battleGetAllStacks()) //dead stacks will be immune anyway
 			{
-				bool immune =  ESpellCastProblem::OK != battleStackIsImmune(caster, spell, mode, stack);
+				bool immune =  ESpellCastProblem::OK != spell->isImmuneByStack(caster, mode, stack);
 				bool casterStack = stack->owner == caster->getOwner();
 				
                 if(spell->id == SpellID::SACRIFICE)
@@ -1796,7 +1774,7 @@ std::vector<BattleHex> CBattleInfoCallback::battleGetPossibleTargets(PlayerColor
 			
 			for(const CStack * stack : battleAliveStacks())
 			{
-				bool immune = ESpellCastProblem::OK != battleStackIsImmune(caster, spell, mode, stack);
+				bool immune = ESpellCastProblem::OK != spell->isImmuneByStack(caster, mode, stack);
 				bool casterStack = stack->owner == caster->getOwner();
 				
 				if(!immune)

+ 0 - 4
lib/CBattleCallback.h

@@ -290,10 +290,6 @@ public:
 	SpellID getRandomBeneficialSpell(const CStack * subject) const;
 	SpellID getRandomCastedSpell(const CStack * caster) const; //called at the beginning of turn for Faerie Dragon
 
-	//checks for creature immunity / anything that prevent casting *at given hex* - doesn't take into acount general problems such as not having spellbook or mana points etc.
-	ESpellCastProblem::ESpellCastProblem battleStackIsImmune(const CGHeroInstance * caster, const CSpell * spell, ECastingMode::ECastingMode mode, const CStack * subject) const; 
-
-
 	const CStack * getStackIf(std::function<bool(const CStack*)> pred) const;
 
 	si8 battleHasShootingPenalty(const CStack * stack, BattleHex destHex)

+ 33 - 5
lib/CSpellHandler.cpp

@@ -166,6 +166,13 @@ namespace
 		ESpellCastProblem::ESpellCastProblem isImmuneByStack(const CGHeroInstance * caster, ECastingMode::ECastingMode mode, const CStack * obj) override;	
 	};
 	
+	class HypnotizeMechanics: public CSpellMechanics
+	{
+	public:
+		HypnotizeMechanics(CSpell * s): CSpellMechanics(s){};	
+		ESpellCastProblem::ESpellCastProblem isImmuneByStack(const CGHeroInstance * caster, ECastingMode::ECastingMode mode, const CStack * obj) override;	
+	};
+	
 	///all rising spells
 	class RisingSpellMechanics: public CSpellMechanics
 	{
@@ -185,7 +192,7 @@ namespace
 	class SacrificeMechanics: public RisingSpellMechanics
 	{
 	public:
-		
+		SacrificeMechanics(CSpell * s): RisingSpellMechanics(s){};		
 	};
 	
 	///CloneMechanics
@@ -239,6 +246,23 @@ namespace
 		return CSpellMechanics::isImmuneByStack(caster,mode,obj);	
 	}
 	
+	///HypnotizeMechanics
+	ESpellCastProblem::ESpellCastProblem HypnotizeMechanics::isImmuneByStack(const CGHeroInstance* caster, ECastingMode::ECastingMode mode, const CStack* obj)
+	{
+		if(nullptr != caster) //do not resist hypnotize casted after attack, for example
+		{
+			//TODO: what with other creatures casting hypnotize, Faerie Dragons style?
+			ui64 subjectHealth = (obj->count - 1) * obj->MaxHealth() + obj->firstHPleft;
+			//apply 'damage' bonus for hypnotize, including hero specialty
+			ui64 maxHealth = owner->calculateBonus(caster->getPrimSkillLevel(PrimarySkill::SPELL_POWER)
+				* owner->power + owner->getPower(caster->getSpellSchoolLevel(owner)), caster, obj);
+			if (subjectHealth > maxHealth)
+				return ESpellCastProblem::STACK_IMMUNE_TO_SPELL;
+		}			
+		return CSpellMechanics::isImmuneByStack(caster,mode,obj);
+	}
+	
+	
 	///SpecialRisingSpellMechanics
 	ESpellCastProblem::ESpellCastProblem SpecialRisingSpellMechanics::isImmuneByStack(const CGHeroInstance* caster, ECastingMode::ECastingMode mode, const CStack* obj)
 	{
@@ -250,7 +274,7 @@ namespace
 		
 		if (caster) //FIXME: Archangels can cast immune stack
 		{
-			auto maxHealth = calculateHealedHP (caster, obj);
+			auto maxHealth = owner->calculateHealedHP (caster, obj);
 			if (maxHealth < obj->MaxHealth()) //must be able to rise at least one full creature
 				return ESpellCastProblem::STACK_IMMUNE_TO_SPELL;
 		}	
@@ -346,7 +370,7 @@ ui32 CSpell::calculateHealedHP(const CGHeroInstance* caster, const CStack* stack
 	if (id == SpellID::SACRIFICE && sacrificedStack)
 		healedHealth = (spellPowerSkill + sacrificedStack->MaxHealth() + levelPower) * sacrificedStack->count;
 	else
-		healedHealth = spellPowerSkill * power + levelPower); //???
+		healedHealth = spellPowerSkill * power + levelPower; //???
 	healedHealth = calculateBonus(healedHealth, caster, stack);
 	return std::min<ui32>(healedHealth, stack->MaxHealth() - stack->firstHPleft + (isRisingSpell() ? stack->baseAmount * stack->MaxHealth() : 0));	
 }
@@ -684,7 +708,11 @@ ESpellCastProblem::ESpellCastProblem CSpell::isImmuneBy(const IBonusBearer* obj)
 
 ESpellCastProblem::ESpellCastProblem CSpell::isImmuneByStack(const CGHeroInstance* caster, ECastingMode::ECastingMode mode, const CStack* obj) const
 {
-	return mechanics->isImmuneByStack(caster,mode,obj);
+	const auto immuneResult = mechanics->isImmuneByStack(caster,mode,obj);
+	
+	if (ESpellCastProblem::NOT_DECIDED != immuneResult) 
+		return immuneResult;
+	return ESpellCastProblem::OK;	
 }
 
 
@@ -728,7 +756,7 @@ void CSpell::setupMechanics()
 		break;
 	case SpellID::SACRIFICE:
 		mechanics = new SacrificeMechanics(this);
-		break
+		break;
 	default:		
 		if(isRisingSpell())
 			mechanics = new SpecialRisingSpellMechanics(this);

+ 2 - 2
server/CGameHandler.cpp

@@ -4040,7 +4040,7 @@ void CGameHandler::handleSpellCasting( SpellID spellID, int spellLvl, BattleHex
 	}
 
 	vstd::erase_if(attackedCres,[=](const CStack * s){
-		return ESpellCastProblem::OK != gs->curB->battleStackIsImmune(caster,spell,mode,s);		
+		return ESpellCastProblem::OK != spell->isImmuneByStack(caster,mode,s);		
 	});
 
 	for (auto cre : attackedCres)
@@ -4453,7 +4453,7 @@ void CGameHandler::handleSpellCasting( SpellID spellID, int spellLvl, BattleHex
 				{
 					if(battleStack->owner == gs->curB->sides.at(casterSide).color) //get enemy stacks which can be affected by this spell
 					{
-						if (ESpellCastProblem::OK == gs->curB->battleStackIsImmune(nullptr, spell, ECastingMode::MAGIC_MIRROR, battleStack))
+						if (ESpellCastProblem::OK == spell->isImmuneByStack(nullptr, ECastingMode::MAGIC_MIRROR, battleStack))
 							mirrorTargets.push_back(battleStack);
 					}
 				}