mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Add UNTIL_OWN_ATTACK bonus duration and use for berserk
This commit is contained in:
		| @@ -427,33 +427,36 @@ bool BattleEvaluator::attemptCastingSpell(const CStack * activeStack) | ||||
|  | ||||
| 				state->nextTurn(unit->unitId()); | ||||
|  | ||||
| 				PotentialTargets pt(unit, damageCache, state); | ||||
| 				PotentialTargets potentialTargets(unit, damageCache, state); | ||||
|  | ||||
| 				if(!pt.possibleAttacks.empty()) | ||||
| 				if(!potentialTargets.possibleAttacks.empty()) | ||||
| 				{ | ||||
| 					AttackPossibility ap = pt.bestAction(); | ||||
| 					AttackPossibility attackPossibility = potentialTargets.bestAction(); | ||||
|  | ||||
| 					auto swb = state->getForUpdate(unit->unitId()); | ||||
| 					*swb = *ap.attackerState; | ||||
| 					auto stackWithBonuses = state->getForUpdate(unit->unitId()); | ||||
| 					*stackWithBonuses = *attackPossibility.attackerState; | ||||
|  | ||||
| 					if(ap.defenderDamageReduce > 0) | ||||
| 						swb->removeUnitBonus(Bonus::UntilAttack); | ||||
| 					if(ap.attackerDamageReduce > 0) | ||||
| 						swb->removeUnitBonus(Bonus::UntilBeingAttacked); | ||||
|  | ||||
| 					for(auto affected : ap.affectedUnits) | ||||
| 					if(attackPossibility.defenderDamageReduce > 0) | ||||
| 					{ | ||||
| 						swb = state->getForUpdate(affected->unitId()); | ||||
| 						*swb = *affected; | ||||
| 						stackWithBonuses->removeUnitBonus(Bonus::UntilAttack); | ||||
| 						stackWithBonuses->removeUnitBonus(Bonus::UntilOwnAttack); | ||||
| 					} | ||||
| 					if(attackPossibility.attackerDamageReduce > 0) | ||||
| 						stackWithBonuses->removeUnitBonus(Bonus::UntilBeingAttacked); | ||||
|  | ||||
| 						if(ap.defenderDamageReduce > 0) | ||||
| 							swb->removeUnitBonus(Bonus::UntilBeingAttacked); | ||||
| 						if(ap.attackerDamageReduce > 0 && ap.attack.defender->unitId() == affected->unitId()) | ||||
| 							swb->removeUnitBonus(Bonus::UntilAttack); | ||||
| 					for(auto affected : attackPossibility.affectedUnits) | ||||
| 					{ | ||||
| 						stackWithBonuses = state->getForUpdate(affected->unitId()); | ||||
| 						*stackWithBonuses = *affected; | ||||
|  | ||||
| 						if(attackPossibility.defenderDamageReduce > 0) | ||||
| 							stackWithBonuses->removeUnitBonus(Bonus::UntilBeingAttacked); | ||||
| 						if(attackPossibility.attackerDamageReduce > 0 && attackPossibility.attack.defender->unitId() == affected->unitId()) | ||||
| 							stackWithBonuses->removeUnitBonus(Bonus::UntilAttack); | ||||
| 					} | ||||
| 				} | ||||
|  | ||||
| 				auto bav = pt.bestActionValue(); | ||||
| 				auto bav = potentialTargets.bestActionValue(); | ||||
|  | ||||
| 				//best action is from effective owner`s point if view, we need to convert to our point if view | ||||
| 				if(state->battleGetOwner(unit) != playerID) | ||||
|   | ||||
| @@ -1221,7 +1221,7 @@ | ||||
| 				"effects" : { | ||||
| 					"attacksNearestCreature" : { | ||||
| 						"type" : "ATTACKS_NEAREST_CREATURE", | ||||
| 						"duration" : "UNTIL_ATTACK" | ||||
| 						"duration" : "UNTIL_OWN_ATTACK" | ||||
| 					} | ||||
| 				} | ||||
| 			}, | ||||
|   | ||||
| @@ -13,4 +13,5 @@ Bonus may have any of these durations. They acts in disjunction. | ||||
| -   UNTIL_BEING_ATTACKED: removed after any damage-inflicting attack | ||||
| -   UNTIL_ATTACK: removed after attack and counterattacks are performed | ||||
| -   STACK_GETS_TURN: removed when stack gets its turn - used for defensive stance | ||||
| -   COMMANDER_KILLED | ||||
| -   COMMANDER_KILLED | ||||
| -   UNTIL_OWN_ATTACK: removed after attack (not counterattack) is performed | ||||
| @@ -162,6 +162,11 @@ struct DLL_LINKAGE Bonus : public std::enable_shared_from_this<Bonus> | ||||
| 		auto set = hb->duration & BonusDuration::COMMANDER_KILLED; | ||||
| 		return set.any(); | ||||
| 	} | ||||
| 	static bool UntilOwnAttack(const Bonus *hb) | ||||
| 	{ | ||||
| 		auto set = hb->duration & BonusDuration::UNTIL_OWN_ATTACK; | ||||
| 		return set.any(); | ||||
| 	} | ||||
| 	inline bool operator == (const BonusType & cf) const | ||||
| 	{ | ||||
| 		return type == cf; | ||||
|   | ||||
| @@ -44,6 +44,7 @@ const std::map<std::string, BonusDuration::Type> bonusDurationMap = | ||||
| 	BONUS_ITEM(UNTIL_ATTACK) | ||||
| 	BONUS_ITEM(STACK_GETS_TURN) | ||||
| 	BONUS_ITEM(COMMANDER_KILLED) | ||||
| 	BONUS_ITEM(UNTIL_OWN_ATTACK) | ||||
| 	{ "UNITL_BEING_ATTACKED", BonusDuration::UNTIL_BEING_ATTACKED }//typo, but used in some mods | ||||
| }; | ||||
| #undef BONUS_ITEM | ||||
|   | ||||
| @@ -215,7 +215,7 @@ enum class BonusType | ||||
| }; | ||||
| namespace BonusDuration  //when bonus is automatically removed | ||||
| { | ||||
| 	using Type = std::bitset<10>; | ||||
| 	using Type = std::bitset<11>; | ||||
| 	extern JsonNode toJson(const Type & duration); | ||||
| 	constexpr Type PERMANENT = 1 << 0; | ||||
| 	constexpr Type ONE_BATTLE = 1 << 1; //at the end of battle | ||||
| @@ -227,6 +227,7 @@ namespace BonusDuration  //when bonus is automatically removed | ||||
| 	constexpr Type UNTIL_ATTACK = 1 << 7; /*removed after attack and counterattacks are performed*/ | ||||
| 	constexpr Type STACK_GETS_TURN = 1 << 8; /*removed when stack gets its turn - used for defensive stance*/ | ||||
| 	constexpr Type COMMANDER_KILLED = 1 << 9; | ||||
| 	constexpr Type UNTIL_OWN_ATTACK = 1 << 10; /*removed after attack is performed (not counterattack)*/; | ||||
| }; | ||||
| enum class BonusSource | ||||
| { | ||||
|   | ||||
| @@ -2260,6 +2260,9 @@ void BattleAttack::applyGs(CGameState * gs) | ||||
| 		stackAttacked.applyGs(gs); | ||||
|  | ||||
| 	attacker->removeBonusesRecursive(Bonus::UntilAttack); | ||||
|  | ||||
| 	if(!this->counter()) | ||||
| 		attacker->removeBonusesRecursive(Bonus::UntilOwnAttack); | ||||
| } | ||||
|  | ||||
| void StartAction::applyGs(CGameState *gs) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user