Core/Players: Fixed issues with incorrect targets being selected for spells

This commit is contained in:
Shauren committed 2013-10-03 17:07:25 +02:00
1 parent dd4404e6e3
commit a368fae588
15 files changed
+93 -102

No files matched your search

+9 -13
View File
@@ -344,7 +344,7 @@ bool ChatHandler::ExecuteCommandInTable(ChatCommand* table, const char* text, st
Player* player = m_session->GetPlayer();
if (!AccountMgr::IsPlayerAccount(m_session->GetSecurity()))
{
uint64 guid = player->GetSelection();
uint64 guid = player->GetTarget();
uint32 areaId = player->GetAreaId();
std::string areaName = "Unknown";
std::string zoneName = "Unknown";
@@ -713,12 +713,10 @@ Player* ChatHandler::getSelectedPlayer()
if (!m_session)
return NULL;
uint64 guid = m_session->GetPlayer()->GetSelection();
if (Player* selected = m_session->GetPlayer()->GetSelectedPlayer())
return selected;
if (guid == 0)
return m_session->GetPlayer();
return ObjectAccessor::FindPlayer(guid);
return m_session->GetPlayer();
}
Unit* ChatHandler::getSelectedUnit()
@@ -726,12 +724,10 @@ Unit* ChatHandler::getSelectedUnit()
if (!m_session)
return NULL;
uint64 guid = m_session->GetPlayer()->GetSelection();
if (Unit* selected = m_session->GetPlayer()->GetSelectedUnit())
return selected;
if (guid == 0)
return m_session->GetPlayer();
return ObjectAccessor::GetUnit(*m_session->GetPlayer(), guid);
return m_session->GetPlayer();
}
WorldObject* ChatHandler::getSelectedObject()
@@ -739,7 +735,7 @@ WorldObject* ChatHandler::getSelectedObject()
if (!m_session)
return NULL;
uint64 guid = m_session->GetPlayer()->GetSelection();
uint64 guid = m_session->GetPlayer()->GetTarget();
if (guid == 0)
return GetNearbyGameObject();
@@ -752,7 +748,7 @@ Creature* ChatHandler::getSelectedCreature()
if (!m_session)
return NULL;
return ObjectAccessor::GetCreatureOrPetOrVehicle(*m_session->GetPlayer(), m_session->GetPlayer()->GetSelection());
return ObjectAccessor::GetCreatureOrPetOrVehicle(*m_session->GetPlayer(), m_session->GetPlayer()->GetTarget());
}
char* ChatHandler::extractKeyFromLink(char* text, char const* linkType, char** something1)
@@ -165,6 +165,7 @@ m_creatureInfo(NULL), m_creatureData(NULL), m_path_id(0), m_formation(NULL)
ResetLootMode(); // restore default loot mode
TriggerJustRespawned = false;
m_isTempWorldObject = false;
_focusSpell = NULL;
}
Creature::~Creature()
@@ -2640,3 +2641,41 @@ void Creature::SetDisplayId(uint32 modelId)
SetFloatValue(UNIT_FIELD_COMBATREACH, minfo->combat_reach * GetObjectScale());
}
}
void Creature::SetTarget(uint64 guid)
{
if (!_focusSpell)
SetUInt64Value(UNIT_FIELD_TARGET, guid);
}
void Creature::FocusTarget(Spell const* focusSpell, WorldObject const* target)
{
// already focused
if (_focusSpell)
return;
_focusSpell = focusSpell;
SetUInt64Value(UNIT_FIELD_TARGET, target->GetGUID());
if (focusSpell->GetSpellInfo()->AttributesEx5 & SPELL_ATTR5_DONT_TURN_DURING_CAST)
AddUnitState(UNIT_STATE_ROTATING);
// Set serverside orientation if needed (needs to be after attribute check)
SetInFront(target);
}
void Creature::ReleaseFocus(Spell const* focusSpell)
{
// focused to something else
if (focusSpell != _focusSpell)
return;
_focusSpell = NULL;
if (Unit* victim = GetVictim())
SetUInt64Value(UNIT_FIELD_TARGET, victim->GetGUID());
else
SetUInt64Value(UNIT_FIELD_TARGET, 0);
if (focusSpell->GetSpellInfo()->AttributesEx5 & SPELL_ATTR5_DONT_TURN_DURING_CAST)
ClearUnitState(UNIT_STATE_ROTATING);
}
@@ -703,6 +703,11 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature
bool m_isTempWorldObject; //true when possessed
// Handling caster facing during spellcast
void SetTarget(uint64 guid);
void FocusTarget(Spell const* focusSpell, WorldObject const* target);
void ReleaseFocus(Spell const* focusSpell);
protected:
bool CreateFromProto(uint32 guidlow, uint32 Entry, uint32 vehId, uint32 team, const CreatureData* data = NULL);
bool InitEntry(uint32 entry, uint32 team=ALLIANCE, const CreatureData* data=NULL);
@@ -762,6 +767,8 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature
//Formation var
CreatureGroup* m_formation;
bool TriggerJustRespawned;
Spell const* _focusSpell; ///> Locks the target during spell cast for proper facing
};
class AssistDelayEvent : public BasicEvent
@@ -1508,7 +1508,7 @@ void GameObject::Use(Unit* user)
Player* player = user->ToPlayer();
Player* targetPlayer = ObjectAccessor::FindPlayer(player->GetSelection());
Player* targetPlayer = ObjectAccessor::FindPlayer(player->GetTarget());
// accept only use by player from same raid as caster, except caster itself
if (!targetPlayer || targetPlayer == player || !targetPlayer->IsInSameRaidWith(player))
+4 -5
View File
@@ -673,7 +673,6 @@ Player::Player(WorldSession* session): Unit(true)
if (!GetSession()->HasPermission(rbac::RBAC_PERM_CAN_FILTER_WHISPERS))
SetAcceptWhispers(true);
m_curSelection = 0;
m_lootGuid = 0;
m_comboTarget = 0;
@@ -22397,15 +22396,15 @@ bool Player::IsQuestRewarded(uint32 quest_id) const
Unit* Player::GetSelectedUnit() const
{
if (m_curSelection)
return ObjectAccessor::GetUnit(*this, m_curSelection);
if (uint64 selectionGUID = GetUInt64Value(UNIT_FIELD_TARGET))
return ObjectAccessor::GetUnit(*this, selectionGUID);
return NULL;
}
Player* Player::GetSelectedPlayer() const
{
if (m_curSelection)
return ObjectAccessor::GetPlayer(*this, m_curSelection);
if (uint64 selectionGUID = GetUInt64Value(UNIT_FIELD_TARGET))
return ObjectAccessor::GetPlayer(*this, selectionGUID);
return NULL;
}
+3 -3
View File
@@ -1506,10 +1506,11 @@ class Player : public Unit, public GridObject<Player>
size_t GetRewardedQuestCount() const { return m_RewardedQuests.size(); }
bool IsQuestRewarded(uint32 quest_id) const;
uint64 GetSelection() const { return m_curSelection; }
Unit* GetSelectedUnit() const;
Player* GetSelectedPlayer() const;
void SetSelection(uint64 guid) { m_curSelection = guid; SetUInt64Value(UNIT_FIELD_TARGET, guid); }
void SetTarget(uint64 /*guid*/) OVERRIDE { } /// Used for serverside target changes, does not apply to players
void SetSelection(uint64 guid) { SetUInt64Value(UNIT_FIELD_TARGET, guid); }
uint8 GetComboPoints() const { return m_comboPoints; }
uint64 GetComboTarget() const { return m_comboTarget; }
@@ -2424,7 +2425,6 @@ class Player : public Unit, public GridObject<Player>
bool m_itemUpdateQueueBlocked;
uint32 m_ExtraFlags;
uint64 m_curSelection;
uint64 m_comboTarget;
int8 m_comboPoints;
+5 -43
View File
@@ -259,7 +259,6 @@ Unit::Unit(bool isWorldObject) :
m_serverSideVisibility.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_ALIVE);
_focusSpell = NULL;
_lastLiquid = NULL;
_isWalkingBeforeCharm = false;
}
@@ -5258,18 +5257,19 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
// cast 45429 Arcane Bolt if Exalted by Scryers
case 45481:
{
if (GetTypeId() != TYPEID_PLAYER)
Player* player = ToPlayer();
if (!player)
return false;
// Get Aldor reputation rank
if (ToPlayer()->GetReputationRank(932) == REP_EXALTED)
if (player->GetReputationRank(932) == REP_EXALTED)
{
target = this;
triggered_spell_id = 45479;
break;
}
// Get Scryers reputation rank
if (ToPlayer()->GetReputationRank(934) == REP_EXALTED)
if (player->GetReputationRank(934) == REP_EXALTED)
{
// triggered at positive/self casts also, current attack target used then
if (target && IsFriendlyTo(target))
@@ -5277,8 +5277,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
target = GetVictim();
if (!target)
{
uint64 selected_guid = ToPlayer()->GetSelection();
target = ObjectAccessor::GetUnit(*this, selected_guid);
target = player->GetSelectedUnit();
if (!target)
return false;
}
@@ -17471,43 +17470,6 @@ bool Unit::SetHover(bool enable, bool /*packetOnly = false*/)
return true;
}
void Unit::SetTarget(uint64 guid)
{
if (!_focusSpell)
SetUInt64Value(UNIT_FIELD_TARGET, guid);
}
void Unit::FocusTarget(Spell const* focusSpell, WorldObject const* target)
{
// already focused
if (_focusSpell)
return;
_focusSpell = focusSpell;
SetUInt64Value(UNIT_FIELD_TARGET, target->GetGUID());
if (focusSpell->GetSpellInfo()->AttributesEx5 & SPELL_ATTR5_DONT_TURN_DURING_CAST)
AddUnitState(UNIT_STATE_ROTATING);
// Set serverside orientation if needed (needs to be after attribute check)
SetInFront(target);
}
void Unit::ReleaseFocus(Spell const* focusSpell)
{
// focused to something else
if (focusSpell != _focusSpell)
return;
_focusSpell = NULL;
if (Unit* victim = GetVictim())
SetUInt64Value(UNIT_FIELD_TARGET, victim->GetGUID());
else
SetUInt64Value(UNIT_FIELD_TARGET, 0);
if (focusSpell->GetSpellInfo()->AttributesEx5 & SPELL_ATTR5_DONT_TURN_DURING_CAST)
ClearUnitState(UNIT_STATE_ROTATING);
}
void Unit::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) const
{
if (!target)
+2 -6
View File
@@ -2124,11 +2124,8 @@ class Unit : public WorldObject
TempSummon* ToTempSummon() { if (IsSummon()) return reinterpret_cast<TempSummon*>(this); else return NULL; }
TempSummon const* ToTempSummon() const { if (IsSummon()) return reinterpret_cast<TempSummon const*>(this); else return NULL; }
void SetTarget(uint64 guid);
// Handling caster facing during spellcast
void FocusTarget(Spell const* focusSpell, WorldObject const* target);
void ReleaseFocus(Spell const* focusSpell);
uint64 GetTarget() const { return GetUInt64Value(UNIT_FIELD_TARGET); }
virtual void SetTarget(uint64 /*guid*/) = 0;
// Movement info
Movement::MoveSpline * movespline;
@@ -2253,7 +2250,6 @@ class Unit : public WorldObject
bool m_cleanupDone; // lock made to not add stuff after cleanup before delete
bool m_duringRemoveFromWorld; // lock made to not add stuff after begining removing from world
Spell const* _focusSpell; ///> Locks the target during spell cast for proper facing
bool _isWalkingBeforeCharm; // Are we walking before we were charmed?
time_t _lastDamagedTime; // Part of Evade mechanics
-2
View File
@@ -1167,8 +1167,6 @@ void WorldSession::HandleInspectOpcode(WorldPacket& recvData)
TC_LOG_DEBUG(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_INSPECT");
_player->SetSelection(guid);
Player* player = ObjectAccessor::FindPlayer(guid);
if (!player)
{
@@ -267,7 +267,6 @@ void WorldSession::HandleNpcTextQueryOpcode(WorldPacket& recvData)
TC_LOG_DEBUG(LOG_FILTER_NETWORKIO, "WORLD: CMSG_NPC_TEXT_QUERY ID '%u'", textID);
recvData >> guid;
GetPlayer()->SetSelection(guid);
GossipText const* pGossip = sObjectMgr->GetGossipText(textID);
+10 -10
View File
@@ -643,7 +643,7 @@ void Spell::InitExplicitTargets(SpellCastTargets const& targets)
if (Player* playerCaster = m_caster->ToPlayer())
{
// selection has to be found and to be valid target for the spell
if (Unit* selectedUnit = ObjectAccessor::GetUnit(*m_caster, playerCaster->GetSelection()))
if (Unit* selectedUnit = ObjectAccessor::GetUnit(*m_caster, playerCaster->GetTarget()))
if (m_spellInfo->CheckExplicitTarget(m_caster, selectedUnit) == SPELL_CAST_OK)
unit = selectedUnit;
}
@@ -1777,9 +1777,9 @@ void Spell::SelectEffectTypeImplicitTargets(uint8 effIndex)
{
case SPELL_EFFECT_SUMMON_RAF_FRIEND:
case SPELL_EFFECT_SUMMON_PLAYER:
if (m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->ToPlayer()->GetSelection())
if (m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->GetTarget())
{
WorldObject* target = ObjectAccessor::FindPlayer(m_caster->ToPlayer()->GetSelection());
WorldObject* target = ObjectAccessor::FindPlayer(m_caster->GetTarget());
CallScriptObjectTargetSelectHandlers(target, SpellEffIndex(effIndex));
@@ -3095,7 +3095,7 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggered
// set target for proper facing
if ((m_casttime || m_spellInfo->IsChanneled()) && !(_triggeredCastFlags & TRIGGERED_IGNORE_SET_FACING))
if (m_caster->GetTypeId() == TYPEID_UNIT && m_targets.GetObjectTarget() && m_caster != m_targets.GetObjectTarget())
m_caster->FocusTarget(this, m_targets.GetObjectTarget());
m_caster->ToCreature()->FocusTarget(this, m_targets.GetObjectTarget());
if (!(_triggeredCastFlags & TRIGGERED_IGNORE_GCD))
TriggerGlobalCooldown();
@@ -3661,8 +3661,8 @@ void Spell::finish(bool ok)
((Puppet*)charm)->UnSummon();
}
if (m_caster->GetTypeId() == TYPEID_UNIT)
m_caster->ReleaseFocus(this);
if (Creature* creatureCaster = m_caster->ToCreature())
creatureCaster->ReleaseFocus(this);
if (!ok)
return;
@@ -5323,10 +5323,10 @@ SpellCastResult Spell::CheckCast(bool strict)
{
if (m_caster->GetTypeId() != TYPEID_PLAYER)
return SPELL_FAILED_BAD_TARGETS;
if (!m_caster->ToPlayer()->GetSelection())
if (!m_caster->GetTarget())
return SPELL_FAILED_BAD_TARGETS;
Player* target = ObjectAccessor::FindPlayer(m_caster->ToPlayer()->GetSelection());
Player* target = m_caster->ToPlayer()->GetSelectedPlayer();
if (!target || m_caster->ToPlayer() == target || (!target->IsInSameRaidWith(m_caster->ToPlayer()) && m_spellInfo->Id != 48955)) // refer-a-friend spell
return SPELL_FAILED_BAD_TARGETS;
@@ -5358,10 +5358,10 @@ SpellCastResult Spell::CheckCast(bool strict)
Player* playerCaster = m_caster->ToPlayer();
//
if (!(playerCaster->GetSelection()))
if (!(playerCaster->GetTarget()))
return SPELL_FAILED_BAD_TARGETS;
Player* target = ObjectAccessor::FindPlayer(playerCaster->GetSelection());
Player* target = playerCaster->GetSelectedPlayer();
if (!target ||
!(target->GetSession()->GetRecruiterId() == playerCaster->GetSession()->GetAccountId() || target->GetSession()->GetAccountId() == playerCaster->GetSession()->GetRecruiterId()))
+6 -6
View File
@@ -450,12 +450,12 @@ public:
uint32 pwConfig = sWorld->getIntConfig(CONFIG_ACC_PASSCHANGESEC); // 0 - PW_NONE, 1 - PW_EMAIL, 2 - PW_RBAC
// Command is supposed to be: .account password [$oldpassword] [$newpassword] [$newpasswordconfirmation] [$emailconfirmation]
char* oldPassword = strtok((char*)args, " "); // This extracts [$oldpassword]
char* newPassword = strtok(NULL, " "); // This extracts [$newpassword]
char* passwordConfirmation = strtok(NULL, " "); // This extracts [$newpasswordconfirmation]
const char* emailConfirmation; // This defines the emailConfirmation variable, which is optional depending on sec type.
if (!(emailConfirmation = strtok(NULL, " "))) // This extracts [$emailconfirmation]. If it doesn't exist, however...
emailConfirmation = ""; // ... it's simply "" for emailConfirmation.
char* oldPassword = strtok((char*)args, " "); // This extracts [$oldpassword]
char* newPassword = strtok(NULL, " "); // This extracts [$newpassword]
char* passwordConfirmation = strtok(NULL, " "); // This extracts [$newpasswordconfirmation]
char const* emailConfirmation = strtok(NULL, " "); // This defines the emailConfirmation variable, which is optional depending on sec type.
if (!emailConfirmation) // This extracts [$emailconfirmation]. If it doesn't exist, however...
emailConfirmation = ""; // ... it's simply "" for emailConfirmation.
//Is any of those variables missing for any reason ? We return false.
if (!oldPassword || !newPassword || !passwordConfirmation)
+1 -1
View File
@@ -179,7 +179,7 @@ public:
return false;
}
if (handler->GetSession()->GetPlayer()->GetSelection())
if (handler->GetSession()->GetPlayer()->GetTarget())
unit->PlayDistanceSound(soundId, handler->GetSession()->GetPlayer());
else
unit->PlayDirectSound(soundId, handler->GetSession()->GetPlayer());
+4 -4
View File
@@ -529,7 +529,7 @@ public:
{
Unit* target = handler->getSelectedUnit();
if (!target || !handler->GetSession()->GetPlayer()->GetSelection())
if (!target || !handler->GetSession()->GetPlayer()->GetTarget())
{
handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
handler->SetSentErrorMessage(true);
@@ -597,7 +597,7 @@ public:
static bool HandleGUIDCommand(ChatHandler* handler, char const* /*args*/)
{
uint64 guid = handler->GetSession()->GetPlayer()->GetSelection();
uint64 guid = handler->GetSession()->GetPlayer()->GetTarget();
if (guid == 0)
{
@@ -1762,7 +1762,7 @@ public:
// accept only explicitly selected target (not implicitly self targeting case)
Unit* target = handler->getSelectedUnit();
if (player->GetSelection() && target)
if (player->GetTarget() && target)
{
if (target->GetTypeId() != TYPEID_UNIT || target->IsPet())
{
@@ -2107,7 +2107,7 @@ public:
}
Unit* target = handler->getSelectedUnit();
if (!target || !handler->GetSession()->GetPlayer()->GetSelection())
if (!target || !handler->GetSession()->GetPlayer()->GetTarget())
{
handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
handler->SetSentErrorMessage(true);
+2 -7
View File
@@ -1297,22 +1297,17 @@ public:
char* receiver_str = strtok((char*)args, " ");
char* text = strtok(NULL, "");
uint64 guid = handler->GetSession()->GetPlayer()->GetSelection();
Creature* creature = handler->GetSession()->GetPlayer()->GetMap()->GetCreature(guid);
Creature* creature = handler->getSelectedCreature();
if (!creature || !receiver_str || !text)
{
return false;
}
uint64 receiver_guid= atol(receiver_str);
uint64 receiver_guid = atol(receiver_str);
// check online security
if (handler->HasLowerSecurity(ObjectAccessor::FindPlayer(receiver_guid), 0))
return false;
creature->MonsterWhisper(text, receiver_guid);
return true;
}