mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Implemented spell countering.
This commit is contained in:
		| @@ -49,20 +49,20 @@ | ||||
| 		{ "id": 38, "effect": 1, "anim": 79, "ranges": [ "0", "0", "0", "0" ] }, | ||||
| 		{ "id": 39, "effect": 1, "anim": 79, "ranges": [ "0", "0", "0", "0" ] }, | ||||
| 		{ "id": 40, "effect": 1, "anim": 79, "ranges": [ "0", "0", "0", "0" ] }, | ||||
| 		{ "id": 41, "effect": 1, "anim": 36, "ranges": [ "0", "0", "0", "X" ] }, | ||||
| 		{ "id": 42, "effect": -1, "anim": 40, "ranges": [ "0", "0", "0", "X" ] }, | ||||
| 		{ "id": 43, "effect": 1, "anim": 4, "ranges": [ "0", "0", "0", "X" ] }, | ||||
| 		{ "id": 41, "effect": 1, "anim": 36, "ranges": [ "0", "0", "0", "X" ], "counters" : [42] }, | ||||
| 		{ "id": 42, "effect": -1, "anim": 40, "ranges": [ "0", "0", "0", "X" ], "counters" : [41] }, | ||||
| 		{ "id": 43, "effect": 1, "anim": 4, "ranges": [ "0", "0", "0", "X" ], "counters" : [45] }, | ||||
| 		{ "id": 44, "effect": 1, "anim": 25, "ranges": [ "0", "0", "0", "X" ] }, | ||||
| 		{ "id": 45, "effect": -1, "anim": 56, "ranges": [ "0", "0", "0", "X" ] }, | ||||
| 		{ "id": 45, "effect": -1, "anim": 56, "ranges": [ "0", "0", "0", "X" ], "counters" : [43] }, | ||||
| 		{ "id": 46, "effect": 1, "anim": 54, "ranges": [ "0", "0", "0", "X" ] }, | ||||
| 		{ "id": 47, "effect": -1, "anim": 14, "ranges": [ "0", "0", "0", "0" ] }, | ||||
| 		{ "id": 48, "effect": 1, "anim": 0, "ranges": [ "0", "0", "0", "X" ] }, | ||||
| 		{ "id": 49, "effect": 1, "anim": 20, "ranges": [ "0", "0", "0", "X" ] }, | ||||
| 		{ "id": 50, "effect": -1, "anim": 30, "ranges": [ "0", "0", "0", "X" ] }, | ||||
| 		{ "id": 51, "effect": 1, "anim": 18, "ranges": [ "0", "0", "0", "X" ] }, | ||||
| 		{ "id": 52, "effect": -1, "anim": 48, "ranges": [ "0", "0", "0", "X" ] }, | ||||
| 		{ "id": 53, "effect": 1, "anim": 31, "ranges": [ "0", "0", "0", "X" ] }, | ||||
| 		{ "id": 54, "effect": -1, "anim": 19, "ranges": [ "0", "0", "0", "X" ] }, | ||||
| 		{ "id": 49, "effect": 1, "anim": 20, "ranges": [ "0", "0", "0", "X" ], "counters" : [50] }, | ||||
| 		{ "id": 50, "effect": -1, "anim": 30, "ranges": [ "0", "0", "0", "X" ], "counters" : [49] }, | ||||
| 		{ "id": 51, "effect": 1, "anim": 18, "ranges": [ "0", "0", "0", "X" ], "counters" : [52] }, | ||||
| 		{ "id": 52, "effect": -1, "anim": 48, "ranges": [ "0", "0", "0", "X" ], "counters" : [51] }, | ||||
| 		{ "id": 53, "effect": 1, "anim": 31, "ranges": [ "0", "0", "0", "X" ], "counters" : [54] }, | ||||
| 		{ "id": 54, "effect": -1, "anim": 19, "ranges": [ "0", "0", "0", "X" ], "counters" : [53] }, | ||||
| 		{ "id": 55, "effect": 1, "anim": 28, "ranges": [ "0", "0", "0", "0" ] }, | ||||
| 		{ "id": 56, "effect": 1, "anim": 17, "ranges": [ "0", "0", "0", "0" ] }, | ||||
| 		{ "id": 57, "effect": -1, "anim": 38, "ranges": [ "0", "0", "0", "0" ] }, | ||||
|   | ||||
| @@ -354,14 +354,17 @@ void CSpellHandler::loadSpells() | ||||
| 	{ | ||||
| 		//reading exact info | ||||
| 		int spellID = spell["id"].Float(); | ||||
| 		CSpell *s = spells[spellID]; | ||||
|  | ||||
| 		spells[spellID]->positiveness = spell["effect"].Float(); | ||||
| 		spells[spellID]->mainEffectAnim = spell["anim"].Float(); | ||||
| 		s->positiveness = spell["effect"].Float(); | ||||
| 		s->mainEffectAnim = spell["anim"].Float(); | ||||
|  | ||||
| 		spells[spellID]->range.resize(4); | ||||
| 		s->range.resize(4); | ||||
| 		int idx = 0; | ||||
| 		BOOST_FOREACH(const JsonNode &range, spell["ranges"].Vector()) | ||||
| 			spells[spellID]->range[idx++] = range.String(); | ||||
| 			s->range[idx++] = range.String(); | ||||
|  | ||||
| 		s->counteredSpells = spell["counters"].StdVector<TSpell>(); | ||||
| 	} | ||||
|  | ||||
| 	spells.push_back(spells[80]); //clone Acid Breath attributes for Acid Breath damage effect | ||||
|   | ||||
| @@ -41,6 +41,8 @@ public: | ||||
| 	bool creatureAbility; //if true, only creatures can use this spell | ||||
| 	si8 positiveness; //1 if spell is positive for influenced stacks, 0 if it is indifferent, -1 if it's negative | ||||
| 	std::vector<std::string> range; //description of spell's range in SRSL by magic school level | ||||
| 	std::vector<TSpell> counteredSpells; //spells that are removed when effect of this spell is placed on creature (for bless-curse, haste-slow, and similar pairs) | ||||
|  | ||||
| 	std::vector<BattleHex> rangeInHexes(BattleHex centralHex, ui8 schoolLvl, ui8 side, bool *outDroppedHexes = NULL ) 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) | ||||
| 	si16 mainEffectAnim; //main spell effect animation, in AC format (or -1 when none) | ||||
| 	ETargetType getTargetType() const; | ||||
| @@ -53,7 +55,7 @@ public: | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & id & name & abbName & descriptions & level & earth & water & fire & air & power & costs  | ||||
| 			& powers & probabilities & AIVals & attributes & combatSpell & creatureAbility & positiveness & range & mainEffectAnim; | ||||
| 			& powers & probabilities & AIVals & attributes & combatSpell & creatureAbility & positiveness & range & counteredSpells & mainEffectAnim; | ||||
| 	} | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -1239,20 +1239,28 @@ DLL_LINKAGE void BattleSpellCast::applyGs( CGameState *gs ) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if(id == 35 || id == 78) //dispel and dispel helpful spells | ||||
| 	//Handle spells removing effects from stacks | ||||
| 	const CSpell *spell = VLC->spellh->spells[id]; | ||||
| 	const bool removeAllSpells = id == Spells::DISPEL; | ||||
| 	const bool removeHelpful = id == Spells::DISPEL_HELPFUL_SPELLS; | ||||
|  | ||||
| 	BOOST_FOREACH(auto stackID, affectedCres) | ||||
| 	{ | ||||
| 		bool onlyHelpful = id == 78; | ||||
| 		for(std::set<ui32>::const_iterator it = affectedCres.begin(); it != affectedCres.end(); ++it) | ||||
| 		if(vstd::contains(resisted, stackID)) | ||||
| 			continue; | ||||
|  | ||||
| 		CStack *s = gs->curB->getStack(stackID); | ||||
| 		s->popBonuses([&](const Bonus *b) -> bool | ||||
| 		{ | ||||
| 			CStack *s = gs->curB->getStack(*it); | ||||
| 			if(s && !vstd::contains(resisted, s->ID)) //if stack exists and it didn't resist | ||||
| 			{ | ||||
| 				if(onlyHelpful) | ||||
| 					s->popBonuses(Selector::positiveSpellEffects); | ||||
| 				else | ||||
| 					s->popBonuses(Selector::sourceType(Bonus::SPELL_EFFECT)); | ||||
| 			} | ||||
| 		} | ||||
| 			//check for each bonus if it should be removed | ||||
| 			const bool isSpellEffect = Selector::sourceType(Bonus::SPELL_EFFECT)(b); | ||||
| 			const bool isPositiveSpell = Selector::positiveSpellEffects(b); | ||||
| 			const int spellID = isSpellEffect ? b->sid : -1; | ||||
|  | ||||
| 			return (removeHelpful && isPositiveSpell) | ||||
| 				|| (removeAllSpells && isSpellEffect) | ||||
| 				|| vstd::contains(spell->counteredSpells, spellID); | ||||
| 		}); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user