fix(Core/Entities): extend combo point system to all Units (#9816)
- Closes #1140
This commit is contained in:
@@ -169,8 +169,6 @@ Player::Player(WorldSession* session): Unit(true), m_mover(this)
|
|||||||
if (AccountMgr::IsPlayerAccount(GetSession()->GetSecurity()))
|
if (AccountMgr::IsPlayerAccount(GetSession()->GetSecurity()))
|
||||||
SetAcceptWhispers(true);
|
SetAcceptWhispers(true);
|
||||||
|
|
||||||
m_comboPoints = 0;
|
|
||||||
|
|
||||||
m_usedTalentCount = 0;
|
m_usedTalentCount = 0;
|
||||||
m_questRewardTalentCount = 0;
|
m_questRewardTalentCount = 0;
|
||||||
m_extraBonusTalentCount = 0;
|
m_extraBonusTalentCount = 0;
|
||||||
@@ -391,7 +389,6 @@ Player::Player(WorldSession* session): Unit(true), m_mover(this)
|
|||||||
|
|
||||||
// Ours
|
// Ours
|
||||||
m_NeedToSaveGlyphs = false;
|
m_NeedToSaveGlyphs = false;
|
||||||
m_comboPointGain = 0;
|
|
||||||
m_MountBlockId = 0;
|
m_MountBlockId = 0;
|
||||||
m_realDodge = 0.0f;
|
m_realDodge = 0.0f;
|
||||||
m_realParry = 0.0f;
|
m_realParry = 0.0f;
|
||||||
@@ -6206,8 +6203,7 @@ void Player::DuelComplete(DuelCompleteType type)
|
|||||||
duel->State = DUEL_STATE_COMPLETED;
|
duel->State = DUEL_STATE_COMPLETED;
|
||||||
opponent->duel->State = DUEL_STATE_COMPLETED;
|
opponent->duel->State = DUEL_STATE_COMPLETED;
|
||||||
|
|
||||||
LOG_DEBUG("entities.unit", "Player::DuelComplete: Player '%s' (%s), Opponent: '%s' (%s)",
|
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());
|
||||||
GetName().c_str(), GetGUID().ToString().c_str(), opponent->GetName().c_str(), opponent->GetGUID().ToString().c_str());
|
|
||||||
|
|
||||||
WorldPacket data(SMSG_DUEL_COMPLETE, (1));
|
WorldPacket data(SMSG_DUEL_COMPLETE, (1));
|
||||||
data << uint8((type != DUEL_INTERRUPTED) ? 1 : 0);
|
data << uint8((type != DUEL_INTERRUPTED) ? 1 : 0);
|
||||||
@@ -6219,7 +6215,7 @@ void Player::DuelComplete(DuelCompleteType type)
|
|||||||
|
|
||||||
if (type != DUEL_INTERRUPTED)
|
if (type != DUEL_INTERRUPTED)
|
||||||
{
|
{
|
||||||
data.Initialize(SMSG_DUEL_WINNER, (1+20)); // we guess size
|
data.Initialize(SMSG_DUEL_WINNER, (1 + 20)); // we guess size
|
||||||
data << uint8(type == DUEL_WON ? 0 : 1); // 0 = just won; 1 = fled
|
data << uint8(type == DUEL_WON ? 0 : 1); // 0 = just won; 1 = fled
|
||||||
data << opponent->GetName();
|
data << opponent->GetName();
|
||||||
data << GetName();
|
data << GetName();
|
||||||
@@ -6277,7 +6273,7 @@ void Player::DuelComplete(DuelCompleteType type)
|
|||||||
opponent->CastSpell(opponent, 52852, true);
|
opponent->CastSpell(opponent, 52852, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Remove Duel Flag object
|
// Remove Duel Flag object
|
||||||
GameObject* obj = GetMap()->GetGameObject(GetGuidValue(PLAYER_DUEL_ARBITER));
|
GameObject* obj = GetMap()->GetGameObject(GetGuidValue(PLAYER_DUEL_ARBITER));
|
||||||
if (obj)
|
if (obj)
|
||||||
{
|
{
|
||||||
@@ -6285,7 +6281,7 @@ void Player::DuelComplete(DuelCompleteType type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* remove auras */
|
/* remove auras */
|
||||||
AuraApplicationMap &itsAuras = opponent->GetAppliedAuras();
|
AuraApplicationMap& itsAuras = opponent->GetAppliedAuras();
|
||||||
for (AuraApplicationMap::iterator i = itsAuras.begin(); i != itsAuras.end();)
|
for (AuraApplicationMap::iterator i = itsAuras.begin(); i != itsAuras.end();)
|
||||||
{
|
{
|
||||||
Aura const* aura = i->second->GetBase();
|
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();)
|
for (AuraApplicationMap::iterator i = myAuras.begin(); i != myAuras.end();)
|
||||||
{
|
{
|
||||||
Aura const* aura = i->second->GetBase();
|
Aura const* aura = i->second->GetBase();
|
||||||
@@ -6310,16 +6306,20 @@ void Player::DuelComplete(DuelCompleteType type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// cleanup combo points
|
// cleanup combo points
|
||||||
if (GetComboTarget() == duel->Opponent->GetGUID())
|
if (GetComboTarget() == duel->Opponent)
|
||||||
|
{
|
||||||
ClearComboPoints();
|
ClearComboPoints();
|
||||||
else if (GetComboTarget() == duel->Opponent->GetPetGUID())
|
}
|
||||||
|
else if (GetComboTargetGUID() == duel->Opponent->GetPetGUID())
|
||||||
|
{
|
||||||
ClearComboPoints();
|
ClearComboPoints();
|
||||||
|
}
|
||||||
|
|
||||||
if (duel->Opponent->GetComboTarget() == GetGUID())
|
if (duel->Opponent->GetComboTarget() == this)
|
||||||
{
|
{
|
||||||
duel->Opponent->ClearComboPoints();
|
duel->Opponent->ClearComboPoints();
|
||||||
}
|
}
|
||||||
else if (duel->Opponent->GetComboTarget() == GetPetGUID())
|
else if (duel->Opponent->GetComboTargetGUID() == GetPetGUID())
|
||||||
{
|
{
|
||||||
duel->Opponent->ClearComboPoints();
|
duel->Opponent->ClearComboPoints();
|
||||||
}
|
}
|
||||||
@@ -10822,75 +10822,6 @@ void Player::SetSelection(ObjectGuid guid)
|
|||||||
ArenaSpectator::SendCommand_GUID(FindMap(), GetGUID(), "TRG", 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)
|
void Player::SetGroup(Group* group, int8 subgroup)
|
||||||
{
|
{
|
||||||
if (group == nullptr)
|
if (group == nullptr)
|
||||||
|
|||||||
@@ -1582,13 +1582,6 @@ public:
|
|||||||
void SetTarget(ObjectGuid /*guid*/ = ObjectGuid::Empty) override { } /// Used for serverside target changes, does not apply to players
|
void SetTarget(ObjectGuid /*guid*/ = ObjectGuid::Empty) override { } /// Used for serverside target changes, does not apply to players
|
||||||
void SetSelection(ObjectGuid guid);
|
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 SendMailResult(uint32 mailId, MailResponseType mailAction, MailResponseResult mailError, uint32 equipError = 0, ObjectGuid::LowType item_guid = 0, uint32 item_count = 0);
|
||||||
void SendNewMail();
|
void SendNewMail();
|
||||||
void UpdateNextMailTimeAndUnreads();
|
void UpdateNextMailTimeAndUnreads();
|
||||||
@@ -2562,9 +2555,6 @@ public:
|
|||||||
void PrepareCharmAISpells();
|
void PrepareCharmAISpells();
|
||||||
uint32 m_charmUpdateTimer;
|
uint32 m_charmUpdateTimer;
|
||||||
|
|
||||||
int8 GetComboPointGain() { return m_comboPointGain; }
|
|
||||||
void SetComboPointGain(int8 combo) { m_comboPointGain = combo; }
|
|
||||||
|
|
||||||
bool NeedToSaveGlyphs() { return m_NeedToSaveGlyphs; }
|
bool NeedToSaveGlyphs() { return m_NeedToSaveGlyphs; }
|
||||||
void SetNeedToSaveGlyphs(bool val) { m_NeedToSaveGlyphs = val; }
|
void SetNeedToSaveGlyphs(bool val) { m_NeedToSaveGlyphs = val; }
|
||||||
|
|
||||||
@@ -2610,8 +2600,6 @@ public:
|
|||||||
// Gamemaster whisper whitelist
|
// Gamemaster whisper whitelist
|
||||||
WhisperListContainer WhisperList;
|
WhisperListContainer WhisperList;
|
||||||
|
|
||||||
// Combo Points
|
|
||||||
int8 m_comboPointGain;
|
|
||||||
// Performance Varibales
|
// Performance Varibales
|
||||||
bool m_NeedToSaveGlyphs;
|
bool m_NeedToSaveGlyphs;
|
||||||
// Mount block bug
|
// Mount block bug
|
||||||
@@ -2753,9 +2741,6 @@ public:
|
|||||||
|
|
||||||
uint32 m_ExtraFlags;
|
uint32 m_ExtraFlags;
|
||||||
|
|
||||||
ObjectGuid m_comboTarget;
|
|
||||||
int8 m_comboPoints;
|
|
||||||
|
|
||||||
QuestStatusMap m_QuestStatus;
|
QuestStatusMap m_QuestStatus;
|
||||||
QuestStatusSaveMap m_QuestStatusSave;
|
QuestStatusSaveMap m_QuestStatusSave;
|
||||||
|
|
||||||
|
|||||||
@@ -208,7 +208,8 @@ Unit::Unit(bool isWorldObject) : WorldObject(isWorldObject),
|
|||||||
m_vehicleKit(nullptr),
|
m_vehicleKit(nullptr),
|
||||||
m_unitTypeMask(UNIT_MASK_NONE),
|
m_unitTypeMask(UNIT_MASK_NONE),
|
||||||
m_HostileRefMgr(this),
|
m_HostileRefMgr(this),
|
||||||
m_comboTarget(nullptr)
|
m_comboTarget(nullptr),
|
||||||
|
m_comboPoints(0)
|
||||||
{
|
{
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(default:4355)
|
#pragma warning(default:4355)
|
||||||
@@ -9086,10 +9087,12 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
|
|||||||
Unit* cptarget = nullptr;
|
Unit* cptarget = nullptr;
|
||||||
if (trigger_spell_id == 51699)
|
if (trigger_spell_id == 51699)
|
||||||
{
|
{
|
||||||
cptarget = ObjectAccessor::GetUnit(*target, pTarget->GetComboTarget());
|
cptarget = pTarget->GetComboTarget();
|
||||||
if (!cptarget)
|
if (!cptarget)
|
||||||
|
{
|
||||||
cptarget = pTarget->GetSelectedUnit();
|
cptarget = pTarget->GetSelectedUnit();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
cptarget = target;
|
cptarget = target;
|
||||||
|
|
||||||
@@ -14069,7 +14072,7 @@ int32 Unit::CalculateSpellDamage(Unit const* target, SpellInfo const* spellProto
|
|||||||
|
|
||||||
int32 Unit::CalcSpellDuration(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 minduration = spellProto->GetDuration();
|
||||||
int32 maxduration = spellProto->GetMaxDuration();
|
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
|
m_Events.KillAllEvents(false); // non-delatable (currently casted spells) will not deleted now but it will deleted at call in Map::RemoveAllObjectsInRemoveList
|
||||||
CombatStop();
|
CombatStop();
|
||||||
|
ClearComboPoints();
|
||||||
ClearComboPointHolders();
|
ClearComboPointHolders();
|
||||||
DeleteThreatList();
|
DeleteThreatList();
|
||||||
getHostileRefMgr().deleteReferences();
|
getHostileRefMgr().deleteReferences();
|
||||||
@@ -15556,7 +15560,7 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
|
|||||||
{
|
{
|
||||||
if (GetTypeId() == TYPEID_PLAYER && getClass() == CLASS_WARRIOR)
|
if (GetTypeId() == TYPEID_PLAYER && getClass() == CLASS_WARRIOR)
|
||||||
{
|
{
|
||||||
ToPlayer()->AddComboPoints(target, 1);
|
AddComboPoints(target, 1);
|
||||||
StartReactiveTimer(REACTIVE_OVERPOWER);
|
StartReactiveTimer(REACTIVE_OVERPOWER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -16208,17 +16212,96 @@ void Unit::RestoreDisplayId()
|
|||||||
SetDisplayId(GetNativeDisplayId());
|
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<int8>(std::min<int8>(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()
|
void Unit::ClearComboPointHolders()
|
||||||
{
|
{
|
||||||
while (!m_ComboPointHolders.empty())
|
while (!m_ComboPointHolders.empty())
|
||||||
{
|
{
|
||||||
ObjectGuid guid = *m_ComboPointHolders.begin();
|
(*m_ComboPointHolders.begin())->ClearComboPoints(); // this also removes it from m_comboPointHolders
|
||||||
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -16232,7 +16315,7 @@ void Unit::ClearAllReactives()
|
|||||||
if (getClass() == CLASS_HUNTER && HasAuraState(AURA_STATE_HUNTER_PARRY))
|
if (getClass() == CLASS_HUNTER && HasAuraState(AURA_STATE_HUNTER_PARRY))
|
||||||
ModifyAuraState(AURA_STATE_HUNTER_PARRY, false);
|
ModifyAuraState(AURA_STATE_HUNTER_PARRY, false);
|
||||||
if (getClass() == CLASS_WARRIOR && GetTypeId() == TYPEID_PLAYER)
|
if (getClass() == CLASS_WARRIOR && GetTypeId() == TYPEID_PLAYER)
|
||||||
ToPlayer()->ClearComboPoints();
|
ClearComboPoints();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Unit::UpdateReactives(uint32 p_time)
|
void Unit::UpdateReactives(uint32 p_time)
|
||||||
@@ -16260,7 +16343,7 @@ void Unit::UpdateReactives(uint32 p_time)
|
|||||||
break;
|
break;
|
||||||
case REACTIVE_OVERPOWER:
|
case REACTIVE_OVERPOWER:
|
||||||
if (getClass() == CLASS_WARRIOR && GetTypeId() == TYPEID_PLAYER)
|
if (getClass() == CLASS_WARRIOR && GetTypeId() == TYPEID_PLAYER)
|
||||||
ToPlayer()->ClearComboPoints();
|
ClearComboPoints();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -2369,8 +2369,19 @@ public:
|
|||||||
void DisableRotate(bool apply);
|
void DisableRotate(bool apply);
|
||||||
void DisableSpline();
|
void DisableSpline();
|
||||||
|
|
||||||
void AddComboPointHolder(ObjectGuid lowguid) { m_ComboPointHolders.insert(lowguid); }
|
///-----------Combo point system-------------------
|
||||||
void RemoveComboPointHolder(ObjectGuid lowguid) { m_ComboPointHolders.erase(lowguid); }
|
// 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();
|
void ClearComboPointHolders();
|
||||||
|
|
||||||
///----------Pet responses methods-----------------
|
///----------Pet responses methods-----------------
|
||||||
@@ -2647,9 +2658,10 @@ private:
|
|||||||
HostileRefMgr m_HostileRefMgr;
|
HostileRefMgr m_HostileRefMgr;
|
||||||
|
|
||||||
FollowerRefMgr m_FollowingRefMgr;
|
FollowerRefMgr m_FollowingRefMgr;
|
||||||
Unit* m_comboTarget;
|
|
||||||
|
|
||||||
ComboPointHolderSet m_ComboPointHolders;
|
Unit* m_comboTarget;
|
||||||
|
int8 m_comboPoints;
|
||||||
|
std::unordered_set<Unit*> m_ComboPointHolders;
|
||||||
|
|
||||||
RedirectThreatInfo _redirectThreatInfo;
|
RedirectThreatInfo _redirectThreatInfo;
|
||||||
|
|
||||||
|
|||||||
@@ -4995,9 +4995,8 @@ void AuraEffect::HandleAuraRetainComboPoints(AuraApplication const* aurApp, uint
|
|||||||
|
|
||||||
// combo points was added in SPELL_EFFECT_ADD_COMBO_POINTS handler
|
// 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)
|
// 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 (!(apply) && GetBase()->GetDuration() == 0)
|
||||||
if (Unit* unit = ObjectAccessor::GetUnit(*target, target->ToPlayer()->GetComboTarget()))
|
target->AddComboPoints(-GetAmount());
|
||||||
target->ToPlayer()->AddComboPoints(unit, -GetAmount());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************/
|
/*********************************************************/
|
||||||
|
|||||||
@@ -572,6 +572,8 @@ Spell::Spell(Unit* caster, SpellInfo const* info, TriggerCastFlags triggerFlags,
|
|||||||
m_referencedFromCurrentSpell = false;
|
m_referencedFromCurrentSpell = false;
|
||||||
m_executedCurrently = false;
|
m_executedCurrently = false;
|
||||||
m_needComboPoints = m_spellInfo->NeedsComboPoints();
|
m_needComboPoints = m_spellInfo->NeedsComboPoints();
|
||||||
|
m_comboPointGain = 0;
|
||||||
|
m_comboTarget = nullptr;
|
||||||
m_delayStart = 0;
|
m_delayStart = 0;
|
||||||
m_delayAtDamageCount = 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);
|
m_powerCost = m_CastItem ? 0 : m_spellInfo->CalcPowerCost(m_caster, m_spellSchoolMask, this);
|
||||||
|
|
||||||
// Set combo point requirement
|
// 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;
|
m_needComboPoints = false;
|
||||||
|
|
||||||
SpellCastResult result = CheckCast(true);
|
SpellCastResult result = CheckCast(true);
|
||||||
@@ -3946,16 +3948,16 @@ void Spell::_handle_immediate_phase()
|
|||||||
|
|
||||||
void Spell::_handle_finish_phase()
|
void Spell::_handle_finish_phase()
|
||||||
{
|
{
|
||||||
if (m_caster->m_movedByPlayer && m_needComboPoints)
|
|
||||||
{
|
|
||||||
// Take for real after all targets are processed
|
// Take for real after all targets are processed
|
||||||
m_caster->m_movedByPlayer->ToPlayer()->ClearComboPoints();
|
if (m_needComboPoints)
|
||||||
|
{
|
||||||
|
m_caster->ClearComboPoints();
|
||||||
|
}
|
||||||
|
|
||||||
// Real add combo points from effects
|
// Real add combo points from effects
|
||||||
if( m_targets.GetUnitTarget() && m_targets.GetUnitTarget()->IsInWorld() && m_targets.GetUnitTarget()->IsAlive() )
|
if (m_comboTarget && m_comboPointGain)
|
||||||
m_caster->m_movedByPlayer->ToPlayer()->AddComboPoints(m_targets.GetUnitTarget(), m_caster->m_movedByPlayer->ToPlayer()->GetComboPointGain());
|
{
|
||||||
|
m_caster->AddComboPoints(m_comboTarget, m_comboPointGain);
|
||||||
m_caster->m_movedByPlayer->ToPlayer()->SetComboPointGain(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_caster->m_extraAttacks && GetSpellInfo()->HasEffect(SPELL_EFFECT_ADD_EXTRA_ATTACKS))
|
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;
|
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 (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;
|
return SPELL_FAILED_NO_COMBO_POINTS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!m_caster->GetComboPoints())
|
||||||
|
{
|
||||||
|
return SPELL_FAILED_NO_COMBO_POINTS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// xinef: check relic cooldown
|
// xinef: check relic cooldown
|
||||||
if (m_CastItem && m_CastItem->GetTemplate()->InventoryType == INVTYPE_RELIC && m_triggeredByAuraSpell)
|
if (m_CastItem && m_CastItem->GetTemplate()->InventoryType == INVTYPE_RELIC && m_triggeredByAuraSpell)
|
||||||
|
|||||||
@@ -527,6 +527,21 @@ public:
|
|||||||
SpellCastTargets m_targets;
|
SpellCastTargets m_targets;
|
||||||
SpellCustomErrors m_customError;
|
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;
|
UsedSpellMods m_appliedMods;
|
||||||
|
|
||||||
PathGenerator* m_pathFinder; // pussywizard: for precomputing path for charge
|
PathGenerator* m_pathFinder; // pussywizard: for precomputing path for charge
|
||||||
|
|||||||
@@ -481,7 +481,7 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex)
|
|||||||
float multiple = ap / 410 + m_spellInfo->Effects[effIndex].DamageMultiplier;
|
float multiple = ap / 410 + m_spellInfo->Effects[effIndex].DamageMultiplier;
|
||||||
int32 energy = -(m_caster->ModifyPower(POWER_ENERGY, -30));
|
int32 energy = -(m_caster->ModifyPower(POWER_ENERGY, -30));
|
||||||
damage += int32(energy * multiple);
|
damage += int32(energy * multiple);
|
||||||
damage += int32(CalculatePct(m_caster->ToPlayer()->GetComboPoints() * ap, 7));
|
damage += int32(CalculatePct(m_caster->GetComboPoints() * ap, 7));
|
||||||
}
|
}
|
||||||
// Wrath
|
// Wrath
|
||||||
else if (m_spellInfo->SpellFamilyFlags[0] & 0x00000001)
|
else if (m_spellInfo->SpellFamilyFlags[0] & 0x00000001)
|
||||||
@@ -3399,8 +3399,7 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex)
|
|||||||
// Hemorrhage
|
// Hemorrhage
|
||||||
if (m_spellInfo->SpellFamilyFlags[0] & 0x2000000)
|
if (m_spellInfo->SpellFamilyFlags[0] & 0x2000000)
|
||||||
{
|
{
|
||||||
if (m_caster->GetTypeId() == TYPEID_PLAYER)
|
AddComboPointGain(unitTarget, 1);
|
||||||
m_caster->ToPlayer()->AddComboPoints(unitTarget, 1);
|
|
||||||
}
|
}
|
||||||
// 50% more damage with daggers
|
// 50% more damage with daggers
|
||||||
if (m_caster->GetTypeId() == TYPEID_PLAYER)
|
if (m_caster->GetTypeId() == TYPEID_PLAYER)
|
||||||
@@ -3460,8 +3459,7 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex)
|
|||||||
// Mangle (Cat): CP
|
// Mangle (Cat): CP
|
||||||
if (m_spellInfo->SpellFamilyFlags[1] & 0x400)
|
if (m_spellInfo->SpellFamilyFlags[1] & 0x400)
|
||||||
{
|
{
|
||||||
if (m_caster->GetTypeId() == TYPEID_PLAYER)
|
AddComboPointGain(unitTarget, 1);
|
||||||
m_caster->ToPlayer()->AddComboPoints(unitTarget, 1);
|
|
||||||
}
|
}
|
||||||
// Shred, Maul - Rend and Tear
|
// Shred, Maul - Rend and Tear
|
||||||
else if (m_spellInfo->SpellFamilyFlags[0] & 0x00008800 && unitTarget->HasAuraState(AURA_STATE_BLEEDING))
|
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*/)
|
void Spell::EffectAddComboPoints(SpellEffIndex /*effIndex*/)
|
||||||
{
|
{
|
||||||
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_caster->m_movedByPlayer->ToPlayer()->AddComboPoints(unitTarget, damage);
|
if (!unitTarget || damage <= 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AddComboPointGain(unitTarget, damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Spell::EffectDuel(SpellEffIndex effIndex)
|
void Spell::EffectDuel(SpellEffIndex effIndex)
|
||||||
|
|||||||
@@ -449,10 +449,10 @@ int32 SpellEffectInfo::CalcValue(Unit const* caster, int32 const* bp, Unit const
|
|||||||
if (caster)
|
if (caster)
|
||||||
{
|
{
|
||||||
// bonus amount from combo points
|
// bonus amount from combo points
|
||||||
if (caster->m_movedByPlayer)
|
if (uint8 comboPoints = caster->GetComboPoints())
|
||||||
if (uint8 comboPoints = caster->m_movedByPlayer->ToPlayer()->GetComboPoints())
|
{
|
||||||
if (float comboDamage = PointsPerComboPoint)
|
value += PointsPerComboPoint * comboPoints;
|
||||||
value += comboDamage * comboPoints;
|
}
|
||||||
|
|
||||||
value = caster->ApplyEffectModifiers(_spellInfo, _effIndex, value);
|
value = caster->ApplyEffectModifiers(_spellInfo, _effIndex, value);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user