Bläddra i källkod

Add TERMINATOR ability support, small fixes

Dydzio 8 år sedan
förälder
incheckning
3eef689005
4 ändrade filer med 44 tillägg och 5 borttagningar
  1. 9 3
      config/bonuses_texts.json
  2. 1 0
      lib/HeroBonus.h
  3. 2 2
      lib/battle/CBattleInfoCallback.cpp
  4. 32 0
      server/CGameHandler.cpp

+ 9 - 3
config/bonuses_texts.json

@@ -420,6 +420,12 @@
 		"description": "This creature is vulnerable to synergy effect"
 	},
 
+	"TERMINATOR":
+	{
+		"name": "Terminator",
+		"description": "Has ${val}% chance to kill extra units after attack"
+	},
+
 	"TWO_HEX_ATTACK_BREATH":
 	{
 		"name": "Breath",
@@ -454,11 +460,11 @@
 	{
 		"name": "Water immunity",
 		"description": "Immune to all Water school spells"
-	}
+	},
 	
 	"WIDE_BREATH":
 	{
-		"name": "Szerokie Zionięcie",
-		"description": "Stożek ognia obejmuje znacznie większy obszar"
+		"name": "Wide breath",
+		"description": "Wide breath attack (multiple hexes)"
 	}
 }

+ 1 - 0
lib/HeroBonus.h

@@ -240,6 +240,7 @@ private:
 	BONUS_NAME(SYNERGY_TARGET) /* dummy skill for alternative upgrades mod */\
 	BONUS_NAME(SHOOTS_ALL_ADJACENT) /* H4 Cyclops-like shoot (attacks all hexes neighboring with target) without spell-like mechanics */\
 	BONUS_NAME(BLOCK_MAGIC_BELOW) /*blocks casting spells of the level < value */ \
+	BONUS_NAME(TERMINATOR) /*kills extra units after hit, subtype = 0 - kill percentage of units, 1 - kill amount, val = chance in percent to trigger, additional info - amount/percentage to kill*/ \
 	/* end of list */
 
 

+ 2 - 2
lib/battle/CBattleInfoCallback.cpp

@@ -1656,13 +1656,13 @@ si8 CBattleInfoCallback::battleMinSpellLevel(ui8 side) const
 		node = getBattleNode();
 
 	if(!node)
-		return 1;
+		return 0;
 
 	auto b = node->getBonuses(Selector::type(Bonus::BLOCK_MAGIC_BELOW));
 	if(b->size())
 		return b->totalValue();
 
-	return 1;
+	return 0;
 }
 
 si8 CBattleInfoCallback::battleMaxSpellLevel(ui8 side) const

+ 32 - 0
server/CGameHandler.cpp

@@ -5418,6 +5418,38 @@ void CGameHandler::handleAfterAttackCasting(const BattleAttack & bat)
 		sendAndApply(&victimInfo);
 		sendAndApply(&resurrectInfo);
 	}
+	if(attacker->hasBonusOfType(Bonus::TERMINATOR, 0) || attacker->hasBonusOfType(Bonus::TERMINATOR, 1))
+	{
+		double chanceToTrigger = 0;
+		int amountToDie = 0;
+
+		if(attacker->hasBonusOfType(Bonus::TERMINATOR, 0)) //killing by percentage
+		{
+			chanceToTrigger = attacker->valOfBonuses(Bonus::TERMINATOR, 0) / 100.0f;
+			int percentageToDie = attacker->getBonus(Selector::type(Bonus::TERMINATOR).And(Selector::subtype(0)))->additionalInfo;
+			amountToDie = defender->getCount() * (percentageToDie / 100.0);
+			
+		}
+		else if(attacker->hasBonusOfType(Bonus::TERMINATOR, 1)) //killing by count
+		{
+			chanceToTrigger = attacker->valOfBonuses(Bonus::TERMINATOR, 1) / 100.0f;
+			amountToDie = attacker->getBonus(Selector::type(Bonus::TERMINATOR).And(Selector::subtype(1)))->additionalInfo;
+		}
+
+		vstd::amin(chanceToTrigger, 1); //cap trigger chance at 100%
+
+		if(getRandomGenerator().getDoubleRange(0, 1)() > chanceToTrigger)
+			return;
+
+		BattleStackAttacked bsa;
+		bsa.attackerID = -1;
+		bsa.stackAttacked = defender->ID;
+		bsa.damageAmount = amountToDie * defender->getCreature()->MaxHealth();
+		bsa.flags = BattleStackAttacked::SPELL_EFFECT;
+		bsa.spellID = SpellID::SLAYER;
+		attacker->prepareAttacked(bsa, getRandomGenerator());
+		sendAndApply(&bsa);
+	}
 }
 
 void CGameHandler::visitObjectOnTile(const TerrainTile &t, const CGHeroInstance * h)