mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	This commit is contained in:
		| @@ -2050,8 +2050,8 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType) | ||||
| 			case ANY_LOCATION: | ||||
| 				if (myNumber > -1) //TODO: this should be checked for all actions | ||||
| 				{ | ||||
| 					creatureCasting = stackCanCastSpell && !spellDestSelectMode; //as isCastingPossibleHere is not called | ||||
| 					legalAction = true; | ||||
| 					if(isCastingPossibleHere (sactive, shere, myNumber)) | ||||
| 						legalAction = true; | ||||
| 				} | ||||
| 				break; | ||||
| 			case AIMED_SPELL_CREATURE: | ||||
|   | ||||
| @@ -624,7 +624,7 @@ std::vector<BattleHex> DefaultSpellMechanics::rangeInHexes(BattleHex centralHex, | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| std::vector<const CStack *> DefaultSpellMechanics::getAffectedStacks(const CBattleInfoCallback * cb, SpellTargetingContext & ctx) const | ||||
| std::vector<const CStack *> DefaultSpellMechanics::getAffectedStacks(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const | ||||
| { | ||||
| 	std::vector<const CStack *> attackedCres = calculateAffectedStacks(cb, ctx); | ||||
| 	handleImmunities(cb, ctx, attackedCres); | ||||
| @@ -707,8 +707,13 @@ ESpellCastProblem::ESpellCastProblem DefaultSpellMechanics::canBeCast(const CBat | ||||
|  | ||||
| ESpellCastProblem::ESpellCastProblem DefaultSpellMechanics::canBeCast(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const | ||||
| { | ||||
| 	//no problems by default, this method is for spell-specific problems | ||||
| 	//common problems handled by CSpell | ||||
| 	if(ctx.mode == ECastingMode::CREATURE_ACTIVE_CASTING || ctx.mode == ECastingMode::HERO_CASTING) | ||||
| 	{ | ||||
| 		std::vector<const CStack *> affected = getAffectedStacks(cb, ctx); | ||||
| 		if(affected.empty()) | ||||
| 			return ESpellCastProblem::NO_APPROPRIATE_TARGET; | ||||
| 	} | ||||
|  | ||||
| 	return ESpellCastProblem::OK; | ||||
| } | ||||
|  | ||||
| @@ -836,6 +841,13 @@ bool DefaultSpellMechanics::requiresCreatureTarget() const | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| ESpellCastProblem::ESpellCastProblem SpecialSpellMechanics::canBeCast(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const | ||||
| { | ||||
| 	//no problems by default | ||||
| 	//common problems handled by CSpell | ||||
| 	return ESpellCastProblem::OK; | ||||
| } | ||||
|  | ||||
| std::vector<const CStack *> SpecialSpellMechanics::calculateAffectedStacks(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const | ||||
| { | ||||
| 	return std::vector<const CStack *>(); | ||||
|   | ||||
| @@ -48,7 +48,7 @@ public: | ||||
| 	DefaultSpellMechanics(CSpell * s): ISpellMechanics(s){}; | ||||
|  | ||||
| 	std::vector<BattleHex> rangeInHexes(BattleHex centralHex, ui8 schoolLvl, ui8 side, bool * outDroppedHexes = nullptr) const override; | ||||
| 	std::vector<const CStack *> getAffectedStacks(const CBattleInfoCallback * cb, SpellTargetingContext & ctx) const override final; | ||||
| 	std::vector<const CStack *> getAffectedStacks(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const override final; | ||||
|  | ||||
| 	ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster) const override; | ||||
| 	ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const override; | ||||
| @@ -91,6 +91,8 @@ class DLL_LINKAGE SpecialSpellMechanics : public DefaultSpellMechanics | ||||
| { | ||||
| public: | ||||
| 	SpecialSpellMechanics(CSpell * s): DefaultSpellMechanics(s){}; | ||||
|  | ||||
| 	ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const override; | ||||
| protected: | ||||
| 	std::vector<const CStack *> calculateAffectedStacks(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const override; | ||||
| }; | ||||
|   | ||||
| @@ -214,7 +214,7 @@ std::vector<BattleHex> CSpell::rangeInHexes(BattleHex centralHex, ui8 schoolLvl, | ||||
| std::vector<const CStack *> CSpell::getAffectedStacks(const CBattleInfoCallback * cb, ECastingMode::ECastingMode mode, const ISpellCaster * caster, int spellLvl, BattleHex destination) const | ||||
| { | ||||
| 	SpellTargetingContext ctx(this, mode, caster, spellLvl, destination); | ||||
| 	return mechanics->getAffectedStacks(cb, ctx);; | ||||
| 	return mechanics->getAffectedStacks(cb, ctx); | ||||
| } | ||||
|  | ||||
| CSpell::ETargetType CSpell::getTargetType() const | ||||
| @@ -362,81 +362,7 @@ ESpellCastProblem::ESpellCastProblem CSpell::canBeCastAt(const CBattleInfoCallba | ||||
| { | ||||
| 	SpellTargetingContext ctx(this, mode, caster, caster->getSpellSchoolLevel(this), destination); | ||||
|  | ||||
| 	ESpellCastProblem::ESpellCastProblem specific = mechanics->canBeCast(cb, ctx); | ||||
|  | ||||
| 	if(specific != ESpellCastProblem::OK) | ||||
| 		return specific; | ||||
|  | ||||
| 	//todo: this should be moved to mechanics | ||||
| 	//rising spells handled by mechanics | ||||
| 	if(ctx.ti.onlyAlive && getTargetType() == CSpell::CREATURE) | ||||
| 	{ | ||||
| 		const CStack * aliveStack = cb->getStackIf([destination](const CStack * s) | ||||
| 		{ | ||||
| 			return s->isValidTarget(false) && s->coversPos(destination); | ||||
| 		}); | ||||
|  | ||||
| 		if(!aliveStack) | ||||
| 			return ESpellCastProblem::NO_APPROPRIATE_TARGET; | ||||
| 		if(ctx.ti.smart && isNegative() && aliveStack->owner == caster->getOwner()) | ||||
| 			return ESpellCastProblem::NO_APPROPRIATE_TARGET; | ||||
| 		if(ctx.ti.smart && isPositive() && aliveStack->owner != caster->getOwner()) | ||||
| 			return ESpellCastProblem::NO_APPROPRIATE_TARGET; | ||||
| 	} | ||||
|  | ||||
| 	return isImmuneAt(cb, caster, mode, destination); | ||||
| } | ||||
|  | ||||
| ESpellCastProblem::ESpellCastProblem CSpell::isImmuneAt(const CBattleInfoCallback * cb, const ISpellCaster * caster, ECastingMode::ECastingMode mode, BattleHex destination) const | ||||
| { | ||||
| 	// Get all stacks at destination hex. only alive if not rising spell | ||||
| 	TStacks stacks = cb->battleGetStacksIf([=](const CStack * s) | ||||
| 	{ | ||||
| 		return s->coversPos(destination) && s->isValidTarget(isRisingSpell()); | ||||
| 	}); | ||||
|  | ||||
| 	if(!stacks.empty()) | ||||
| 	{ | ||||
| 		bool allImmune = true; | ||||
|  | ||||
| 		ESpellCastProblem::ESpellCastProblem problem = ESpellCastProblem::INVALID; | ||||
|  | ||||
| 		for(auto s : stacks) | ||||
| 		{ | ||||
| 			ESpellCastProblem::ESpellCastProblem res = isImmuneByStack(caster,s); | ||||
|  | ||||
| 			if(res == ESpellCastProblem::OK) | ||||
| 			{ | ||||
| 				allImmune = false; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				problem = res; | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if(allImmune) | ||||
| 			return problem; | ||||
| 	} | ||||
| 	else //no target stack on this tile | ||||
| 	{ | ||||
| 		if(getTargetType() == CSpell::CREATURE) | ||||
| 		{ | ||||
| 			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; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
|  				return ESpellCastProblem::WRONG_SPELL_TARGET; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return ESpellCastProblem::OK; | ||||
| 	return mechanics->canBeCast(cb, ctx); | ||||
| } | ||||
|  | ||||
| int CSpell::adjustRawDamage(const ISpellCaster * caster, const CStack * affectedCreature, int rawDamage) const | ||||
|   | ||||
| @@ -298,10 +298,6 @@ public://internal, for use only by Mechanics classes | ||||
| 	ESpellCastProblem::ESpellCastProblem internalIsImmune(const ISpellCaster * caster, const CStack *obj) const; | ||||
|  | ||||
| private: | ||||
|  | ||||
| 	///checks for creature immunity *at given hex*. | ||||
| 	ESpellCastProblem::ESpellCastProblem isImmuneAt(const CBattleInfoCallback * cb, const ISpellCaster * caster, ECastingMode::ECastingMode mode, BattleHex destination) const; | ||||
|  | ||||
| 	void setIsOffensive(const bool val); | ||||
| 	void setIsRising(const bool val); | ||||
|  | ||||
|   | ||||
| @@ -107,7 +107,7 @@ public: | ||||
| 	virtual ~ISpellMechanics(){}; | ||||
|  | ||||
| 	virtual std::vector<BattleHex> rangeInHexes(BattleHex centralHex, ui8 schoolLvl, ui8 side, bool * outDroppedHexes = nullptr) const = 0; | ||||
| 	virtual std::vector<const CStack *> getAffectedStacks(const CBattleInfoCallback * cb, SpellTargetingContext & ctx) const = 0; | ||||
| 	virtual std::vector<const CStack *> getAffectedStacks(const CBattleInfoCallback * cb, const SpellTargetingContext & ctx) const = 0; | ||||
|  | ||||
| 	virtual ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, const ECastingMode::ECastingMode mode, const ISpellCaster * caster) const = 0; | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user