aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorOvahlord <dreadkiller@gmx.de>2024-07-31 06:05:41 +0200
committerOvahlord <dreadkiller@gmx.de>2024-07-31 06:05:41 +0200
commit2401e32c552ac119666bd2e27de9fb4b064868e1 (patch)
tree31af5d9b4fc52e4bf53948675aaac5f09f953e46 /src
parente49328d0939c11ce4f8460f6185c09a4320bdaaf (diff)
Core/Misc: update Combo Points handling to Cataclysm
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp23
-rw-r--r--src/server/game/Entities/Unit/Unit.h5
-rw-r--r--src/server/game/Spells/Spell.cpp18
-rw-r--r--src/server/game/Spells/Spell.h2
-rw-r--r--src/server/game/Spells/SpellEffects.cpp14
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)