diff options
author | Ovahlord <dreadkiller@gmx.de> | 2024-07-31 06:05:41 +0200 |
---|---|---|
committer | Ovahlord <dreadkiller@gmx.de> | 2024-07-31 06:05:41 +0200 |
commit | 2401e32c552ac119666bd2e27de9fb4b064868e1 (patch) | |
tree | 31af5d9b4fc52e4bf53948675aaac5f09f953e46 /src | |
parent | e49328d0939c11ce4f8460f6185c09a4320bdaaf (diff) |
Core/Misc: update Combo Points handling to Cataclysm
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 23 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 5 | ||||
-rw-r--r-- | src/server/game/Spells/Spell.cpp | 18 | ||||
-rw-r--r-- | src/server/game/Spells/Spell.h | 2 | ||||
-rw-r--r-- | src/server/game/Spells/SpellEffects.cpp | 14 |
5 files changed, 60 insertions, 2 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 750a422c27d..83cfb123c5a 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -8790,6 +8790,9 @@ void Unit::setDeathState(DeathState s) if (m_vignette && !m_vignette->Data->GetFlags().HasFlag(VignetteFlags::PersistsThroughDeath)) SetVignette(0); + if (!GetComboTarget().IsEmpty()) + ClearComboTarget(); + // players in instance don't have ZoneScript, but they have InstanceScript if (ZoneScript* zoneScript = GetZoneScript() ? GetZoneScript() : GetInstanceScript()) zoneScript->OnUnitDeath(this); @@ -11052,6 +11055,10 @@ void Unit::SetMeleeAnimKitId(uint16 animKitId) } } + // Combo Points handling - clear target after killing it + if (attacker && attacker->GetComboTarget() == victim->GetGUID()) + attacker->ClearComboTarget(); + // achievement stuff if (attacker && victim->GetTypeId() == TYPEID_PLAYER) { @@ -14151,6 +14158,22 @@ void Unit::SetVignette(uint32 vignetteId) m_vignette = Vignettes::Create(vignette, this); } +void Unit::AddComboPoints(ObjectGuid targetGuid, int32 points) +{ + // if we lose our target or our target changes, reset combo points back to zero + if (targetGuid.IsEmpty() || targetGuid != m_unitData->ComboTarget) + SetPower(POWER_COMBO_POINTS, 0, false); + + SetComboTarget(targetGuid); + ModifyPower(POWER_COMBO_POINTS, points); +} + +void Unit::ClearComboTarget() +{ + SetComboTarget(ObjectGuid::Empty); + ModifyPower(POWER_COMBO_POINTS, 0); +} + std::string Unit::GetDebugInfo() const { std::stringstream sstr; diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 0f270c821f5..d23baf4d10a 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1808,6 +1808,11 @@ class TC_GAME_API Unit : public WorldObject Vignettes::VignetteData const* GetVignette() const { return m_vignette.get(); } void SetVignette(uint32 vignetteId); + ObjectGuid GetComboTarget() const { return m_unitData->ComboTarget; } + void SetComboTarget(ObjectGuid targetGuid) { SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::ComboTarget), targetGuid); }; + void AddComboPoints(ObjectGuid targetGuid, int32 points); + void ClearComboTarget(); + std::string GetDebugInfo() const override; UF::UpdateField<UF::UnitData, 0, TYPEID_UNIT> m_unitData; diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 7ef1c4d6547..5f2aa10b04e 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -608,6 +608,8 @@ m_spellValue(new SpellValue(m_spellInfo, caster)), _spellEvent(nullptr) && !m_spellInfo->HasAttribute(SPELL_ATTR1_NO_REFLECTION) && !m_spellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES) && !m_spellInfo->IsPassive(); + m_consumeAllComboPoints = m_spellInfo->HasAttribute(SPELL_ATTR1_FINISHING_MOVE_DAMAGE) || m_spellInfo->HasAttribute(SPELL_ATTR1_FINISHING_MOVE_DURATION); + CleanupTargetList(); for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) @@ -2997,6 +2999,10 @@ void Spell::TargetInfo::DoDamageAndTriggers(Spell* spell) spell->m_hitMask |= hitMask; spell->m_procSpellType |= procSpellType; + // Don't consume combo points from finishing moves when missing the target and having SPELL_ATTR1_DISCOUNT_POWER_ON_MISS + if (spell->m_consumeAllComboPoints && MissCondition != SPELL_MISS_NONE && spell->m_spellInfo->HasAttribute(SPELL_ATTR1_DISCOUNT_POWER_ON_MISS)) + spell->m_consumeAllComboPoints = false; + // _spellHitTarget can be null if spell is missed in DoSpellHitOnUnit if (MissCondition != SPELL_MISS_EVADE && _spellHitTarget && !spell->m_caster->IsFriendlyTo(unit) && (!spell->IsPositive() || spell->m_spellInfo->HasEffect(SPELL_EFFECT_DISPEL))) { @@ -4205,10 +4211,17 @@ void Spell::_handle_immediate_phase() void Spell::_handle_finish_phase() { - if (Unit* unitCaster = m_caster->ToUnit()) + Unit* unitCaster = m_caster->ToUnit(); + if (unitCaster) + { if (m_spellInfo->HasEffect(SPELL_EFFECT_ADD_EXTRA_ATTACKS)) unitCaster->SetLastExtraAttackSpell(m_spellInfo->Id); + // Finishing moves use up all their combo points after cast and reset their combo target + if (m_consumeAllComboPoints) + unitCaster->ClearComboTarget(); + } + // Handle procs on finish if (!m_originalCaster) return; @@ -5857,6 +5870,9 @@ SpellCastResult Spell::CheckCast(bool strict, int32* param1 /*= nullptr*/, int32 if (m_spellInfo->HasAttribute(SPELL_ATTR0_ONLY_STEALTHED) && !(unitCaster->HasStealthAura())) return SPELL_FAILED_ONLY_STEALTHED; } + + if (m_consumeAllComboPoints && !unitCaster->GetPower(POWER_COMBO_POINTS)) + return SPELL_FAILED_NO_COMBO_POINTS; } // caster state requirements diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index 9e91b29cd72..6d2db462efa 100644 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -355,6 +355,7 @@ class TC_GAME_API Spell void EffectTaunt(); void EffectDurabilityDamagePCT(); void EffectModifyThreatPercent(); + void EffectAddComboPoints(); void EffectResurrectNew(); void EffectAddExtraAttacks(); void EffectSpiritHeal(); @@ -707,6 +708,7 @@ class TC_GAME_API Spell int32 m_channeledDuration; // Calculated channeled spell duration in order to calculate correct pushback. bool m_canReflect; // can reflect this spell? bool m_autoRepeat; + bool m_consumeAllComboPoints; // For finishing moves that should consume all combo points after cast uint8 m_runesState; uint8 m_delayAtDamageCount; diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index b959ec5858c..262308b72fa 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -413,7 +413,7 @@ NonDefaultConstructible<SpellEffectHandlerFn> SpellEffectHandlers[TOTAL_SPELL_EF &Spell::EffectNULL, //325 SPELL_EFFECT_325 &Spell::EffectNULL, //326 SPELL_EFFECT_326 &Spell::EffectNULL, //327 SPELL_EFFECT_PULL - &Spell::EffectNULL, //328 SPELL_EFFECT_ADD_COMBO_POINTS + &Spell::EffectAddComboPoints, //328 SPELL_EFFECT_ADD_COMBO_POINTS &Spell::EffectResurrectNew, //329 SPELL_EFFECT_RESURRECT_NEW &Spell::EffectActivateRune, //330 SPELL_EFFECT_ACTIVATE_RUNE }; @@ -5932,6 +5932,18 @@ void Spell::EffectTeleportGraveyard() target->RepopAtGraveyard(); } +void Spell::EffectAddComboPoints() +{ + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + + Unit* caster = Object::ToUnit(m_caster); + if (!caster) + return; + + caster->AddComboPoints(unitTarget->GetGUID(), damage); +} + void Spell::EffectActivateRune() { if (effectHandleMode != SPELL_EFFECT_HANDLE_LAUNCH) |