aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Entities/Unit
diff options
context:
space:
mode:
authorTreeston <treeston.mmoc@gmail.com>2017-06-25 03:41:16 +0200
committerariel- <ariel-@users.noreply.github.com>2017-06-24 22:41:16 -0300
commit489478b74d96c2ea940a2316fd11f8e81991cf07 (patch)
tree5faa936414542c9c7442d6386fc22b2d1d508ffc /src/server/game/Entities/Unit
parent641c2036abed70adff5c384e1679c5c3c986bd72 (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.cpp103
-rw-r--r--src/server/game/Entities/Unit/Unit.h28
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;