From 7cf7543747c1be81e20a522e9ebc9e1aa6b3dd28 Mon Sep 17 00:00:00 2001 From: Dydzio Date: Mon, 1 Jan 2024 21:16:38 +0100 Subject: [PATCH] Configurable ferocity bonus --- Mods/vcmi/config/vcmi/english.json | 2 +- docs/modders/Bonus/Bonus_Types.md | 7 +++++++ lib/bonuses/BonusEnum.h | 2 +- server/battles/BattleActionProcessor.cpp | 14 ++++++++++---- 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/Mods/vcmi/config/vcmi/english.json b/Mods/vcmi/config/vcmi/english.json index e187f931b..8adc06222 100644 --- a/Mods/vcmi/config/vcmi/english.json +++ b/Mods/vcmi/config/vcmi/english.json @@ -380,7 +380,7 @@ "core.bonus.FEARLESS.name": "Fearless", "core.bonus.FEARLESS.description": "Immune to Fear ability", "core.bonus.FEROCITY.name": "Ferocity", - "core.bonus.FEROCITY.description": "DESCRIPTION TO BE ADDED", + "core.bonus.FEROCITY.description": "Attacks ${val} additional times if killed anybody", "core.bonus.FLYING.name": "Fly", "core.bonus.FLYING.description": "Flies when moving (ignores obstacles)", "core.bonus.FREE_SHOOTING.name": "Shoot Close", diff --git a/docs/modders/Bonus/Bonus_Types.md b/docs/modders/Bonus/Bonus_Types.md index 6836066cc..ca008ae37 100644 --- a/docs/modders/Bonus/Bonus_Types.md +++ b/docs/modders/Bonus/Bonus_Types.md @@ -608,6 +608,13 @@ Affected unit can use ranged attacks only within specified range - val: max shooting range in hexes - addInfo: optional, range at which ranged penalty will trigger (default is 10) +### FEROCITY + +Affected unit will attack additional times if killed creatures during attacking (including ADDITIONAL_ATTACK bonus attacks) + +- val: amount of additional attacks (negative number will reduce number of unperformed attacks if any left) +- addInfo: optional, amount of creatures needed to kill (default is 1) + ## Special abilities ### CATAPULT diff --git a/lib/bonuses/BonusEnum.h b/lib/bonuses/BonusEnum.h index 2b694a5d4..6a8c34fae 100644 --- a/lib/bonuses/BonusEnum.h +++ b/lib/bonuses/BonusEnum.h @@ -173,7 +173,7 @@ class JsonNode; BONUS_NAME(UNLIMITED_MOVEMENT) /*cheat bonus*/ \ BONUS_NAME(MAX_MORALE) /*cheat bonus*/ \ BONUS_NAME(MAX_LUCK) /*cheat bonus*/ \ - BONUS_NAME(FEROCITY) /*extra attack, only if at least 1 creature killed in opponent target unit*/ \ + BONUS_NAME(FEROCITY) /*extra attacks, only if at least some creatures killed in opponent target unit, val = amount of additional attacks, additional info = amount of creatures killed to trigger (default 1)*/ \ /* end of list */ diff --git a/server/battles/BattleActionProcessor.cpp b/server/battles/BattleActionProcessor.cpp index dd82fe62e..eeea4ec19 100644 --- a/server/battles/BattleActionProcessor.cpp +++ b/server/battles/BattleActionProcessor.cpp @@ -271,7 +271,7 @@ bool BattleActionProcessor::doAttackAction(const CBattleInfoCallback & battle, c const bool firstStrike = destinationStack->hasBonusOfType(BonusType::FIRST_STRIKE); const bool retaliation = destinationStack->ableToRetaliate(); bool ferocityApplied = false; - int32_t defenderCreatureQuantity = destinationStack->getCount(); + int32_t defenderInitialQuantity = destinationStack->getCount(); for (int i = 0; i < totalAttacks; ++i) { @@ -286,10 +286,16 @@ bool BattleActionProcessor::doAttackAction(const CBattleInfoCallback & battle, c { makeAttack(battle, stack, destinationStack, (i ? 0 : distance), destinationTile, i==0, false, false);//no distance travelled on second attack - if(!ferocityApplied && stack->hasBonusOfType(BonusType::FEROCITY) && destinationStack->getCount() < defenderCreatureQuantity) + if(!ferocityApplied && stack->hasBonusOfType(BonusType::FEROCITY)) { - ferocityApplied = true; - ++totalAttacks; + auto ferocityBonus = stack->getBonus(Selector::type()(BonusType::FEROCITY)); + int32_t requiredCreaturesToKill = ferocityBonus->additionalInfo != CAddInfo::NONE ? ferocityBonus->additionalInfo[0] : 1; + if(defenderInitialQuantity - destinationStack->getCount() >= requiredCreaturesToKill) + { + ferocityApplied = true; + int additionalAttacksCount = stack->valOfBonuses(BonusType::FEROCITY); + totalAttacks += additionalAttacksCount; + } } }