fix(Core/Spells): Far Sight auras are supposed to extend view distance and allows seeing objects from further distance (#7068)
- Closes #5793.
This commit is contained in:
@@ -1670,6 +1670,11 @@ bool WorldObject::CanSeeOrDetect(WorldObject const* obj, bool ignoreStealth, boo
|
|||||||
|
|
||||||
if (thisPlayer->GetViewpoint())
|
if (thisPlayer->GetViewpoint())
|
||||||
viewpoint = thisPlayer->GetViewpoint();
|
viewpoint = thisPlayer->GetViewpoint();
|
||||||
|
|
||||||
|
if (thisPlayer->GetFarSightDistance() && !thisPlayer->isInFront(obj))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Xinef: check reversely obj vs viewpoint, object could be a gameObject which overrides _IsWithinDist function to include gameobject size
|
// Xinef: check reversely obj vs viewpoint, object could be a gameObject which overrides _IsWithinDist function to include gameobject size
|
||||||
|
|||||||
@@ -919,7 +919,7 @@ public:
|
|||||||
|
|
||||||
[[nodiscard]] float GetGridActivationRange() const;
|
[[nodiscard]] float GetGridActivationRange() const;
|
||||||
[[nodiscard]] float GetVisibilityRange() const;
|
[[nodiscard]] float GetVisibilityRange() const;
|
||||||
float GetSightRange(const WorldObject* target = nullptr) const;
|
virtual float GetSightRange(const WorldObject* target = nullptr) const;
|
||||||
//bool CanSeeOrDetect(WorldObject const* obj, bool ignoreStealth = false, bool distanceCheck = false) const;
|
//bool CanSeeOrDetect(WorldObject const* obj, bool ignoreStealth = false, bool distanceCheck = false) const;
|
||||||
bool CanSeeOrDetect(WorldObject const* obj, bool ignoreStealth = false, bool distanceCheck = false, bool checkAlert = false) const;
|
bool CanSeeOrDetect(WorldObject const* obj, bool ignoreStealth = false, bool distanceCheck = false, bool checkAlert = false) const;
|
||||||
|
|
||||||
|
|||||||
@@ -15154,3 +15154,29 @@ void Player::SetServerSideVisibilityDetect(ServerSideVisibilityType type, Accoun
|
|||||||
|
|
||||||
m_serverSideVisibilityDetect.SetValue(type, sec);
|
m_serverSideVisibilityDetect.SetValue(type, sec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Player::SetFarSightDistance(float radius)
|
||||||
|
{
|
||||||
|
_farSightDistance = radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::ResetFarSightDistance()
|
||||||
|
{
|
||||||
|
_farSightDistance.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
Optional<float> Player::GetFarSightDistance() const
|
||||||
|
{
|
||||||
|
return _farSightDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Player::GetSightRange(const WorldObject* target) const
|
||||||
|
{
|
||||||
|
float sightRange = WorldObject::GetSightRange(target);
|
||||||
|
if (_farSightDistance)
|
||||||
|
{
|
||||||
|
sightRange += *_farSightDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sightRange;
|
||||||
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#include "KillRewarder.h"
|
#include "KillRewarder.h"
|
||||||
#include "MapReference.h"
|
#include "MapReference.h"
|
||||||
#include "ObjectMgr.h"
|
#include "ObjectMgr.h"
|
||||||
|
#include "Optional.h"
|
||||||
#include "PetDefines.h"
|
#include "PetDefines.h"
|
||||||
#include "PlayerTaxi.h"
|
#include "PlayerTaxi.h"
|
||||||
#include "QuestDef.h"
|
#include "QuestDef.h"
|
||||||
@@ -2521,7 +2522,13 @@ public:
|
|||||||
std::string GetMapAreaAndZoneString();
|
std::string GetMapAreaAndZoneString();
|
||||||
std::string GetCoordsMapAreaAndZoneString();
|
std::string GetCoordsMapAreaAndZoneString();
|
||||||
|
|
||||||
protected:
|
void SetFarSightDistance(float radius);
|
||||||
|
void ResetFarSightDistance();
|
||||||
|
Optional<float> GetFarSightDistance() const;
|
||||||
|
|
||||||
|
float GetSightRange(const WorldObject* target = nullptr) const override;
|
||||||
|
|
||||||
|
protected:
|
||||||
// Gamemaster whisper whitelist
|
// Gamemaster whisper whitelist
|
||||||
WhisperListContainer WhisperList;
|
WhisperListContainer WhisperList;
|
||||||
|
|
||||||
@@ -2874,6 +2881,8 @@ private:
|
|||||||
Creature* m_CinematicObject;
|
Creature* m_CinematicObject;
|
||||||
|
|
||||||
WorldLocation _corpseLocation;
|
WorldLocation _corpseLocation;
|
||||||
|
|
||||||
|
Optional<float> _farSightDistance = { };
|
||||||
};
|
};
|
||||||
|
|
||||||
void AddItemsSetItem(Player* player, Item* item);
|
void AddItemsSetItem(Player* player, Item* item);
|
||||||
|
|||||||
@@ -19173,8 +19173,13 @@ bool Unit::UpdatePosition(float x, float y, float z, float orientation, bool tel
|
|||||||
GetMap()->CreatureRelocation(ToCreature(), x, y, z, orientation);
|
GetMap()->CreatureRelocation(ToCreature(), x, y, z, orientation);
|
||||||
}
|
}
|
||||||
else if (turn)
|
else if (turn)
|
||||||
|
{
|
||||||
UpdateOrientation(orientation);
|
UpdateOrientation(orientation);
|
||||||
|
|
||||||
|
if (GetTypeId() == TYPEID_PLAYER && ToPlayer()->GetFarSightDistance())
|
||||||
|
UpdateObjectVisibility(false);
|
||||||
|
}
|
||||||
|
|
||||||
return (relocated || turn);
|
return (relocated || turn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -19687,24 +19692,31 @@ void Unit::ExecuteDelayedUnitRelocationEvent()
|
|||||||
if (active->IsVehicle())
|
if (active->IsVehicle())
|
||||||
active = player;
|
active = player;
|
||||||
|
|
||||||
float dx = active->m_last_notify_position.GetPositionX() - active->GetPositionX();
|
if (!player->GetFarSightDistance())
|
||||||
float dy = active->m_last_notify_position.GetPositionY() - active->GetPositionY();
|
{
|
||||||
float dz = active->m_last_notify_position.GetPositionZ() - active->GetPositionZ();
|
float dx = active->m_last_notify_position.GetPositionX() - active->GetPositionX();
|
||||||
float distsq = dx * dx + dy * dy + dz * dz;
|
float dy = active->m_last_notify_position.GetPositionY() - active->GetPositionY();
|
||||||
|
float dz = active->m_last_notify_position.GetPositionZ() - active->GetPositionZ();
|
||||||
|
float distsq = dx * dx + dy * dy + dz * dz;
|
||||||
|
|
||||||
float mindistsq = DynamicVisibilityMgr::GetReqMoveDistSq(active->FindMap()->GetEntry()->map_type);
|
float mindistsq = DynamicVisibilityMgr::GetReqMoveDistSq(active->FindMap()->GetEntry()->map_type);
|
||||||
if (distsq < mindistsq)
|
if (distsq < mindistsq)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
active->m_last_notify_position.Relocate(active->GetPositionX(), active->GetPositionY(), active->GetPositionZ());
|
active->m_last_notify_position.Relocate(active->GetPositionX(), active->GetPositionY(), active->GetPositionZ());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Acore::PlayerRelocationNotifier relocateNoLarge(*player, false); // visit only objects which are not large; default distance
|
Acore::PlayerRelocationNotifier relocateNoLarge(*player, false); // visit only objects which are not large; default distance
|
||||||
Cell::VisitAllObjects(viewPoint, relocateNoLarge, player->GetSightRange() + VISIBILITY_INC_FOR_GOBJECTS);
|
Cell::VisitAllObjects(viewPoint, relocateNoLarge, player->GetSightRange() + VISIBILITY_INC_FOR_GOBJECTS);
|
||||||
relocateNoLarge.SendToSelf();
|
relocateNoLarge.SendToSelf();
|
||||||
Acore::PlayerRelocationNotifier relocateLarge(*player, true); // visit only large objects; maximum distance
|
|
||||||
Cell::VisitAllObjects(viewPoint, relocateLarge, MAX_VISIBILITY_DISTANCE);
|
if (!player->GetFarSightDistance())
|
||||||
relocateLarge.SendToSelf();
|
{
|
||||||
|
Acore::PlayerRelocationNotifier relocateLarge(*player, true); // visit only large objects; maximum distance
|
||||||
|
Cell::VisitAllObjects(viewPoint, relocateLarge, MAX_VISIBILITY_DISTANCE);
|
||||||
|
relocateLarge.SendToSelf();
|
||||||
|
}
|
||||||
|
|
||||||
this->AddToNotify(NOTIFY_AI_RELOCATION);
|
this->AddToNotify(NOTIFY_AI_RELOCATION);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,10 +19,12 @@ void VisibleNotifier::Visit(GameObjectMapType& m)
|
|||||||
{
|
{
|
||||||
for (GameObjectMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
|
for (GameObjectMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
|
||||||
{
|
{
|
||||||
if (i_largeOnly != iter->GetSource()->IsVisibilityOverridden())
|
GameObject* go = iter->GetSource();
|
||||||
|
if (i_largeOnly != go->IsVisibilityOverridden())
|
||||||
continue;
|
continue;
|
||||||
vis_guids.erase(iter->GetSource()->GetGUID());
|
|
||||||
i_player.UpdateVisibilityOf(iter->GetSource(), i_data, i_visibleNow);
|
vis_guids.erase(go->GetGUID());
|
||||||
|
i_player.UpdateVisibilityOf(go, i_data, i_visibleNow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,8 +63,10 @@ void VisibleNotifier::SendToSelf()
|
|||||||
for (GuidUnorderedSet::const_iterator it = vis_guids.begin(); it != vis_guids.end(); ++it)
|
for (GuidUnorderedSet::const_iterator it = vis_guids.begin(); it != vis_guids.end(); ++it)
|
||||||
{
|
{
|
||||||
if (WorldObject* obj = ObjectAccessor::GetWorldObject(i_player, *it))
|
if (WorldObject* obj = ObjectAccessor::GetWorldObject(i_player, *it))
|
||||||
|
{
|
||||||
if (i_largeOnly != obj->IsVisibilityOverridden())
|
if (i_largeOnly != obj->IsVisibilityOverridden())
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// pussywizard: static transports are removed only in RemovePlayerFromMap and here if can no longer detect (eg. phase changed)
|
// pussywizard: static transports are removed only in RemovePlayerFromMap and here if can no longer detect (eg. phase changed)
|
||||||
if ((*it).IsTransport())
|
if ((*it).IsTransport())
|
||||||
@@ -92,6 +96,7 @@ void VisibleNotifier::SendToSelf()
|
|||||||
{
|
{
|
||||||
if (i_largeOnly != (*it)->IsVisibilityOverridden())
|
if (i_largeOnly != (*it)->IsVisibilityOverridden())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
i_player.GetInitialVisiblePackets(*it);
|
i_player.GetInitialVisiblePackets(*it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include "GameObject.h"
|
#include "GameObject.h"
|
||||||
#include "Object.h"
|
#include "Object.h"
|
||||||
#include "ObjectGridLoader.h"
|
#include "ObjectGridLoader.h"
|
||||||
|
#include "Optional.h"
|
||||||
#include "Player.h"
|
#include "Player.h"
|
||||||
#include "Spell.h"
|
#include "Spell.h"
|
||||||
#include "Unit.h"
|
#include "Unit.h"
|
||||||
@@ -34,7 +35,8 @@ namespace Acore
|
|||||||
bool i_largeOnly;
|
bool i_largeOnly;
|
||||||
UpdateData i_data;
|
UpdateData i_data;
|
||||||
|
|
||||||
VisibleNotifier(Player& player, bool gobjOnly, bool largeOnly) : i_player(player), vis_guids(player.m_clientGUIDs), i_visibleNow(player.m_newVisible), i_gobjOnly(gobjOnly), i_largeOnly(largeOnly)
|
VisibleNotifier(Player& player, bool gobjOnly, bool largeOnly) :
|
||||||
|
i_player(player), vis_guids(player.m_clientGUIDs), i_visibleNow(player.m_newVisible), i_gobjOnly(gobjOnly), i_largeOnly(largeOnly)
|
||||||
{
|
{
|
||||||
i_visibleNow.clear();
|
i_visibleNow.clear();
|
||||||
}
|
}
|
||||||
@@ -57,7 +59,7 @@ namespace Acore
|
|||||||
|
|
||||||
struct PlayerRelocationNotifier : public VisibleNotifier
|
struct PlayerRelocationNotifier : public VisibleNotifier
|
||||||
{
|
{
|
||||||
PlayerRelocationNotifier(Player& player, bool largeOnly) : VisibleNotifier(player, false, largeOnly) {}
|
PlayerRelocationNotifier(Player& player, bool largeOnly): VisibleNotifier(player, false, largeOnly) { }
|
||||||
|
|
||||||
template<class T> void Visit(GridRefManager<T>& m) { VisibleNotifier::Visit(m); }
|
template<class T> void Visit(GridRefManager<T>& m) { VisibleNotifier::Visit(m); }
|
||||||
void Visit(PlayerMapType&);
|
void Visit(PlayerMapType&);
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ inline void Acore::VisibleNotifier::Visit(GridRefManager<T>& m)
|
|||||||
{
|
{
|
||||||
if (i_largeOnly != iter->GetSource()->IsVisibilityOverridden())
|
if (i_largeOnly != iter->GetSource()->IsVisibilityOverridden())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
vis_guids.erase(iter->GetSource()->GetGUID());
|
vis_guids.erase(iter->GetSource()->GetGUID());
|
||||||
i_player.UpdateVisibilityOf(iter->GetSource(), i_data, i_visibleNow);
|
i_player.UpdateVisibilityOf(iter->GetSource(), i_data, i_visibleNow);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ pAuraEffectHandler AuraEffectHandler[TOTAL_AURAS] =
|
|||||||
&AuraEffect::HandleModPowerCost, // 73 SPELL_AURA_MOD_POWER_COST_SCHOOL
|
&AuraEffect::HandleModPowerCost, // 73 SPELL_AURA_MOD_POWER_COST_SCHOOL
|
||||||
&AuraEffect::HandleNoImmediateEffect, // 74 SPELL_AURA_REFLECT_SPELLS_SCHOOL implemented in Unit::SpellHitResult
|
&AuraEffect::HandleNoImmediateEffect, // 74 SPELL_AURA_REFLECT_SPELLS_SCHOOL implemented in Unit::SpellHitResult
|
||||||
&AuraEffect::HandleNoImmediateEffect, // 75 SPELL_AURA_MOD_LANGUAGE
|
&AuraEffect::HandleNoImmediateEffect, // 75 SPELL_AURA_MOD_LANGUAGE
|
||||||
&AuraEffect::HandleNoImmediateEffect, // 76 SPELL_AURA_FAR_SIGHT
|
&AuraEffect::HandleFarSight, // 76 SPELL_AURA_FAR_SIGHT
|
||||||
&AuraEffect::HandleModMechanicImmunity, // 77 SPELL_AURA_MECHANIC_IMMUNITY
|
&AuraEffect::HandleModMechanicImmunity, // 77 SPELL_AURA_MECHANIC_IMMUNITY
|
||||||
&AuraEffect::HandleAuraMounted, // 78 SPELL_AURA_MOUNTED
|
&AuraEffect::HandleAuraMounted, // 78 SPELL_AURA_MOUNTED
|
||||||
&AuraEffect::HandleModDamagePercentDone, // 79 SPELL_AURA_MOD_DAMAGE_PERCENT_DONE
|
&AuraEffect::HandleModDamagePercentDone, // 79 SPELL_AURA_MOD_DAMAGE_PERCENT_DONE
|
||||||
@@ -5476,6 +5476,32 @@ void AuraEffect::HandleBindSight(AuraApplication const* aurApp, uint8 mode, bool
|
|||||||
caster->ToPlayer()->SetViewpoint(target, apply);
|
caster->ToPlayer()->SetViewpoint(target, apply);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AuraEffect::HandleFarSight(AuraApplication const* /*aurApp*/, uint8 mode, bool apply) const
|
||||||
|
{
|
||||||
|
if (!(mode & AURA_EFFECT_HANDLE_REAL))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Unit* caster = GetCaster();
|
||||||
|
if (!caster || caster->GetTypeId() != TYPEID_PLAYER)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Player* player = caster->ToPlayer();
|
||||||
|
if (apply)
|
||||||
|
{
|
||||||
|
player->SetFarSightDistance(m_spellInfo->GetMaxRange());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
player->ResetFarSightDistance();
|
||||||
|
}
|
||||||
|
|
||||||
|
caster->UpdateObjectVisibility(!apply);
|
||||||
|
}
|
||||||
|
|
||||||
void AuraEffect::HandleForceReaction(AuraApplication const* aurApp, uint8 mode, bool apply) const
|
void AuraEffect::HandleForceReaction(AuraApplication const* aurApp, uint8 mode, bool apply) const
|
||||||
{
|
{
|
||||||
if (!(mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK))
|
if (!(mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK))
|
||||||
|
|||||||
@@ -287,6 +287,7 @@ public:
|
|||||||
void HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool apply) const;
|
void HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool apply) const;
|
||||||
void HandleChannelDeathItem(AuraApplication const* aurApp, uint8 mode, bool apply) const;
|
void HandleChannelDeathItem(AuraApplication const* aurApp, uint8 mode, bool apply) const;
|
||||||
void HandleBindSight(AuraApplication const* aurApp, uint8 mode, bool apply) const;
|
void HandleBindSight(AuraApplication const* aurApp, uint8 mode, bool apply) const;
|
||||||
|
void HandleFarSight(AuraApplication const* aurApp, uint8 mode, bool apply) const;
|
||||||
void HandleForceReaction(AuraApplication const* aurApp, uint8 mode, bool apply) const;
|
void HandleForceReaction(AuraApplication const* aurApp, uint8 mode, bool apply) const;
|
||||||
void HandleAuraEmpathy(AuraApplication const* aurApp, uint8 mode, bool apply) const;
|
void HandleAuraEmpathy(AuraApplication const* aurApp, uint8 mode, bool apply) const;
|
||||||
void HandleAuraModFaction(AuraApplication const* aurApp, uint8 mode, bool apply) const;
|
void HandleAuraModFaction(AuraApplication const* aurApp, uint8 mode, bool apply) const;
|
||||||
|
|||||||
Reference in New Issue
Block a user