From 2c6a692000426d4d924f82f778c694dcec3fd324 Mon Sep 17 00:00:00 2001 From: UltraNix <80540499+UltraNix@users.noreply.github.com> Date: Fri, 7 Jan 2022 11:18:03 +0100 Subject: [PATCH] fix(Core/Entities): extend combo point system to all Units (#9816) - Closes #1140 --- src/server/game/Entities/Player/Player.cpp | 165 +++++------------- src/server/game/Entities/Player/Player.h | 15 -- src/server/game/Entities/Unit/Unit.cpp | 109 ++++++++++-- src/server/game/Entities/Unit/Unit.h | 20 ++- .../game/Spells/Auras/SpellAuraEffects.cpp | 5 +- src/server/game/Spells/Spell.cpp | 39 +++-- src/server/game/Spells/Spell.h | 15 ++ src/server/game/Spells/SpellEffects.cpp | 23 +-- src/server/game/Spells/SpellInfo.cpp | 8 +- 9 files changed, 217 insertions(+), 182 deletions(-) diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index eb4cb6f50..67cb4fd8b 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -169,8 +169,6 @@ Player::Player(WorldSession* session): Unit(true), m_mover(this) if (AccountMgr::IsPlayerAccount(GetSession()->GetSecurity())) SetAcceptWhispers(true); - m_comboPoints = 0; - m_usedTalentCount = 0; m_questRewardTalentCount = 0; m_extraBonusTalentCount = 0; @@ -391,7 +389,6 @@ Player::Player(WorldSession* session): Unit(true), m_mover(this) // Ours m_NeedToSaveGlyphs = false; - m_comboPointGain = 0; m_MountBlockId = 0; m_realDodge = 0.0f; m_realParry = 0.0f; @@ -6202,12 +6199,11 @@ void Player::DuelComplete(DuelCompleteType type) if (duel->State == DUEL_STATE_COMPLETED) return; - Player* opponent = duel->Opponent; - duel->State = DUEL_STATE_COMPLETED; + Player* opponent = duel->Opponent; + duel->State = DUEL_STATE_COMPLETED; opponent->duel->State = DUEL_STATE_COMPLETED; - LOG_DEBUG("entities.unit", "Player::DuelComplete: Player '%s' (%s), Opponent: '%s' (%s)", - GetName().c_str(), GetGUID().ToString().c_str(), opponent->GetName().c_str(), opponent->GetGUID().ToString().c_str()); + LOG_DEBUG("entities.unit", "Player::DuelComplete: Player '%s' (%s), Opponent: '%s' (%s)", GetName().c_str(), GetGUID().ToString().c_str(), opponent->GetName().c_str(), opponent->GetGUID().ToString().c_str()); WorldPacket data(SMSG_DUEL_COMPLETE, (1)); data << uint8((type != DUEL_INTERRUPTED) ? 1 : 0); @@ -6219,8 +6215,8 @@ void Player::DuelComplete(DuelCompleteType type) if (type != DUEL_INTERRUPTED) { - data.Initialize(SMSG_DUEL_WINNER, (1+20)); // we guess size - data << uint8(type == DUEL_WON ? 0 : 1); // 0 = just won; 1 = fled + data.Initialize(SMSG_DUEL_WINNER, (1 + 20)); // we guess size + data << uint8(type == DUEL_WON ? 0 : 1); // 0 = just won; 1 = fled data << opponent->GetName(); data << GetName(); SendMessageToSet(&data, true); @@ -6230,45 +6226,45 @@ void Player::DuelComplete(DuelCompleteType type) switch (type) { - case DUEL_FLED: - // if initiator and opponent are on the same team - // or initiator and opponent are not PvP enabled, forcibly stop attacking - if (GetTeamId() == opponent->GetTeamId()) + case DUEL_FLED: + // if initiator and opponent are on the same team + // or initiator and opponent are not PvP enabled, forcibly stop attacking + if (GetTeamId() == opponent->GetTeamId()) + { + AttackStop(); + opponent->AttackStop(); + } + else + { + if (!IsPvP()) { AttackStop(); + } + if (!opponent->IsPvP()) + { opponent->AttackStop(); } - else - { - if (!IsPvP()) - { - AttackStop(); - } - if (!opponent->IsPvP()) - { - opponent->AttackStop(); - } - } - break; - case DUEL_WON: - UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOSE_DUEL, 1); - opponent->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL, 1); + } + break; + case DUEL_WON: + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOSE_DUEL, 1); + opponent->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL, 1); - // Credit for quest Death's Challenge - if (getClass() == CLASS_DEATH_KNIGHT && opponent->GetQuestStatus(12733) == QUEST_STATUS_INCOMPLETE) - { - opponent->CastSpell(opponent, 52994, true); - } + // Credit for quest Death's Challenge + if (getClass() == CLASS_DEATH_KNIGHT && opponent->GetQuestStatus(12733) == QUEST_STATUS_INCOMPLETE) + { + opponent->CastSpell(opponent, 52994, true); + } - // Honor points after duel (the winner) - ImpConfig - if (uint32 amount = sWorld->getIntConfig(CONFIG_HONOR_AFTER_DUEL)) - { - opponent->RewardHonor(nullptr, 1, amount); - } + // Honor points after duel (the winner) - ImpConfig + if (uint32 amount = sWorld->getIntConfig(CONFIG_HONOR_AFTER_DUEL)) + { + opponent->RewardHonor(nullptr, 1, amount); + } - break; - default: - break; + break; + default: + break; } // Victory emote spell @@ -6277,7 +6273,7 @@ void Player::DuelComplete(DuelCompleteType type) opponent->CastSpell(opponent, 52852, true); } - //Remove Duel Flag object + // Remove Duel Flag object GameObject* obj = GetMap()->GetGameObject(GetGuidValue(PLAYER_DUEL_ARBITER)); if (obj) { @@ -6285,7 +6281,7 @@ void Player::DuelComplete(DuelCompleteType type) } /* remove auras */ - AuraApplicationMap &itsAuras = opponent->GetAppliedAuras(); + AuraApplicationMap& itsAuras = opponent->GetAppliedAuras(); for (AuraApplicationMap::iterator i = itsAuras.begin(); i != itsAuras.end();) { Aura const* aura = i->second->GetBase(); @@ -6299,7 +6295,7 @@ void Player::DuelComplete(DuelCompleteType type) } } - AuraApplicationMap &myAuras = GetAppliedAuras(); + AuraApplicationMap& myAuras = GetAppliedAuras(); for (AuraApplicationMap::iterator i = myAuras.begin(); i != myAuras.end();) { Aura const* aura = i->second->GetBase(); @@ -6310,16 +6306,20 @@ void Player::DuelComplete(DuelCompleteType type) } // cleanup combo points - if (GetComboTarget() == duel->Opponent->GetGUID()) + if (GetComboTarget() == duel->Opponent) + { ClearComboPoints(); - else if (GetComboTarget() == duel->Opponent->GetPetGUID()) + } + else if (GetComboTargetGUID() == duel->Opponent->GetPetGUID()) + { ClearComboPoints(); + } - if (duel->Opponent->GetComboTarget() == GetGUID()) + if (duel->Opponent->GetComboTarget() == this) { duel->Opponent->ClearComboPoints(); } - else if (duel->Opponent->GetComboTarget() == GetPetGUID()) + else if (duel->Opponent->GetComboTargetGUID() == GetPetGUID()) { duel->Opponent->ClearComboPoints(); } @@ -10822,75 +10822,6 @@ void Player::SetSelection(ObjectGuid guid) ArenaSpectator::SendCommand_GUID(FindMap(), GetGUID(), "TRG", guid); } -void Player::SendComboPoints() -{ - Unit* combotarget = ObjectAccessor::GetUnit(*this, m_comboTarget); - if (combotarget) - { - WorldPacket data; - if (m_mover != this) - { - data.Initialize(SMSG_PET_UPDATE_COMBO_POINTS, m_mover->GetPackGUID().size() + combotarget->GetPackGUID().size() + 1); - data << m_mover->GetPackGUID(); - } - else - data.Initialize(SMSG_UPDATE_COMBO_POINTS, combotarget->GetPackGUID().size() + 1); - data << combotarget->GetPackGUID(); - data << uint8(m_comboPoints); - GetSession()->SendPacket(&data); - } -} - -void Player::AddComboPoints(Unit* target, int8 count) -{ - if (!count) - return; - - int8* comboPoints = &m_comboPoints; - - // without combo points lost (duration checked in aura) - RemoveAurasByType(SPELL_AURA_RETAIN_COMBO_POINTS); - - if (target->GetGUID() == m_comboTarget) - *comboPoints += count; - else - { - if (m_comboTarget) - if (Unit* target2 = ObjectAccessor::GetUnit(*this, m_comboTarget)) - target2->RemoveComboPointHolder(GetGUID()); - - m_comboTarget = target->GetGUID(); - *comboPoints = count; - - target->AddComboPointHolder(GetGUID()); - } - - if (*comboPoints > 5) - *comboPoints = 5; - else if (*comboPoints < 0) - *comboPoints = 0; - - SendComboPoints(); -} - -void Player::ClearComboPoints() -{ - if (!m_comboTarget) - return; - - // without combopoints lost (duration checked in aura) - RemoveAurasByType(SPELL_AURA_RETAIN_COMBO_POINTS); - - m_comboPoints = 0; - - SendComboPoints(); - - if (Unit* target = ObjectAccessor::GetUnit(*this, m_comboTarget)) - target->RemoveComboPointHolder(GetGUID()); - - m_comboTarget.Clear(); -} - void Player::SetGroup(Group* group, int8 subgroup) { if (group == nullptr) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index ba2210457..9aaa22575 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1582,13 +1582,6 @@ public: void SetTarget(ObjectGuid /*guid*/ = ObjectGuid::Empty) override { } /// Used for serverside target changes, does not apply to players void SetSelection(ObjectGuid guid); - [[nodiscard]] uint8 GetComboPoints() const { return m_comboPoints; } - [[nodiscard]] ObjectGuid GetComboTarget() const { return m_comboTarget; } - - void AddComboPoints(Unit* target, int8 count); - void ClearComboPoints(); - void SendComboPoints(); - void SendMailResult(uint32 mailId, MailResponseType mailAction, MailResponseResult mailError, uint32 equipError = 0, ObjectGuid::LowType item_guid = 0, uint32 item_count = 0); void SendNewMail(); void UpdateNextMailTimeAndUnreads(); @@ -2562,9 +2555,6 @@ public: void PrepareCharmAISpells(); uint32 m_charmUpdateTimer; - int8 GetComboPointGain() { return m_comboPointGain; } - void SetComboPointGain(int8 combo) { m_comboPointGain = combo; } - bool NeedToSaveGlyphs() { return m_NeedToSaveGlyphs; } void SetNeedToSaveGlyphs(bool val) { m_NeedToSaveGlyphs = val; } @@ -2610,8 +2600,6 @@ public: // Gamemaster whisper whitelist WhisperListContainer WhisperList; - // Combo Points - int8 m_comboPointGain; // Performance Varibales bool m_NeedToSaveGlyphs; // Mount block bug @@ -2753,9 +2741,6 @@ public: uint32 m_ExtraFlags; - ObjectGuid m_comboTarget; - int8 m_comboPoints; - QuestStatusMap m_QuestStatus; QuestStatusSaveMap m_QuestStatusSave; diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 8837c9b34..d87332c66 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -208,7 +208,8 @@ Unit::Unit(bool isWorldObject) : WorldObject(isWorldObject), m_vehicleKit(nullptr), m_unitTypeMask(UNIT_MASK_NONE), m_HostileRefMgr(this), - m_comboTarget(nullptr) + m_comboTarget(nullptr), + m_comboPoints(0) { #ifdef _MSC_VER #pragma warning(default:4355) @@ -9086,9 +9087,11 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg Unit* cptarget = nullptr; if (trigger_spell_id == 51699) { - cptarget = ObjectAccessor::GetUnit(*target, pTarget->GetComboTarget()); + cptarget = pTarget->GetComboTarget(); if (!cptarget) + { cptarget = pTarget->GetSelectedUnit(); + } } else cptarget = target; @@ -14069,7 +14072,7 @@ int32 Unit::CalculateSpellDamage(Unit const* target, SpellInfo const* spellProto int32 Unit::CalcSpellDuration(SpellInfo const* spellProto) { - uint8 comboPoints = m_movedByPlayer ? m_movedByPlayer->ToPlayer()->GetComboPoints() : 0; + uint8 comboPoints = GetComboPoints(); int32 minduration = spellProto->GetDuration(); int32 maxduration = spellProto->GetMaxDuration(); @@ -14938,6 +14941,7 @@ void Unit::CleanupBeforeRemoveFromMap(bool finalCleanup) m_Events.KillAllEvents(false); // non-delatable (currently casted spells) will not deleted now but it will deleted at call in Map::RemoveAllObjectsInRemoveList CombatStop(); + ClearComboPoints(); ClearComboPointHolders(); DeleteThreatList(); getHostileRefMgr().deleteReferences(); @@ -15556,7 +15560,7 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u { if (GetTypeId() == TYPEID_PLAYER && getClass() == CLASS_WARRIOR) { - ToPlayer()->AddComboPoints(target, 1); + AddComboPoints(target, 1); StartReactiveTimer(REACTIVE_OVERPOWER); } } @@ -16208,17 +16212,96 @@ void Unit::RestoreDisplayId() SetDisplayId(GetNativeDisplayId()); } +void Unit::AddComboPoints(Unit* target, int8 count) +{ + if (!count) + { + return; + } + + // remove Premed-like effects + // (NB: this Aura removes the already-added CP when it expires from duration - now that we've added CP, this shouldn't happen anymore) + RemoveAurasByType(SPELL_AURA_RETAIN_COMBO_POINTS); + + if (target && target != m_comboTarget) + { + if (m_comboTarget) + { + m_comboTarget->RemoveComboPointHolder(this); + } + + m_comboTarget = target; + m_comboPoints = count; + target->AddComboPointHolder(this); + } + else + { + m_comboPoints = std::max(std::min(m_comboPoints + count, 5), 0); + } + + SendComboPoints(); +} + +void Unit::ClearComboPoints() +{ + if (!m_comboTarget) + { + return; + } + + // remove Premed-like effects + // (NB: this Aura retains the CP while it's active - now that CP have reset, it shouldn't be there anymore) + RemoveAurasByType(SPELL_AURA_RETAIN_COMBO_POINTS); + + m_comboPoints = 0; + SendComboPoints(); + m_comboTarget->RemoveComboPointHolder(this); + m_comboTarget = nullptr; +} + +void Unit::SendComboPoints() +{ + if (m_cleanupDone) + { + return; + } + + PackedGuid const packGUID = m_comboTarget ? m_comboTarget->GetPackGUID() : PackedGuid(); + if (Player* playerMe = ToPlayer()) + { + WorldPacket data(SMSG_UPDATE_COMBO_POINTS, packGUID.size() + 1); + data << packGUID; + data << uint8(m_comboPoints); + playerMe->SendDirectMessage(&data); + } + + ObjectGuid ownerGuid = GetCharmerOrOwnerGUID(); + Player* owner = nullptr; + if (ownerGuid.IsPlayer()) + { + owner = ObjectAccessor::GetPlayer(*this, ownerGuid); + } + + if (m_movedByPlayer || owner) + { + WorldPacket data(SMSG_PET_UPDATE_COMBO_POINTS, GetPackGUID().size() + packGUID.size() + 1); + data << GetPackGUID(); + data << packGUID; + data << uint8(m_comboPoints); + + if (m_movedByPlayer) + m_movedByPlayer->ToPlayer()->SendDirectMessage(&data); + + if (owner && owner != m_movedByPlayer) + owner->SendDirectMessage(&data); + } +} + void Unit::ClearComboPointHolders() { while (!m_ComboPointHolders.empty()) { - ObjectGuid guid = *m_ComboPointHolders.begin(); - - Player* player = ObjectAccessor::GetPlayer(*this, guid); - if (player && player->GetComboTarget() == GetGUID()) // recheck for safe - player->ClearComboPoints(); // remove also guid from m_ComboPointHolders; - else - m_ComboPointHolders.erase(guid); // or remove manually + (*m_ComboPointHolders.begin())->ClearComboPoints(); // this also removes it from m_comboPointHolders } } @@ -16232,7 +16315,7 @@ void Unit::ClearAllReactives() if (getClass() == CLASS_HUNTER && HasAuraState(AURA_STATE_HUNTER_PARRY)) ModifyAuraState(AURA_STATE_HUNTER_PARRY, false); if (getClass() == CLASS_WARRIOR && GetTypeId() == TYPEID_PLAYER) - ToPlayer()->ClearComboPoints(); + ClearComboPoints(); } void Unit::UpdateReactives(uint32 p_time) @@ -16260,7 +16343,7 @@ void Unit::UpdateReactives(uint32 p_time) break; case REACTIVE_OVERPOWER: if (getClass() == CLASS_WARRIOR && GetTypeId() == TYPEID_PLAYER) - ToPlayer()->ClearComboPoints(); + ClearComboPoints(); break; default: break; diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index c28aaf0c0..3b2dd74a3 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -2369,8 +2369,19 @@ public: void DisableRotate(bool apply); void DisableSpline(); - void AddComboPointHolder(ObjectGuid lowguid) { m_ComboPointHolders.insert(lowguid); } - void RemoveComboPointHolder(ObjectGuid lowguid) { m_ComboPointHolders.erase(lowguid); } + ///-----------Combo point system------------------- + // This unit having CP on other units + [[nodiscard]] uint8 GetComboPoints(Unit const* who = nullptr) const { return (who && m_comboTarget != who) ? 0 : m_comboPoints; } + [[nodiscard]] uint8 GetComboPoints(ObjectGuid const& guid) const { return (m_comboTarget && m_comboTarget->GetGUID() == guid) ? m_comboPoints : 0; } + [[nodiscard]] Unit* GetComboTarget() const { return m_comboTarget; } + [[nodiscard]] ObjectGuid const GetComboTargetGUID() const { return m_comboTarget ? m_comboTarget->GetGUID() : ObjectGuid::Empty; } + void AddComboPoints(Unit* target, int8 count); + void AddComboPoints(int8 count) { AddComboPoints(nullptr, count); } + void ClearComboPoints(); + void SendComboPoints(); + // Other units having CP on this unit + void AddComboPointHolder(Unit* unit) { m_ComboPointHolders.insert(unit); } + void RemoveComboPointHolder(Unit* unit) { m_ComboPointHolders.erase(unit); } void ClearComboPointHolders(); ///----------Pet responses methods----------------- @@ -2647,9 +2658,10 @@ private: HostileRefMgr m_HostileRefMgr; FollowerRefMgr m_FollowingRefMgr; - Unit* m_comboTarget; - ComboPointHolderSet m_ComboPointHolders; + Unit* m_comboTarget; + int8 m_comboPoints; + std::unordered_set m_ComboPointHolders; RedirectThreatInfo _redirectThreatInfo; diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 9f83abab6..4436a7f89 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -4995,9 +4995,8 @@ void AuraEffect::HandleAuraRetainComboPoints(AuraApplication const* aurApp, uint // combo points was added in SPELL_EFFECT_ADD_COMBO_POINTS handler // remove only if aura expire by time (in case combo points amount change aura removed without combo points lost) - if (!(apply) && GetBase()->GetDuration() == 0 && target->ToPlayer()->GetComboTarget()) - if (Unit* unit = ObjectAccessor::GetUnit(*target, target->ToPlayer()->GetComboTarget())) - target->ToPlayer()->AddComboPoints(unit, -GetAmount()); + if (!(apply) && GetBase()->GetDuration() == 0) + target->AddComboPoints(-GetAmount()); } /*********************************************************/ diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index ea57c72a4..d7fbb265f 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -572,6 +572,8 @@ Spell::Spell(Unit* caster, SpellInfo const* info, TriggerCastFlags triggerFlags, m_referencedFromCurrentSpell = false; m_executedCurrently = false; m_needComboPoints = m_spellInfo->NeedsComboPoints(); + m_comboPointGain = 0; + m_comboTarget = nullptr; m_delayStart = 0; m_delayAtDamageCount = 0; @@ -3315,7 +3317,7 @@ SpellCastResult Spell::prepare(SpellCastTargets const* targets, AuraEffect const m_powerCost = m_CastItem ? 0 : m_spellInfo->CalcPowerCost(m_caster, m_spellSchoolMask, this); // Set combo point requirement - if ((_triggeredCastFlags & TRIGGERED_IGNORE_COMBO_POINTS) || m_CastItem || !m_caster->m_movedByPlayer) + if ((_triggeredCastFlags & TRIGGERED_IGNORE_COMBO_POINTS) || m_CastItem) m_needComboPoints = false; SpellCastResult result = CheckCast(true); @@ -3946,16 +3948,16 @@ void Spell::_handle_immediate_phase() void Spell::_handle_finish_phase() { - if (m_caster->m_movedByPlayer && m_needComboPoints) + // Take for real after all targets are processed + if (m_needComboPoints) { - // Take for real after all targets are processed - m_caster->m_movedByPlayer->ToPlayer()->ClearComboPoints(); + m_caster->ClearComboPoints(); + } - // Real add combo points from effects - if( m_targets.GetUnitTarget() && m_targets.GetUnitTarget()->IsInWorld() && m_targets.GetUnitTarget()->IsAlive() ) - m_caster->m_movedByPlayer->ToPlayer()->AddComboPoints(m_targets.GetUnitTarget(), m_caster->m_movedByPlayer->ToPlayer()->GetComboPointGain()); - - m_caster->m_movedByPlayer->ToPlayer()->SetComboPointGain(0); + // Real add combo points from effects + if (m_comboTarget && m_comboPointGain) + { + m_caster->AddComboPoints(m_comboTarget, m_comboPointGain); } if (m_caster->m_extraAttacks && GetSpellInfo()->HasEffect(SPELL_EFFECT_ADD_EXTRA_ATTACKS)) @@ -6322,11 +6324,24 @@ SpellCastResult Spell::CheckCast(bool strict) return SPELL_FAILED_ITEM_ALREADY_ENCHANTED; } - // check if caster has at least 1 combo point for spells that require combo points + // check if caster has at least 1 combo point on target for spells that require combo points if (m_needComboPoints) - if (Player* plrCaster = m_caster->ToPlayer()) - if (!plrCaster->GetComboPoints()) + { + if (m_spellInfo->NeedsExplicitUnitTarget()) + { + if (!m_caster->GetComboPoints(m_targets.GetUnitTarget())) + { return SPELL_FAILED_NO_COMBO_POINTS; + } + } + else + { + if (!m_caster->GetComboPoints()) + { + return SPELL_FAILED_NO_COMBO_POINTS; + } + } + } // xinef: check relic cooldown if (m_CastItem && m_CastItem->GetTemplate()->InventoryType == INVTYPE_RELIC && m_triggeredByAuraSpell) diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index 8d9fc2e18..87d8cdcd8 100644 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -527,6 +527,21 @@ public: SpellCastTargets m_targets; SpellCustomErrors m_customError; + void AddComboPointGain(Unit* target, int8 amount) + { + if (target != m_comboTarget) + { + m_comboTarget = target; + m_comboPointGain = amount; + } + else + { + m_comboPointGain += amount; + } + } + Unit* m_comboTarget; + int8 m_comboPointGain; + UsedSpellMods m_appliedMods; PathGenerator* m_pathFinder; // pussywizard: for precomputing path for charge diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 7ee7e6a4d..d5083d85c 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -481,7 +481,7 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex) float multiple = ap / 410 + m_spellInfo->Effects[effIndex].DamageMultiplier; int32 energy = -(m_caster->ModifyPower(POWER_ENERGY, -30)); damage += int32(energy * multiple); - damage += int32(CalculatePct(m_caster->ToPlayer()->GetComboPoints() * ap, 7)); + damage += int32(CalculatePct(m_caster->GetComboPoints() * ap, 7)); } // Wrath else if (m_spellInfo->SpellFamilyFlags[0] & 0x00000001) @@ -3399,8 +3399,7 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex) // Hemorrhage if (m_spellInfo->SpellFamilyFlags[0] & 0x2000000) { - if (m_caster->GetTypeId() == TYPEID_PLAYER) - m_caster->ToPlayer()->AddComboPoints(unitTarget, 1); + AddComboPointGain(unitTarget, 1); } // 50% more damage with daggers if (m_caster->GetTypeId() == TYPEID_PLAYER) @@ -3460,8 +3459,7 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex) // Mangle (Cat): CP if (m_spellInfo->SpellFamilyFlags[1] & 0x400) { - if (m_caster->GetTypeId() == TYPEID_PLAYER) - m_caster->ToPlayer()->AddComboPoints(unitTarget, 1); + AddComboPointGain(unitTarget, 1); } // Shred, Maul - Rend and Tear else if (m_spellInfo->SpellFamilyFlags[0] & 0x00008800 && unitTarget->HasAuraState(AURA_STATE_BLEEDING)) @@ -4325,19 +4323,16 @@ void Spell::EffectSanctuary(SpellEffIndex /*effIndex*/) void Spell::EffectAddComboPoints(SpellEffIndex /*effIndex*/) { if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) - return; - - if (!m_caster->m_movedByPlayer || !unitTarget || damage <= 0) - return; - - if (m_spellInfo->Id == 14157 || // Ruthlessness and Netherblade set - m_spellInfo->Id == 70802) // xinef: mayhem, rogue t10p4 { - m_caster->m_movedByPlayer->ToPlayer()->SetComboPointGain(m_caster->m_movedByPlayer->ToPlayer()->GetComboPointGain() + damage); return; } - m_caster->m_movedByPlayer->ToPlayer()->AddComboPoints(unitTarget, damage); + if (!unitTarget || damage <= 0) + { + return; + } + + AddComboPointGain(unitTarget, damage); } void Spell::EffectDuel(SpellEffIndex effIndex) diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 500d94c83..e2624fb7d 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -449,10 +449,10 @@ int32 SpellEffectInfo::CalcValue(Unit const* caster, int32 const* bp, Unit const if (caster) { // bonus amount from combo points - if (caster->m_movedByPlayer) - if (uint8 comboPoints = caster->m_movedByPlayer->ToPlayer()->GetComboPoints()) - if (float comboDamage = PointsPerComboPoint) - value += comboDamage * comboPoints; + if (uint8 comboPoints = caster->GetComboPoints()) + { + value += PointsPerComboPoint * comboPoints; + } value = caster->ApplyEffectModifiers(_spellInfo, _effIndex, value);