fix(Core/Entities): extend combo point system to all Units (#9816)
- Closes #1140
This commit is contained in:
parent
2e6213d526
commit
2c6a692000
9 changed files with 217 additions and 182 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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<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()
|
||||
{
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -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<Unit*> m_ComboPointHolders;
|
||||
|
||||
RedirectThreatInfo _redirectThreatInfo;
|
||||
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
|
||||
/*********************************************************/
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue