Ver Fonte

formatting

AlexVinS há 10 anos atrás
pai
commit
5fda2aac9a

+ 35 - 36
lib/spells/AdventureSpellMechanics.cpp

@@ -22,7 +22,7 @@
 ///SummonBoatMechanics
 bool SummonBoatMechanics::applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const
 {
-	const int schoolLevel = parameters.caster->getSpellSchoolLevel(owner);	
+	const int schoolLevel = parameters.caster->getSpellSchoolLevel(owner);
 	//check if spell works at all
 	if(env->getRandomGenerator().nextInt(99) >= owner->getPower(schoolLevel)) //power is % chance of success
 	{
@@ -42,14 +42,14 @@ bool SummonBoatMechanics::applyAdventureEffects(const SpellCastEnvironment * env
 	{
 		env->complain("There is no water tile available!");
 		return false;
-	}	
-	
+	}
+
 	for(const CGObjectInstance * obj : env->getMap()->objects)
 	{
 		if(obj && obj->ID == Obj::BOAT)
 		{
 			const CGBoat *b = static_cast<const CGBoat*>(obj);
-			if(b->hero) 
+			if(b->hero)
 				continue; //we're looking for unoccupied boat
 
 			double nDist = b->pos.dist2d(parameters.caster->getPosition());
@@ -58,7 +58,7 @@ bool SummonBoatMechanics::applyAdventureEffects(const SpellCastEnvironment * env
 				nearest = b;
 				dist = nDist;
 			}
-		}						
+		}
 	}
 
 	if(nullptr != nearest) //we found boat to summon
@@ -83,8 +83,8 @@ bool SummonBoatMechanics::applyAdventureEffects(const SpellCastEnvironment * env
 		no.subID = parameters.caster->getBoatType();
 		no.pos = summonPos + int3(1,0,0);;
 		env->sendAndApply(&no);
-	}	
-	return true;	
+	}
+	return true;
 }
 
 ///ScuttleBoatMechanics
@@ -101,7 +101,7 @@ bool ScuttleBoatMechanics::applyAdventureEffects(const SpellCastEnvironment* env
 		env->sendAndApply(&iw);
 		return true;
 	}
-		
+
 	if(!env->getMap()->isInTheMap(parameters.pos))
 	{
 		env->complain("Invalid dst tile for scuttle!");
@@ -115,12 +115,11 @@ bool ScuttleBoatMechanics::applyAdventureEffects(const SpellCastEnvironment* env
 		env->complain("There is no boat to scuttle!");
 		return false;
 	}
-		
 
 	RemoveObject ro;
 	ro.id = t->visitableObjects.back()->id;
 	env->sendAndApply(&ro);
-	return true;	
+	return true;
 }
 
 ///DimensionDoorMechanics
@@ -130,8 +129,8 @@ bool DimensionDoorMechanics::applyAdventureEffects(const SpellCastEnvironment* e
 	{
 		env->complain("Destination is out of map!");
 		return false;
-	}	
-	
+	}
+
 	const TerrainTile * dest = env->getCb()->getTile(parameters.pos);
 	const TerrainTile * curr = env->getCb()->getTile(parameters.caster->getSightCenter());
 
@@ -140,21 +139,21 @@ bool DimensionDoorMechanics::applyAdventureEffects(const SpellCastEnvironment* e
 		env->complain("Destination tile doesn't exist!");
 		return false;
 	}
-	
+
 	if(nullptr == curr)
 	{
 		env->complain("Source tile doesn't exist!");
 		return false;
-	}	
-		
+	}
+
 	if(parameters.caster->movement <= 0)
 	{
 		env->complain("Hero needs movement points to cast Dimension Door!");
 		return false;
 	}
-	
+
 	const int schoolLevel = parameters.caster->getSpellSchoolLevel(owner);
-			
+
 	if(parameters.caster->getBonusesCount(Bonus::SPELL_EFFECT, SpellID::DIMENSION_DOOR) >= owner->getPower(schoolLevel)) //limit casts per turn
 	{
 		InfoWindow iw;
@@ -175,7 +174,7 @@ bool DimensionDoorMechanics::applyAdventureEffects(const SpellCastEnvironment* e
 		InfoWindow iw;
 		iw.player = parameters.caster->tempOwner;
 		iw.text.addTxt(MetaString::GENERAL_TXT, 70); //Dimension Door failed!
-		env->sendAndApply(&iw);		
+		env->sendAndApply(&iw);
 	}
 	else if(env->moveHero(parameters.caster->id, parameters.pos + parameters.caster->getVisitableOffset(), true))
 	{
@@ -184,7 +183,7 @@ bool DimensionDoorMechanics::applyAdventureEffects(const SpellCastEnvironment* e
 		smp.val = std::max<ui32>(0, parameters.caster->movement - 300);
 		env->sendAndApply(&smp);
 	}
-	return true; 	
+	return true;
 }
 
 ///TownPortalMechanics
@@ -194,28 +193,28 @@ bool TownPortalMechanics::applyAdventureEffects(const SpellCastEnvironment * env
 	{
 		env->complain("Destination tile not present!");
 		return false;
-	}	
+	}
 
 	TerrainTile tile = env->getMap()->getTile(parameters.pos);
 	if (tile.visitableObjects.empty() || tile.visitableObjects.back()->ID != Obj::TOWN)
 	{
-		env->complain("Town not found for Town Portal!");	
+		env->complain("Town not found for Town Portal!");
 		return false;
-	}		
+	}
 
 	CGTownInstance * town = static_cast<CGTownInstance*>(tile.visitableObjects.back());
 	if (town->tempOwner != parameters.caster->tempOwner)
 	{
 		env->complain("Can't teleport to another player!");
 		return false;
-	}			
-	
+	}
+
 	if (town->visitingHero)
 	{
 		env->complain("Can't teleport to occupied town!");
 		return false;
 	}
-	
+
 	if (parameters.caster->getSpellSchoolLevel(owner) < 2)
 	{
 		si32 dist = town->pos.dist2dSQ(parameters.caster->pos);
@@ -234,31 +233,31 @@ bool TownPortalMechanics::applyAdventureEffects(const SpellCastEnvironment * env
 			env->complain("This hero can only teleport to nearest town!");
 			return false;
 		}
-			
+
 	}
-	env->moveHero(parameters.caster->id, town->visitablePos() + parameters.caster->getVisitableOffset() ,1);	
+	env->moveHero(parameters.caster->id, town->visitablePos() + parameters.caster->getVisitableOffset() ,1);
 	return true;
 }
 
 bool ViewMechanics::applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const
 {
 	ShowWorldViewEx pack;
-	
+
 	pack.player = parameters.caster->tempOwner;
-	
+
 	const int spellLevel = parameters.caster->getSpellSchoolLevel(owner);
-	
+
 	for(const CGObjectInstance * obj : env->getMap()->objects)
 	{
-		//we need to send only not visible objects
-		
+		//todo:we need to send only not visible objects
+
 		if(filterObject(obj, spellLevel))
 			pack.objectPositions.push_back(ObjectPosInfo(obj));
-	}	
-	
+	}
+
 	env->sendAndApply(&pack);
-	
-	return true;	
+
+	return true;
 }
 
 bool ViewAirMechanics::filterObject(const CGObjectInstance * obj, const int spellLevel) const

+ 25 - 26
lib/spells/AdventureSpellMechanics.h

@@ -7,67 +7,66 @@
  * Full text of license available in license.txt file, in main folder
  *
  */
- 
- #pragma once
- 
- #include "CDefaultSpellMechanics.h"
 
+#pragma once
 
-class SummonBoatMechanics: public DefaultSpellMechanics 
+#include "CDefaultSpellMechanics.h"
+
+class SummonBoatMechanics: public DefaultSpellMechanics
 {
 public:
 	SummonBoatMechanics(CSpell * s): DefaultSpellMechanics(s){};
 protected:
-	bool applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const override;	
+	bool applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const override;
 };
 
-class ScuttleBoatMechanics: public DefaultSpellMechanics 
+class ScuttleBoatMechanics: public DefaultSpellMechanics
 {
 public:
 	ScuttleBoatMechanics(CSpell * s): DefaultSpellMechanics(s){};
 protected:
-	bool applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const override;	
+	bool applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const override;
 };
 
-class DimensionDoorMechanics: public DefaultSpellMechanics 
+class DimensionDoorMechanics: public DefaultSpellMechanics
 {
-public:	
-	DimensionDoorMechanics(CSpell * s): DefaultSpellMechanics(s){};	
+public:
+	DimensionDoorMechanics(CSpell * s): DefaultSpellMechanics(s){};
 protected:
-	bool applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const override;	
+	bool applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const override;
 };
 
-class TownPortalMechanics: public DefaultSpellMechanics 
+class TownPortalMechanics: public DefaultSpellMechanics
 {
-public:	
-	TownPortalMechanics(CSpell * s): DefaultSpellMechanics(s){};	
+public:
+	TownPortalMechanics(CSpell * s): DefaultSpellMechanics(s){};
 protected:
-	bool applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const override;	
+	bool applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const override;
 };
 
-class ViewMechanics: public DefaultSpellMechanics 
+class ViewMechanics: public DefaultSpellMechanics
 {
-public:	
+public:
 	ViewMechanics(CSpell * s): DefaultSpellMechanics(s){};
 protected:
-	bool applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const override;	
+	bool applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const override;
 	virtual bool filterObject(const CGObjectInstance * obj, const int spellLevel) const = 0;
 };
 
-class ViewAirMechanics: public ViewMechanics 
+class ViewAirMechanics: public ViewMechanics
 {
-public:	
-	ViewAirMechanics(CSpell * s): ViewMechanics(s){};	
+public:
+	ViewAirMechanics(CSpell * s): ViewMechanics(s){};
 protected:
 	bool filterObject(const CGObjectInstance * obj, const int spellLevel) const override;
 };
 
-class ViewEarthMechanics: public ViewMechanics 
+class ViewEarthMechanics: public ViewMechanics
 {
-public:	
-	ViewEarthMechanics(CSpell * s): ViewMechanics(s){};	
+public:
+	ViewEarthMechanics(CSpell * s): ViewMechanics(s){};
 protected:
-	bool filterObject(const CGObjectInstance * obj, const int spellLevel) const override;	
+	bool filterObject(const CGObjectInstance * obj, const int spellLevel) const override;
 };
 
 

+ 28 - 30
lib/spells/BattleSpellMechanics.cpp

@@ -7,7 +7,6 @@
  * Full text of license available in license.txt file, in main folder
  *
  */
-
 #include "StdInc.h"
 
 #include "BattleSpellMechanics.h"
@@ -19,7 +18,7 @@
 std::set<const CStack *> ChainLightningMechanics::getAffectedStacks(SpellTargetingContext & ctx) const
 {
 	std::set<const CStack* > attackedCres;
-	
+
 	std::set<BattleHex> possibleHexes;
 	for(auto stack : ctx.cb->battleGetAllStacks())
 	{
@@ -47,8 +46,8 @@ std::set<const CStack *> ChainLightningMechanics::getAffectedStacks(SpellTargeti
 		if(possibleHexes.empty()) //not enough targets
 			break;
 		lightningHex = BattleHex::getClosestTile(stack->attackerOwned, ctx.destination, possibleHexes);
-	}	
-		
+	}
+
 	return attackedCres;
 }
 
@@ -63,7 +62,7 @@ void CloneMechanics::applyBattleEffects(const SpellCastEnvironment * env, Battle
 		env->complain ("No target stack to clone!");
 		return;
 	}
-	const int attacker = !(bool)parameters.casterSide; 
+	const int attacker = !(bool)parameters.casterSide;
 
 	BattleStackAdded bsa;
 	bsa.creID = clonedStack->type->idNumber;
@@ -78,7 +77,7 @@ void CloneMechanics::applyBattleEffects(const SpellCastEnvironment * env, Battle
 	ssp.which = BattleSetStackProperty::CLONED;
 	ssp.val = 0;
 	ssp.absolute = 1;
-	env->sendAndApply(&ssp);	
+	env->sendAndApply(&ssp);
 }
 
 ESpellCastProblem::ESpellCastProblem CloneMechanics::isImmuneByStack(const CGHeroInstance * caster, const CStack * obj) const
@@ -105,22 +104,22 @@ ESpellCastProblem::ESpellCastProblem CloneMechanics::isImmuneByStack(const CGHer
 		if(maxLevel < creLevel) //tier 1-5 for basic, 1-6 for advanced, any level for expert
 			return ESpellCastProblem::STACK_IMMUNE_TO_SPELL;
 	}
-	//use default algorithm only if there is no mechanics-related problem		
-	return DefaultSpellMechanics::isImmuneByStack(caster, obj);	
+	//use default algorithm only if there is no mechanics-related problem
+	return DefaultSpellMechanics::isImmuneByStack(caster, obj);
 }
 
 ///CureMechanics
 void CureMechanics::applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const
 {
 	DefaultSpellMechanics::applyBattle(battle, packet);
-	
+
 	for(auto stackID : packet->affectedCres)
 	{
 		if(vstd::contains(packet->resisted, stackID))
 		{
 			logGlobal->errorStream() << "Resistance to positive spell CURE";
 			continue;
-		}			
+		}
 
 		CStack *s = battle->getStack(stackID);
 		s->popBonuses([&](const Bonus *b) -> bool
@@ -132,14 +131,14 @@ void CureMechanics::applyBattle(BattleInfo * battle, const BattleSpellCast * pac
 			}
 			return false; //not a spell effect
 		});
-	}		
+	}
 }
 
 ///DispellMechanics
 void DispellMechanics::applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const
 {
 	DefaultSpellMechanics::applyBattle(battle, packet);
-	
+
 	for(auto stackID : packet->affectedCres)
 	{
 		if(vstd::contains(packet->resisted, stackID))
@@ -150,7 +149,7 @@ void DispellMechanics::applyBattle(BattleInfo * battle, const BattleSpellCast *
 		{
 			return Selector::sourceType(Bonus::SPELL_EFFECT)(b);
 		});
-	}	
+	}
 }
 
 
@@ -166,7 +165,7 @@ ESpellCastProblem::ESpellCastProblem HypnotizeMechanics::isImmuneByStack(const C
 			* owner->power + owner->getPower(caster->getSpellSchoolLevel(owner)), caster, obj);
 		if (subjectHealth > maxHealth)
 			return ESpellCastProblem::STACK_IMMUNE_TO_SPELL;
-	}			
+	}
 	return DefaultSpellMechanics::isImmuneByStack(caster, obj);
 }
 
@@ -217,8 +216,8 @@ void ObstacleMechanics::applyBattleEffects(const SpellCastEnvironment * env, Bat
 		BattleObstaclePlaced bop;
 		bop.obstacle = obstacle;
 		env->sendAndApply(&bop);
-	};	
-	
+	};
+
 	switch(owner->id)
 	{
 	case SpellID::QUICKSAND:
@@ -253,17 +252,17 @@ void ObstacleMechanics::applyBattleEffects(const SpellCastEnvironment * env, Bat
 				placeObstacle(hex);
 		}
 		break;
-	default:		
+	default:
 		assert(0);
-	}			
+	}
 }
 
 
 ///WallMechanics
 std::vector<BattleHex> WallMechanics::rangeInHexes(BattleHex centralHex, ui8 schoolLvl, ui8 side, bool * outDroppedHexes) const
 {
-	std::vector<BattleHex> ret;	
-	
+	std::vector<BattleHex> ret;
+
 	//Special case - shape of obstacle depends on caster's side
 	//TODO make it possible through spell config
 
@@ -293,7 +292,7 @@ std::vector<BattleHex> WallMechanics::rangeInHexes(BattleHex centralHex, ui8 sch
 	if(schoolLvl >= 2) //advanced versions of fire wall / force field cotnains of 3 hexes
 		addIfValid(centralHex.moveInDir(secondStep, false)); //moveInDir function modifies subject hex
 
-	return ret;	
+	return ret;
 }
 
 ///RemoveObstacleMechanics
@@ -306,7 +305,7 @@ void RemoveObstacleMechanics::applyBattleEffects(const SpellCastEnvironment * en
 		env->sendAndApply(&obr);
 	}
 	else
-		env->complain("There's no obstacle to remove!");	
+		env->complain("There's no obstacle to remove!");
 }
 
 ///SpecialRisingSpellMechanics
@@ -338,7 +337,6 @@ void SacrificeMechanics::applyBattleEffects(const SpellCastEnvironment * env, Ba
 	BattleStacksRemoved bsr;
 	bsr.stackIDs.insert(parameters.selectedStack->ID); //somehow it works for teleport?
 	env->sendAndApply(&bsr);
-		
 }
 
 
@@ -350,15 +348,15 @@ ESpellCastProblem::ESpellCastProblem SpecialRisingSpellMechanics::isImmuneByStac
 
 	if(obj->count >= obj->baseAmount)
 		return ESpellCastProblem::STACK_IMMUNE_TO_SPELL;
-	
+
 	if(caster) //FIXME: Archangels can cast immune stack
 	{
 		auto maxHealth = calculateHealedHP(caster, obj, nullptr);
 		if (maxHealth < obj->MaxHealth()) //must be able to rise at least one full creature
 			return ESpellCastProblem::STACK_IMMUNE_TO_SPELL;
-	}	
-	
-	return DefaultSpellMechanics::isImmuneByStack(caster,obj);	
+	}
+
+	return DefaultSpellMechanics::isImmuneByStack(caster,obj);
 }
 
 ///SummonMechanics
@@ -400,7 +398,7 @@ void SummonMechanics::applyBattleEffects(const SpellCastEnvironment * env, Battl
 	if(bsa.amount)
 		env->sendAndApply(&bsa);
 	else
-		env->complain("Summoning didn't summon any!");	
+		env->complain("Summoning didn't summon any!");
 }
 
 
@@ -414,6 +412,6 @@ void TeleportMechanics::applyBattleEffects(const SpellCastEnvironment * env, Bat
 	tiles.push_back(parameters.destination);
 	bsm.tilesToMove = tiles;
 	bsm.teleporting = true;
-	env->sendAndApply(&bsm);	
+	env->sendAndApply(&bsm);
 }
-	
+

+ 25 - 28
lib/spells/BattleSpellMechanics.h

@@ -7,16 +7,15 @@
  * Full text of license available in license.txt file, in main folder
  *
  */
- 
- #pragma once
- 
- #include "CDefaultSpellMechanics.h"
 
+#pragma once
+
+#include "CDefaultSpellMechanics.h"
 
 class ChainLightningMechanics: public DefaultSpellMechanics
 {
 public:
-	ChainLightningMechanics(CSpell * s): DefaultSpellMechanics(s){};	
+	ChainLightningMechanics(CSpell * s): DefaultSpellMechanics(s){};
 	std::set<const CStack *> getAffectedStacks(SpellTargetingContext & ctx) const override;
 };
 
@@ -26,48 +25,46 @@ public:
 	CloneMechanics(CSpell * s): DefaultSpellMechanics(s){};
 	ESpellCastProblem::ESpellCastProblem isImmuneByStack(const CGHeroInstance * caster, const CStack * obj) const override;
 protected:
-	void applyBattleEffects(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;	
+	void applyBattleEffects(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
 };
 
 class CureMechanics: public DefaultSpellMechanics
 {
 public:
-	CureMechanics(CSpell * s): DefaultSpellMechanics(s){};	
-	
-	void applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const override;	
-};
-
+	CureMechanics(CSpell * s): DefaultSpellMechanics(s){};
 
+	void applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const override;
+};
 
 class DispellMechanics: public DefaultSpellMechanics
 {
 public:
 	DispellMechanics(CSpell * s): DefaultSpellMechanics(s){};
-	
-	void applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const override;	
+
+	void applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const override;
 };
 
 class HypnotizeMechanics: public DefaultSpellMechanics
 {
 public:
-	HypnotizeMechanics(CSpell * s): DefaultSpellMechanics(s){};	
-	ESpellCastProblem::ESpellCastProblem isImmuneByStack(const CGHeroInstance * caster, const CStack * obj) const override;	
-}; 
+	HypnotizeMechanics(CSpell * s): DefaultSpellMechanics(s){};
+	ESpellCastProblem::ESpellCastProblem isImmuneByStack(const CGHeroInstance * caster, const CStack * obj) const override;
+};
 
 class ObstacleMechanics: public DefaultSpellMechanics
 {
 public:
-	ObstacleMechanics(CSpell * s): DefaultSpellMechanics(s){};		
+	ObstacleMechanics(CSpell * s): DefaultSpellMechanics(s){};
 
 protected:
-	void applyBattleEffects(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;	
+	void applyBattleEffects(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
 };
 
 class WallMechanics: public ObstacleMechanics
 {
 public:
-	WallMechanics(CSpell * s): ObstacleMechanics(s){};	
-	std::vector<BattleHex> rangeInHexes(BattleHex centralHex, ui8 schoolLvl, ui8 side, bool *outDroppedHexes = nullptr) const override;		
+	WallMechanics(CSpell * s): ObstacleMechanics(s){};
+	std::vector<BattleHex> rangeInHexes(BattleHex centralHex, ui8 schoolLvl, ui8 side, bool *outDroppedHexes = nullptr) const override;
 };
 
 class RemoveObstacleMechanics: public DefaultSpellMechanics
@@ -75,23 +72,23 @@ class RemoveObstacleMechanics: public DefaultSpellMechanics
 public:
 	RemoveObstacleMechanics(CSpell * s): DefaultSpellMechanics(s){};
 protected:
-	void applyBattleEffects(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;		
+	void applyBattleEffects(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
 };
 
 ///all rising spells
 class RisingSpellMechanics: public DefaultSpellMechanics
 {
 public:
-	RisingSpellMechanics(CSpell * s): DefaultSpellMechanics(s){};		
-	
+	RisingSpellMechanics(CSpell * s): DefaultSpellMechanics(s){};
+
 };
 
 class SacrificeMechanics: public RisingSpellMechanics
 {
 public:
-	SacrificeMechanics(CSpell * s): RisingSpellMechanics(s){};	
+	SacrificeMechanics(CSpell * s): RisingSpellMechanics(s){};
 protected:
-	void applyBattleEffects(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;		
+	void applyBattleEffects(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
 };
 
 ///all rising spells but SACRIFICE
@@ -99,7 +96,7 @@ class SpecialRisingSpellMechanics: public RisingSpellMechanics
 {
 public:
 	SpecialRisingSpellMechanics(CSpell * s): RisingSpellMechanics(s){};
-	ESpellCastProblem::ESpellCastProblem isImmuneByStack(const CGHeroInstance * caster, const CStack * obj) const override;						
+	ESpellCastProblem::ESpellCastProblem isImmuneByStack(const CGHeroInstance * caster, const CStack * obj) const override;
 };
 
 class SummonMechanics: public DefaultSpellMechanics
@@ -107,7 +104,7 @@ class SummonMechanics: public DefaultSpellMechanics
 public:
 	SummonMechanics(CSpell * s): DefaultSpellMechanics(s){};
 protected:
-	void applyBattleEffects(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;		
+	void applyBattleEffects(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
 };
 
 class TeleportMechanics: public DefaultSpellMechanics
@@ -115,5 +112,5 @@ class TeleportMechanics: public DefaultSpellMechanics
 public:
 	TeleportMechanics(CSpell * s): DefaultSpellMechanics(s){};
 protected:
-	void applyBattleEffects(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;		
+	void applyBattleEffects(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
 };

+ 67 - 73
lib/spells/CDefaultSpellMechanics.cpp

@@ -117,7 +117,6 @@ namespace SRSLPraserHelpers
 	}
 }
 
-
 ///DefaultSpellMechanics
 void DefaultSpellMechanics::applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const
 {
@@ -128,7 +127,7 @@ void DefaultSpellMechanics::applyBattle(BattleInfo * battle, const BattleSpellCa
 			battle->sides[packet->side].castSpellsCount++;
 		}
 	}
-	
+
 	//handle countering spells
 	for(auto stackID : packet->affectedCres)
 	{
@@ -144,7 +143,7 @@ void DefaultSpellMechanics::applyBattle(BattleInfo * battle, const BattleSpellCa
 
 			return isSpellEffect && vstd::contains(owner->counteredSpells, spellID);
 		});
-	}	
+	}
 }
 
 bool DefaultSpellMechanics::adventureCast(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const
@@ -154,29 +153,29 @@ bool DefaultSpellMechanics::adventureCast(const SpellCastEnvironment * env, Adve
 		env->complain("Attempt to cast non adventure spell in adventure mode");
 		return false;
 	}
-	
+
 	const CGHeroInstance * caster = parameters.caster;
 	const int cost = caster->getSpellCost(owner);
-	
+
 	if(!caster->canCastThisSpell(owner))
 	{
 		env->complain("Hero cannot cast this spell!");
-		return false;		
+		return false;
 	}
 
 	if(caster->mana < cost)
 	{
 		env->complain("Hero doesn't have enough spell points to cast this spell!");
-		return false;		
+		return false;
 	}
 
 	{
 		AdvmapSpellCast asc;
 		asc.caster = caster;
 		asc.spellID = owner->id;
-		env->sendAndApply(&asc);		
+		env->sendAndApply(&asc);
 	}
-	
+
 	if(applyAdventureEffects(env, parameters))
 	{
 		SetMana sm;
@@ -194,27 +193,27 @@ bool DefaultSpellMechanics::applyAdventureEffects(const SpellCastEnvironment * e
 	if(owner->hasEffects())
 	{
 		const int schoolLevel = parameters.caster->getSpellSchoolLevel(owner);
-		
+
 		std::vector<Bonus> bonuses;
-		
+
 		owner->getEffects(bonuses, schoolLevel);
-		
+
 		for(Bonus b : bonuses)
 		{
 			GiveBonus gb;
 			gb.id = parameters.caster->id.getNum();
 			gb.bonus = b;
-			env->sendAndApply(&gb);			
+			env->sendAndApply(&gb);
 		}
-		
+
 		return true;
 	}
 	else
 	{
 		//There is no generic algorithm of adventure cast
 		env->complain("Unimplemented adventure spell");
-		return false;				
-	}	
+		return false;
+	}
 }
 
 
@@ -229,11 +228,11 @@ void DefaultSpellMechanics::battleCast(const SpellCastEnvironment * env, BattleS
 	sc.castedByHero = nullptr != parameters.caster;
 	sc.casterStack = (parameters.casterStack ? parameters.casterStack->ID : -1);
 	sc.manaGained = 0;
-	
-	int spellCost = 0;	
-	
+
+	int spellCost = 0;
+
 	//calculate spell cost
-	if(parameters.caster) 
+	if(parameters.caster)
 	{
 		spellCost = parameters.cb->battleGetSpellCost(owner, parameters.caster);
 
@@ -249,21 +248,20 @@ void DefaultSpellMechanics::battleCast(const SpellCastEnvironment * env, BattleS
 			}
 			sc.manaGained = (manaChannel * spellCost) / 100;
 		}
-	}	
-	
-	
+	}
+
 	//calculating affected creatures for all spells
 	//must be vector, as in Chain Lightning order matters
 	std::vector<const CStack*> attackedCres; //CStack vector is somewhat more suitable than ID vector
 
 	auto creatures = owner->getAffectedStacks(parameters.cb, parameters.mode, parameters.casterColor, parameters.spellLvl, parameters.destination, parameters.caster);
 	std::copy(creatures.begin(), creatures.end(), std::back_inserter(attackedCres));
-	
+
 	for (auto cre : attackedCres)
 	{
 		sc.affectedCres.insert(cre->ID);
 	}
-	
+
 	//checking if creatures resist
 	//resistance is applied only to negative spells
 	if(owner->isNegative())
@@ -271,52 +269,51 @@ void DefaultSpellMechanics::battleCast(const SpellCastEnvironment * env, BattleS
 		for(auto s : attackedCres)
 		{
 			const int prob = std::min((s)->magicResistance(), 100); //probability of resistance in %
-			
+
 			if(env->getRandomGenerator().nextInt(99) < prob)
 			{
 				sc.resisted.push_back(s->ID);
 			}
 		}
 	}
-	
-	StacksInjured si;	
+
+	StacksInjured si;
 	SpellCastContext ctx(attackedCres, sc, si);
-	
+
 	applyBattleEffects(env, parameters, ctx);
-	
+
 	env->sendAndApply(&sc);
-	
 
 	//spend mana
-	if(parameters.caster) 
+	if(parameters.caster)
 	{
 		SetMana sm;
 		sm.absolute = false;
-		
+
 		sm.hid = parameters.caster->id;
 		sm.val = -spellCost;
-		
+
 		env->sendAndApply(&sm);
-		
+
 		if(sc.manaGained > 0)
 		{
 			assert(parameters.secHero);
-			
+
 			sm.hid = parameters.secHero->id;
 			sm.val = sc.manaGained;
 			env->sendAndApply(&sm);
-		}		
+		}
 	}
-	
+
 	if(!si.stacks.empty()) //after spellcast info shows
 		env->sendAndApply(&si);
-	
+
 	//reduce number of casts remaining
 	//TODO: this should be part of BattleSpellCast apply
-	if (parameters.mode == ECastingMode::CREATURE_ACTIVE_CASTING || parameters.mode == ECastingMode::ENCHANTER_CASTING) 
+	if (parameters.mode == ECastingMode::CREATURE_ACTIVE_CASTING || parameters.mode == ECastingMode::ENCHANTER_CASTING)
 	{
 		assert(parameters.casterStack);
-		
+
 		BattleSetStackProperty ssp;
 		ssp.stackID = parameters.casterStack->ID;
 		ssp.which = BattleSetStackProperty::CASTS;
@@ -346,7 +343,7 @@ void DefaultSpellMechanics::battleCast(const SpellCastEnvironment * env, BattleS
 				if(!mirrorTargets.empty())
 				{
 					int targetHex = (*RandomGeneratorUtil::nextItem(mirrorTargets, env->getRandomGenerator()))->position;
-					
+
 					BattleSpellCastParameters mirrorParameters = parameters;
 					mirrorParameters.spellLvl = 0;
 					mirrorParameters.casterSide = 1-parameters.casterSide;
@@ -357,12 +354,12 @@ void DefaultSpellMechanics::battleCast(const SpellCastEnvironment * env, BattleS
 					mirrorParameters.mode = ECastingMode::MAGIC_MIRROR;
 					mirrorParameters.casterStack = (attackedCre);
 					mirrorParameters.selectedStack = nullptr;
-					
-					battleCast(env, mirrorParameters);					
+
+					battleCast(env, mirrorParameters);
 				}
 			}
 		}
-	}	
+	}
 }
 
 int DefaultSpellMechanics::calculateDuration(const CGHeroInstance * caster, int usedSpellPower) const
@@ -380,28 +377,28 @@ int DefaultSpellMechanics::calculateDuration(const CGHeroInstance * caster, int
 		return 1;
 	default: //other spells
 		return caster->getPrimSkillLevel(PrimarySkill::SPELL_POWER) + caster->valOfBonuses(Bonus::SPELL_DURATION);
-	}	
+	}
 }
 
 ui32 DefaultSpellMechanics::calculateHealedHP(const CGHeroInstance* caster, const CStack* stack, const CStack* sacrificedStack) const
 {
 	int healedHealth;
-	
+
 	if(!owner->isHealingSpell())
 	{
 		logGlobal->errorStream() << "calculateHealedHP called for nonhealing spell "<< owner->name;
 		return 0;
-	}		
-	
+	}
+
 	const int spellPowerSkill = caster->getPrimSkillLevel(PrimarySkill::SPELL_POWER);
 	const int levelPower = owner->getPower(caster->getSpellSchoolLevel(owner));
-	
+
 	if (owner->id == SpellID::SACRIFICE && sacrificedStack)
 		healedHealth = (spellPowerSkill + sacrificedStack->MaxHealth() + levelPower) * sacrificedStack->count;
 	else
 		healedHealth = spellPowerSkill * owner->power + levelPower; //???
 	healedHealth = owner->calculateBonus(healedHealth, caster, stack);
-	return std::min<ui32>(healedHealth, stack->MaxHealth() - stack->firstHPleft + (owner->isRisingSpell() ? stack->baseAmount * stack->MaxHealth() : 0));		
+	return std::min<ui32>(healedHealth, stack->MaxHealth() - stack->firstHPleft + (owner->isRisingSpell() ? stack->baseAmount * stack->MaxHealth() : 0));
 }
 
 
@@ -448,7 +445,7 @@ void DefaultSpellMechanics::applyBattleEffects(const SpellCastEnvironment * env,
 				++chainLightningModifier;
 		}
 	}
-	
+
 	if(owner->hasEffects())
 	{
 		int stackSpellPower = 0;
@@ -531,7 +528,7 @@ void DefaultSpellMechanics::applyBattleEffects(const SpellCastEnvironment * env,
 			env->sendAndApply(&sse);
 
 	}
-	
+
 	if(owner->isHealingSpell())
 	{
 		int hpGained = 0;
@@ -563,7 +560,7 @@ void DefaultSpellMechanics::applyBattleEffects(const SpellCastEnvironment * env,
 					//any typical spell (commander's cure or animate dead)
 					int healedHealth = parameters.usedSpellPower * owner->power + owner->getPower(parameters.spellLvl);
 					hi.healedHP = std::min<ui32>(healedHealth, attackedCre->MaxHealth() - attackedCre->firstHPleft + (resurrect ? attackedCre->baseAmount * attackedCre->MaxHealth() : 0));
-				}					
+				}
 			}
 			else
 				hi.healedHP = calculateHealedHP(parameters.caster, attackedCre, parameters.selectedStack); //Casted by hero
@@ -572,14 +569,13 @@ void DefaultSpellMechanics::applyBattleEffects(const SpellCastEnvironment * env,
 		}
 		if(!shr.healedStacks.empty())
 			env->sendAndApply(&shr);
-	}		
+	}
 }
 
-
 std::vector<BattleHex> DefaultSpellMechanics::rangeInHexes(BattleHex centralHex, ui8 schoolLvl, ui8 side, bool *outDroppedHexes) const
 {
 	using namespace SRSLPraserHelpers;
-	
+
 	std::vector<BattleHex> ret;
 	std::string rng = owner->getLevelInfo(schoolLvl).range + ','; //copy + artificial comma for easier handling
 
@@ -639,19 +635,18 @@ std::vector<BattleHex> DefaultSpellMechanics::rangeInHexes(BattleHex centralHex,
 
 	//remove duplicates (TODO check if actually needed)
 	range::unique(ret);
-	return ret;		
+	return ret;
 }
 
-
 std::set<const CStack *> DefaultSpellMechanics::getAffectedStacks(SpellTargetingContext & ctx) const
 {
 	std::set<const CStack* > attackedCres;//std::set to exclude multiple occurrences of two hex creatures
-	
+
 	const ui8 attackerSide = ctx.cb->playerToSide(ctx.casterColor) == 1;
 	const auto attackedHexes = rangeInHexes(ctx.destination, ctx.schoolLvl, attackerSide);
 
 	const CSpell::TargetInfo ti(owner, ctx.schoolLvl, ctx.mode);
-	
+
 	//TODO: more generic solution for mass spells
 	if(owner->getLevelInfo(ctx.schoolLvl).range.size() > 1) //custom many-hex range
 	{
@@ -669,17 +664,17 @@ std::set<const CStack *> DefaultSpellMechanics::getAffectedStacks(SpellTargeting
 			const bool positiveToAlly = owner->isPositive() && s->owner == ctx.casterColor;
 			const bool negativeToEnemy = owner->isNegative() && s->owner != ctx.casterColor;
 			const bool validTarget = s->isValidTarget(!ti.onlyAlive); //todo: this should be handled by spell class
-	
+
 			//for single target spells select stacks covering destination tile
 			const bool rangeCovers = ti.massive || s->coversPos(ctx.destination);
 			//handle smart targeting
 			const bool positivenessFlag = !ti.smart || owner->isNeutral() || positiveToAlly || negativeToEnemy;
-			
-			return rangeCovers && positivenessFlag && validTarget;		
+
+			return rangeCovers && positivenessFlag && validTarget;
 		};
-		
+
 		TStacks stacks = ctx.cb->battleGetStacksIf(predicate);
-		
+
 		if(ti.massive)
 		{
 			//for massive spells add all targets
@@ -696,13 +691,13 @@ std::set<const CStack *> DefaultSpellMechanics::getAffectedStacks(SpellTargeting
 				{
 					attackedCres.insert(stack);
 					break;
-				}				
-			}	
-			
+				}
+			}
+
 			if(attackedCres.empty() && !stacks.empty())
 			{
 				attackedCres.insert(stacks.front());
-			}						
+			}
 		}
 	}
 	else //custom range from attackedHexes
@@ -712,12 +707,11 @@ std::set<const CStack *> DefaultSpellMechanics::getAffectedStacks(SpellTargeting
 			if(const CStack * st = ctx.cb->battleGetStackByPos(hex, ti.onlyAlive))
 				attackedCres.insert(st);
 		}
-	}	
-	
+	}
+
 	return attackedCres;
 }
 
-
 ESpellCastProblem::ESpellCastProblem DefaultSpellMechanics::isImmuneByStack(const CGHeroInstance * caster, const CStack * obj) const
 {
 	//by default use general algorithm

+ 12 - 14
lib/spells/CDefaultSpellMechanics.h

@@ -10,7 +10,6 @@
 
 #pragma once
 
-
 #include "ISpellMechanics.h"
 
 class BattleSpellCast;
@@ -18,9 +17,9 @@ class StacksInjured;
 
 struct SpellCastContext
 {
-	SpellCastContext(std::vector<const CStack*> & attackedCres, BattleSpellCast & sc, StacksInjured & si):
-		attackedCres(attackedCres), sc(sc), si(si){}; 
-	std::vector<const CStack*> & attackedCres;
+	SpellCastContext(std::vector<const CStack *> & attackedCres, BattleSpellCast & sc, StacksInjured & si):
+		attackedCres(attackedCres), sc(sc), si(si){};
+	std::vector<const CStack *> & attackedCres;
 	BattleSpellCast & sc;
 	StacksInjured & si;
 };
@@ -29,25 +28,24 @@ class DefaultSpellMechanics: public ISpellMechanics
 {
 public:
 	DefaultSpellMechanics(CSpell * s): ISpellMechanics(s){};
-	
+
 	std::vector<BattleHex> rangeInHexes(BattleHex centralHex, ui8 schoolLvl, ui8 side, bool * outDroppedHexes = nullptr) const override;
 	std::set<const CStack *> getAffectedStacks(SpellTargetingContext & ctx) const override;
-	
+
 	ESpellCastProblem::ESpellCastProblem isImmuneByStack(const CGHeroInstance * caster, const CStack * obj) const override;
-	
-	bool adventureCast(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const override final; 
+
+	bool adventureCast(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const override final;
 	void battleCast(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters) const override;
-	
+
 	void applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const override;
 protected:
-	
 	virtual void applyBattleEffects(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters, SpellCastContext & ctx) const;
-	
+
 	virtual int calculateDuration(const CGHeroInstance * caster, int usedSpellPower) const;
-	
+
 	///calculate healed HP for all spells casted by hero
-	ui32 calculateHealedHP(const CGHeroInstance* caster, const CStack* stack, const CStack* sacrificedStack) const;
-	
+	ui32 calculateHealedHP(const CGHeroInstance * caster, const CStack * stack, const CStack * sacrificedStack) const;
+
 	///actual adventure cast implementation
 	virtual bool applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const;
 };

+ 112 - 126
lib/spells/CSpellHandler.cpp

@@ -1,3 +1,13 @@
+/*
+ * CSpellHandler.cpp, part of VCMI engine
+ *
+ * Authors: listed in file AUTHORS in main folder
+ *
+ * License: GNU General Public License v2.0 or later
+ * Full text of license available in license.txt file, in main folder
+ *
+ */
+
 #include "StdInc.h"
 
 #include <cctype>
@@ -19,23 +29,11 @@
 
 #include "ISpellMechanics.h"
 
-
-
-/*
- * CSpellHandler.cpp, part of VCMI engine
- *
- * Authors: listed in file AUTHORS in main folder
- *
- * License: GNU General Public License v2.0 or later
- * Full text of license available in license.txt file, in main folder
- *
- */
-
 namespace SpellConfig
 {
 	static const std::string LEVEL_NAMES[] = {"none", "basic", "advanced", "expert"};
-	
-	static const SpellSchoolInfo SCHOOL[4] = 
+
+	static const SpellSchoolInfo SCHOOL[4] =
 	{
 		{
 			ESpellSchool::AIR,
@@ -69,16 +67,15 @@ namespace SpellConfig
 			SecondarySkill::EARTH_MAGIC,
 			Bonus::EARTH_SPELLS
 		}
-	};	
+	};
 }
 
 BattleSpellCastParameters::BattleSpellCastParameters(const BattleInfo* cb)
 	: spellLvl(0), destination(BattleHex::INVALID), casterSide(0),casterColor(PlayerColor::CANNOT_DETERMINE),caster(nullptr), secHero(nullptr),
 	usedSpellPower(0),mode(ECastingMode::HERO_CASTING), casterStack(nullptr), selectedStack(nullptr), cb(cb)
 {
-	
-}
 
+}
 
 ///CSpell::LevelInfo
 CSpell::LevelInfo::LevelInfo()
@@ -118,14 +115,14 @@ void CSpell::applyBattle(BattleInfo * battle, const BattleSpellCast * packet) co
 bool CSpell::adventureCast(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const
 {
 	assert(env);
-		
+
 	return mechanics->adventureCast(env, parameters);
 }
 
 void CSpell::battleCast(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters) const
 {
 	assert(env);
-	
+
 	mechanics->battleCast(env, parameters);
 }
 
@@ -133,19 +130,19 @@ bool CSpell::isCastableBy(const IBonusBearer * caster, bool hasSpellBook, const
 {
 	if(!hasSpellBook)
 		return false;
-	
+
 	const bool inSpellBook = vstd::contains(spellBook, id);
 	const bool isBonus = caster->hasBonusOfType(Bonus::SPELL, id);
-	
+
 	bool inTome = false;
-	
+
 	forEachSchool([&](const SpellSchoolInfo & cnf, bool & stop)
 	{
 		if(caster->hasBonusOfType(cnf.knoledgeBonus))
 		{
 			inTome = stop = true;
-		}				
-	});	
+		}
+	});
 
     if (isSpecialSpell())
     {
@@ -158,7 +155,7 @@ bool CSpell::isCastableBy(const IBonusBearer * caster, bool hasSpellBook, const
     else
     {
        return inSpellBook || inTome || isBonus || caster->hasBonusOfType(Bonus::SPELLS_OF_LEVEL, level);
-    }	
+    }
 }
 
 const CSpell::LevelInfo & CSpell::getLevelInfo(const int level) const
@@ -172,7 +169,7 @@ const CSpell::LevelInfo & CSpell::getLevelInfo(const int level) const
 	return levels.at(level);
 }
 
-ui32 CSpell::calculateBonus(ui32 baseDamage, const CGHeroInstance* caster, const CStack* affectedCreature) const
+ui32 CSpell::calculateBonus(ui32 baseDamage, const CGHeroInstance * caster, const CStack * affectedCreature) const
 {
 	ui32 ret = baseDamage;
 	//applying sorcery secondary skill
@@ -180,17 +177,17 @@ ui32 CSpell::calculateBonus(ui32 baseDamage, const CGHeroInstance* caster, const
 	{
 		ret *= (100.0 + caster->valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, SecondarySkill::SORCERY)) / 100.0;
 		ret *= (100.0 + caster->valOfBonuses(Bonus::SPELL_DAMAGE) + caster->valOfBonuses(Bonus::SPECIFIC_SPELL_DAMAGE, id.toEnum())) / 100.0;
-		
+
 		forEachSchool([&](const SpellSchoolInfo & cnf, bool & stop)
 		{
 			ret *= (100.0 + caster->valOfBonuses(cnf.damagePremyBonus)) / 100.0;
 			stop = true; //only bonus from one school is used
-		});		
+		});
 
 		if (affectedCreature && affectedCreature->getCreature()->level) //Hero specials like Solmyr, Deemer
 			ret *= (100. + ((caster->valOfBonuses(Bonus::SPECIAL_SPELL_LEV, id.toEnum()) * caster->level) / affectedCreature->getCreature()->level)) / 100.0;
 	}
-	return ret;	
+	return ret;
 }
 
 ui32 CSpell::calculateDamage(const CGHeroInstance * caster, const CStack * affectedCreature, int spellSchoolLevel, int usedSpellPower) const
@@ -208,15 +205,15 @@ ui32 CSpell::calculateDamage(const CGHeroInstance * caster, const CStack * affec
 	if(nullptr != affectedCreature)
 	{
 		//applying protections - when spell has more then one elements, only one protection should be applied (I think)
-		
+
 		forEachSchool([&](const SpellSchoolInfo & cnf, bool & stop)
 		{
 			if(affectedCreature->hasBonusOfType(Bonus::SPELL_DAMAGE_REDUCTION, (ui8)cnf.id))
 			{
 				ret *= affectedCreature->valOfBonuses(Bonus::SPELL_DAMAGE_REDUCTION, (ui8)cnf.id);
 				ret /= 100;
-				stop = true;//only bonus from one school is used	
-			}				
+				stop = true;//only bonus from one school is used
+			}
 		});
 
 		//general spell dmg reduction
@@ -233,7 +230,7 @@ ui32 CSpell::calculateDamage(const CGHeroInstance * caster, const CStack * affec
 		}
 	}
 	ret = calculateBonus(ret, caster, affectedCreature);
-	return ret;	
+	return ret;
 }
 
 std::vector<BattleHex> CSpell::rangeInHexes(BattleHex centralHex, ui8 schoolLvl, ui8 side, bool *outDroppedHexes) const
@@ -241,26 +238,25 @@ std::vector<BattleHex> CSpell::rangeInHexes(BattleHex centralHex, ui8 schoolLvl,
 	return mechanics->rangeInHexes(centralHex,schoolLvl,side,outDroppedHexes);
 }
 
-std::set<const CStack* > CSpell::getAffectedStacks(const CBattleInfoCallback * cb, ECastingMode::ECastingMode mode, PlayerColor casterColor, int spellLvl, BattleHex destination, const CGHeroInstance * caster) const
+std::set<const CStack *> CSpell::getAffectedStacks(const CBattleInfoCallback * cb, ECastingMode::ECastingMode mode, PlayerColor casterColor, int spellLvl, BattleHex destination, const CGHeroInstance * caster) const
 {
 	ISpellMechanics::SpellTargetingContext ctx(this, cb,mode,casterColor,spellLvl,destination);
 
 	std::set<const CStack* > attackedCres = mechanics->getAffectedStacks(ctx);
-	
-	//now handle immunities		
+
+	//now handle immunities
 	auto predicate = [&, this](const CStack * s)->bool
 	{
 		bool hitDirectly = ctx.ti.alwaysHitDirectly && s->coversPos(destination);
 		bool notImmune = (ESpellCastProblem::OK == isImmuneByStack(caster, s));
-		
-		return !(hitDirectly || notImmune);  
-	};	
+
+		return !(hitDirectly || notImmune);
+	};
 	vstd::erase_if(attackedCres, predicate);
-	
+
 	return attackedCres;
 }
 
-
 CSpell::ETargetType CSpell::getTargetType() const
 {
 	return targetType;
@@ -280,14 +276,13 @@ void CSpell::forEachSchool(const std::function<void(const SpellSchoolInfo &, boo
 		if(school.at(cnf.id))
 		{
 			cb(cnf, stop);
-			
+
 			if(stop)
 				break;
-		}				
-	}	
+		}
+	}
 }
 
-
 bool CSpell::isCombatSpell() const
 {
 	return combatSpell;
@@ -348,12 +343,12 @@ bool CSpell::hasEffects() const
 	return !levels[0].effects.empty();
 }
 
-const std::string& CSpell::getIconImmune() const
+const std::string & CSpell::getIconImmune() const
 {
 	return iconImmune;
 }
 
-const std::string& CSpell::getCastSound() const
+const std::string & CSpell::getCastSound() const
 {
 	return castSound;
 }
@@ -377,8 +372,7 @@ si32 CSpell::getProbability(const TFaction factionId) const
 	return probabilities.at(factionId);
 }
 
-
-void CSpell::getEffects(std::vector<Bonus>& lst, const int level) const
+void CSpell::getEffects(std::vector<Bonus> & lst, const int level) const
 {
 	if(level < 0 || level >= GameConstants::SPELL_SCHOOL_LEVELS)
 	{
@@ -408,17 +402,17 @@ ESpellCastProblem::ESpellCastProblem CSpell::isImmuneAt(const CBattleInfoCallbac
 	TStacks stacks = cb->battleGetStacksIf([=](const CStack * s){
 		return s->coversPos(destination) && (isRisingSpell() || s->alive());
 	});
-	
+
 	if(!stacks.empty())
 	{
 		bool allImmune = true;
-		
-		ESpellCastProblem::ESpellCastProblem problem;		
-		
+
+		ESpellCastProblem::ESpellCastProblem problem;
+
 		for(auto s : stacks)
 		{
 			ESpellCastProblem::ESpellCastProblem res = isImmuneByStack(caster,s);
-			
+
 			if(res == ESpellCastProblem::OK)
 			{
 				allImmune = false;
@@ -428,7 +422,7 @@ ESpellCastProblem::ESpellCastProblem CSpell::isImmuneAt(const CBattleInfoCallbac
 				problem = res;
 			}
 		}
-		
+
 		if(allImmune)
 			return problem;
 	}
@@ -439,23 +433,22 @@ ESpellCastProblem::ESpellCastProblem CSpell::isImmuneAt(const CBattleInfoCallbac
 			if(caster && mode == ECastingMode::HERO_CASTING) //TODO why???
 			{
 				const CSpell::TargetInfo ti(this, caster->getSpellSchoolLevel(this), mode);
-				
+
 				if(!ti.massive)
-					return ESpellCastProblem::WRONG_SPELL_TARGET;					
+					return ESpellCastProblem::WRONG_SPELL_TARGET;
 			}
 			else
 			{
  				return ESpellCastProblem::WRONG_SPELL_TARGET;
-			}			
+			}
 		}
 	}
 
-	return ESpellCastProblem::OK;	
+	return ESpellCastProblem::OK;
 }
 
-
 ESpellCastProblem::ESpellCastProblem CSpell::isImmuneBy(const IBonusBearer* obj) const
-{	
+{
 	//todo: use new bonus API
 	//1. Check absolute limiters
 	for(auto b : absoluteLimiters)
@@ -470,16 +463,16 @@ ESpellCastProblem::ESpellCastProblem CSpell::isImmuneBy(const IBonusBearer* obj)
 		if (obj->hasBonusOfType(b))
 			return ESpellCastProblem::STACK_IMMUNE_TO_SPELL;
 	}
-	
+
 	//check receptivity
 	if (isPositive() && obj->hasBonusOfType(Bonus::RECEPTIVE)) //accept all positive spells
-		return ESpellCastProblem::OK;	
+		return ESpellCastProblem::OK;
 
 	//3. Check negation
 	//FIXME: Orb of vulnerability mechanics is not such trivial
 	if(obj->hasBonusOfType(Bonus::NEGATE_ALL_NATURAL_IMMUNITIES)) //Orb of vulnerability
 		return ESpellCastProblem::NOT_DECIDED;
-		
+
 	//4. Check negatable limit
 	for(auto b : limiters)
 	{
@@ -496,31 +489,31 @@ ESpellCastProblem::ESpellCastProblem CSpell::isImmuneBy(const IBonusBearer* obj)
 	}
 
 	//6. Check elemental immunities
-	
+
 	ESpellCastProblem::ESpellCastProblem tmp = ESpellCastProblem::NOT_DECIDED;
-	
+
 	forEachSchool([&](const SpellSchoolInfo & cnf, bool & stop)
 	{
 		auto element = cnf.immunityBonus;
-		
+
 		if(obj->hasBonusOfType(element, 0)) //always resist if immune to all spells altogether
 		{
 			tmp = ESpellCastProblem::STACK_IMMUNE_TO_SPELL;
 			stop = true;
-		}				
+		}
 		else if(!isPositive()) //negative or indifferent
 		{
 			if((isDamageSpell() && obj->hasBonusOfType(element, 2)) || obj->hasBonusOfType(element, 1))
 			{
 				tmp = ESpellCastProblem::STACK_IMMUNE_TO_SPELL;
 				stop = true;
-			}			
-		}	
+			}
+		}
 	});
-	
+
 	if(tmp != ESpellCastProblem::NOT_DECIDED)
 		return tmp;
-	
+
 	TBonusListPtr levelImmunities = obj->getBonuses(Selector::type(Bonus::LEVEL_SPELL_IMMUNITY));
 
 	if(obj->hasBonusOfType(Bonus::SPELL_IMMUNITY, id)
@@ -532,16 +525,15 @@ ESpellCastProblem::ESpellCastProblem CSpell::isImmuneBy(const IBonusBearer* obj)
 	return ESpellCastProblem::NOT_DECIDED;
 }
 
-ESpellCastProblem::ESpellCastProblem CSpell::isImmuneByStack(const CGHeroInstance* caster, const CStack* obj) const
+ESpellCastProblem::ESpellCastProblem CSpell::isImmuneByStack(const CGHeroInstance * caster, const CStack * obj) const
 {
 	const auto immuneResult = mechanics->isImmuneByStack(caster,obj);
-	
-	if (ESpellCastProblem::NOT_DECIDED != immuneResult) 
+
+	if (ESpellCastProblem::NOT_DECIDED != immuneResult)
 		return immuneResult;
-	return ESpellCastProblem::OK;	
+	return ESpellCastProblem::OK;
 }
 
-
 void CSpell::setIsOffensive(const bool val)
 {
 	isOffensive = val;
@@ -568,7 +560,6 @@ void CSpell::setup()
 	setupMechanics();
 }
 
-
 void CSpell::setupMechanics()
 {
 	if(nullptr != mechanics)
@@ -576,26 +567,26 @@ void CSpell::setupMechanics()
 		logGlobal->errorStream() << "Spell " << this->name << " mechanics already set";
 		delete mechanics;
 	}
-	
-	mechanics = ISpellMechanics::createMechanics(this);	
+
+	mechanics = ISpellMechanics::createMechanics(this);
 }
 
 ///CSpell::AnimationInfo
 CSpell::AnimationInfo::AnimationInfo()
 {
-	
+
 }
 
 CSpell::AnimationInfo::~AnimationInfo()
 {
-	
+
 }
 
 std::string CSpell::AnimationInfo::selectProjectile(const double angle) const
-{	
-	std::string res;	
+{
+	std::string res;
 	double maximum = 0.0;
-	
+
 	for(const auto & info : projectile)
 	{
 		if(info.minimumAngle < angle && info.minimumAngle > maximum)
@@ -604,10 +595,9 @@ std::string CSpell::AnimationInfo::selectProjectile(const double angle) const
 			res = info.resourceName;
 		}
 	}
-	
-	return std::move(res);	
-}
 
+	return std::move(res);
+}
 
 ///CSpell::TargetInfo
 CSpell::TargetInfo::TargetInfo(const CSpell * spell, const int level)
@@ -626,7 +616,7 @@ CSpell::TargetInfo::TargetInfo(const CSpell * spell, const int level, ECastingMo
 	else if(mode == ECastingMode::SPELL_LIKE_ATTACK)
 	{
 		alwaysHitDirectly = true;
-	}	
+	}
 }
 
 void CSpell::TargetInfo::init(const CSpell * spell, const int level)
@@ -642,8 +632,7 @@ void CSpell::TargetInfo::init(const CSpell * spell, const int level)
 	clearTarget = levelInfo.clearTarget;
 }
 
-
-bool DLL_LINKAGE isInScreenRange(const int3 &center, const int3 &pos)
+bool DLL_LINKAGE isInScreenRange(const int3 & center, const int3 & pos)
 {
 	int3 diff = pos - center;
 	if(diff.x >= -9  &&  diff.x <= 9  &&  diff.y >= -8  &&  diff.y <= 8)
@@ -665,7 +654,7 @@ std::vector<JsonNode> CSpellHandler::loadLegacyData(size_t dataSize)
 
 	CLegacyConfigParser parser("DATA/SPTRAITS.TXT");
 
-	auto readSchool = [&](JsonMap& schools, const std::string& name)
+	auto readSchool = [&](JsonMap & schools, const std::string & name)
 	{
 		if (parser.readString() == "x")
 		{
@@ -710,14 +699,14 @@ std::vector<JsonNode> CSpellHandler::loadLegacyData(size_t dataSize)
 
 			auto& chances = lineNode["gainChance"].Struct();
 
-			for(size_t i = 0; i < GameConstants::F_NUMBER ; i++){
+			for(size_t i = 0; i < GameConstants::F_NUMBER; i++){
 				chances[ETownType::names[i]].Float() = parser.readNumber();
 			}
 
 			auto AIVals = parser.readNumArray<si32>(GameConstants::SPELL_SCHOOL_LEVELS);
 
 			std::vector<std::string> descriptions;
-			for(size_t i = 0; i < GameConstants::SPELL_SCHOOL_LEVELS ; i++)
+			for(size_t i = 0; i < GameConstants::SPELL_SCHOOL_LEVELS; i++)
 				descriptions.push_back(parser.readString());
 
 			parser.readString(); //ignore attributes. All data present in JSON
@@ -733,8 +722,6 @@ std::vector<JsonNode> CSpellHandler::loadLegacyData(size_t dataSize)
 			}
 
 			legacyData.push_back(lineNode);
-
-
 		}
 		while (parser.endLine() && !parser.isNextEntryEmpty());
 	};
@@ -768,7 +755,7 @@ const std::string CSpellHandler::getTypeName() const
 	return "spell";
 }
 
-CSpell * CSpellHandler::loadFromJson(const JsonNode& json)
+CSpell * CSpellHandler::loadFromJson(const JsonNode & json)
 {
 	using namespace SpellConfig;
 
@@ -792,7 +779,7 @@ CSpell * CSpellHandler::loadFromJson(const JsonNode& json)
 	logGlobal->traceStream() << __FUNCTION__ << ": loading spell " << spell->name;
 
 	const auto schoolNames = json["school"];
-	
+
 	for(const SpellSchoolInfo & info : SpellConfig::SCHOOL)
 	{
 		spell->school[info.id] = schoolNames[info.jsonName].Bool();
@@ -823,7 +810,7 @@ CSpell * CSpellHandler::loadFromJson(const JsonNode& json)
 		spell->targetType = CSpell::OBSTACLE;
 	else if(targetType == "LOCATION")
 		spell->targetType = CSpell::LOCATION;
-	else 
+	else
 		logGlobal->warnStream() << "Spell " << spell->name << ". Target type " << (targetType.empty() ? "empty" : "unknown ("+targetType+")") << ". Assumed NO_TARGET.";
 
 	for(const auto & counteredSpell: json["counters"].Struct())
@@ -874,7 +861,7 @@ CSpell * CSpellHandler::loadFromJson(const JsonNode& json)
 
 	spell->isSpecial = flags["special"].Bool();
 
-	auto findBonus = [&](std::string name, std::vector<Bonus::BonusType> &vec)
+	auto findBonus = [&](std::string name, std::vector<Bonus::BonusType> & vec)
 	{
 		auto it = bonusNameMap.find(name);
 		if(it == bonusNameMap.end())
@@ -887,7 +874,7 @@ CSpell * CSpellHandler::loadFromJson(const JsonNode& json)
 		}
 	};
 
-	auto readBonusStruct = [&](std::string name, std::vector<Bonus::BonusType> &vec)
+	auto readBonusStruct = [&](std::string name, std::vector<Bonus::BonusType> & vec)
 	{
 		for(auto bonusData: json[name].Struct())
 		{
@@ -901,7 +888,7 @@ CSpell * CSpellHandler::loadFromJson(const JsonNode& json)
 
 	readBonusStruct("immunity", spell->immunities);
 	readBonusStruct("absoluteImmunity", spell->absoluteImmunities);
-	readBonusStruct("limit", spell->limiters);	
+	readBonusStruct("limit", spell->limiters);
 	readBonusStruct("absoluteLimit", spell->absoluteLimiters);
 
 
@@ -914,41 +901,41 @@ CSpell * CSpellHandler::loadFromJson(const JsonNode& json)
 	spell->iconScroll = graphicsNode["iconScroll"].String();
 
 	const JsonNode & animationNode = json["animation"];
-	
-	auto loadAnimationQueue = [&](const std::string & jsonName, CSpell::TAnimationQueue & q)	
+
+	auto loadAnimationQueue = [&](const std::string & jsonName, CSpell::TAnimationQueue & q)
 	{
-		auto queueNode = animationNode[jsonName].Vector();		
+		auto queueNode = animationNode[jsonName].Vector();
 		for(const JsonNode & item : queueNode)
-		{	
+		{
 			CSpell::TAnimation newItem;
 			newItem.verticalPosition = VerticalPosition::TOP;
-			
+
 			if(item.getType() == JsonNode::DATA_STRING)
 				newItem.resourceName = item.String();
 			else if(item.getType() == JsonNode::DATA_STRUCT)
 			{
 				newItem.resourceName = item["defName"].String();
-				
+
 				auto vPosStr = item["verticalPosition"].String();
 				if("bottom" == vPosStr)
 					newItem.verticalPosition = VerticalPosition::BOTTOM;
-			}	
-			q.push_back(newItem);		
+			}
+			q.push_back(newItem);
 		}
 	};
-	
+
 	loadAnimationQueue("affect", spell->animationInfo.affect);
 	loadAnimationQueue("cast", spell->animationInfo.cast);
-	loadAnimationQueue("hit", spell->animationInfo.hit);	
-	
+	loadAnimationQueue("hit", spell->animationInfo.hit);
+
 	const JsonVector & projectile = animationNode["projectile"].Vector();
-	
+
 	for(const JsonNode & item : projectile)
 	{
 		CSpell::ProjectileInfo info;
 		info.resourceName = item["defName"].String();
 		info.minimumAngle = item["minimumAngle"].Float();
-		
+
 		spell->animationInfo.projectile.push_back(info);
 	}
 
@@ -963,19 +950,19 @@ CSpell * CSpellHandler::loadFromJson(const JsonNode& json)
 	for(int levelIndex = 0; levelIndex < levelsCount; levelIndex++)
 	{
 		const JsonNode & levelNode = json["levels"][LEVEL_NAMES[levelIndex]];
-		
+
 		CSpell::LevelInfo & levelObject = spell->levels[levelIndex];
 
-		const si32 levelPower     = levelObject.power = levelNode["power"].Float();		
+		const si32 levelPower     = levelObject.power = levelNode["power"].Float();
 
 		levelObject.description   = levelNode["description"].String();
 		levelObject.cost          = levelNode["cost"].Float();
 		levelObject.AIValue       = levelNode["aiValue"].Float();
 		levelObject.smartTarget   = levelNode["targetModifier"]["smart"].Bool();
 		levelObject.clearTarget   = levelNode["targetModifier"]["clearTarget"].Bool();
-		levelObject.clearAffected = levelNode["targetModifier"]["clearAffected"].Bool();			
+		levelObject.clearAffected = levelNode["targetModifier"]["clearAffected"].Bool();
 		levelObject.range         = levelNode["range"].String();
-		
+
 		for(const auto & elem : levelNode["effects"].Struct())
 		{
 			const JsonNode & bonusNode = elem.second;
@@ -992,7 +979,7 @@ CSpell * CSpellHandler::loadFromJson(const JsonNode& json)
 
 			levelObject.effects.push_back(*b);
 		}
-		
+
 	}
 
 	return spell;
@@ -1013,19 +1000,18 @@ void CSpellHandler::afterLoadFinalization()
 void CSpellHandler::beforeValidate(JsonNode & object)
 {
 	//handle "base" level info
-	
-	JsonNode& levels = object["levels"];
-	JsonNode& base = levels["base"];
-	
+
+	JsonNode & levels = object["levels"];
+	JsonNode & base = levels["base"];
+
 	auto inheritNode = [&](const std::string & name){
 		JsonUtils::inherit(levels[name],base);
 	};
-	
+
 	inheritNode("none");
 	inheritNode("basic");
 	inheritNode("advanced");
 	inheritNode("expert");
-
 }
 
 

+ 60 - 73
lib/spells/CSpellHandler.h

@@ -1,13 +1,3 @@
-#pragma once
-
-#include "../IHandlerBase.h"
-#include "../ConstTransitivePtr.h"
-#include "../int3.h"
-#include "../GameConstants.h"
-#include "../BattleHex.h"
-#include "../HeroBonus.h"
-
-
 /*
  * CSpellHandler.h, part of VCMI engine
  *
@@ -18,22 +8,25 @@
  *
  */
 
-class CGObjectInstance;
+#pragma once
 
+#include "../IHandlerBase.h"
+#include "../ConstTransitivePtr.h"
+#include "../int3.h"
+#include "../GameConstants.h"
+#include "../BattleHex.h"
+#include "../HeroBonus.h"
+
+class CGObjectInstance;
 class CSpell;
 class ISpellMechanics;
-
 class CLegacyConfigParser;
-
 class CGHeroInstance;
 class CStack;
-
 class CBattleInfoCallback;
 class BattleInfo;
-
 struct CPackForClient;
 struct BattleSpellCast;
-
 class CGameInfoCallback;
 class CRandomGenerator;
 class CMap;
@@ -42,10 +35,10 @@ struct SpellSchoolInfo
 {
 	ESpellSchool id; //backlink
 	Bonus::BonusType damagePremyBonus;
-	Bonus::BonusType immunityBonus;	
+	Bonus::BonusType immunityBonus;
 	std::string jsonName;
 	SecondarySkill::ESecondarySkill skill;
-	Bonus::BonusType knoledgeBonus;			
+	Bonus::BonusType knoledgeBonus;
 };
 
 ///callback to be provided by server
@@ -54,13 +47,13 @@ class DLL_LINKAGE SpellCastEnvironment
 public:
 	virtual ~SpellCastEnvironment(){};
 	virtual void sendAndApply(CPackForClient * info) const = 0;
-	
+
 	virtual CRandomGenerator & getRandomGenerator() const = 0;
 	virtual void complain(const std::string & problem) const = 0;
-	
+
 	virtual const CMap * getMap() const = 0;
-	virtual const CGameInfoCallback * getCb() const = 0;	
-	
+	virtual const CGameInfoCallback * getCb() const = 0;
+
 	virtual bool moveHero(ObjectInstanceID hid, int3 dst, ui8 teleporting, PlayerColor asker = PlayerColor::NEUTRAL) const =0;	//TODO: remove
 };
 
@@ -78,14 +71,14 @@ public:
 	int usedSpellPower;
 	ECastingMode::ECastingMode mode;
 	const CStack * casterStack;
-	const CStack * selectedStack;	
-	const BattleInfo * cb;		
+	const CStack * selectedStack;
+	const BattleInfo * cb;
 };
 
 struct DLL_LINKAGE AdventureSpellCastParameters
 {
 	const CGHeroInstance * caster;
-	int3 pos;	
+	int3 pos;
 };
 
 enum class VerticalPosition : ui8{TOP, CENTER, BOTTOM};
@@ -93,41 +86,40 @@ enum class VerticalPosition : ui8{TOP, CENTER, BOTTOM};
 class DLL_LINKAGE CSpell
 {
 public:
-	
 	struct ProjectileInfo
 	{
 		///in radians. Only positive value. Negative angle is handled by vertical flip
-		double minimumAngle; 
-		
+		double minimumAngle;
+
 		///resource name
 		std::string resourceName;
-		 
-		template <typename Handler> void serialize(Handler &h, const int version)
+
+		template <typename Handler> void serialize(Handler & h, const int version)
 		{
-			h & minimumAngle & resourceName; 
-		}		
+			h & minimumAngle & resourceName;
+		}
 	};
-	
+
 	struct AnimationItem
 	{
 		std::string resourceName;
 		VerticalPosition verticalPosition;
-		
-		template <typename Handler> void serialize(Handler &h, const int version)
+
+		template <typename Handler> void serialize(Handler & h, const int version)
 		{
-			h & resourceName & verticalPosition; 
-		}		
+			h & resourceName & verticalPosition;
+		}
 	};
-	
+
 	typedef AnimationItem TAnimation;
-	typedef std::vector<TAnimation> TAnimationQueue; 
-	
+	typedef std::vector<TAnimation> TAnimationQueue;
+
 	struct DLL_LINKAGE AnimationInfo
 	{
 		AnimationInfo();
 		~AnimationInfo();
 
-		///displayed on all affected targets. 
+		///displayed on all affected targets.
 		TAnimationQueue affect;
 
 		///displayed on caster.
@@ -140,14 +132,13 @@ public:
 		///use selectProjectile to access
 		std::vector<ProjectileInfo> projectile;
 
-		template <typename Handler> void serialize(Handler &h, const int version)
+		template <typename Handler> void serialize(Handler & h, const int version)
 		{
 			h & projectile & hit & cast;
 		}
 
 		std::string selectProjectile(const double angle) const;
 	} animationInfo;
-	
 public:
 	struct LevelInfo
 	{
@@ -192,13 +183,13 @@ public:
 		bool onlyAlive;
 		///no immunity on primary target (mostly spell-like attack)
 		bool alwaysHitDirectly;
-		
+
 		bool clearTarget;
 		bool clearAffected;
-		
+
 		TargetInfo(const CSpell * spell, const int level);
 		TargetInfo(const CSpell * spell, const int level, ECastingMode::ECastingMode mode);
-		
+
 	private:
 		void init(const CSpell * spell, const int level);
 	};
@@ -210,7 +201,7 @@ public:
 	si32 level;
 
 	std::map<ESpellSchool, bool> school; //todo: use this instead of separate boolean fields
-	
+
 	si32 power; //spell's power
 
 	std::map<TFaction, si32> probabilities; //% chance to gain for castles
@@ -223,16 +214,14 @@ public:
 
 	CSpell();
 	~CSpell();
-	
+
 	bool isCastableBy(const IBonusBearer * caster, bool hasSpellBook, const std::set<SpellID> & spellBook) const;
-	
 
-	std::vector<BattleHex> rangeInHexes(BattleHex centralHex, ui8 schoolLvl, ui8 side, bool *outDroppedHexes = nullptr ) const; //convert range to specific hexes; last optional out parameter is set to true, if spell would cover unavailable hexes (that are not included in ret)
+	std::vector<BattleHex> rangeInHexes(BattleHex centralHex, ui8 schoolLvl, ui8 side, bool * outDroppedHexes = nullptr ) const; //convert range to specific hexes; last optional out parameter is set to true, if spell would cover unavailable hexes (that are not included in ret)
 	ETargetType getTargetType() const; //deprecated
 
 	CSpell::TargetInfo getTargetInfo(const int level) const;
 
-
 	bool isCombatSpell() const;
 	bool isAdventureSpell() const;
 	bool isCreatureAbility() const;
@@ -243,29 +232,29 @@ public:
 
 	bool isDamageSpell() const;
 	bool isHealingSpell() const;
-	bool isRisingSpell() const;	
+	bool isRisingSpell() const;
 	bool isOffensiveSpell() const;
 
 	bool isSpecialSpell() const;
 
 	bool hasEffects() const;
 	void getEffects(std::vector<Bonus> &lst, const int level) const;
-	
+
 	///checks for creature immunity / anything that prevent casting *at given hex* - doesn't take into account general problems such as not having spellbook or mana points etc.
 	ESpellCastProblem::ESpellCastProblem isImmuneAt(const CBattleInfoCallback * cb, const CGHeroInstance * caster, ECastingMode::ECastingMode mode, BattleHex destination) const;
-	
+
 	//internal, for use only by Mechanics classes
 	ESpellCastProblem::ESpellCastProblem isImmuneBy(const IBonusBearer *obj) const;
-	
+
 	//checks for creature immunity / anything that prevent casting *at given target* - doesn't take into account general problems such as not having spellbook or mana points etc.
 	ESpellCastProblem::ESpellCastProblem isImmuneByStack(const CGHeroInstance * caster, const CStack * obj) const;
-	
+
 	//internal, for use only by Mechanics classes. applying secondary skills
 	ui32 calculateBonus(ui32 baseDamage, const CGHeroInstance * caster, const CStack * affectedCreature) const;
-	
+
 	///calculate spell damage on stack taking caster`s secondary skills and affectedCreature`s bonuses into account
 	ui32 calculateDamage(const CGHeroInstance * caster, const CStack * affectedCreature, int spellSchoolLevel, int usedSpellPower) const;
-	
+
 	///selects from allStacks actually affected stacks
 	std::set<const CStack *> getAffectedStacks(const CBattleInfoCallback * cb, ECastingMode::ECastingMode mode, PlayerColor casterColor, int spellLvl, BattleHex destination, const CGHeroInstance * caster = nullptr) const;
 
@@ -282,7 +271,7 @@ public:
 	 * Calls cb for each school this spell belongs to
 	 *
 	 * Set stop to true to abort looping
-	 */	
+	 */
 	void forEachSchool(const std::function<void (const SpellSchoolInfo &, bool &)> & cb) const;
 
 	/**
@@ -303,8 +292,8 @@ public:
 		h & defaultProbability;
 		h & isSpecial;
 		h & castSound & iconBook & iconEffect & iconScenarioBonus & iconScroll;
-		h & levels;		
-		h & school;		
+		h & levels;
+		h & school;
 		h & animationInfo;
 
 		if(!h.saving)
@@ -315,21 +304,21 @@ public:
 public:
 	///Server logic. Has write access to GameState via packets.
 	///May be executed on client side by (future) non-cheat-proof scripts.
-	
-	bool adventureCast(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const; 
-	void battleCast(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters) const; 	
-		
-public:	
+
+	bool adventureCast(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const;
+	void battleCast(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters) const;
+
+public:
 	///Client-server logic. Has direct write access to GameState.
 	///Shall be called (only) when applying packets on BOTH SIDES
-	
+
 	///implementation of BattleSpellCast applying
 	void applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const;
-		
+
 private:
 	void setIsOffensive(const bool val);
 	void setIsRising(const bool val);
-	
+
 	//call this after load or deserialization. cant be done in constructor.
 	void setup();
 	void setupMechanics();
@@ -351,9 +340,7 @@ private:
 	std::vector<Bonus::BonusType> absoluteLimiters; //all of them are required to be affected, can't be negated
 
 	///graphics related stuff
-
 	std::string iconImmune;
-
 	std::string iconBook;
 	std::string iconEffect;
 	std::string iconScenarioBonus;
@@ -363,7 +350,7 @@ private:
 	std::string castSound;
 
 	std::vector<LevelInfo> levels;
-	
+
 	ISpellMechanics * mechanics;//(!) do not serialize
 };
 
@@ -393,7 +380,7 @@ public:
 	{
 		h & objects ;
 	}
-		
+
 protected:
 	CSpell * loadFromJson(const JsonNode & json) override;
 };

+ 9 - 10
lib/spells/CreatureSpellMechanics.cpp

@@ -20,7 +20,7 @@ void AcidBreathDamageMechanics::applyBattleEffects(const SpellCastEnvironment *
 {
 	//calculating dmg to display
 	ctx.sc.dmgToDisplay = parameters.usedSpellPower;
-	
+
 	for(auto & attackedCre : ctx.attackedCres) //no immunities
 	{
 		BattleStackAttacked bsa;
@@ -31,7 +31,7 @@ void AcidBreathDamageMechanics::applyBattleEffects(const SpellCastEnvironment *
 		bsa.attackerID = -1;
 		(attackedCre)->prepareAttacked(bsa, env->getRandomGenerator());
 		ctx.si.stacks.push_back(bsa);
-	}	
+	}
 }
 
 ///DeathStareMechanics
@@ -41,7 +41,7 @@ void DeathStareMechanics::applyBattleEffects(const SpellCastEnvironment * env, B
 	ctx.sc.dmgToDisplay = parameters.usedSpellPower;
 	if(!ctx.attackedCres.empty())
 		vstd::amin(ctx.sc.dmgToDisplay, (*ctx.attackedCres.begin())->count); //stack is already reduced after attack
-	
+
 	for(auto & attackedCre : ctx.attackedCres)
 	{
 		BattleStackAttacked bsa;
@@ -52,15 +52,14 @@ void DeathStareMechanics::applyBattleEffects(const SpellCastEnvironment * env, B
 		bsa.attackerID = -1;
 		(attackedCre)->prepareAttacked(bsa, env->getRandomGenerator());
 		ctx.si.stacks.push_back(bsa);
-	}	
+	}
 }
 
-
 ///DispellHelpfulMechanics
 void DispellHelpfulMechanics::applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const
 {
 	DefaultSpellMechanics::applyBattle(battle, packet);
-	
+
 	for(auto stackID : packet->affectedCres)
 	{
 		if(vstd::contains(packet->resisted, stackID))
@@ -71,7 +70,7 @@ void DispellHelpfulMechanics::applyBattle(BattleInfo * battle, const BattleSpell
 		{
 			return Selector::positiveSpellEffects(b);
 		});
-	}	
+	}
 }
 
 ESpellCastProblem::ESpellCastProblem DispellHelpfulMechanics::isImmuneByStack(const CGHeroInstance * caster,  const CStack * obj) const
@@ -90,7 +89,7 @@ ESpellCastProblem::ESpellCastProblem DispellHelpfulMechanics::isImmuneByStack(co
 	{
 		return ESpellCastProblem::NO_SPELLS_TO_DISPEL;
 	}
-	
-	//use default algorithm only if there is no mechanics-related problem		
-	return DefaultSpellMechanics::isImmuneByStack(caster,obj);	
+
+	//use default algorithm only if there is no mechanics-related problem
+	return DefaultSpellMechanics::isImmuneByStack(caster,obj);
 }

+ 9 - 9
lib/spells/CreatureSpellMechanics.h

@@ -7,17 +7,17 @@
  * Full text of license available in license.txt file, in main folder
  *
  */
- 
- #pragma once
- 
- #include "CDefaultSpellMechanics.h"
+
+#pragma once
+
+#include "CDefaultSpellMechanics.h"
 
 class AcidBreathDamageMechanics: public DefaultSpellMechanics
 {
 public:
 	AcidBreathDamageMechanics(CSpell * s): DefaultSpellMechanics(s){};
 protected:
-	void applyBattleEffects(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;		
+	void applyBattleEffects(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
 };
 
 class DeathStareMechanics: public DefaultSpellMechanics
@@ -25,15 +25,15 @@ class DeathStareMechanics: public DefaultSpellMechanics
 public:
 	DeathStareMechanics(CSpell * s): DefaultSpellMechanics(s){};
 protected:
-	void applyBattleEffects(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;		
+	void applyBattleEffects(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
 };
 
 class DispellHelpfulMechanics: public DefaultSpellMechanics
 {
 public:
 	DispellHelpfulMechanics(CSpell * s): DefaultSpellMechanics(s){};
-	
+
 	void applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const override;
-	
-	ESpellCastProblem::ESpellCastProblem isImmuneByStack(const CGHeroInstance * caster, const CStack * obj) const override;	
+
+	ESpellCastProblem::ESpellCastProblem isImmuneByStack(const CGHeroInstance * caster, const CStack * obj) const override;
 };

+ 13 - 14
lib/spells/ISpellMechanics.cpp

@@ -17,12 +17,11 @@
 #include "BattleSpellMechanics.h"
 #include "CreatureSpellMechanics.h"
 
-
 ///ISpellMechanics
 ISpellMechanics::ISpellMechanics(CSpell * s):
 	owner(s)
 {
-	
+
 }
 
 ISpellMechanics * ISpellMechanics::createMechanics(CSpell * s)
@@ -32,20 +31,20 @@ ISpellMechanics * ISpellMechanics::createMechanics(CSpell * s)
 	case SpellID::ACID_BREATH_DAMAGE:
 		return new AcidBreathDamageMechanics(s);
 	case SpellID::CHAIN_LIGHTNING:
-		return new ChainLightningMechanics(s);		
+		return new ChainLightningMechanics(s);
 	case SpellID::CLONE:
 		return new CloneMechanics(s);
 	case SpellID::CURE:
 		return new CureMechanics(s);
 	case SpellID::DEATH_STARE:
-		return new DeathStareMechanics(s);			
+		return new DeathStareMechanics(s);
 	case SpellID::DISPEL:
-		return new DispellMechanics(s);	
+		return new DispellMechanics(s);
 	case SpellID::DISPEL_HELPFUL_SPELLS:
 		return new DispellHelpfulMechanics(s);
 	case SpellID::FIRE_WALL:
 	case SpellID::FORCE_FIELD:
-		return new WallMechanics(s);		
+		return new WallMechanics(s);
 	case SpellID::HYPNOTIZE:
 		return new HypnotizeMechanics(s);
 	case SpellID::LAND_MINE:
@@ -61,11 +60,11 @@ ISpellMechanics * ISpellMechanics::createMechanics(CSpell * s)
 	case SpellID::SUMMON_AIR_ELEMENTAL:
 		return new SummonMechanics(s);
 	case SpellID::TELEPORT:
-		return new TeleportMechanics(s);	
+		return new TeleportMechanics(s);
 	case SpellID::SUMMON_BOAT:
 		return new SummonBoatMechanics(s);
-	case SpellID::SCUTTLE_BOAT:		
-		return new ScuttleBoatMechanics(s);		
+	case SpellID::SCUTTLE_BOAT:
+		return new ScuttleBoatMechanics(s);
 	case SpellID::DIMENSION_DOOR:
 		return new DimensionDoorMechanics(s);
 	case SpellID::FLY:
@@ -77,12 +76,12 @@ ISpellMechanics * ISpellMechanics::createMechanics(CSpell * s)
 		return new TownPortalMechanics(s);
 	case SpellID::VIEW_EARTH:
 		return new ViewEarthMechanics(s);
-	case SpellID::VIEW_AIR:			
+	case SpellID::VIEW_AIR:
 		return new ViewAirMechanics(s);
-	default:		
+	default:
 		if(s->isRisingSpell())
 			return new SpecialRisingSpellMechanics(s);
-		else	
-			return new DefaultSpellMechanics(s);		
-	}	
+		else
+			return new DefaultSpellMechanics(s);
+	}
 }

+ 14 - 18
lib/spells/ISpellMechanics.h

@@ -7,7 +7,7 @@
  * Full text of license available in license.txt file, in main folder
  *
  */
- 
+
 #pragma once
 
 #include "CSpellHandler.h"
@@ -16,39 +16,35 @@
 class DLL_LINKAGE ISpellMechanics
 {
 public:
-	
 	struct DLL_LINKAGE SpellTargetingContext
 	{
-		const CBattleInfoCallback * cb;		
+		const CBattleInfoCallback * cb;
 		CSpell::TargetInfo ti;
 		ECastingMode::ECastingMode mode;
 		BattleHex destination;
 		PlayerColor casterColor;
 		int schoolLvl;
-		
+
 		SpellTargetingContext(const CSpell * s, const CBattleInfoCallback * c, ECastingMode::ECastingMode m, PlayerColor cc, int lvl, BattleHex dest)
 			: cb(c), ti(s,lvl, m), mode(m), destination(dest), casterColor(cc), schoolLvl(lvl)
 		{};
-		
+
 	};
-	
 public:
 	ISpellMechanics(CSpell * s);
-	virtual ~ISpellMechanics(){};	
-	
-	virtual std::vector<BattleHex> rangeInHexes(BattleHex centralHex, ui8 schoolLvl, ui8 side, bool *outDroppedHexes = nullptr) const = 0;
+	virtual ~ISpellMechanics(){};
+
+	virtual std::vector<BattleHex> rangeInHexes(BattleHex centralHex, ui8 schoolLvl, ui8 side, bool * outDroppedHexes = nullptr) const = 0;
 	virtual std::set<const CStack *> getAffectedStacks(SpellTargetingContext & ctx) const = 0;
-	
+
 	virtual ESpellCastProblem::ESpellCastProblem isImmuneByStack(const CGHeroInstance * caster, const CStack * obj) const = 0;
-                   
-	virtual bool adventureCast(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const = 0; 
-	virtual void battleCast(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters) const = 0; 	
-	
+
+	virtual bool adventureCast(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const = 0;
+	virtual void battleCast(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters) const = 0;
+
 	static ISpellMechanics * createMechanics(CSpell * s);
-	
+
 	virtual void applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const = 0;
-	
 protected:
-	CSpell * owner;	
+	CSpell * owner;
 };
-

+ 2 - 2
lib/spells/ViewSpellInt.cpp

@@ -17,11 +17,11 @@
 ObjectPosInfo::ObjectPosInfo():
 	pos(),id(Obj::NO_OBJ), subId(-1), owner(PlayerColor::CANNOT_DETERMINE)
 {
-	
+
 }
 
 ObjectPosInfo::ObjectPosInfo(const CGObjectInstance * obj):
 	pos(obj->pos),id(obj->ID), subId(obj->subID), owner(obj->tempOwner)
 {
-	
+
 }

+ 9 - 9
lib/spells/ViewSpellInt.h

@@ -7,26 +7,26 @@
  * Full text of license available in license.txt file, in main folder
  *
  */
- 
+
  #pragma once
- 
- #include "../int3.h" 
+
+ #include "../int3.h"
  #include "../GameConstants.h"
- 
+
  class CGObjectInstance;
- 
+
  struct DLL_LINKAGE ObjectPosInfo
  {
- 	int3 pos; 	
+ 	int3 pos;
  	Obj id;
  	si32 subId;
  	PlayerColor owner;
  	ObjectPosInfo();
  	ObjectPosInfo(const CGObjectInstance * obj);
- 	
-	template <typename Handler> void serialize(Handler &h, const int version)
+
+	template <typename Handler> void serialize(Handler & h, const int version)
 	{
 		h & pos & id & subId & owner;
-	} 	
+	}
  };