[10636] Implement server side check combo points req. for spell cast.

Thanks to nos4r2zod for problem research.
This commit is contained in:
VladimirMangos 2010-10-21 14:08:00 +04:00
parent 7a26fdd45d
commit 691412d05c
7 changed files with 35 additions and 29 deletions

View file

@ -430,7 +430,6 @@ Player::Player (WorldSession *session): Unit(), m_mover(this), m_camera(this), m
if(GetSession()->GetSecurity() == SEC_PLAYER) if(GetSession()->GetSecurity() == SEC_PLAYER)
SetAcceptWhispers(true); SetAcceptWhispers(true);
m_comboTarget = 0;
m_comboPoints = 0; m_comboPoints = 0;
m_usedTalentCount = 0; m_usedTalentCount = 0;
@ -6900,14 +6899,14 @@ void Player::DuelComplete(DuelCompleteType type)
RemoveAurasDueToSpell(auras2remove[i]); RemoveAurasDueToSpell(auras2remove[i]);
// cleanup combo points // cleanup combo points
if(GetComboTarget()==duel->opponent->GetGUID()) if (GetComboTargetGuid() == duel->opponent->GetObjectGuid())
ClearComboPoints(); ClearComboPoints();
else if(GetComboTarget()==duel->opponent->GetPetGUID()) else if (GetComboTargetGuid().GetRawValue() == duel->opponent->GetPetGUID())
ClearComboPoints(); ClearComboPoints();
if(duel->opponent->GetComboTarget()==GetGUID()) if (duel->opponent->GetComboTargetGuid() == GetObjectGuid())
duel->opponent->ClearComboPoints(); duel->opponent->ClearComboPoints();
else if(duel->opponent->GetComboTarget()==GetPetGUID()) else if (duel->opponent->GetComboTargetGuid().GetRawValue() == GetPetGUID())
duel->opponent->ClearComboPoints(); duel->opponent->ClearComboPoints();
//cleanups //cleanups
@ -19448,7 +19447,7 @@ void Player::InitPrimaryProfessions()
void Player::SendComboPoints() void Player::SendComboPoints()
{ {
Unit *combotarget = ObjectAccessor::GetUnit(*this, m_comboTarget); Unit *combotarget = ObjectAccessor::GetUnit(*this, m_comboTargetGuid);
if (combotarget) if (combotarget)
{ {
WorldPacket data(SMSG_UPDATE_COMBO_POINTS, combotarget->GetPackGUID().size()+1); WorldPacket data(SMSG_UPDATE_COMBO_POINTS, combotarget->GetPackGUID().size()+1);
@ -19466,17 +19465,17 @@ void Player::AddComboPoints(Unit* target, int8 count)
// without combo points lost (duration checked in aura) // without combo points lost (duration checked in aura)
RemoveSpellsCausingAura(SPELL_AURA_RETAIN_COMBO_POINTS); RemoveSpellsCausingAura(SPELL_AURA_RETAIN_COMBO_POINTS);
if(target->GetGUID() == m_comboTarget) if(target->GetObjectGuid() == m_comboTargetGuid)
{ {
m_comboPoints += count; m_comboPoints += count;
} }
else else
{ {
if(m_comboTarget) if (!m_comboTargetGuid.IsEmpty())
if(Unit* target2 = ObjectAccessor::GetUnit(*this,m_comboTarget)) if(Unit* target2 = ObjectAccessor::GetUnit(*this, m_comboTargetGuid))
target2->RemoveComboPointHolder(GetGUIDLow()); target2->RemoveComboPointHolder(GetGUIDLow());
m_comboTarget = target->GetGUID(); m_comboTargetGuid = target->GetObjectGuid();
m_comboPoints = count; m_comboPoints = count;
target->AddComboPointHolder(GetGUIDLow()); target->AddComboPointHolder(GetGUIDLow());
@ -19490,7 +19489,7 @@ void Player::AddComboPoints(Unit* target, int8 count)
void Player::ClearComboPoints() void Player::ClearComboPoints()
{ {
if(!m_comboTarget) if (m_comboTargetGuid.IsEmpty())
return; return;
// without combopoints lost (duration checked in aura) // without combopoints lost (duration checked in aura)
@ -19500,10 +19499,10 @@ void Player::ClearComboPoints()
SendComboPoints(); SendComboPoints();
if(Unit* target = ObjectAccessor::GetUnit(*this,m_comboTarget)) if(Unit* target = ObjectAccessor::GetUnit(*this,m_comboTargetGuid))
target->RemoveComboPointHolder(GetGUIDLow()); target->RemoveComboPointHolder(GetGUIDLow());
m_comboTarget = 0; m_comboTargetGuid.Clear();
} }
void Player::SetGroup(Group *group, int8 subgroup) void Player::SetGroup(Group *group, int8 subgroup)

View file

@ -1583,7 +1583,7 @@ class MANGOS_DLL_SPEC Player : public Unit
void SetSelectionGuid(ObjectGuid guid) { m_curSelectionGuid = guid; SetTargetGuid(guid); } void SetSelectionGuid(ObjectGuid guid) { m_curSelectionGuid = guid; SetTargetGuid(guid); }
uint8 GetComboPoints() { return m_comboPoints; } uint8 GetComboPoints() { return m_comboPoints; }
const uint64& GetComboTarget() const { return m_comboTarget; } ObjectGuid const& GetComboTargetGuid() const { return m_comboTargetGuid; }
void AddComboPoints(Unit* target, int8 count); void AddComboPoints(Unit* target, int8 count);
void ClearComboPoints(); void ClearComboPoints();
@ -2512,7 +2512,7 @@ class MANGOS_DLL_SPEC Player : public Unit
uint32 m_ExtraFlags; uint32 m_ExtraFlags;
ObjectGuid m_curSelectionGuid; ObjectGuid m_curSelectionGuid;
uint64 m_comboTarget; ObjectGuid m_comboTargetGuid;
int8 m_comboPoints; int8 m_comboPoints;
QuestStatusMap mQuestStatus; QuestStatusMap mQuestStatus;

View file

@ -275,9 +275,9 @@ const uint32 ItemQualityColors[MAX_ITEM_QUALITY] = {
#define SPELL_ATTR_EX_UNK17 0x00020000 // 17 for auras SPELL_AURA_TRACK_CREATURES, SPELL_AURA_TRACK_RESOURCES and SPELL_AURA_TRACK_STEALTHED select non-stacking tracking spells #define SPELL_ATTR_EX_UNK17 0x00020000 // 17 for auras SPELL_AURA_TRACK_CREATURES, SPELL_AURA_TRACK_RESOURCES and SPELL_AURA_TRACK_STEALTHED select non-stacking tracking spells
#define SPELL_ATTR_EX_UNK18 0x00040000 // 18 #define SPELL_ATTR_EX_UNK18 0x00040000 // 18
#define SPELL_ATTR_EX_UNK19 0x00080000 // 19 #define SPELL_ATTR_EX_UNK19 0x00080000 // 19
#define SPELL_ATTR_EX_REQ_COMBO_POINTS1 0x00100000 // 20 Req combo points on target #define SPELL_ATTR_EX_REQ_TARGET_COMBO_POINTS 0x00100000 // 20 Req combo points on target
#define SPELL_ATTR_EX_UNK21 0x00200000 // 21 #define SPELL_ATTR_EX_UNK21 0x00200000 // 21
#define SPELL_ATTR_EX_REQ_COMBO_POINTS2 0x00400000 // 22 Req combo points on target #define SPELL_ATTR_EX_REQ_COMBO_POINTS 0x00400000 // 22 Use combo points (in 4.x not required combo point target selected)
#define SPELL_ATTR_EX_UNK23 0x00800000 // 23 #define SPELL_ATTR_EX_UNK23 0x00800000 // 23
#define SPELL_ATTR_EX_UNK24 0x01000000 // 24 Req fishing pole?? #define SPELL_ATTR_EX_UNK24 0x01000000 // 24 Req fishing pole??
#define SPELL_ATTR_EX_UNK25 0x02000000 // 25 #define SPELL_ATTR_EX_UNK25 0x02000000 // 25

View file

@ -4297,14 +4297,21 @@ SpellCastResult Spell::CheckCast(bool strict)
return SPELL_FAILED_CASTER_AURASTATE; return SPELL_FAILED_CASTER_AURASTATE;
} }
// cancel autorepeat spells if cast start when moving if (m_caster->GetTypeId() == TYPEID_PLAYER)
// (not wand currently autorepeat cast delayed to moving stop anyway in spell update code)
if( m_caster->GetTypeId() == TYPEID_PLAYER && ((Player*)m_caster)->isMoving() )
{ {
// skip stuck spell to allow use it in falling case and apply spell limitations at movement // cancel autorepeat spells if cast start when moving
if( (!((Player*)m_caster)->m_movementInfo.HasMovementFlag(MOVEFLAG_FALLINGFAR) || m_spellInfo->Effect[EFFECT_INDEX_0] != SPELL_EFFECT_STUCK) && // (not wand currently autorepeat cast delayed to moving stop anyway in spell update code)
(IsAutoRepeat() || (m_spellInfo->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) != 0) ) if (((Player*)m_caster)->isMoving() )
return SPELL_FAILED_MOVING; {
// skip stuck spell to allow use it in falling case and apply spell limitations at movement
if ((!((Player*)m_caster)->m_movementInfo.HasMovementFlag(MOVEFLAG_FALLINGFAR) || m_spellInfo->Effect[EFFECT_INDEX_0] != SPELL_EFFECT_STUCK) &&
(IsAutoRepeat() || (m_spellInfo->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) != 0))
return SPELL_FAILED_MOVING;
}
if (!m_IsTriggeredSpell && NeedsComboPoints(m_spellInfo) &&
(!m_targets.getUnitTarget() || m_targets.getUnitTarget()->GetObjectGuid() != ((Player*)m_caster)->GetComboTargetGuid()))
return SPELL_FAILED_NO_COMBO_POINTS;
} }
if(Unit *target = m_targets.getUnitTarget()) if(Unit *target = m_targets.getUnitTarget())

View file

@ -6261,8 +6261,8 @@ void Aura::HandleAuraRetainComboPoints(bool apply, bool Real)
// 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 && m_removeMode == AURA_REMOVE_BY_EXPIRE && target->GetComboTarget()) if (!apply && m_removeMode == AURA_REMOVE_BY_EXPIRE && !target->GetComboTargetGuid().IsEmpty())
if(Unit* unit = ObjectAccessor::GetUnit(*GetTarget(),target->GetComboTarget())) if (Unit* unit = ObjectAccessor::GetUnit(*GetTarget(),target->GetComboTargetGuid()))
target->AddComboPoints(unit, -m_modifier.m_amount); target->AddComboPoints(unit, -m_modifier.m_amount);
} }

View file

@ -462,7 +462,7 @@ inline bool IsChanneledSpell(SpellEntry const* spellInfo)
inline bool NeedsComboPoints(SpellEntry const* spellInfo) inline bool NeedsComboPoints(SpellEntry const* spellInfo)
{ {
return (spellInfo->AttributesEx & (SPELL_ATTR_EX_REQ_COMBO_POINTS1 | SPELL_ATTR_EX_REQ_COMBO_POINTS2)); return (spellInfo->AttributesEx & (SPELL_ATTR_EX_REQ_TARGET_COMBO_POINTS | SPELL_ATTR_EX_REQ_COMBO_POINTS));
} }
inline SpellSchoolMask GetSpellSchoolMask(SpellEntry const* spellInfo) inline SpellSchoolMask GetSpellSchoolMask(SpellEntry const* spellInfo)

View file

@ -8628,7 +8628,7 @@ int32 Unit::CalculateSpellDamage(Unit const* target, SpellEntry const* spellProt
int32 value = basePoints; int32 value = basePoints;
// random damage // random damage
if(comboDamage != 0 && unitPlayer && target && (target->GetGUID() == unitPlayer->GetComboTarget())) if (comboDamage != 0 && unitPlayer && target && (target->GetObjectGuid() == unitPlayer->GetComboTargetGuid()))
value += (int32)(comboDamage * comboPoints); value += (int32)(comboDamage * comboPoints);
if(Player* modOwner = GetSpellModOwner()) if(Player* modOwner = GetSpellModOwner())
@ -10021,7 +10021,7 @@ void Unit::ClearComboPointHolders()
uint32 lowguid = *m_ComboPointHolders.begin(); uint32 lowguid = *m_ComboPointHolders.begin();
Player* plr = sObjectMgr.GetPlayer(ObjectGuid(HIGHGUID_PLAYER, lowguid)); Player* plr = sObjectMgr.GetPlayer(ObjectGuid(HIGHGUID_PLAYER, lowguid));
if(plr && plr->GetComboTarget()==GetGUID()) // recheck for safe if (plr && plr->GetComboTargetGuid() == GetObjectGuid())// recheck for safe
plr->ClearComboPoints(); // remove also guid from m_ComboPointHolders; plr->ClearComboPoints(); // remove also guid from m_ComboPointHolders;
else else
m_ComboPointHolders.erase(lowguid); // or remove manually m_ComboPointHolders.erase(lowguid); // or remove manually