mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Block spellcasting if 0 creatures will be raised
This commit is contained in:
parent
0a80c6c27b
commit
5dcef193a3
@ -25,6 +25,30 @@ namespace spells
|
||||
namespace effects
|
||||
{
|
||||
|
||||
int DemonSummon::raisedCreatureAmount(const Mechanics * m, const battle::Unit * unit) const
|
||||
{
|
||||
if(!unit || unit->alive() || unit->isGhost())
|
||||
return 0;
|
||||
|
||||
const auto *creatureType = creature.toEntity(m->creatures());
|
||||
|
||||
int32_t deadCount = unit->unitBaseAmount();
|
||||
int32_t deadTotalHealth = unit->getTotalHealth();
|
||||
int32_t raisedMaxHealth = creatureType->getMaxHealth();
|
||||
int32_t raisedTotalHealth = m->applySpellBonus(m->getEffectValue(), unit);
|
||||
|
||||
// Can't raise stack with more HP than original stack
|
||||
int32_t maxAmountFromHealth = deadTotalHealth / raisedMaxHealth;
|
||||
// Can't raise stack with more creatures than original stack
|
||||
int32_t maxAmountFromAmount = deadCount;
|
||||
// Can't raise stack with more HP than our spellpower
|
||||
int32_t maxAmountFromSpellpower = raisedTotalHealth / raisedMaxHealth;
|
||||
|
||||
int32_t finalAmount = std::min( { maxAmountFromHealth, maxAmountFromAmount, maxAmountFromSpellpower } );
|
||||
|
||||
return finalAmount;
|
||||
}
|
||||
|
||||
void DemonSummon::apply(ServerCallback * server, const Mechanics * m, const EffectTarget & target) const
|
||||
{
|
||||
BattleUnitsChanged pack;
|
||||
@ -49,21 +73,7 @@ void DemonSummon::apply(ServerCallback * server, const Mechanics * m, const Effe
|
||||
break;
|
||||
}
|
||||
|
||||
const auto *creatureType = creature.toEntity(m->creatures());
|
||||
|
||||
int32_t deadCount = targetStack->unitBaseAmount();
|
||||
int32_t deadTotalHealth = targetStack->getTotalHealth();
|
||||
int32_t raisedMaxHealth = creatureType->getMaxHealth();
|
||||
int32_t raisedTotalHealth = m->applySpellBonus(m->getEffectValue(), targetStack);
|
||||
|
||||
// Can't raise stack with more HP than original stack
|
||||
int32_t maxAmountFromHealth = deadTotalHealth / raisedMaxHealth;
|
||||
// Can't raise stack with more creatures than original stack
|
||||
int32_t maxAmountFromAmount = deadCount;
|
||||
// Can't raise stack with more HP than our spellpower
|
||||
int32_t maxAmountFromSpellpower = raisedTotalHealth / raisedMaxHealth;
|
||||
|
||||
int32_t finalAmount = std::min( { maxAmountFromHealth, maxAmountFromAmount, maxAmountFromSpellpower } );
|
||||
int32_t finalAmount = raisedCreatureAmount(m, targetStack);
|
||||
|
||||
if(finalAmount < 1)
|
||||
{
|
||||
@ -111,9 +121,7 @@ bool DemonSummon::isValidTarget(const Mechanics * m, const battle::Unit * unit)
|
||||
if (unit->isGhost())
|
||||
return false;
|
||||
|
||||
const auto *creatureType = creature.toEntity(m->creatures());
|
||||
|
||||
if (unit->getTotalHealth() < creatureType->getMaxHealth())
|
||||
if (raisedCreatureAmount(m, unit) == 0)
|
||||
return false;
|
||||
|
||||
return m->isReceptive(unit);
|
||||
|
@ -30,7 +30,9 @@ protected:
|
||||
void serializeJsonUnitEffect(JsonSerializeFormat & handler) override final;
|
||||
|
||||
private:
|
||||
CreatureID creature = CreatureID(0);
|
||||
int32_t raisedCreatureAmount(const Mechanics * m, const battle::Unit * unit) const;
|
||||
|
||||
CreatureID creature;
|
||||
|
||||
bool permanent = false;
|
||||
};
|
||||
|
@ -48,6 +48,12 @@ bool Summon::applicable(Problem & problem, const Mechanics * m) const
|
||||
return m->adaptGenericProblem(problem);
|
||||
}
|
||||
|
||||
if (summonedCreatureAmount(m) == 0)
|
||||
{
|
||||
logMod->debug("Attempt to summon zero creatures!");
|
||||
return m->adaptGenericProblem(problem);
|
||||
}
|
||||
|
||||
if(exclusive)
|
||||
{
|
||||
//check if there are summoned creatures of other type
|
||||
@ -88,11 +94,34 @@ bool Summon::applicable(Problem & problem, const Mechanics * m) const
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t Summon::summonedCreatureHealth(const Mechanics * m, const battle::Unit * unit) const
|
||||
{
|
||||
auto valueWithBonus = m->applySpecificSpellBonus(m->calculateRawEffectValue(0, m->getEffectPower()));
|
||||
|
||||
if(summonByHealth)
|
||||
return valueWithBonus;
|
||||
else
|
||||
return valueWithBonus * unit->getMaxHealth();
|
||||
}
|
||||
|
||||
int32_t Summon::summonedCreatureAmount(const Mechanics * m) const
|
||||
{
|
||||
auto valueWithBonus = m->applySpecificSpellBonus(m->calculateRawEffectValue(0, m->getEffectPower()));
|
||||
|
||||
if(summonByHealth)
|
||||
{
|
||||
const auto *creatureType = creature.toEntity(m->creatures());
|
||||
auto creatureMaxHealth = creatureType->getMaxHealth();
|
||||
return valueWithBonus / creatureMaxHealth;
|
||||
}
|
||||
else
|
||||
{
|
||||
return valueWithBonus;
|
||||
}
|
||||
}
|
||||
|
||||
void Summon::apply(ServerCallback * server, const Mechanics * m, const EffectTarget & target) const
|
||||
{
|
||||
//new feature - percentage bonus
|
||||
auto valueWithBonus = m->applySpecificSpellBonus(m->calculateRawEffectValue(0, m->getEffectPower()));//TODO: consider use base power too
|
||||
|
||||
BattleUnitsChanged pack;
|
||||
pack.battleID = m->battle()->getBattle()->getBattleID();
|
||||
|
||||
@ -102,25 +131,14 @@ void Summon::apply(ServerCallback * server, const Mechanics * m, const EffectTar
|
||||
{
|
||||
const battle::Unit * summoned = dest.unitValue;
|
||||
std::shared_ptr<battle::Unit> state = summoned->acquire();
|
||||
int64_t healthValue = (summonByHealth ? valueWithBonus : (valueWithBonus * summoned->getMaxHealth()));
|
||||
int64_t healthValue = summonedCreatureHealth(m, summoned);
|
||||
state->heal(healthValue, EHealLevel::OVERHEAL, (permanent ? EHealPower::PERMANENT : EHealPower::ONE_BATTLE));
|
||||
pack.changedStacks.emplace_back(summoned->unitId(), UnitChanges::EOperation::RESET_STATE);
|
||||
state->save(pack.changedStacks.back().data);
|
||||
}
|
||||
else
|
||||
{
|
||||
int32_t amount = 0;
|
||||
|
||||
if(summonByHealth)
|
||||
{
|
||||
const auto *creatureType = creature.toEntity(m->creatures());
|
||||
auto creatureMaxHealth = creatureType->getMaxHealth();
|
||||
amount = static_cast<int32_t>(valueWithBonus / creatureMaxHealth);
|
||||
}
|
||||
else
|
||||
{
|
||||
amount = static_cast<int32_t>(valueWithBonus);
|
||||
}
|
||||
int32_t amount = summonedCreatureAmount(m);
|
||||
|
||||
if(amount < 1)
|
||||
{
|
||||
|
@ -38,6 +38,9 @@ protected:
|
||||
void serializeJsonEffect(JsonSerializeFormat & handler) override final;
|
||||
|
||||
private:
|
||||
int32_t summonedCreatureAmount(const Mechanics * m) const;
|
||||
int32_t summonedCreatureHealth(const Mechanics * m, const battle::Unit * unit) const;
|
||||
|
||||
CreatureID creature;
|
||||
|
||||
bool permanent = false;
|
||||
|
Loading…
Reference in New Issue
Block a user