diff options
| author | Treeston <treeston.mmoc@gmail.com> | 2017-06-25 03:41:16 +0200 |
|---|---|---|
| committer | ariel- <ariel-@users.noreply.github.com> | 2017-06-24 22:41:16 -0300 |
| commit | 489478b74d96c2ea940a2316fd11f8e81991cf07 (patch) | |
| tree | 5faa936414542c9c7442d6386fc22b2d1d508ffc /src/server/game/Entities/Unit | |
| parent | 641c2036abed70adff5c384e1679c5c3c986bd72 (diff) | |
Core/Entities: Extend combo point system to all Units and fix numerous quirks with rogue CP and vehicles (Malygos P3) (#19914)
- Implement Wolverine Bite (fixes #752)
- General combo point system cleanup
Diffstat (limited to 'src/server/game/Entities/Unit')
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 103 | ||||
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 28 |
2 files changed, 111 insertions, 20 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index aac3257e865..bb43c34182a 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -283,7 +283,7 @@ Unit::Unit(bool isWorldObject) : i_AI(nullptr), i_disabledAI(nullptr), m_AutoRepeatFirstCast(false), m_procDeep(0), m_removedAurasCount(0), i_motionMaster(new MotionMaster(this)), m_regenTimer(0), m_ThreatManager(this), m_vehicle(nullptr), m_vehicleKit(nullptr), m_unitTypeMask(UNIT_MASK_NONE), m_Diminishing(), - m_HostileRefManager(this), m_spellHistory(new SpellHistory(this)) + m_HostileRefManager(this), m_comboTarget(nullptr), m_comboPoints(0), m_spellHistory(new SpellHistory(this)) { m_objectType |= TYPEMASK_UNIT; m_objectTypeId = TYPEID_UNIT; @@ -9751,7 +9751,7 @@ int32 Unit::CalculateSpellDamage(Unit const* target, SpellInfo const* spellProto int32 Unit::CalcSpellDuration(SpellInfo const* spellProto) { - uint8 comboPoints = m_playerMovingMe ? m_playerMovingMe->GetComboPoints() : 0; + uint8 comboPoints = GetComboPoints(); int32 minduration = spellProto->GetDuration(); int32 maxduration = spellProto->GetMaxDuration(); @@ -10676,6 +10676,7 @@ void Unit::CleanupBeforeRemoveFromMap(bool finalCleanup) m_Events.KillAllEvents(false); // non-delatable (currently cast spells) will not deleted now but it will deleted at call in Map::RemoveAllObjectsInRemoveList CombatStop(); + ClearComboPoints(); ClearComboPointHolders(); DeleteThreatList(); getHostileRefManager().deleteReferences(); @@ -11196,9 +11197,14 @@ void Unit::ProcSkillsAndReactives(bool isVictim, Unit* procTarget, uint32 typeMa // Overpower on victim dodge if ((hitMask & PROC_HIT_DODGE) && GetTypeId() == TYPEID_PLAYER && getClass() == CLASS_WARRIOR) { - ToPlayer()->AddComboPoints(procTarget, 1); + AddComboPoints(procTarget, 1); StartReactiveTimer(REACTIVE_OVERPOWER); } + else if ((hitMask & PROC_HIT_CRITICAL) && IsHunterPet()) + { + AddComboPoints(procTarget, 1); + StartReactiveTimer(REACTIVE_WOLVERINE_BITE); + } } } } @@ -11499,20 +11505,83 @@ void Unit::RestoreDisplayId() SetDisplayId(GetNativeDisplayId()); } -void Unit::ClearComboPointHolders() +void Unit::AddComboPoints(Unit* target, int8 count) { - while (!m_ComboPointHolders.empty()) + 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) { - ObjectGuid guid = *m_ComboPointHolders.begin(); + if (m_comboTarget) + m_comboTarget->RemoveComboPointHolder(this); + m_comboTarget = target; + m_comboPoints = count; + target->AddComboPointHolder(this); + } + else + m_comboPoints = std::max<int8>(std::min<int8>(m_comboPoints + count, 5),0); - 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 + 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; + data.Initialize(SMSG_UPDATE_COMBO_POINTS, packGUID.size() + 1); + data << packGUID; + data << uint8(m_comboPoints); + playerMe->SendDirectMessage(&data); + } + Player* movingMe = GetPlayerMovingMe(); + ObjectGuid ownerGuid = GetCharmerOrOwnerGUID(); + Player* owner = nullptr; + if (ownerGuid.IsPlayer()) + owner = ObjectAccessor::GetPlayer(*this, ownerGuid); + if (movingMe || owner) + { + WorldPacket data; + data.Initialize(SMSG_PET_UPDATE_COMBO_POINTS, GetPackGUID().size() + packGUID.size() + 1); + data << GetPackGUID(); + data << packGUID; + data << uint8(m_comboPoints); + if (movingMe) + movingMe->SendDirectMessage(&data); + if (owner && owner != movingMe) + owner->SendDirectMessage(&data); } } +void Unit::ClearComboPointHolders() +{ + while (!m_ComboPointHolders.empty()) + (*m_ComboPointHolders.begin())->ClearComboPoints(); // this also removes it from m_comboPointHolders +} + void Unit::ClearAllReactives() { for (uint8 i = 0; i < MAX_REACTIVE; ++i) @@ -11523,7 +11592,9 @@ 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(); + if (IsHunterPet()) + ClearComboPoints(); } void Unit::UpdateReactives(uint32 p_time) @@ -11551,7 +11622,13 @@ void Unit::UpdateReactives(uint32 p_time) break; case REACTIVE_OVERPOWER: if (getClass() == CLASS_WARRIOR && GetTypeId() == TYPEID_PLAYER) - ToPlayer()->ClearComboPoints(); + ClearComboPoints(); + break; + case REACTIVE_WOLVERINE_BITE: + if (IsHunterPet()) + ClearComboPoints(); + break; + default: break; } } diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 32f2f1c1870..73ca8add151 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -912,12 +912,13 @@ struct TC_GAME_API CharmInfo enum ReactiveType { - REACTIVE_DEFENSE = 0, - REACTIVE_HUNTER_PARRY = 1, - REACTIVE_OVERPOWER = 2 + REACTIVE_DEFENSE = 0, + REACTIVE_HUNTER_PARRY = 1, + REACTIVE_OVERPOWER = 2, + REACTIVE_WOLVERINE_BITE = 3, + MAX_REACTIVE }; -#define MAX_REACTIVE 3 #define SUMMON_SLOT_PET 0 #define SUMMON_SLOT_TOTEM 1 #define MAX_TOTEM_SLOT 5 @@ -1794,8 +1795,19 @@ class TC_GAME_API Unit : public WorldObject void SetControlled(bool apply, UnitState state); - 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 + uint8 GetComboPoints(Unit const* who = nullptr) const { return (who && m_comboTarget != who) ? 0 : m_comboPoints; } + uint8 GetComboPoints(ObjectGuid const& guid) const { return (m_comboTarget && m_comboTarget->GetGUID() == guid) ? m_comboPoints : 0; } + Unit* GetComboTarget() const { return m_comboTarget; } + ObjectGuid 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----------------- @@ -2014,7 +2026,9 @@ class TC_GAME_API Unit : public WorldObject FollowerRefManager m_FollowingRefManager; - GuidSet m_ComboPointHolders; + Unit* m_comboTarget; + int8 m_comboPoints; + std::unordered_set<Unit*> m_ComboPointHolders; RedirectThreatInfo _redirectThreadInfo; |
