From c310138fc3b762af411e979caa2c889733fb236e Mon Sep 17 00:00:00 2001 From: dydzio Date: Fri, 20 Jan 2017 15:48:45 +0100 Subject: [PATCH] Add WoG ghost ability support --- config/bonuses.json | 9 +++++++++ config/bonuses_texts.json | 6 ++++++ lib/HeroBonus.h | 1 + lib/NetPacks.h | 4 ++-- lib/NetPacksLib.cpp | 7 +++++-- server/CGameHandler.cpp | 29 ++++++++++++++++++++++++++++- 6 files changed, 51 insertions(+), 5 deletions(-) diff --git a/config/bonuses.json b/config/bonuses.json index f72c6d8f9..812a6843a 100644 --- a/config/bonuses.json +++ b/config/bonuses.json @@ -442,6 +442,15 @@ "icon": "zvs/Lib1.res/E_SHOOT" } }, + + "SOUL_STEAL": + { + "graphics": + { + "icon": "zvs/Lib1.res/E_SUMMON2" + } + }, + "SPELLCASTER": { "graphics": diff --git a/config/bonuses_texts.json b/config/bonuses_texts.json index 1ed5b625a..10ebf4d4e 100644 --- a/config/bonuses_texts.json +++ b/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": { diff --git a/lib/HeroBonus.h b/lib/HeroBonus.h index b1a72848f..19b4157fd 100644 --- a/lib/HeroBonus.h +++ b/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)\ diff --git a/lib/NetPacks.h b/lib/NetPacks.h index 93b7177b5..d9ef7940f 100644 --- a/lib/NetPacks.h +++ b/lib/NetPacks.h @@ -1305,9 +1305,9 @@ struct StacksHealedOrResurrected : public CPackForClient }; std::vector 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 void serialize(Handler &h, const int version) diff --git a/lib/NetPacksLib.cpp b/lib/NetPacksLib.cpp index f7ebe6197..ee6931851 100644 --- a/lib/NetPacksLib.cpp +++ b/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; diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index 773ce6c7b..588b6e7db 100644 --- a/server/CGameHandler.cpp +++ b/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 {