Procházet zdrojové kódy

vcmi: replace KINGx bonuses to one KING bonus

val = level of slayer which require to affect.
Can break saves.
Konstantin před 2 roky
rodič
revize
62e579f672

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

@@ -214,12 +214,8 @@
 	"core.bonus.HP_REGENERATION.description": "Heals ${val} hit points every round",
 	"core.bonus.HP_REGENERATION.description": "Heals ${val} hit points every round",
 	"core.bonus.JOUSTING.name": "Champion Charge",
 	"core.bonus.JOUSTING.name": "Champion Charge",
 	"core.bonus.JOUSTING.description": "+${val}% damage per hex travelled",
 	"core.bonus.JOUSTING.description": "+${val}% damage per hex travelled",
-	"core.bonus.KING1.name": "King 1",
-	"core.bonus.KING1.description": "Vulnerable to basic SLAYER",
-	"core.bonus.KING2.name": "King 2",
-	"core.bonus.KING2.description": "Vulnerable to advanced SLAYER",
-	"core.bonus.KING3.name": "King 3",
-	"core.bonus.KING3.description":"Vulnerable to expert SLAYER",
+	"core.bonus.KING.name": "King",
+	"core.bonus.KING.description": "Vulnerable to SLAYER level ${val} or higher",
 	"core.bonus.LEVEL_SPELL_IMMUNITY.name": "Spell immunity 1-${val}",
 	"core.bonus.LEVEL_SPELL_IMMUNITY.name": "Spell immunity 1-${val}",
 	"core.bonus.LEVEL_SPELL_IMMUNITY.description": "Immune to spells of levels 1-${val}",
 	"core.bonus.LEVEL_SPELL_IMMUNITY.description": "Immune to spells of levels 1-${val}",
 	"core.bonus.LIMITED_SHOOTING_RANGE.name" : "Limited shooting range",
 	"core.bonus.LIMITED_SHOOTING_RANGE.name" : "Limited shooting range",

+ 2 - 6
Mods/vcmi/config/vcmi/russian.json

@@ -227,12 +227,8 @@
 	"core.bonus.HP_REGENERATION.description": "Исцеляет ${val} очков здоровья каждый ход",
 	"core.bonus.HP_REGENERATION.description": "Исцеляет ${val} очков здоровья каждый ход",
 	"core.bonus.JOUSTING.name": "Разгон",
 	"core.bonus.JOUSTING.name": "Разгон",
 	"core.bonus.JOUSTING.description": "+${val}% урона за каждую пройденную клетку",
 	"core.bonus.JOUSTING.description": "+${val}% урона за каждую пройденную клетку",
-	"core.bonus.KING1.name": "Король 1",
-	"core.bonus.KING1.description": "Уязвимость к заклинанию Палач 1 ступени",
-	"core.bonus.KING2.name": "Король 2",
-	"core.bonus.KING2.description": "Уязвимость к заклинанию Палач 2 ступени",
-	"core.bonus.KING3.name": "Король 3",
-	"core.bonus.KING3.description":"Уязвимость к заклинанию Палач 3 ступени",
+	"core.bonus.KING.name": "Король",
+	"core.bonus.KING.description": "Уязвимость к заклинанию Палач ${val} ступени и выше",
 	"core.bonus.LEVEL_SPELL_IMMUNITY.name": "Иммунитет к заклинаниям 1-${val}",
 	"core.bonus.LEVEL_SPELL_IMMUNITY.name": "Иммунитет к заклинаниям 1-${val}",
 	"core.bonus.LEVEL_SPELL_IMMUNITY.description": "Иммунитет к заклинаниям до ${val} уровня",
 	"core.bonus.LEVEL_SPELL_IMMUNITY.description": "Иммунитет к заклинаниям до ${val} уровня",
 	"core.bonus.LIMITED_SHOOTING_RANGE.name" : "Ограниченный радиуст стрельбы",
 	"core.bonus.LIMITED_SHOOTING_RANGE.name" : "Ограниченный радиуст стрельбы",

+ 2 - 6
Mods/vcmi/config/vcmi/ukrainian.json

@@ -202,12 +202,8 @@
 	"core.bonus.HP_REGENERATION.description" : "Відновлює ${val} очок здоров'я кожного раунду",
 	"core.bonus.HP_REGENERATION.description" : "Відновлює ${val} очок здоров'я кожного раунду",
 	"core.bonus.JOUSTING.name" : "Турнірна перевага",
 	"core.bonus.JOUSTING.name" : "Турнірна перевага",
 	"core.bonus.JOUSTING.description" : "+${val}% шкоди за кожен пройдений гекс",
 	"core.bonus.JOUSTING.description" : "+${val}% шкоди за кожен пройдений гекс",
-	"core.bonus.KING1.name" : "Король 1",
-	"core.bonus.KING1.description" : "Вразливий до 1-го рівня закляття Вбивця",
-	"core.bonus.KING2.name" : "Король 2",
-	"core.bonus.KING2.description" : "Вразливий до 2-го рівня закляття Вбивця",
-	"core.bonus.KING3.name" : "Король 3",
-	"core.bonus.KING3.description" : "Вразливий до 3-го рівня закляття Вбивця",
+	"core.bonus.KING.name" : "Король",
+	"core.bonus.KING.description" : "Вразливий до ${val}-го рівня закляття Вбивця",
 	"core.bonus.LEVEL_SPELL_IMMUNITY.name" : "Імунітет до заклять 1-${val}",
 	"core.bonus.LEVEL_SPELL_IMMUNITY.name" : "Імунітет до заклять 1-${val}",
 	"core.bonus.LEVEL_SPELL_IMMUNITY.description" : "Імунітет до заклять рівнів 1-${val}",
 	"core.bonus.LEVEL_SPELL_IMMUNITY.description" : "Імунітет до заклять рівнів 1-${val}",
 	"core.bonus.LIFE_DRAIN.name" : "Висмоктує життя (${val}%)",
 	"core.bonus.LIFE_DRAIN.name" : "Висмоктує життя (${val}%)",

+ 1 - 17
config/bonuses.json

@@ -271,23 +271,7 @@
 		}
 		}
 	},
 	},
 
 
-	"KING1":
-	{
-		"graphics":
-		{
-			"icon":  "zvs/Lib1.res/E_KING1"
-		}
-	},
-
-	"KING2":
-	{
-		"graphics":
-		{
-			"icon":  "zvs/Lib1.res/E_KING2"
-		}
-	},
-
-	"KING3":
+	"KING":
 	{
 	{
 		"graphics":
 		"graphics":
 		{
 		{

+ 8 - 0
lib/CBonusTypeHandler.cpp

@@ -170,6 +170,14 @@ std::string CBonusTypeHandler::bonusToGraphics(const std::shared_ptr<Bonus> & bo
 		}
 		}
 		break;
 		break;
 	}
 	}
+	case Bonus::KING:
+	{
+		if(vstd::iswithin(bonus->val, 0, 3))
+		{
+			fileName = "E_KING" + std::to_string(std::max(1, bonus->val)) + ".bmp";
+		}
+		break;
+	}
 	case Bonus::GENERAL_DAMAGE_REDUCTION:
 	case Bonus::GENERAL_DAMAGE_REDUCTION:
 	{
 	{
 		switch(bonus->subtype)
 		switch(bonus->subtype)

+ 3 - 3
lib/CCreatureHandler.cpp

@@ -486,9 +486,9 @@ void CCreatureHandler::loadBonuses(JsonNode & creature, std::string bonuses)
 		{"IS_UNDEAD",              makeBonusNode("UNDEAD")},
 		{"IS_UNDEAD",              makeBonusNode("UNDEAD")},
 		{"const_no_melee_penalty", makeBonusNode("NO_MELEE_PENALTY")},
 		{"const_no_melee_penalty", makeBonusNode("NO_MELEE_PENALTY")},
 		{"const_jousting",         makeBonusNode("JOUSTING", 5)},
 		{"const_jousting",         makeBonusNode("JOUSTING", 5)},
-		{"KING_1",                 makeBonusNode("KING1")},
-		{"KING_2",                 makeBonusNode("KING2")},
-		{"KING_3",                 makeBonusNode("KING3")},
+		{"KING_1",                 makeBonusNode("KING")}, // Slayer with no expertise
+		{"KING_2",                 makeBonusNode("KING", 2)}, // Advanced Slayer or better
+		{"KING_3",                 makeBonusNode("KING", 3)}, // Expert Slayer only
 		{"const_no_wall_penalty",  makeBonusNode("NO_WALL_PENALTY")},
 		{"const_no_wall_penalty",  makeBonusNode("NO_WALL_PENALTY")},
 		{"CATAPULT",               makeBonusNode("CATAPULT")},
 		{"CATAPULT",               makeBonusNode("CATAPULT")},
 		{"MULTI_HEADED",           makeBonusNode("ATTACKS_ALL_ADJACENT")},
 		{"MULTI_HEADED",           makeBonusNode("ATTACKS_ALL_ADJACENT")},

+ 1 - 3
lib/HeroBonus.h

@@ -220,9 +220,7 @@ public:
 	BONUS_NAME(NO_MELEE_PENALTY)						\
 	BONUS_NAME(NO_MELEE_PENALTY)						\
 	BONUS_NAME(JOUSTING) /*for champions*/				\
 	BONUS_NAME(JOUSTING) /*for champions*/				\
 	BONUS_NAME(HATE) /*eg. angels hate devils, subtype - ID of hated creature, val - damage bonus percent */ \
 	BONUS_NAME(HATE) /*eg. angels hate devils, subtype - ID of hated creature, val - damage bonus percent */ \
-	BONUS_NAME(KING1)									\
-	BONUS_NAME(KING2)									\
-	BONUS_NAME(KING3)									\
+	BONUS_NAME(KING) /* val - required slayer bonus val to affect */\
 	BONUS_NAME(MAGIC_RESISTANCE) /*in % (value)*/		\
 	BONUS_NAME(MAGIC_RESISTANCE) /*in % (value)*/		\
 	BONUS_NAME(CHANGES_SPELL_COST_FOR_ALLY) /*in mana points (value) , eg. mage*/ \
 	BONUS_NAME(CHANGES_SPELL_COST_FOR_ALLY) /*in mana points (value) , eg. mage*/ \
 	BONUS_NAME(CHANGES_SPELL_COST_FOR_ENEMY) /*in mana points (value) , eg. pegasus */ \
 	BONUS_NAME(CHANGES_SPELL_COST_FOR_ENEMY) /*in mana points (value) , eg. pegasus */ \

+ 1 - 3
lib/battle/CBattleInfoCallback.cpp

@@ -1611,9 +1611,7 @@ SpellID CBattleInfoCallback::getRandomBeneficialSpell(CRandomGenerator & rand, c
 		{
 		{
 			const auto * kingMonster = getAliveEnemy([&](const CStack * stack) -> bool //look for enemy, non-shooting stack
 			const auto * kingMonster = getAliveEnemy([&](const CStack * stack) -> bool //look for enemy, non-shooting stack
 			{
 			{
-				const auto isKing = Selector::type()(Bonus::KING1)
-									.Or(Selector::type()(Bonus::KING2))
-									.Or(Selector::type()(Bonus::KING3));
+				const auto isKing = Selector::type()(Bonus::KING);
 
 
 				return stack->hasBonus(isKing);
 				return stack->hasBonus(isKing);
 			});
 			});

+ 2 - 14
lib/battle/DamageCalculator.cpp

@@ -133,24 +133,12 @@ int DamageCalculator::getActorAttackSlayer() const
 	static const auto selectorSlayer = Selector::type()(Bonus::SLAYER);
 	static const auto selectorSlayer = Selector::type()(Bonus::SLAYER);
 
 
 	auto slayerEffects = info.attacker->getBonuses(selectorSlayer, cachingStrSlayer);
 	auto slayerEffects = info.attacker->getBonuses(selectorSlayer, cachingStrSlayer);
+	auto slayerAffected = info.defender->unitType()->valOfBonuses(Selector::type()(Bonus::KING));
 
 
 	if(std::shared_ptr<const Bonus> slayerEffect = slayerEffects->getFirst(Selector::all))
 	if(std::shared_ptr<const Bonus> slayerEffect = slayerEffects->getFirst(Selector::all))
 	{
 	{
-		std::vector<int32_t> affectedIds;
 		const auto spLevel = slayerEffect->val;
 		const auto spLevel = slayerEffect->val;
-		const CCreature * defenderType = info.defender->unitType();
-		bool isAffected = false;
-
-		for(const auto & b : defenderType->getBonusList())
-		{
-			if((b->type == Bonus::KING3 && spLevel >= 3) || //expert
-				(b->type == Bonus::KING2 && spLevel >= 2) || //adv +
-				(b->type == Bonus::KING1 && spLevel >= 0)) //none or basic +
-			{
-				isAffected = true;
-				break;
-			}
-		}
+		bool isAffected = spLevel >= slayerAffected;
 
 
 		if(isAffected)
 		if(isAffected)
 		{
 		{