Browse Source

Add "WoG werewolf"-like ability support

dydzio 8 years ago
parent
commit
daec6d933c
4 changed files with 55 additions and 0 deletions
  1. 8 0
      config/bonuses.json
  2. 6 0
      config/bonuses_texts.json
  3. 1 0
      lib/HeroBonus.h
  4. 40 0
      server/CGameHandler.cpp

+ 8 - 0
config/bonuses.json

@@ -524,6 +524,14 @@
 			"icon":  "zvs/Lib1.res/ThreeHeaded"
 		}
 	},
+	
+	"TRANSMUTATION":
+	{
+		"graphics":
+		{
+			"icon":  "zvs/Lib1.res/E_SGTYPE"
+		}
+	},
 
 	"UNDEAD":
 	{

+ 6 - 0
config/bonuses_texts.json

@@ -388,6 +388,12 @@
 		"name": "Three-headed attack",
 		"description": "Attacks three adjacent units"
 	},
+	
+	"TRANSMUTATION":
+	{
+		"name": "Transmutation",
+		"description": "${val}% chance to transform attacked unit to other type"
+	},
 
 	"UNDEAD":
 	{

+ 1 - 0
lib/HeroBonus.h

@@ -211,6 +211,7 @@ public:
 	BONUS_NAME(ENCHANTED) /* permanently enchanted with spell subID of level = val, if val > 3 then spell is mass and has level of val-3*/ \
 	BONUS_NAME(REBIRTH) /* val - percent of life restored, subtype = 0 - regular, 1 - at least one unit (sacred Phoenix) */\
 	BONUS_NAME(SOUL_STEAL) /*val - number of units gained per enemy killed, subtype = 0 - gained units survive after battle, 1 - they do not*/ \
+	BONUS_NAME(TRANSMUTATION) /*val - chance to trigger in %, subtype = 0 - resurrection based on HP, 1 - based on unit count, additional info - target creature ID (attacker default)*/\
 	BONUS_NAME(ADDITIONAL_UNITS) /*val of units with id = subtype will be added to hero's army at the beginning of battle */\
 	BONUS_NAME(SPOILS_OF_WAR) /*val * 10^-6 * gained exp resources of subtype will be given to hero after battle*/\
 	BONUS_NAME(BLOCK)\

+ 40 - 0
server/CGameHandler.cpp

@@ -5188,6 +5188,8 @@ void CGameHandler::handleAfterAttackCasting(const BattleAttack & bat)
 	if (!attacker || bat.bsa.empty()) // can be already dead
 		return;
 
+	const CStack *defender = gs->curB->battleGetStackByID(bat.bsa.at(0).stackAttacked);
+
 	auto cast = [=](SpellID spellID, int power)
 	{
 		const CSpell * spell = SpellID(spellID).toSpell();
@@ -5246,6 +5248,44 @@ void CGameHandler::handleAfterAttackCasting(const BattleAttack & bat)
 	{
 		cast(SpellID::ACID_BREATH_DAMAGE, acidDamage * attacker->count);
 	}
+
+	if (attacker->hasBonusOfType(Bonus::TRANSMUTATION) && defender->isLiving()) //transmutation mechanics, similar to WoG werewolf ability
+	{
+		double chanceToTrigger = attacker->valOfBonuses(Bonus::TRANSMUTATION) / 100.0f;
+		vstd::amin(chanceToTrigger, 1); //cap at 100%
+
+		if (getRandomGenerator().getDoubleRange(0, 1)() > chanceToTrigger)
+			return;
+		
+		int bonusAdditionalInfo = attacker->getBonus(Selector::type(Bonus::TRANSMUTATION))->additionalInfo;
+
+		if (defender->getCreature()->idNumber == bonusAdditionalInfo ||
+			(bonusAdditionalInfo == -1 && defender->getCreature()->idNumber == attacker->getCreature()->idNumber))
+			return;
+
+		BattleStackAdded resurrectInfo;
+		resurrectInfo.pos = defender->position;
+
+		if (bonusAdditionalInfo != -1)
+			resurrectInfo.creID = (CreatureID)bonusAdditionalInfo;
+		else
+			resurrectInfo.creID = attacker->getCreature()->idNumber;
+		
+		if (attacker->hasBonusOfType((Bonus::TRANSMUTATION), 0))
+		{
+			resurrectInfo.amount = std::max((defender->count * defender->MaxHealth()) / resurrectInfo.creID.toCreature()->MaxHealth(), 1u);
+		}
+		else if (attacker->hasBonusOfType((Bonus::TRANSMUTATION), 1))
+			resurrectInfo.amount = defender->count;
+		else
+			return; //wrong subtype
+
+		BattleStacksRemoved victimInfo;
+		victimInfo.stackIDs.insert(bat.bsa.at(0).stackAttacked);
+
+		sendAndApply(&victimInfo);
+		sendAndApply(&resurrectInfo);
+	}
 }
 
 bool CGameHandler::castSpell(const CGHeroInstance *h, SpellID spellID, const int3 &pos)