1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-06-23 00:28:08 +02:00

Various tweaks / enchancements to bonus mechanics

- Added CREATURE_SPELL_POWER for commanders
- Added spell modifiers to various spells: Hypnotize (Astral), Firewall (Luna), Landmine 
- Fixed ENEMY_DEFENCE_REDUCTION, GENERAL_ATTACK_REDUCTION
- Extended usefulness of ONLY_DISTANCE_FIGHT, ONLY_MELEE_FIGHT ranges
This commit is contained in:
DjWarmonger
2013-02-06 08:02:46 +00:00
parent dc091a1ce1
commit 1ef205e5f1
6 changed files with 41 additions and 41 deletions

View File

@ -282,6 +282,7 @@
"abilities": [ [ "MAGIC_RESISTANCE", 5, 0, 0 ], "abilities": [ [ "MAGIC_RESISTANCE", 5, 0, 0 ],
[ "CASTS", 1, 0, 0 ] , [ "CASTS", 1, 0, 0 ] ,
[ "CREATURE_ENCHANT_POWER", 1, 0, 0 ] , [ "CREATURE_ENCHANT_POWER", 1, 0, 0 ] ,
[ "CREATURE_SPELL_POWER", 100, 0, 0 ] ,
[ "SPELLCASTER", 3, 37, 0 ] ], //expert cure [ "SPELLCASTER", 3, 37, 0 ] ], //expert cure
"graphics" : "graphics" :
{ {
@ -309,6 +310,7 @@
"abilities": [ [ "MAGIC_RESISTANCE", 5, 0, 0 ], "abilities": [ [ "MAGIC_RESISTANCE", 5, 0, 0 ],
[ "CASTS", 1, 0, 0 ] , [ "CASTS", 1, 0, 0 ] ,
[ "CREATURE_ENCHANT_POWER", 1, 0, 0 ] , [ "CREATURE_ENCHANT_POWER", 1, 0, 0 ] ,
[ "CREATURE_SPELL_POWER", 100, 0, 0 ] ,
[ "SPELLCASTER", 3, 27, 0 ] ], //expert shield [ "SPELLCASTER", 3, 27, 0 ] ], //expert shield
"graphics" : "graphics" :
{ {
@ -337,6 +339,7 @@
"abilities": [ [ "MAGIC_RESISTANCE", 5, 0, 0 ], "abilities": [ [ "MAGIC_RESISTANCE", 5, 0, 0 ],
[ "CASTS", 1, 0, 0 ] , [ "CASTS", 1, 0, 0 ] ,
[ "CREATURE_ENCHANT_POWER", 1, 0, 0 ] , [ "CREATURE_ENCHANT_POWER", 1, 0, 0 ] ,
[ "CREATURE_SPELL_POWER", 100, 0, 0 ] ,
[ "SPELLCASTER", 3, 44, 0 ] ], //expert precision [ "SPELLCASTER", 3, 44, 0 ] ], //expert precision
"graphics" : "graphics" :
{ {
@ -366,6 +369,7 @@
"abilities": [ [ "MAGIC_RESISTANCE", 5, 0, 0 ], "abilities": [ [ "MAGIC_RESISTANCE", 5, 0, 0 ],
[ "CASTS", 1, 0, 0 ] , [ "CASTS", 1, 0, 0 ] ,
[ "CREATURE_ENCHANT_POWER", 1, 0, 0 ] , [ "CREATURE_ENCHANT_POWER", 1, 0, 0 ] ,
[ "CREATURE_SPELL_POWER", 100, 0, 0 ] ,
[ "SPELLCASTER", 3, 29, 0 ] ], //expert fire shield [ "SPELLCASTER", 3, 29, 0 ] ], //expert fire shield
"graphics" : "graphics" :
{ {
@ -393,6 +397,7 @@
"abilities": [ [ "MAGIC_RESISTANCE", 5, 0, 0 ], "abilities": [ [ "MAGIC_RESISTANCE", 5, 0, 0 ],
[ "CASTS", 1, 0, 0 ] , [ "CASTS", 1, 0, 0 ] ,
[ "CREATURE_ENCHANT_POWER", 1, 0, 0 ] , [ "CREATURE_ENCHANT_POWER", 1, 0, 0 ] ,
[ "CREATURE_SPELL_POWER", 100, 0, 0 ] ,
[ "SPELLCASTER", 3, 39, 0 ] ], //expert animate dead [ "SPELLCASTER", 3, 39, 0 ] ], //expert animate dead
"graphics" : "graphics" :
{ {
@ -420,6 +425,7 @@
"abilities": [ [ "MAGIC_RESISTANCE", 5, 0, 0 ], "abilities": [ [ "MAGIC_RESISTANCE", 5, 0, 0 ],
[ "CASTS", 1, 0, 0 ] , [ "CASTS", 1, 0, 0 ] ,
[ "CREATURE_ENCHANT_POWER", 1, 0, 0 ] , [ "CREATURE_ENCHANT_POWER", 1, 0, 0 ] ,
[ "CREATURE_SPELL_POWER", 100, 0, 0 ] ,
[ "SPELLCASTER", 3, 46, 0 ] ], //expert stone skin [ "SPELLCASTER", 3, 46, 0 ] ], //expert stone skin
"graphics" : "graphics" :
{ {
@ -447,6 +453,7 @@
"abilities": [ [ "MAGIC_RESISTANCE", 5, 0, 0 ], "abilities": [ [ "MAGIC_RESISTANCE", 5, 0, 0 ],
[ "CASTS", 1, 0, 0 ] , [ "CASTS", 1, 0, 0 ] ,
[ "CREATURE_ENCHANT_POWER", 1, 0, 0 ] , [ "CREATURE_ENCHANT_POWER", 1, 0, 0 ] ,
[ "CREATURE_SPELL_POWER", 100, 0, 0 ] ,
[ "SPELLCASTER", 3, 37, 0 ] ], //expert cure [ "SPELLCASTER", 3, 37, 0 ] ], //expert cure
"graphics" : "graphics" :
{ {
@ -474,6 +481,7 @@
"abilities": [ [ "MAGIC_RESISTANCE", 5, 0, 0 ], "abilities": [ [ "MAGIC_RESISTANCE", 5, 0, 0 ],
[ "CASTS", 1, 0, 0 ] , [ "CASTS", 1, 0, 0 ] ,
[ "CREATURE_ENCHANT_POWER", 1, 0, 0 ] , [ "CREATURE_ENCHANT_POWER", 1, 0, 0 ] ,
[ "CREATURE_SPELL_POWER", 100, 0, 0 ] ,
[ "SPELLCASTER", 3, 53, 0 ] ], //expert haste [ "SPELLCASTER", 3, 53, 0 ] ], //expert haste
"graphics" : "graphics" :
{ {
@ -502,6 +510,7 @@
"abilities": [ [ "MAGIC_RESISTANCE", 5, 0, 0 ], "abilities": [ [ "MAGIC_RESISTANCE", 5, 0, 0 ],
[ "CASTS", 1, 0, 0 ] , [ "CASTS", 1, 0, 0 ] ,
[ "CREATURE_ENCHANT_POWER", 1, 0, 0 ] , [ "CREATURE_ENCHANT_POWER", 1, 0, 0 ] ,
[ "CREATURE_SPELL_POWER", 100, 0, 0 ] ,
[ "SPELLCASTER", 3, 58, 0 ] ], //expert counterstrike [ "SPELLCASTER", 3, 58, 0 ] ], //expert counterstrike
"graphics" : "graphics" :
{ {

View File

@ -161,6 +161,7 @@ CStack * BattleInfo::generateNewStack(const CStackBasicDescriptor &base, bool at
return ret; return ret;
} }
//All spells casted by hero 9resurrection, cure, sacrifice)
ui32 BattleInfo::calculateHealedHP(const CGHeroInstance * caster, const CSpell * spell, const CStack * stack, const CStack * sacrificedStack) const ui32 BattleInfo::calculateHealedHP(const CGHeroInstance * caster, const CSpell * spell, const CStack * stack, const CStack * sacrificedStack) const
{ {
bool resurrect = resurrects(spell->id); bool resurrect = resurrects(spell->id);
@ -172,11 +173,13 @@ ui32 BattleInfo::calculateHealedHP(const CGHeroInstance * caster, const CSpell *
healedHealth = calculateSpellBonus(healedHealth, spell, caster, stack); healedHealth = calculateSpellBonus(healedHealth, spell, caster, stack);
return std::min<ui32>(healedHealth, stack->MaxHealth() - stack->firstHPleft + (resurrect ? stack->baseAmount * stack->MaxHealth() : 0)); return std::min<ui32>(healedHealth, stack->MaxHealth() - stack->firstHPleft + (resurrect ? stack->baseAmount * stack->MaxHealth() : 0));
} }
//Archangel
ui32 BattleInfo::calculateHealedHP(int healedHealth, const CSpell * spell, const CStack * stack) const ui32 BattleInfo::calculateHealedHP(int healedHealth, const CSpell * spell, const CStack * stack) const
{ {
bool resurrect = resurrects(spell->id); bool resurrect = resurrects(spell->id);
return std::min<ui32>(healedHealth, stack->MaxHealth() - stack->firstHPleft + (resurrect ? stack->baseAmount * stack->MaxHealth() : 0)); return std::min<ui32>(healedHealth, stack->MaxHealth() - stack->firstHPleft + (resurrect ? stack->baseAmount * stack->MaxHealth() : 0));
} }
//Casted by stack, no hero bonus applied
ui32 BattleInfo::calculateHealedHP(const CSpell * spell, int usedSpellPower, int spellSchoolLevel, const CStack * stack) const ui32 BattleInfo::calculateHealedHP(const CSpell * spell, int usedSpellPower, int spellSchoolLevel, const CStack * stack) const
{ {
bool resurrect = resurrects(spell->id); bool resurrect = resurrects(spell->id);
@ -752,7 +755,7 @@ std::vector<ui32> BattleInfo::calculateResistedStacks(const CSpell * sp, const C
if( (*it)->hasBonusOfType(Bonus::SPELL_IMMUNITY, sp->id) //100% sure spell immunity if( (*it)->hasBonusOfType(Bonus::SPELL_IMMUNITY, sp->id) //100% sure spell immunity
|| ( (*it)->count - 1 ) * (*it)->MaxHealth() + (*it)->firstHPleft || ( (*it)->count - 1 ) * (*it)->MaxHealth() + (*it)->firstHPleft
> >
usedSpellPower * 25 + sp->powers[spellLevel] //TODO: allow 'damage' bonus for hypnotize calculateSpellBonus (usedSpellPower * 25 + sp->powers[spellLevel], sp, caster, *it) //apply 'damage' bonus for hypnotize, including hero specialty
) )
{ {
ret.push_back((*it)->ID); ret.push_back((*it)->ID);

View File

@ -110,9 +110,9 @@ struct DLL_LINKAGE BattleInfo : public CBonusSystemNode, public CBattleInfoCallb
CStack * generateNewStack(const CStackBasicDescriptor &base, bool attackerOwned, int slot, BattleHex position) const; //helper for CGameHandler::setupBattle and spells addign new stacks to the battlefield CStack * generateNewStack(const CStackBasicDescriptor &base, bool attackerOwned, int slot, BattleHex position) const; //helper for CGameHandler::setupBattle and spells addign new stacks to the battlefield
int getIdForNewStack() const; //suggest a currently unused ID that'd suitable for generating a new stack int getIdForNewStack() const; //suggest a currently unused ID that'd suitable for generating a new stack
//std::pair<const CStack *, BattleHex> getNearestStack(const CStack * closest, boost::logic::tribool attackerOwned) const; //if attackerOwned is indetermnate, returened stack is of any owner; hex is the number of hex we should be looking from; returns (nerarest creature, predecessorHex) //std::pair<const CStack *, BattleHex> getNearestStack(const CStack * closest, boost::logic::tribool attackerOwned) const; //if attackerOwned is indetermnate, returened stack is of any owner; hex is the number of hex we should be looking from; returns (nerarest creature, predecessorHex)
ui32 calculateHealedHP(const CGHeroInstance * caster, const CSpell * spell, const CStack * stack, const CStack * sacrificedStack = NULL) const; ui32 calculateHealedHP(const CGHeroInstance * caster, const CSpell * spell, const CStack * stack, const CStack * sacrificedStack = NULL) const; //Sacrifice
ui32 calculateHealedHP(int healedHealth, const CSpell * spell, const CStack * stack) const; //for Archangel ui32 calculateHealedHP(int healedHealth, const CSpell * spell, const CStack * stack) const; //for Archangel
ui32 calculateHealedHP(const CSpell * spell, int usedSpellPower, int spellSchoolLevel, const CStack * stack) const; //unused ui32 calculateHealedHP(const CSpell * spell, int usedSpellPower, int spellSchoolLevel, const CStack * stack) const; //healing spells casted by stacks
bool resurrects(TSpell spellid) const; //TODO: move it to spellHandler? bool resurrects(TSpell spellid) const; //TODO: move it to spellHandler?
const CGHeroInstance * getHero(TPlayerColor player) const; //returns fighting hero that belongs to given player const CGHeroInstance * getHero(TPlayerColor player) const; //returns fighting hero that belongs to given player

View File

@ -787,8 +787,14 @@ TDmgRange CBattleInfoCallback::calculateDmgRange(const CStack* attacker, const C
TDmgRange CBattleInfoCallback::calculateDmgRange(const BattleAttackInfo &info) const TDmgRange CBattleInfoCallback::calculateDmgRange(const BattleAttackInfo &info) const
{ {
auto battleBonusValue = [&](const IBonusBearer * bearer, CSelector selector) -> int
{
return bearer->getBonuses(selector, Selector::effectRange(Bonus::NO_LIMIT) || //any regular bonuses or just ones for melee/ranged
(info.shooting ? Selector::effectRange(Bonus::ONLY_DISTANCE_FIGHT) : Selector::effectRange(Bonus::ONLY_MELEE_FIGHT)))->totalValue();
};
double additiveBonus = 1.0, multBonus = 1.0, double additiveBonus = 1.0, multBonus = 1.0,
minDmg = info.attackerBonuses->getMinDamage() * info.attackerCount, minDmg = info.attackerBonuses->getMinDamage() * info.attackerCount,//TODO: ONLY_MELEE_FIGHT / ONLY_DISTANCE_FIGHT
maxDmg = info.attackerBonuses->getMaxDamage() * info.attackerCount; maxDmg = info.attackerBonuses->getMaxDamage() * info.attackerCount;
const CCreature *attackerType = info.attacker->getCreature(), const CCreature *attackerType = info.attacker->getCreature(),
@ -813,35 +819,14 @@ TDmgRange CBattleInfoCallback::calculateDmgRange(const BattleAttackInfo &info) c
} }
int attackDefenceDifference = 0; int attackDefenceDifference = 0;
if(info.attackerBonuses->hasBonusOfType(Bonus::GENERAL_ATTACK_REDUCTION))
{
double multAttackReduction = info.attackerBonuses->valOfBonuses(Bonus::GENERAL_ATTACK_REDUCTION, -1024) / 100.0;
attackDefenceDifference = info.attackerBonuses->Attack() * multAttackReduction;
}
else
{
attackDefenceDifference = info.attackerBonuses->Attack();
}
if(info.attackerBonuses->hasBonusOfType(Bonus::ENEMY_DEFENCE_REDUCTION)) double multAttackReduction = (100 - battleBonusValue (info.attackerBonuses, Selector::type(Bonus::GENERAL_ATTACK_REDUCTION))) / 100.0;
{ attackDefenceDifference += battleBonusValue (info.attackerBonuses, Selector::typeSubtype(Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK)) * multAttackReduction;
double multDefenceReduction = (100 - info.attackerBonuses->valOfBonuses(Bonus::ENEMY_DEFENCE_REDUCTION, -1024)) / 100.0;
attackDefenceDifference -= info.defenderBonuses->Defense() * multDefenceReduction;
}
else
{
attackDefenceDifference -= info.defenderBonuses->Defense();
}
//calculating total attack/defense skills modifier double multDefenceReduction = (100 - battleBonusValue (info.attackerBonuses, Selector::type(Bonus::ENEMY_DEFENCE_REDUCTION))) / 100.0;
attackDefenceDifference -= info.defenderBonuses->Defense() * multDefenceReduction;
if(info.shooting) //precision handling (etc.) if(const Bonus *slayerEffect = info.attackerBonuses->getEffect(Spells::SLAYER)) //slayer handling //TODO: apply only ONLY_MELEE_FIGHT / DISTANCE_FIGHT?
attackDefenceDifference += info.attackerBonuses->getBonuses(Selector::typeSubtype(Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK), Selector::effectRange(Bonus::ONLY_DISTANCE_FIGHT))->totalValue();
else //bloodlust handling (etc.)
attackDefenceDifference += info.attackerBonuses->getBonuses(Selector::typeSubtype(Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK), Selector::effectRange(Bonus::ONLY_MELEE_FIGHT))->totalValue();
if(const Bonus *slayerEffect = info.attackerBonuses->getEffect(Spells::SLAYER)) //slayer handling
{ {
std::vector<int> affectedIds; std::vector<int> affectedIds;
int spLevel = slayerEffect->val; int spLevel = slayerEffect->val;
@ -918,17 +903,17 @@ TDmgRange CBattleInfoCallback::calculateDmgRange(const BattleAttackInfo &info) c
} }
//handling spell effects //handling spell effects
if(!info.shooting && info.defenderBonuses->hasBonusOfType(Bonus::GENERAL_DAMAGE_REDUCTION, 0)) //eg. shield if(!info.shooting) //eg. shield
{ {
multBonus *= (100 - info.defenderBonuses->valOfBonuses(Bonus::GENERAL_DAMAGE_REDUCTION, 0)) / 100.0; multBonus *= (100 - info.defenderBonuses->valOfBonuses(Bonus::GENERAL_DAMAGE_REDUCTION, 0)) / 100.0;
} }
else if(info.shooting && info.defenderBonuses->hasBonusOfType(Bonus::GENERAL_DAMAGE_REDUCTION, 1)) //eg. air shield else if(info.shooting) //eg. air shield
{ {
multBonus *= (100 - info.defenderBonuses->valOfBonuses(Bonus::GENERAL_DAMAGE_REDUCTION, 1)) / 100.0; multBonus *= (100 - info.defenderBonuses->valOfBonuses(Bonus::GENERAL_DAMAGE_REDUCTION, 1)) / 100.0;
} }
TBonusListPtr curseEffects = info.attackerBonuses->getBonuses(Selector::type(Bonus::ALWAYS_MINIMUM_DAMAGE)); //attacker->getEffect(42); TBonusListPtr curseEffects = info.attackerBonuses->getBonuses(Selector::type(Bonus::ALWAYS_MINIMUM_DAMAGE));
TBonusListPtr blessEffects = info.attackerBonuses->getBonuses(Selector::type(Bonus::ALWAYS_MAXIMUM_DAMAGE)); //attacker->getEffect(43); TBonusListPtr blessEffects = info.attackerBonuses->getBonuses(Selector::type(Bonus::ALWAYS_MAXIMUM_DAMAGE));
int curseBlessAdditiveModifier = blessEffects->totalValue() - curseEffects->totalValue(); int curseBlessAdditiveModifier = blessEffects->totalValue() - curseEffects->totalValue();
double curseMultiplicativePenalty = curseEffects->size() ? (*std::max_element(curseEffects->begin(), curseEffects->end(), &Bonus::compareByAdditionalInfo))->additionalInfo : 0; double curseMultiplicativePenalty = curseEffects->size() ? (*std::max_element(curseEffects->begin(), curseEffects->end(), &Bonus::compareByAdditionalInfo))->additionalInfo : 0;

View File

@ -126,7 +126,7 @@ typedef boost::function<bool(const Bonus*)> CSelector;
BONUS_NAME(CATAPULT) \ BONUS_NAME(CATAPULT) \
BONUS_NAME(ENEMY_DEFENCE_REDUCTION) /*in % (value) eg. behemots*/ \ BONUS_NAME(ENEMY_DEFENCE_REDUCTION) /*in % (value) eg. behemots*/ \
BONUS_NAME(GENERAL_DAMAGE_REDUCTION) /* shield / air shield effect */ \ BONUS_NAME(GENERAL_DAMAGE_REDUCTION) /* shield / air shield effect */ \
BONUS_NAME(GENERAL_ATTACK_REDUCTION) /*eg. while stoned or blinded - in %, subtype: -1 - any damage, 0 - melee damage, 1 - ranged damage*/ \ BONUS_NAME(GENERAL_ATTACK_REDUCTION) /*eg. while stoned or blinded - in %,// subtype not used, use ONLY_MELEE_FIGHT / DISTANCE_FIGHT*/ \
BONUS_NAME(DEFENSIVE_STANCE) /* val - bonus to defense while defending */ \ BONUS_NAME(DEFENSIVE_STANCE) /* val - bonus to defense while defending */ \
BONUS_NAME(ATTACKS_ALL_ADJACENT) /*eg. hydra*/ \ BONUS_NAME(ATTACKS_ALL_ADJACENT) /*eg. hydra*/ \
BONUS_NAME(MORE_DAMAGE_FROM_SPELL) /*value - damage increase in %, subtype - spell id*/ \ BONUS_NAME(MORE_DAMAGE_FROM_SPELL) /*value - damage increase in %, subtype - spell id*/ \

View File

@ -365,6 +365,9 @@ void CGameHandler::levelUpCommander (const CCommanderInstance * c, int skill)
scp.accumulatedBonus.type = Bonus::MAGIC_RESISTANCE; scp.accumulatedBonus.type = Bonus::MAGIC_RESISTANCE;
scp.accumulatedBonus.val = difference (VLC->creh->skillLevels, c->secondarySkills, ECommander::RESISTANCE); scp.accumulatedBonus.val = difference (VLC->creh->skillLevels, c->secondarySkills, ECommander::RESISTANCE);
sendAndApply (&scp); //additional pack sendAndApply (&scp); //additional pack
scp.accumulatedBonus.type = Bonus::CREATURE_SPELL_POWER;
scp.accumulatedBonus.val = difference (VLC->creh->skillLevels, c->secondarySkills, ECommander::SPELL_POWER) * 100; //like hero with spellpower = ability level
sendAndApply (&scp); //additional pack
scp.accumulatedBonus.type = Bonus::CASTS; scp.accumulatedBonus.type = Bonus::CASTS;
scp.accumulatedBonus.val = difference (VLC->creh->skillLevels, c->secondarySkills, ECommander::CASTS); scp.accumulatedBonus.val = difference (VLC->creh->skillLevels, c->secondarySkills, ECommander::CASTS);
sendAndApply (&scp); //additional pack sendAndApply (&scp); //additional pack
@ -4179,22 +4182,22 @@ void CGameHandler::handleSpellCasting( int spellID, int spellLvl, BattleHex dest
for(auto it = attackedCres.begin(); it != attackedCres.end(); ++it) for(auto it = attackedCres.begin(); it != attackedCres.end(); ++it)
{ {
if(vstd::contains(sc.resisted, (*it)->ID) //this creature resisted the spell if(vstd::contains(sc.resisted, (*it)->ID) //this creature resisted the spell
|| (spellID == Spells::ANIMATE_DEAD && !(*it)->hasBonusOfType(Bonus::UNDEAD)) //we try to cast animate dead on living stack || (spellID == Spells::ANIMATE_DEAD && !(*it)->hasBonusOfType(Bonus::UNDEAD)) //we try to cast animate dead on living stack, TODO: showuld be not affected earlier
) )
continue; continue;
StacksHealedOrResurrected::HealInfo hi; StacksHealedOrResurrected::HealInfo hi;
hi.stackID = (*it)->ID; hi.stackID = (*it)->ID;
if (stack) if (stack) //casted by creature
{ {
if (hpGained) if (hpGained)
{ {
hi.healedHP = gs->curB->calculateHealedHP(hpGained, spell, *it); hi.healedHP = gs->curB->calculateHealedHP(hpGained, spell, *it); //archangel
} }
else else
hi.healedHP = gs->curB->calculateHealedHP(spell, usedSpellPower, spellLvl, *it); hi.healedHP = gs->curB->calculateHealedHP(spell, usedSpellPower, spellLvl, *it); //any typical spell (commander's cure or animate dead)
} }
else else
hi.healedHP = gs->curB->calculateHealedHP(caster, spell, *it, gs->curB->battleGetStackByID(selectedStack)); hi.healedHP = gs->curB->calculateHealedHP(caster, spell, *it, gs->curB->battleGetStackByID(selectedStack)); //Casted by hero
hi.lowLevelResurrection = spellLvl <= 1; hi.lowLevelResurrection = spellLvl <= 1;
shr.healedStacks.push_back(hi); shr.healedStacks.push_back(hi);
} }
@ -4633,7 +4636,7 @@ void CGameHandler::handleDamageFromObstacle(const CObstacleInstance &obstacle, c
//helper info //helper info
const SpellCreatedObstacle *spellObstacle = dynamic_cast<const SpellCreatedObstacle*>(&obstacle); //not nice but we may need spell params const SpellCreatedObstacle *spellObstacle = dynamic_cast<const SpellCreatedObstacle*>(&obstacle); //not nice but we may need spell params
const ui8 side = !curStack->attackerOwned; const ui8 side = curStack->attackerOwned; //if enemy is defending (false = 0), side of our hero is also 0 (attacker)
const CGHeroInstance *hero = gs->curB->heroes[side]; const CGHeroInstance *hero = gs->curB->heroes[side];
if(obstacle.obstacleType == CObstacleInstance::MOAT) if(obstacle.obstacleType == CObstacleInstance::MOAT)