mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	| @@ -772,7 +772,7 @@ void CSpellWindow::SpellArea::clickRight(tribool down, bool previousState) | ||||
| 		std::string dmgInfo; | ||||
| 		const CGHeroInstance * hero = owner->myHero; | ||||
| 		int causedDmg = owner->myInt->cb->estimateSpellDamage( CGI->spellh->spells[mySpell], (hero ? hero : NULL)); | ||||
| 		if(causedDmg == 0) | ||||
| 		if(causedDmg == 0 || mySpell == 57) //Titan's Lightning Bolt already has damage info included | ||||
| 			dmgInfo = ""; | ||||
| 		else | ||||
| 		{ | ||||
|   | ||||
							
								
								
									
										2
									
								
								global.h
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								global.h
									
									
									
									
									
								
							| @@ -25,7 +25,7 @@ typedef boost::int32_t si32; //signed int 32 bits (4 bytes) | ||||
| typedef boost::int16_t si16; //signed int 16 bits (2 bytes) | ||||
| typedef boost::int8_t si8; //signed int 8 bits (1 byte) | ||||
| typedef si64 expType; | ||||
| typedef ui16 spelltype; | ||||
| typedef ui32 TSpell; | ||||
| typedef std::pair<ui32, ui32> TDmgRange; | ||||
| typedef ui8 TBonusType; | ||||
| typedef si32 TBonusSubtype; | ||||
|   | ||||
| @@ -914,13 +914,9 @@ ui32 BattleInfo::calculateSpellDmg( const CSpell * sp, const CGHeroInstance * ca | ||||
|  | ||||
| 	//15 - magic arrows, 16 - ice bolt, 17 - lightning bolt, 18 - implosion, 20 - frost ring, 21 - fireball, 22 - inferno, 23 - meteor shower, | ||||
| 	//24 - death ripple, 25 - destroy undead, 26 - armageddon, 77 - thunderbolt | ||||
| 	 | ||||
| 	//FIXME: what point of dmgMultipliers map? all damage multipliers are already present in CSpell::power | ||||
| 	//TODO: better way to determine damage spells | ||||
| 	static std::map <int, int> dmgMultipliers = boost::assign::map_list_of(15, 10)(16, 20)(17, 25)(18, 75)(20, 10)(21, 10)(22, 10)(23, 25)(24, 5)(25, 10)(26, 50)(77, 10); | ||||
|  | ||||
| 	//check if spell really does damage - if not, return 0 | ||||
| 	if(dmgMultipliers.find(sp->id) == dmgMultipliers.end()) | ||||
| 	if(VLC->spellh->damageSpells.find(sp->id) == VLC->spellh->damageSpells.end()) | ||||
| 		return 0; | ||||
|  | ||||
| 	ret = usedSpellPower * sp->power; | ||||
| @@ -1782,6 +1778,21 @@ bool NegateRemover(const Bonus* b) | ||||
| 	return b->source == Bonus::CREATURE_ABILITY; | ||||
| } | ||||
|  | ||||
| bool BattleInfo::battleTestElementalImmunity(const CStack * subject, const CSpell * spell, Bonus::BonusType element, bool damageSpell) const //helper for battleisImmune | ||||
| { | ||||
| 	if (spell->positiveness < 1) //negative or indifferent | ||||
| 	{ | ||||
| 		if (damageSpell && subject->hasBonusOfType(element, 2) || subject->hasBonusOfType(element, 1)) | ||||
| 			return true; | ||||
| 	} | ||||
| 	else if (spell->positiveness == 1) //positive | ||||
| 	{ | ||||
| 		if (subject->hasBonusOfType(element, 0)) //must be immune to all spells | ||||
| 			return true; | ||||
| 	} | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
| SpellCasting::ESpellCastProblem BattleInfo::battleIsImmune(const CGHeroInstance * caster, const CSpell * spell, SpellCasting::ECastingMode mode, THex dest) const | ||||
| { | ||||
| 	const CStack * subject = getStackT(dest, false); | ||||
| @@ -1792,59 +1803,31 @@ SpellCasting::ESpellCastProblem BattleInfo::battleIsImmune(const CGHeroInstance | ||||
|  | ||||
| 		if ((spell->id == 41 || spell->id == 42) && subject->hasBonusOfType(Bonus::UNDEAD)) //undeads are immune to bless & curse | ||||
| 			return SpellCasting::STACK_IMMUNE_TO_SPELL; //TODO: more general logic for new spells? | ||||
| 		 | ||||
| 		bool damageSpell = (VLC->spellh->damageSpells.find(spell->id) != VLC->spellh->damageSpells.end()); | ||||
|  | ||||
| 		if (damageSpell && subject->hasBonusOfType(Bonus::DIRECT_DAMAGE_IMMUNITY)); | ||||
| 			return SpellCasting::STACK_IMMUNE_TO_SPELL; | ||||
|  | ||||
| 		if (spell->fire) | ||||
| 		{ | ||||
|  | ||||
| 			if (spell->positiveness == -1) //negative | ||||
| 			{ | ||||
| 				if (subject->hasBonusOfType(Bonus::FIRE_IMMUNITY)) //both damage and curse spells, TODO: separate them | ||||
| 					return SpellCasting::STACK_IMMUNE_TO_SPELL; | ||||
| 			} | ||||
| 			else if (spell->positiveness == 1) | ||||
| 			{ | ||||
| 				if (subject->hasBonusOfType(Bonus::FIRE_IMMUNITY, 1)) | ||||
| 					return SpellCasting::STACK_IMMUNE_TO_SPELL; | ||||
| 			} | ||||
| 			if (battleTestElementalImmunity(subject, spell, Bonus::FIRE_IMMUNITY, damageSpell)); | ||||
| 				return SpellCasting::STACK_IMMUNE_TO_SPELL; | ||||
| 		} | ||||
| 		if (spell->water) | ||||
| 		{ | ||||
| 			if (spell->positiveness == -1) //negative | ||||
| 			{ | ||||
| 				if (subject->hasBonusOfType(Bonus::WATER_IMMUNITY)) //both damage and curse spells, TODO: separate them | ||||
| 					return SpellCasting::STACK_IMMUNE_TO_SPELL; | ||||
| 			} | ||||
| 			else if (spell->positiveness == 1) | ||||
| 			{ | ||||
| 				if (subject->hasBonusOfType(Bonus::WATER_IMMUNITY, 1)) | ||||
| 					return SpellCasting::STACK_IMMUNE_TO_SPELL; | ||||
| 			} | ||||
| 			if (battleTestElementalImmunity(subject, spell, Bonus::WATER_IMMUNITY, damageSpell)); | ||||
| 				return SpellCasting::STACK_IMMUNE_TO_SPELL; | ||||
| 		} | ||||
| 		if (spell->earth) | ||||
| 		{ | ||||
| 			if (spell->positiveness == -1) //negative | ||||
| 			{ | ||||
| 				if (subject->hasBonusOfType(Bonus::EARTH_IMMUNITY)) //both damage and curse spells, TODO: separate them | ||||
| 					return SpellCasting::STACK_IMMUNE_TO_SPELL; | ||||
| 			} | ||||
| 			else if (spell->positiveness == 1) | ||||
| 			{ | ||||
| 				if (subject->hasBonusOfType(Bonus::EARTH_IMMUNITY, 1)) | ||||
| 					return SpellCasting::STACK_IMMUNE_TO_SPELL; | ||||
| 			} | ||||
| 			if (battleTestElementalImmunity(subject, spell, Bonus::EARTH_IMMUNITY, damageSpell)); | ||||
| 				return SpellCasting::STACK_IMMUNE_TO_SPELL; | ||||
| 		} | ||||
| 		if (spell->air) | ||||
| 		{ | ||||
| 			if (spell->positiveness == -1) //negative | ||||
| 			{ | ||||
| 				if (subject->hasBonusOfType(Bonus::AIR_IMMUNITY)) //both damage and curse spells, TODO: separate them | ||||
| 					return SpellCasting::STACK_IMMUNE_TO_SPELL; | ||||
| 			} | ||||
| 			else if (spell->positiveness == 1) | ||||
| 			{ | ||||
| 				if (subject->hasBonusOfType(Bonus::AIR_IMMUNITY, 1)) | ||||
| 					return SpellCasting::STACK_IMMUNE_TO_SPELL; | ||||
| 			} | ||||
| 			if (battleTestElementalImmunity(subject, spell, Bonus::AIR_IMMUNITY, damageSpell)); | ||||
| 				return SpellCasting::STACK_IMMUNE_TO_SPELL; | ||||
| 		} | ||||
|  | ||||
| 		BonusList immunities = subject->getBonuses(Selector::type(Bonus::LEVEL_SPELL_IMMUNITY)); | ||||
|   | ||||
| @@ -109,6 +109,7 @@ struct DLL_EXPORT BattleInfo : public CBonusSystemNode | ||||
| 	SpellCasting::ESpellCastProblem battleCanCastThisSpell(int player, const CSpell * spell, SpellCasting::ECastingMode mode) const; //checks if given player can cast given spell | ||||
| 	SpellCasting::ESpellCastProblem battleIsImmune(const CGHeroInstance * caster, const CSpell * spell, SpellCasting::ECastingMode mode, THex dest) const; //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. | ||||
| 	SpellCasting::ESpellCastProblem battleCanCastThisSpellHere(int player, const CSpell * spell, SpellCasting::ECastingMode mode, THex dest); //checks if given player can cast given spell at given tile in given mode | ||||
| 	bool battleTestElementalImmunity(const CStack * subject, const CSpell * spell, Bonus::BonusType element, bool damageSpell) const; | ||||
|  | ||||
| 	std::vector<ui32> calculateResistedStacks(const CSpell * sp, const CGHeroInstance * caster, const CGHeroInstance * hero2, const std::set<CStack*> affectedCreatures, int casterSideOwner, SpellCasting::ECastingMode mode) const; | ||||
|  | ||||
|   | ||||
| @@ -4,6 +4,7 @@ | ||||
| #include "CLodHandler.h" | ||||
| #include "../lib/VCMI_Lib.h" | ||||
| #include <boost/algorithm/string/replace.hpp> | ||||
| #include <boost/assign/std/set.hpp> | ||||
| #include <cctype> | ||||
|  | ||||
|  | ||||
| @@ -18,6 +19,7 @@ extern CLodHandler *bitmaph; | ||||
|  * Full text of license available in license.txt file, in main folder | ||||
|  * | ||||
|  */ | ||||
| using namespace boost::assign; | ||||
|  | ||||
| namespace SRSLPraserHelpers | ||||
| { | ||||
| @@ -323,4 +325,6 @@ void CSpellHandler::loadSpells() | ||||
| 	} | ||||
| 	ast.close(); | ||||
| 	spells.push_back(spells[80]); //clone Acid Breath attributes for Acid Breath damage effect | ||||
|  | ||||
| 	damageSpells += 11, 13, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 57, 77; | ||||
| } | ||||
|   | ||||
| @@ -63,11 +63,12 @@ class DLL_EXPORT CSpellHandler | ||||
| public: | ||||
| 	CSpellHandler(); | ||||
| 	std::vector< ConstTransitivePtr<CSpell> > spells; | ||||
| 	std::set<TSpell> damageSpells; //they inflict damage and require particular threatment | ||||
| 	void loadSpells(); | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & spells; | ||||
| 		h & spells & damageSpells; | ||||
| 	} | ||||
| }; | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user