mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Merge pull request #4623 from Laserlicht/invincible_bonus
INVINCIBLE bonus
This commit is contained in:
		| @@ -337,7 +337,10 @@ BattleAction BattleEvaluator::moveOrAttack(const CStack * stack, BattleHex hex, | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		return BattleAction::makeMove(stack, hex); | ||||
| 		if(stack->position == hex) | ||||
| 			return BattleAction::makeDefend(stack); | ||||
| 		else | ||||
| 			return BattleAction::makeMove(stack, hex); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -296,7 +296,11 @@ BattleAction CStupidAI::goTowards(const BattleID & battleID, const CStack * stac | ||||
| 	for(auto hex : hexes) | ||||
| 	{ | ||||
| 		if(vstd::contains(avHexes, hex)) | ||||
| 		{ | ||||
| 			if(stack->position == hex) | ||||
| 				return BattleAction::makeDefend(stack); | ||||
| 			return BattleAction::makeMove(stack, hex); | ||||
| 		} | ||||
|  | ||||
| 		if(stack->coversPos(hex)) | ||||
| 		{ | ||||
| @@ -336,7 +340,11 @@ BattleAction CStupidAI::goTowards(const BattleID & battleID, const CStack * stac | ||||
| 			} | ||||
|  | ||||
| 			if(vstd::contains(avHexes, currentDest)) | ||||
| 			{ | ||||
| 				if(stack->position == currentDest) | ||||
| 					return BattleAction::makeDefend(stack); | ||||
| 				return BattleAction::makeMove(stack, currentDest); | ||||
| 			} | ||||
|  | ||||
| 			currentDest = reachability.predecessors[currentDest]; | ||||
| 		} | ||||
|   | ||||
| @@ -665,5 +665,7 @@ | ||||
| 	"core.bonus.WIDE_BREATH.name": "Wide breath", | ||||
| 	"core.bonus.WIDE_BREATH.description": "Wide breath attack (multiple hexes)", | ||||
| 	"core.bonus.DISINTEGRATE.name": "Disintegrate", | ||||
| 	"core.bonus.DISINTEGRATE.description": "No corpse remains after death" | ||||
| 	"core.bonus.DISINTEGRATE.description": "No corpse remains after death", | ||||
| 	"core.bonus.INVINCIBLE.name": "Invincible", | ||||
| 	"core.bonus.INVINCIBLE.description": "Cannot be affected by anything" | ||||
| } | ||||
|   | ||||
| @@ -600,6 +600,15 @@ | ||||
| 			"icon":  "zvs/Lib1.res/DISINTEGRATE" | ||||
| 		} | ||||
|  | ||||
| 	}, | ||||
|  | ||||
| 	"INVINCIBLE": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/INVINCIBLE" | ||||
| 		} | ||||
|  | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -10,6 +10,10 @@ | ||||
| 			"cavalryChargeImmunity" : | ||||
| 			{ | ||||
| 				"type" : "CHARGE_IMMUNITY" | ||||
| 			}, | ||||
| 			"invincible" : | ||||
| 			{ | ||||
| 				"type" : "INVINCIBLE" | ||||
| 			} | ||||
| 		}, | ||||
| 		"graphics" : | ||||
|   | ||||
| @@ -1022,4 +1022,8 @@ Internal bonus, do not use | ||||
|  | ||||
| ### DISINTEGRATE | ||||
|  | ||||
| After death of unit no corpse remains | ||||
| When a unit affected by this bonus dies, no corpse is left behind | ||||
|  | ||||
| ### INVINCIBLE | ||||
|  | ||||
| The unit affected by this bonus cannot be target of attacks or spells | ||||
|   | ||||
| @@ -296,6 +296,9 @@ std::vector<BattleHex> CStack::meleeAttackHexes(const battle::Unit * attacker, c | ||||
|  | ||||
| bool CStack::isMeleeAttackPossible(const battle::Unit * attacker, const battle::Unit * defender, BattleHex attackerPos, BattleHex defenderPos) | ||||
| { | ||||
| 	if(defender->hasBonusOfType(BonusType::INVINCIBLE)) | ||||
| 		return false; | ||||
| 		 | ||||
| 	return !meleeAttackHexes(attacker, defender, attackerPos, defenderPos).empty(); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -685,6 +685,9 @@ bool CBattleInfoCallback::battleCanAttack(const battle::Unit * stack, const batt | ||||
| 	if (!stack || !target) | ||||
| 		return false; | ||||
|  | ||||
| 	if(target->hasBonusOfType(BonusType::INVINCIBLE)) | ||||
| 		return false; | ||||
|  | ||||
| 	if(!battleMatchOwner(stack, target)) | ||||
| 		return false; | ||||
|  | ||||
| @@ -730,6 +733,9 @@ bool CBattleInfoCallback::battleCanShoot(const battle::Unit * attacker, BattleHe | ||||
| 	if(!attacker || !defender) | ||||
| 		return false; | ||||
|  | ||||
| 	if(defender->hasBonusOfType(BonusType::INVINCIBLE)) | ||||
| 		return false; | ||||
|  | ||||
| 	if(battleMatchOwner(attacker, defender) && defender->alive()) | ||||
| 	{ | ||||
| 		if(battleCanShoot(attacker)) | ||||
|   | ||||
| @@ -179,6 +179,7 @@ class JsonNode; | ||||
| 	BONUS_NAME(RESOURCES_CONSTANT_BOOST) /*Bonus that does not account for propagation and gives extra resources per day. val - resource amount, subtype - resource type*/ \ | ||||
| 	BONUS_NAME(RESOURCES_TOWN_MULTIPLYING_BOOST) /*Bonus that does not account for propagation and gives extra resources per day with amount multiplied by number of owned towns. val - base resource amount to be multiplied times number of owned towns, subtype - resource type*/ \ | ||||
| 	BONUS_NAME(DISINTEGRATE) /* after death no corpse remains */ \ | ||||
| 	BONUS_NAME(INVINCIBLE) /* cannot be target of attacks or spells */ \ | ||||
| 	/* end of list */ | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -228,8 +228,11 @@ bool BattleSpellMechanics::canBeCastAt(const Target & target, Problem & problem) | ||||
| 			mainTarget = battle()->battleGetUnitByPos(target.front().hexValue, true); | ||||
| 		} | ||||
|  | ||||
| 		if (mainTarget && mainTarget == caster) | ||||
| 		if(mainTarget && mainTarget == caster) | ||||
| 			return false; // can't cast on self | ||||
|  | ||||
| 		if(mainTarget && mainTarget->hasBonusOfType(BonusType::INVINCIBLE)) | ||||
| 			return false; | ||||
| 	} | ||||
|  | ||||
| 	return effects->applicable(problem, this, target, spellTarget); | ||||
|   | ||||
| @@ -425,6 +425,10 @@ int64_t CSpell::adjustRawDamage(const spells::Caster * caster, const battle::Uni | ||||
| 			ret *= 100 + bearer->valOfBonuses(BonusType::MORE_DAMAGE_FROM_SPELL, BonusSubtypeID(id)); | ||||
| 			ret /= 100; | ||||
| 		} | ||||
|  | ||||
| 		//invincible | ||||
| 		if(bearer->hasBonusOfType(BonusType::INVINCIBLE)) | ||||
| 			ret = 0; | ||||
| 	} | ||||
| 	ret = caster->getSpellBonus(this, ret, affectedCreature); | ||||
| 	return ret; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user