Jelajahi Sumber

Add ENEMY_ATTACK_REDUCTION bonus - fixes HotA Nix

Dydzio 1 tahun lalu
induk
melakukan
675f9b11fa

+ 2 - 0
Mods/vcmi/config/vcmi/english.json

@@ -371,6 +371,8 @@
 	"core.bonus.ENCHANTER.description": "Can cast mass ${subtype.spell} every turn",
 	"core.bonus.ENCHANTED.name": "Enchanted",
 	"core.bonus.ENCHANTED.description": "Affected by permanent ${subtype.spell}",
+	"core.bonus.ENEMY_ATTACK_REDUCTION.name": "Ignore Attack (${val}%)",
+	"core.bonus.ENEMY_ATTACK_REDUCTION.description": "When being attacked, ${val}% of the attacker's attack is ignored",
 	"core.bonus.ENEMY_DEFENCE_REDUCTION.name": "Ignore Defense (${val}%)",
 	"core.bonus.ENEMY_DEFENCE_REDUCTION.description": "When attacking, ${val}% of the defender's defense is ignored",
 	"core.bonus.FIRE_IMMUNITY.name": "Fire immunity",

+ 8 - 0
config/bonuses.json

@@ -152,6 +152,14 @@
 		}
 	},
 
+	"ENEMY_ATTACK_REDUCTION":
+	{
+		"graphics":
+		{
+			"icon":  "zvs/Lib1.res/E_RDEF"
+		}
+	},
+
 	"ENEMY_DEFENCE_REDUCTION":
 	{
 		"graphics":

+ 6 - 0
docs/modders/Bonus/Bonus_Types.md

@@ -615,6 +615,12 @@ Affected unit will attack additional times if killed creatures in target unit du
 - 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)
 
+### ENEMY_ATTACK_REDUCTION
+
+Affected unit will ignore specified percentage of attacked unit attack (Nix)
+
+- val: amount of attack points to ignore, percentage
+
 ## Special abilities
 
 ### CATAPULT

+ 13 - 1
lib/battle/DamageCalculator.cpp

@@ -124,7 +124,19 @@ int DamageCalculator::getActorAttackBase() const
 
 int DamageCalculator::getActorAttackEffective() const
 {
-	return getActorAttackBase() + getActorAttackSlayer();
+	return getActorAttackBase() + getActorAttackSlayer() + getActorAttackIgnored();
+}
+
+int DamageCalculator::getActorAttackIgnored() const
+{
+	double multAttackReduction = battleBonusValue(info.defender, Selector::type()(BonusType::ENEMY_ATTACK_REDUCTION)) / 100.0;
+
+	if(multAttackReduction > 0)
+	{
+		int reduction = std::round(multAttackReduction * getActorAttackBase());
+		return -std::min(reduction,getActorAttackBase());
+	}
+	return 0;
 }
 
 int DamageCalculator::getActorAttackSlayer() const

+ 1 - 0
lib/battle/DamageCalculator.h

@@ -38,6 +38,7 @@ class DLL_LINKAGE DamageCalculator
 	int getActorAttackBase() const;
 	int getActorAttackEffective() const;
 	int getActorAttackSlayer() const;
+	int getActorAttackIgnored() const;
 	int getTargetDefenseBase() const;
 	int getTargetDefenseEffective() const;
 	int getTargetDefenseIgnored() const;

+ 1 - 0
lib/bonuses/BonusEnum.h

@@ -175,6 +175,7 @@ class JsonNode;
 	BONUS_NAME(MAX_LUCK) /*cheat bonus*/ \
 	BONUS_NAME(FEROCITY) /*extra attacks, only if at least some creatures killed while attacking target unit, val = amount of additional attacks, additional info = amount of creatures killed to trigger (default 1)*/ \
 	BONUS_NAME(ACCURATE_SHOT) /*HotA Sea Dog-like ability - ranged only, val = full arrow trigger percent, subtype = spell identifier that killed value goes through (death stare by default) - use 'accurateShot' as part of spell name for proper battle log description*/ \
+	BONUS_NAME(ENEMY_ATTACK_REDUCTION) /*in % (value) eg. Nix (HotA)*/ \
 	/* end of list */