mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Broken CHealth dependency on CStack
This commit is contained in:
parent
f0713c1d36
commit
44fc0cb57b
@ -108,7 +108,7 @@ void CRetaliations::reset()
|
||||
}
|
||||
|
||||
///CHealth
|
||||
CHealth::CHealth(const CStack * Owner):
|
||||
CHealth::CHealth(const IUnitHealthInfo * Owner):
|
||||
owner(Owner)
|
||||
{
|
||||
reset();
|
||||
@ -123,11 +123,11 @@ CHealth::CHealth(const CHealth & other):
|
||||
|
||||
}
|
||||
|
||||
void CHealth::init(const int32_t baseAmount)
|
||||
void CHealth::init()
|
||||
{
|
||||
reset();
|
||||
fullUnits = baseAmount > 1 ? baseAmount - 1 : 0;
|
||||
firstHPleft = baseAmount > 0 ? owner->MaxHealth() : 0;
|
||||
fullUnits = owner->unitBaseAmount() > 1 ? owner->unitBaseAmount() - 1 : 0;
|
||||
firstHPleft = owner->unitBaseAmount() > 0 ? owner->unitMaxHealth() : 0;
|
||||
}
|
||||
|
||||
void CHealth::addResurrected(int32_t amount)
|
||||
@ -138,24 +138,16 @@ void CHealth::addResurrected(int32_t amount)
|
||||
|
||||
int64_t CHealth::available() const
|
||||
{
|
||||
return static_cast<int64_t>(firstHPleft) + owner->MaxHealth() * fullUnits;
|
||||
return static_cast<int64_t>(firstHPleft) + owner->unitMaxHealth() * fullUnits;
|
||||
}
|
||||
|
||||
int64_t CHealth::total() const
|
||||
{
|
||||
return static_cast<int64_t>(owner->MaxHealth()) * owner->baseAmount;
|
||||
return static_cast<int64_t>(owner->unitMaxHealth()) * owner->unitBaseAmount();
|
||||
}
|
||||
|
||||
void CHealth::damage(int32_t & amount)
|
||||
{
|
||||
if(owner->isClone())
|
||||
{
|
||||
// block ability should not kill clone (0 damage)
|
||||
if(amount > 0)
|
||||
reset();
|
||||
return;
|
||||
}
|
||||
|
||||
const int32_t oldCount = getCount();
|
||||
|
||||
const bool withKills = amount >= firstHPleft;
|
||||
@ -186,7 +178,7 @@ void CHealth::damage(int32_t & amount)
|
||||
|
||||
void CHealth::heal(int32_t & amount, EHealLevel level, EHealPower power)
|
||||
{
|
||||
const int32_t unitHealth = owner->MaxHealth();
|
||||
const int32_t unitHealth = owner->unitMaxHealth();
|
||||
const int32_t oldCount = getCount();
|
||||
|
||||
int32_t maxHeal = std::numeric_limits<int32_t>::max();
|
||||
@ -223,7 +215,7 @@ void CHealth::heal(int32_t & amount, EHealLevel level, EHealPower power)
|
||||
|
||||
void CHealth::setFromTotal(const int64_t totalHealth)
|
||||
{
|
||||
const int32_t unitHealth = owner->MaxHealth();
|
||||
const int32_t unitHealth = owner->unitMaxHealth();
|
||||
firstHPleft = totalHealth % unitHealth;
|
||||
fullUnits = totalHealth / unitHealth;
|
||||
|
||||
@ -265,7 +257,6 @@ void CHealth::fromInfo(const CHealthInfo & info)
|
||||
|
||||
void CHealth::toInfo(CHealthInfo & info) const
|
||||
{
|
||||
info.stackId = owner->ID;
|
||||
info.firstHPleft = firstHPleft;
|
||||
info.fullUnits = fullUnits;
|
||||
info.resurrected = resurrected;
|
||||
@ -275,7 +266,7 @@ void CHealth::takeResurrected()
|
||||
{
|
||||
int64_t totalHealth = total();
|
||||
|
||||
totalHealth -= resurrected * owner->MaxHealth();
|
||||
totalHealth -= resurrected * owner->unitMaxHealth();
|
||||
vstd::amax(totalHealth, 0);
|
||||
setFromTotal(totalHealth);
|
||||
resurrected = 0;
|
||||
@ -290,7 +281,7 @@ CStack::CStack(const CStackInstance * Base, PlayerColor O, int I, ui8 Side, Slot
|
||||
assert(base);
|
||||
type = base->type;
|
||||
baseAmount = base->count;
|
||||
health.init(baseAmount); //???
|
||||
health.init(); //???
|
||||
setNodeType(STACK_BATTLE);
|
||||
}
|
||||
|
||||
@ -308,7 +299,7 @@ CStack::CStack(const CStackBasicDescriptor * stack, PlayerColor O, int I, ui8 Si
|
||||
{
|
||||
type = stack->type;
|
||||
baseAmount = stack->count;
|
||||
health.init(baseAmount); //???
|
||||
health.init(); //???
|
||||
setNodeType(STACK_BATTLE);
|
||||
}
|
||||
|
||||
@ -350,6 +341,7 @@ void CStack::init()
|
||||
void CStack::localInit(BattleInfo * battleInfo)
|
||||
{
|
||||
battle = battleInfo;
|
||||
cloneID = -1;
|
||||
assert(type);
|
||||
|
||||
exportBonuses();
|
||||
@ -367,8 +359,7 @@ void CStack::localInit(BattleInfo * battleInfo)
|
||||
shots.reset();
|
||||
counterAttacks.reset();
|
||||
casts.reset();
|
||||
health.init(baseAmount);
|
||||
cloneID = -1;
|
||||
health.init();
|
||||
}
|
||||
|
||||
ui32 CStack::level() const
|
||||
@ -620,8 +611,27 @@ std::string CStack::nodeName() const
|
||||
|
||||
CHealth CStack::healthAfterAttacked(int32_t & damage) const
|
||||
{
|
||||
CHealth res = health;
|
||||
return healthAfterAttacked(damage, health);
|
||||
}
|
||||
|
||||
CHealth CStack::healthAfterAttacked(int32_t & damage, const CHealth & customHealth) const
|
||||
{
|
||||
CHealth res = customHealth;
|
||||
|
||||
if(isClone())
|
||||
{
|
||||
// block ability should not kill clone (0 damage)
|
||||
if(damage > 0)
|
||||
{
|
||||
damage = 1;//??? what should be actual damage against clone?
|
||||
res.reset();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
res.damage(damage);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -646,11 +656,11 @@ void CStack::prepareAttacked(BattleStackAttacked & bsa, CRandomGenerator & rand)
|
||||
|
||||
void CStack::prepareAttacked(BattleStackAttacked & bsa, CRandomGenerator & rand, const CHealth & customHealth) const
|
||||
{
|
||||
CHealth afterAttack = customHealth;
|
||||
afterAttack.damage(bsa.damageAmount);
|
||||
CHealth afterAttack = healthAfterAttacked(bsa.damageAmount, customHealth);
|
||||
|
||||
bsa.killedAmount = customHealth.getCount() - afterAttack.getCount();
|
||||
afterAttack.toInfo(bsa.newHealth);
|
||||
bsa.newHealth.stackId = ID;
|
||||
bsa.newHealth.delta = -bsa.damageAmount;
|
||||
|
||||
if(afterAttack.available() <= 0 && isClone())
|
||||
@ -824,6 +834,16 @@ void CStack::getCastDescription(const CSpell * spell, const std::vector<const CS
|
||||
text.addReplacement(MetaString::SPELL_NAME, spell->id.toEnum());
|
||||
}
|
||||
|
||||
int32_t CStack::unitMaxHealth() const
|
||||
{
|
||||
return MaxHealth();
|
||||
}
|
||||
|
||||
int32_t CStack::unitBaseAmount() const
|
||||
{
|
||||
return baseAmount;
|
||||
}
|
||||
|
||||
void CStack::addText(MetaString & text, ui8 type, int32_t serial, const boost::logic::tribool & plural) const
|
||||
{
|
||||
if(boost::logic::indeterminate(plural))
|
||||
|
22
lib/CStack.h
22
lib/CStack.h
@ -81,13 +81,20 @@ private:
|
||||
mutable int32_t totalCache;
|
||||
};
|
||||
|
||||
class DLL_LINKAGE IUnitHealthInfo
|
||||
{
|
||||
public:
|
||||
virtual int32_t unitMaxHealth() const = 0;
|
||||
virtual int32_t unitBaseAmount() const = 0;
|
||||
};
|
||||
|
||||
class DLL_LINKAGE CHealth
|
||||
{
|
||||
public:
|
||||
CHealth(const CStack * Owner);
|
||||
CHealth(const IUnitHealthInfo * Owner);
|
||||
CHealth(const CHealth & other);
|
||||
|
||||
void init(const int32_t baseAmount);
|
||||
void init();
|
||||
void reset();
|
||||
|
||||
void damage(int32_t & amount);
|
||||
@ -114,14 +121,14 @@ public:
|
||||
private:
|
||||
void addResurrected(int32_t amount);
|
||||
void setFromTotal(const int64_t totalHealth);
|
||||
const CStack * owner;
|
||||
const IUnitHealthInfo * owner;
|
||||
|
||||
int32_t firstHPleft;
|
||||
int32_t fullUnits;
|
||||
int32_t resurrected;
|
||||
};
|
||||
|
||||
class DLL_LINKAGE CStack : public CBonusSystemNode, public ISpellCaster
|
||||
class DLL_LINKAGE CStack : public CBonusSystemNode, public ISpellCaster, public IUnitHealthInfo
|
||||
{
|
||||
public:
|
||||
const CStackInstance * base; //garrison slot from which stack originates (nullptr for war machines, summoned cres, etc)
|
||||
@ -195,6 +202,8 @@ public:
|
||||
BattleHex::EDir destShiftDir() const;
|
||||
|
||||
CHealth healthAfterAttacked(int32_t & damage) const;
|
||||
CHealth healthAfterAttacked(int32_t & damage, const CHealth & customHealth) const;
|
||||
|
||||
CHealth healthAfterHealed(int32_t & toHeal, EHealLevel level, EHealPower power) const;
|
||||
|
||||
void prepareAttacked(BattleStackAttacked & bsa, CRandomGenerator & rand) const; //requires bsa.damageAmout filled
|
||||
@ -221,6 +230,11 @@ public:
|
||||
void getCasterName(MetaString & text) const override;
|
||||
void getCastDescription(const CSpell * spell, const std::vector<const CStack *> & attacked, MetaString & text) const override;
|
||||
|
||||
///IUnitHealthInfo
|
||||
|
||||
int32_t unitMaxHealth() const override;
|
||||
int32_t unitBaseAmount() const override;
|
||||
|
||||
///MetaStrings
|
||||
|
||||
void addText(MetaString & text, ui8 type, int32_t serial, const boost::logic::tribool & plural = boost::logic::indeterminate) const;
|
||||
|
@ -43,6 +43,7 @@ void HealingSpellMechanics::applyBattleEffects(const SpellCastEnvironment * env,
|
||||
|
||||
CHealthInfo hi;
|
||||
health.toInfo(hi);
|
||||
hi.stackId = attackedCre->ID;
|
||||
hi.delta = stackHPgained;
|
||||
shr.healedStacks.push_back(hi);
|
||||
}
|
||||
|
@ -965,6 +965,7 @@ void CGameHandler::applyBattleEffects(BattleAttack &bat, const CStack *att, cons
|
||||
|
||||
CHealthInfo hi;
|
||||
health.toInfo(hi);
|
||||
hi.stackId = att->ID;
|
||||
hi.delta = toHeal;
|
||||
shi.healedStacks.push_back(hi);
|
||||
|
||||
@ -989,6 +990,7 @@ void CGameHandler::applyBattleEffects(BattleAttack &bat, const CStack *att, cons
|
||||
CHealth health = att->healthAfterHealed(toHeal, EHealLevel::OVERHEAL, ((i == 0) ? EHealPower::ONE_BATTLE : EHealPower::PERMANENT));
|
||||
CHealthInfo hi;
|
||||
health.toInfo(hi);
|
||||
hi.stackId = att->ID;
|
||||
hi.delta = toHeal;
|
||||
if(hi.delta > 0)
|
||||
shi.healedStacks.push_back(hi);
|
||||
@ -4242,7 +4244,8 @@ bool CGameHandler::makeBattleAction(BattleAction &ba)
|
||||
|
||||
CHealthInfo hi;
|
||||
health.toInfo(hi);
|
||||
|
||||
hi.stackId = destStack->ID;
|
||||
hi.delta = toHeal;
|
||||
shr.healedStacks.push_back(hi);
|
||||
sendAndApply(&shr);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user