Pārlūkot izejas kodu

Add UNTIL_OWN_ATTACK bonus duration and use for berserk

Dydzio 1 gadu atpakaļ
vecāks
revīzija
fe39faf36c

+ 20 - 17
AI/BattleAI/BattleEvaluator.cpp

@@ -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);
+					if(attackPossibility.defenderDamageReduce > 0)
+					{
+						stackWithBonuses->removeUnitBonus(Bonus::UntilAttack);
+						stackWithBonuses->removeUnitBonus(Bonus::UntilOwnAttack);
+					}
+					if(attackPossibility.attackerDamageReduce > 0)
+						stackWithBonuses->removeUnitBonus(Bonus::UntilBeingAttacked);
 
-					for(auto affected : ap.affectedUnits)
+					for(auto affected : attackPossibility.affectedUnits)
 					{
-						swb = state->getForUpdate(affected->unitId());
-						*swb = *affected;
+						stackWithBonuses = state->getForUpdate(affected->unitId());
+						*stackWithBonuses = *affected;
 
-						if(ap.defenderDamageReduce > 0)
-							swb->removeUnitBonus(Bonus::UntilBeingAttacked);
-						if(ap.attackerDamageReduce > 0 && ap.attack.defender->unitId() == affected->unitId())
-							swb->removeUnitBonus(Bonus::UntilAttack);
+						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)

+ 1 - 1
config/spells/timed.json

@@ -1221,7 +1221,7 @@
 				"effects" : {
 					"attacksNearestCreature" : {
 						"type" : "ATTACKS_NEAREST_CREATURE",
-						"duration" : "UNTIL_ATTACK"
+						"duration" : "UNTIL_OWN_ATTACK"
 					}
 				}
 			},

+ 2 - 1
docs/modders/Bonus/Bonus_Duration_Types.md

@@ -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

+ 5 - 0
lib/bonuses/Bonus.h

@@ -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;

+ 1 - 0
lib/bonuses/BonusEnum.cpp

@@ -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

+ 2 - 1
lib/bonuses/BonusEnum.h

@@ -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
 {

+ 3 - 0
lib/networkPacks/NetPacksLib.cpp

@@ -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)