diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Object/Object.cpp | 47 | ||||
-rw-r--r-- | src/server/game/Entities/Object/Object.h | 3 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuraEffects.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuras.cpp | 6 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuras.h | 2 | ||||
-rw-r--r-- | src/server/game/Spells/Spell.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Spells/SpellInfo.cpp | 29 |
7 files changed, 48 insertions, 43 deletions
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 9a0a941a98a..855138c3c6f 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -2346,26 +2346,43 @@ double WorldObject::ApplyEffectModifiers(SpellInfo const* spellInfo, uint8 effIn return value; } -int32 WorldObject::CalcSpellDuration(SpellInfo const* spellInfo) const +int32 WorldObject::CalcSpellDuration(SpellInfo const* spellInfo, std::vector<SpellPowerCost> const* powerCosts) const { - int32 comboPoints = 0; - int32 maxComboPoints = 5; - if (Unit const* unit = ToUnit()) - { - comboPoints = unit->GetPower(POWER_COMBO_POINTS); - maxComboPoints = unit->GetMaxPower(POWER_COMBO_POINTS); - } - int32 minduration = spellInfo->GetDuration(); + if (minduration <= 0) + return minduration; + int32 maxduration = spellInfo->GetMaxDuration(); + if (minduration == maxduration) + return minduration; - int32 duration; - if (comboPoints && minduration != -1 && minduration != maxduration) - duration = minduration + int32((maxduration - minduration) * comboPoints / maxComboPoints); - else - duration = minduration; + Unit const* unit = ToUnit(); + if (!unit) + return minduration; + + if (!powerCosts) + return minduration; + + // we want only baseline cost here + auto itr = std::find_if(spellInfo->PowerCosts.begin(), spellInfo->PowerCosts.end(), [=](SpellPowerEntry const* powerEntry) + { + return powerEntry && powerEntry->PowerType == POWER_COMBO_POINTS && (!powerEntry->RequiredAuraSpellID || unit->HasAura(powerEntry->RequiredAuraSpellID)); + }); + + if (itr == spellInfo->PowerCosts.end()) + return minduration; + + auto consumedItr = std::find_if(powerCosts->begin(), powerCosts->end(), + [](SpellPowerCost const& consumed) { return consumed.Power == POWER_COMBO_POINTS; }); + if (consumedItr == powerCosts->end()) + return minduration; + + int32 baseComboCost = (*itr)->ManaCost + (*itr)->OptionalCost; + if (PowerTypeEntry const* powerTypeEntry = sDB2Manager.GetPowerTypeEntry(POWER_COMBO_POINTS)) + baseComboCost += int32(CalculatePct(powerTypeEntry->MaxBasePower, (*itr)->PowerCostPct + (*itr)->OptionalCostPct)); - return duration; + float durationPerComboPoint = float(maxduration - minduration) / baseComboCost; + return minduration + int32(durationPerComboPoint * consumedItr->Amount); } int32 WorldObject::ModSpellDuration(SpellInfo const* spellInfo, WorldObject const* target, int32 duration, bool positive, uint32 effectMask) const diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index 629367079a8..b1281a3cff7 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -64,6 +64,7 @@ struct FactionTemplateEntry; struct Loot; struct PositionFullTerrainStatus; struct QuaternionData; +struct SpellPowerCost; enum ZLiquidStatus : uint32; namespace WorldPackets @@ -642,7 +643,7 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation float GetSpellMinRangeForTarget(Unit const* target, SpellInfo const* spellInfo) const; double ApplyEffectModifiers(SpellInfo const* spellInfo, uint8 effIndex, double value) const; - int32 CalcSpellDuration(SpellInfo const* spellInfo) const; + int32 CalcSpellDuration(SpellInfo const* spellInfo, std::vector<SpellPowerCost> const* powerCosts) const; int32 ModSpellDuration(SpellInfo const* spellInfo, WorldObject const* target, int32 duration, bool positive, uint32 effectMask) const; void ModSpellCastTime(SpellInfo const* spellInfo, int32& castTime, Spell* spell = nullptr) const; void ModSpellDurationTime(SpellInfo const* spellInfo, int32& durationTime, Spell* spell = nullptr) const; diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index d511bc2dfa3..665e6fca4de 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -750,7 +750,7 @@ Optional<float> AuraEffect::CalculateEstimatedAmount(Unit const* caster, int32 a float AuraEffect::CalculateEstimatedfTotalPeriodicAmount(Unit* caster, Unit* target, SpellInfo const* spellInfo, SpellEffectInfo const& spellEffectInfo, float amount, uint8 stack) { - int32 maxDuration = Aura::CalcMaxDuration(spellInfo, caster); + int32 maxDuration = Aura::CalcMaxDuration(spellInfo, caster, nullptr); if (maxDuration <= 0) return 0.0f; diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index 59c54cd73df..7021f4a0367 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -859,10 +859,10 @@ void Aura::Update(uint32 diff, Unit* caster) int32 Aura::CalcMaxDuration(Unit* caster) const { - return Aura::CalcMaxDuration(GetSpellInfo(), caster); + return Aura::CalcMaxDuration(GetSpellInfo(), caster, nullptr); } -/*static*/ int32 Aura::CalcMaxDuration(SpellInfo const* spellInfo, WorldObject* caster) +/*static*/ int32 Aura::CalcMaxDuration(SpellInfo const* spellInfo, WorldObject const* caster, std::vector<SpellPowerCost> const* powerCosts) { Player* modOwner = nullptr; int32 maxDuration; @@ -870,7 +870,7 @@ int32 Aura::CalcMaxDuration(Unit* caster) const if (caster) { modOwner = caster->GetSpellModOwner(); - maxDuration = caster->CalcSpellDuration(spellInfo); + maxDuration = caster->CalcSpellDuration(spellInfo, powerCosts); } else maxDuration = spellInfo->GetDuration(); diff --git a/src/server/game/Spells/Auras/SpellAuras.h b/src/server/game/Spells/Auras/SpellAuras.h index aa9829401e0..b57958d003e 100644 --- a/src/server/game/Spells/Auras/SpellAuras.h +++ b/src/server/game/Spells/Auras/SpellAuras.h @@ -168,7 +168,7 @@ class TC_GAME_API Aura void SetMaxDuration(int32 duration) { m_maxDuration = duration; } int32 CalcMaxDuration() const { return CalcMaxDuration(GetCaster()); } int32 CalcMaxDuration(Unit* caster) const; - static int32 CalcMaxDuration(SpellInfo const* spellInfo, WorldObject* caster); + static int32 CalcMaxDuration(SpellInfo const* spellInfo, WorldObject const* caster, std::vector<SpellPowerCost> const* powerCosts); int32 GetDuration() const { return m_duration; } void SetDuration(int32 duration, bool withMods = false); void RefreshDuration(bool withMods = false); diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 1cbc3817bdd..c4aa677563c 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -3164,7 +3164,7 @@ SpellMissInfo Spell::PreprocessSpellHit(Unit* unit, TargetInfo& hitInfo) } } - hitInfo.AuraDuration = Aura::CalcMaxDuration(m_spellInfo, origCaster); + hitInfo.AuraDuration = Aura::CalcMaxDuration(m_spellInfo, origCaster, &m_powerCost); // unit is immune to aura if it was diminished to 0 duration if (!hitInfo.Positive && !unit->ApplyDiminishingToDuration(m_spellInfo, hitInfo.AuraDuration, origCaster, diminishLevel)) diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 2d92b671ba3..b0cef2841d6 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -3959,22 +3959,16 @@ Optional<SpellPowerCost> SpellInfo::CalcPowerCost(SpellPowerEntry const* power, // Spell drain all exist power on cast (Only paladin lay of Hands) if (HasAttribute(SPELL_ATTR1_USE_ALL_MANA)) { + if (optionalCost) + return {}; + // If power type - health drain all if (power->PowerType == POWER_HEALTH) - { - SpellPowerCost cost; - cost.Power = POWER_HEALTH; - cost.Amount = unitCaster->GetHealth(); - return cost; - } + return SpellPowerCost{ .Power = POWER_HEALTH, .Amount = int32(unitCaster->GetHealth()) }; + // Else drain all power if (power->PowerType < MAX_POWERS) - { - SpellPowerCost cost; - cost.Power = Powers(power->PowerType); - cost.Amount = unitCaster->GetPower(cost.Power); - return cost; - } + return SpellPowerCost{ .Power = Powers(power->PowerType), .Amount = unitCaster->GetPower(Powers(power->PowerType)) }; TC_LOG_ERROR("spells", "SpellInfo::CalcPowerCost: Unknown power type '{}' in spell {}", power->PowerType, Id); return {}; @@ -4158,10 +4152,7 @@ Optional<SpellPowerCost> SpellInfo::CalcPowerCost(SpellPowerEntry const* power, if (initiallyNegative != (powerCost < 0)) powerCost = 0; - SpellPowerCost cost; - cost.Power = Powers(power->PowerType); - cost.Amount = powerCost; - return cost; + return SpellPowerCost{ .Power = Powers(power->PowerType), .Amount = powerCost }; } std::vector<SpellPowerCost> SpellInfo::CalcPowerCost(WorldObject const* caster, SpellSchoolMask schoolMask, Spell* spell) const @@ -4180,11 +4171,7 @@ std::vector<SpellPowerCost> SpellInfo::CalcPowerCost(WorldObject const* caster, if (itr != costs.end()) return *itr; - SpellPowerCost cost; - cost.Power = powerType; - cost.Amount = 0; - costs.push_back(cost); - return costs.back(); + return costs.emplace_back<SpellPowerCost>({ .Power = powerType, .Amount = 0 }); }; for (SpellPowerEntry const* power : PowerCosts) |