1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Add UNTIL_OWN_ATTACK bonus duration and use for berserk

This commit is contained in:
Dydzio 2023-12-19 19:52:40 +01:00
parent f40e711721
commit fe39faf36c
7 changed files with 35 additions and 21 deletions

View File

@ -427,33 +427,36 @@ bool BattleEvaluator::attemptCastingSpell(const CStack * activeStack)
state->nextTurn(unit->unitId()); 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()); auto stackWithBonuses = state->getForUpdate(unit->unitId());
*swb = *ap.attackerState; *stackWithBonuses = *attackPossibility.attackerState;
if(ap.defenderDamageReduce > 0) if(attackPossibility.defenderDamageReduce > 0)
swb->removeUnitBonus(Bonus::UntilAttack);
if(ap.attackerDamageReduce > 0)
swb->removeUnitBonus(Bonus::UntilBeingAttacked);
for(auto affected : ap.affectedUnits)
{ {
swb = state->getForUpdate(affected->unitId()); stackWithBonuses->removeUnitBonus(Bonus::UntilAttack);
*swb = *affected; stackWithBonuses->removeUnitBonus(Bonus::UntilOwnAttack);
}
if(attackPossibility.attackerDamageReduce > 0)
stackWithBonuses->removeUnitBonus(Bonus::UntilBeingAttacked);
if(ap.defenderDamageReduce > 0) for(auto affected : attackPossibility.affectedUnits)
swb->removeUnitBonus(Bonus::UntilBeingAttacked); {
if(ap.attackerDamageReduce > 0 && ap.attack.defender->unitId() == affected->unitId()) stackWithBonuses = state->getForUpdate(affected->unitId());
swb->removeUnitBonus(Bonus::UntilAttack); *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 //best action is from effective owner`s point if view, we need to convert to our point if view
if(state->battleGetOwner(unit) != playerID) if(state->battleGetOwner(unit) != playerID)

View File

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

View File

@ -14,3 +14,4 @@ Bonus may have any of these durations. They acts in disjunction.
- UNTIL_ATTACK: removed after attack and counterattacks are performed - UNTIL_ATTACK: removed after attack and counterattacks are performed
- STACK_GETS_TURN: removed when stack gets its turn - used for defensive stance - 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

View File

@ -162,6 +162,11 @@ struct DLL_LINKAGE Bonus : public std::enable_shared_from_this<Bonus>
auto set = hb->duration & BonusDuration::COMMANDER_KILLED; auto set = hb->duration & BonusDuration::COMMANDER_KILLED;
return set.any(); 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 inline bool operator == (const BonusType & cf) const
{ {
return type == cf; return type == cf;

View File

@ -44,6 +44,7 @@ const std::map<std::string, BonusDuration::Type> bonusDurationMap =
BONUS_ITEM(UNTIL_ATTACK) BONUS_ITEM(UNTIL_ATTACK)
BONUS_ITEM(STACK_GETS_TURN) BONUS_ITEM(STACK_GETS_TURN)
BONUS_ITEM(COMMANDER_KILLED) BONUS_ITEM(COMMANDER_KILLED)
BONUS_ITEM(UNTIL_OWN_ATTACK)
{ "UNITL_BEING_ATTACKED", BonusDuration::UNTIL_BEING_ATTACKED }//typo, but used in some mods { "UNITL_BEING_ATTACKED", BonusDuration::UNTIL_BEING_ATTACKED }//typo, but used in some mods
}; };
#undef BONUS_ITEM #undef BONUS_ITEM

View File

@ -215,7 +215,7 @@ enum class BonusType
}; };
namespace BonusDuration //when bonus is automatically removed namespace BonusDuration //when bonus is automatically removed
{ {
using Type = std::bitset<10>; using Type = std::bitset<11>;
extern JsonNode toJson(const Type & duration); extern JsonNode toJson(const Type & duration);
constexpr Type PERMANENT = 1 << 0; constexpr Type PERMANENT = 1 << 0;
constexpr Type ONE_BATTLE = 1 << 1; //at the end of battle 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 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 STACK_GETS_TURN = 1 << 8; /*removed when stack gets its turn - used for defensive stance*/
constexpr Type COMMANDER_KILLED = 1 << 9; constexpr Type COMMANDER_KILLED = 1 << 9;
constexpr Type UNTIL_OWN_ATTACK = 1 << 10; /*removed after attack is performed (not counterattack)*/;
}; };
enum class BonusSource enum class BonusSource
{ {

View File

@ -2260,6 +2260,9 @@ void BattleAttack::applyGs(CGameState * gs)
stackAttacked.applyGs(gs); stackAttacked.applyGs(gs);
attacker->removeBonusesRecursive(Bonus::UntilAttack); attacker->removeBonusesRecursive(Bonus::UntilAttack);
if(!this->counter())
attacker->removeBonusesRecursive(Bonus::UntilOwnAttack);
} }
void StartAction::applyGs(CGameState *gs) void StartAction::applyGs(CGameState *gs)