Browse Source

Add WoG ghost ability support

dydzio 8 years ago
parent
commit
c310138fc3
6 changed files with 51 additions and 5 deletions
  1. 9 0
      config/bonuses.json
  2. 6 0
      config/bonuses_texts.json
  3. 1 0
      lib/HeroBonus.h
  4. 2 2
      lib/NetPacks.h
  5. 5 2
      lib/NetPacksLib.cpp
  6. 28 1
      server/CGameHandler.cpp

+ 9 - 0
config/bonuses.json

@@ -442,6 +442,15 @@
 			"icon":  "zvs/Lib1.res/E_SHOOT"
 		}
 	},
+	
+	"SOUL_STEAL":
+	{
+		"graphics":
+		{
+			"icon":  "zvs/Lib1.res/E_SUMMON2"
+		}
+	},
+	
 	"SPELLCASTER":
 	{
 		"graphics":

+ 6 - 0
config/bonuses_texts.json

@@ -328,6 +328,12 @@
 		"name": "Ranged",
 		"description": "Creature can shoot"
 	},
+	
+	"SOUL_STEAL":
+	{
+		"name": "Soul Steal",
+		"description": "Gains ${val}% new creatures for each enemy killed"
+	},
 
 	"SPELLCASTER":
 	{

+ 1 - 0
lib/HeroBonus.h

@@ -210,6 +210,7 @@ public:
 	BONUS_NAME(CREATURE_ENCHANT_POWER) /* total duration of spells cast by creature */ \
 	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(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)\

+ 2 - 2
lib/NetPacks.h

@@ -1305,9 +1305,9 @@ struct StacksHealedOrResurrected : public CPackForClient
 	};
 
 	std::vector<HealInfo> healedStacks;
-	bool lifeDrain; //if true, this heal is an effect of life drain
+	bool lifeDrain; //if true, this heal is an effect of life drain or soul steal
 	bool tentHealing; //if true, than it's healing via First Aid Tent
-	si32 drainedFrom; //if life drain - then stack life was drain from, if tentHealing - stack that is a healer
+	si32 drainedFrom; //if life drain or soul steal - then stack life was drain from, if tentHealing - stack that is a healer
 	bool cure; //archangel cast also remove negative effects
 
 	template <typename Handler> void serialize(Handler &h, const int version)

+ 5 - 2
lib/NetPacksLib.cpp

@@ -1616,8 +1616,11 @@ DLL_LINKAGE void StacksHealedOrResurrected::applyGs(CGameState *gs)
 
 			changedStack->state.insert(EBattleStackState::ALIVE);
 		}
-
-		int res = std::min(elem.healedHP / changedStack->MaxHealth() , changedStack->baseAmount - changedStack->count);
+		int res;
+		if(changedStack->hasBonusOfType(Bonus::SOUL_STEAL)) //WoG ghost soul steal ability allows getting more units than before battle
+			res = elem.healedHP / changedStack->MaxHealth();
+		else
+			res = std::min(elem.healedHP / changedStack->MaxHealth() , changedStack->baseAmount - changedStack->count);		
 		changedStack->count += res;
 		if(elem.lowLevelResurrection)
 			changedStack->resurrected += res;

+ 28 - 1
server/CGameHandler.cpp

@@ -906,7 +906,28 @@ void CGameHandler::applyBattleEffects(BattleAttack &bat, const CStack *att, cons
 			bsa.healedStacks.push_back(shi);
 		}
 	}
-	bat.bsa.push_back(bsa); //add this stack to the list of victims after drain life has been calculated
+
+	//soul steal handling
+	if (att->hasBonusOfType(Bonus::SOUL_STEAL) && def->isLiving())
+	{
+		StacksHealedOrResurrected shi;
+		shi.lifeDrain = true;
+		shi.tentHealing = false;
+		shi.cure = false;
+		shi.drainedFrom = def->ID;
+
+		StacksHealedOrResurrected::HealInfo hi;
+		hi.stackID = att->ID;
+		hi.healedHP = bsa.killedAmount * att->valOfBonuses(Bonus::SOUL_STEAL) * att->MaxHealth(); //TODO: Should unit be additionally healed after life drain?
+		hi.lowLevelResurrection = false;
+		shi.healedStacks.push_back(hi);
+
+		if (hi.healedHP > 0)
+		{
+			bsa.healedStacks.push_back(shi);
+		}
+	}
+	bat.bsa.push_back(bsa); //add this stack to the list of victims after drain life has been calculated 
 
 	//fire shield handling
 	if (!bat.shot() && !vstd::contains(def->state, EBattleStackState::CLONED) &&
@@ -6222,6 +6243,12 @@ CasualtiesAfterBattle::CasualtiesAfterBattle(const CArmedInstance * _army, Battl
 				StackLocation sl(army, st->slot);
 				newStackCounts.push_back(TStackAndItsNewCount(sl, st->count));
 			}
+			else if (st->count > army->getStackCount(st->slot) && st->hasBonusOfType(Bonus::SOUL_STEAL, 0)) //allow WoG ghost amount grow from battles
+			{
+				logGlobal->debug("Stack gained %d units.", army->getStackCount(st->slot) - st->count);
+				StackLocation sl(army, st->slot);
+				newStackCounts.push_back(TStackAndItsNewCount(sl, st->count));
+			}
 		}
 		else
 		{