Merge branch 'master' into Playerbot

This commit is contained in:
Yunfan Li
2025-08-09 15:02:41 +08:00
92 changed files with 1095 additions and 752 deletions
+1 -1
View File
@@ -104,7 +104,7 @@ void TotemAI::UpdateAI(uint32 /*diff*/)
victim = nullptr;
Acore::NearestAttackableUnitInObjectRangeCheck u_check(me, me, max_range);
Acore::UnitLastSearcher<Acore::NearestAttackableUnitInObjectRangeCheck> checker(me, victim, u_check);
Cell::VisitAllObjects(me, checker, max_range);
Cell::VisitObjects(me, checker, max_range);
}
if (!victim && me->GetCharmerOrOwnerOrSelf()->IsInCombat())
@@ -491,7 +491,7 @@ Unit* ScriptedAI::DoSelectLowestHpFriendly(float range, uint32 minHPDiff)
Unit* unit = nullptr;
Acore::MostHPMissingInRange u_check(me, range, minHPDiff);
Acore::UnitLastSearcher<Acore::MostHPMissingInRange> searcher(me, unit, u_check);
Cell::VisitAllObjects(me, searcher, range);
Cell::VisitObjects(me, searcher, range);
return unit;
}
@@ -501,7 +501,7 @@ std::list<Creature*> ScriptedAI::DoFindFriendlyCC(float range)
std::list<Creature*> list;
Acore::FriendlyCCedInRange u_check(me, range);
Acore::CreatureListSearcher<Acore::FriendlyCCedInRange> searcher(me, list, u_check);
Cell::VisitAllObjects(me, searcher, range);
Cell::VisitObjects(me, searcher, range);
return list;
}
@@ -510,7 +510,7 @@ std::list<Creature*> ScriptedAI::DoFindFriendlyMissingBuff(float range, uint32 u
std::list<Creature*> list;
Acore::FriendlyMissingBuffInRange u_check(me, range, uiSpellid);
Acore::CreatureListSearcher<Acore::FriendlyMissingBuffInRange> searcher(me, list, u_check);
Cell::VisitAllObjects(me, searcher, range);
Cell::VisitObjects(me, searcher, range);
return list;
}
@@ -521,7 +521,7 @@ Player* ScriptedAI::GetPlayerAtMinimumRange(float minimumRange)
Acore::PlayerAtMinimumRangeAway check(me, minimumRange);
Acore::PlayerSearcher<Acore::PlayerAtMinimumRangeAway> searcher(me, player, check);
Cell::VisitWorldObjects(me, searcher, minimumRange);
Cell::VisitObjects(me, searcher, minimumRange);
return player;
}
@@ -4030,7 +4030,7 @@ void SmartScript::GetWorldObjectsInDist(ObjectVector& targets, float dist) const
Acore::AllWorldObjectsInRange u_check(obj, dist);
Acore::WorldObjectListSearcher<Acore::AllWorldObjectsInRange> searcher(obj, targets, u_check);
Cell::VisitAllObjects(obj, searcher, dist);
Cell::VisitObjects(obj, searcher, dist);
}
void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, uint32 var1, bool bvar, SpellInfo const* spell, GameObject* gob)
@@ -5252,7 +5252,7 @@ Unit* SmartScript::DoSelectLowestHpFriendly(float range, uint32 MinHPDiff) const
Acore::MostHPMissingInRange u_check(me, range, MinHPDiff);
Acore::UnitLastSearcher<Acore::MostHPMissingInRange> searcher(me, unit, u_check);
Cell::VisitGridObjects(me, searcher, range);
Cell::VisitObjects(me, searcher, range);
return unit;
}
@@ -5266,7 +5266,7 @@ Unit* SmartScript::DoSelectLowestHpPercentFriendly(float range, uint32 minHpPct,
Unit* unit = nullptr;
Acore::MostHPPercentMissingInRange u_check(me, range, minHpPct, maxHpPct);
Acore::UnitLastSearcher<Acore::MostHPPercentMissingInRange> searcher(me, unit, u_check);
Cell::VisitGridObjects(me, searcher, range);
Cell::VisitObjects(me, searcher, range);
return unit;
}
@@ -5277,7 +5277,7 @@ void SmartScript::DoFindFriendlyCC(std::vector<Creature*>& creatures, float rang
Acore::FriendlyCCedInRange u_check(me, range);
Acore::CreatureListSearcher<Acore::FriendlyCCedInRange> searcher(me, creatures, u_check);
Cell::VisitGridObjects(me, searcher, range);
Cell::VisitObjects(me, searcher, range);
}
void SmartScript::DoFindFriendlyMissingBuff(std::vector<Creature*>& creatures, float range, uint32 spellid) const
@@ -5287,7 +5287,7 @@ void SmartScript::DoFindFriendlyMissingBuff(std::vector<Creature*>& creatures, f
Acore::FriendlyMissingBuffInRange u_check(me, range, spellid);
Acore::CreatureListSearcher<Acore::FriendlyMissingBuffInRange> searcher(me, creatures, u_check);
Cell::VisitGridObjects(me, searcher, range);
Cell::VisitObjects(me, searcher, range);
}
Unit* SmartScript::DoFindClosestFriendlyInRange(float range, bool playerOnly) const
@@ -5298,7 +5298,7 @@ Unit* SmartScript::DoFindClosestFriendlyInRange(float range, bool playerOnly) co
Unit* unit = nullptr;
Acore::AnyFriendlyNotSelfUnitInObjectRangeCheck u_check(me, me, range, playerOnly);
Acore::UnitLastSearcher<Acore::AnyFriendlyNotSelfUnitInObjectRangeCheck> searcher(me, unit, u_check);
Cell::VisitAllObjects(me, searcher, range);
Cell::VisitObjects(me, searcher, range);
return unit;
}
@@ -754,8 +754,7 @@ void AchievementMgr::SendAchievementEarned(AchievementEntry const* achievement)
Acore::BroadcastTextBuilder _builder(GetPlayer(), CHAT_MSG_ACHIEVEMENT, BROADCAST_TEXT_ACHIEVEMENT_EARNED, GetPlayer()->getGender(), GetPlayer(), achievement->ID);
Acore::LocalizedPacketDo<Acore::BroadcastTextBuilder> _localizer(_builder);
Acore::PlayerDistWorker<Acore::LocalizedPacketDo<Acore::BroadcastTextBuilder>> _worker(GetPlayer(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), _localizer);
TypeContainerVisitor<Acore::PlayerDistWorker<Acore::LocalizedPacketDo<Acore::BroadcastTextBuilder> >, WorldTypeMapContainer > message(_worker);
Cell::VisitWorldObjects(GetPlayer(), _worker, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY));
Cell::VisitObjects(GetPlayer(), _worker, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY));
}
WorldPacket data(SMSG_ACHIEVEMENT_EARNED, 8 + 4 + 8);
+2 -2
View File
@@ -805,7 +805,7 @@ Creature* Battlefield::SpawnCreature(uint32 entry, float x, float y, float z, fl
return nullptr;
}
Creature* creature = new Creature(true);
Creature* creature = new Creature();
if (!creature->Create(map->GenerateLowGuid<HighGuid::Unit>(), map, PHASEMASK_NORMAL, entry, 0, x, y, z, o))
{
LOG_ERROR("bg.battlefield", "Battlefield::SpawnCreature: Can't create creature entry: {}", entry);
@@ -1019,7 +1019,7 @@ bool BfCapturePoint::Update(uint32 diff)
std::list<Player*> players;
Acore::AnyPlayerInObjectRangeCheck checker(capturePoint, radius);
Acore::PlayerListSearcher<Acore::AnyPlayerInObjectRangeCheck> searcher(capturePoint, players, checker);
Cell::VisitWorldObjects(capturePoint, searcher, radius);
Cell::VisitObjects(capturePoint, searcher, radius);
for (std::list<Player*>::iterator itr = players.begin(); itr != players.end(); ++itr)
if ((*itr)->IsOutdoorPvPActive())
+1 -1
View File
@@ -643,7 +643,7 @@ GameObject* ChatHandler::GetNearbyGameObject() const
GameObject* obj = nullptr;
Acore::NearestGameObjectCheck check(*pl);
Acore::GameObjectLastSearcher<Acore::NearestGameObjectCheck> searcher(pl, obj, check);
Cell::VisitGridObjects(pl, searcher, SIZE_OF_GRIDS);
Cell::VisitObjects(pl, searcher, SIZE_OF_GRIDS);
return obj;
}
+1 -1
View File
@@ -26,7 +26,7 @@
#include "UpdateMask.h"
#include "World.h"
Corpse::Corpse(CorpseType type) : WorldObject(type != CORPSE_BONES), m_type(type)
Corpse::Corpse(CorpseType type) : WorldObject(), m_type(type)
{
m_objectType |= TYPEMASK_CORPSE;
m_objectTypeId = TYPEID_CORPSE;
@@ -269,7 +269,7 @@ bool TemporaryThreatModifierEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
return true;
}
Creature::Creature(bool isWorldObject): Unit(isWorldObject), MovableMapObject(), m_groupLootTimer(0), lootingGroupLowGUID(0), m_lootRecipientGroup(0),
Creature::Creature(): Unit(), MovableMapObject(), m_groupLootTimer(0), lootingGroupLowGUID(0), m_lootRecipientGroup(0),
m_corpseRemoveTime(0), m_respawnTime(0), m_respawnDelay(300), m_corpseDelay(60), m_wanderDistance(0.0f), m_boundaryCheckTime(2500),
m_transportCheckTimer(1000), lootPickPocketRestoreTime(0), m_combatPulseTime(0), m_combatPulseDelay(0), m_reactState(REACT_AGGRESSIVE), m_defaultMovementType(IDLE_MOTION_TYPE),
m_spawnId(0), m_equipmentId(0), m_originalEquipmentId(0), m_AlreadyCallAssistance(false),
@@ -371,7 +371,7 @@ void Creature::RemoveFromWorld()
void Creature::DisappearAndDie()
{
DestroyForNearbyPlayers();
DestroyForVisiblePlayers();
//SetVisibility(VISIBILITY_OFF);
//ObjectAccessor::UpdateObjectVisibility(this);
if (IsAlive())
@@ -408,7 +408,7 @@ void Creature::RemoveCorpse(bool setSpawnTime, bool skipVisibility)
setDeathState(DeathState::Dead);
RemoveAllAuras();
if (!skipVisibility) // pussywizard
DestroyForNearbyPlayers(); // pussywizard: previous UpdateObjectVisibility()
DestroyForVisiblePlayers(); // pussywizard: previous UpdateObjectVisibility()
loot.clear();
uint32 respawnDelay = m_respawnDelay;
if (IsAIEnabled)
@@ -1079,7 +1079,7 @@ void Creature::DoFleeToGetAssistance()
Acore::NearestAssistCreatureInCreatureRangeCheck u_check(this, GetVictim(), radius);
Acore::CreatureLastSearcher<Acore::NearestAssistCreatureInCreatureRangeCheck> searcher(this, creature, u_check);
Cell::VisitGridObjects(this, searcher, radius);
Cell::VisitObjects(this, searcher, radius);
SetNoSearchAssistance(true);
UpdateSpeed(MOVE_RUN, false);
@@ -2401,7 +2401,7 @@ Unit* Creature::SelectNearestTarget(float dist, bool playerOnly /* = false */) c
Acore::NearestHostileUnitCheck u_check(this, dist, playerOnly);
Acore::UnitLastSearcher<Acore::NearestHostileUnitCheck> searcher(this, target, u_check);
Cell::VisitAllObjects(this, searcher, dist);
Cell::VisitObjects(this, searcher, dist);
return target;
}
@@ -2418,7 +2418,7 @@ Unit* Creature::SelectNearestTargetInAttackDistance(float dist) const
Unit* target = nullptr;
Acore::NearestHostileUnitInAttackDistanceCheck u_check(this, dist);
Acore::UnitLastSearcher<Acore::NearestHostileUnitInAttackDistanceCheck> searcher(this, target, u_check);
Cell::VisitAllObjects(this, searcher, std::max(dist, ATTACK_DISTANCE));
Cell::VisitObjects(this, searcher, std::max(dist, ATTACK_DISTANCE));
return target;
}
@@ -2454,7 +2454,7 @@ void Creature::CallAssistance(Unit* target /*= nullptr*/)
Acore::AnyAssistCreatureInRangeCheck u_check(this, target, radius);
Acore::CreatureListSearcher<Acore::AnyAssistCreatureInRangeCheck> searcher(this, assistList, u_check);
Cell::VisitGridObjects(this, searcher, radius);
Cell::VisitObjects(this, searcher, radius);
if (!assistList.empty())
{
@@ -2490,7 +2490,7 @@ void Creature::CallForHelp(float radius, Unit* target /*= nullptr*/)
Acore::CallOfHelpCreatureInRangeDo u_do(this, target, radius);
Acore::CreatureWorker<Acore::CallOfHelpCreatureInRangeDo> worker(this, u_do);
Cell::VisitGridObjects(this, worker, radius);
Cell::VisitObjects(this, worker, radius);
}
bool Creature::CanAssistTo(Unit const* u, Unit const* enemy, bool checkfaction /*= true*/) const
+1 -1
View File
@@ -42,7 +42,7 @@ class CreatureGroup;
class Creature : public Unit, public GridObject<Creature>, public MovableMapObject, public UpdatableMapObject
{
public:
explicit Creature(bool isWorldObject = false);
explicit Creature();
~Creature() override;
void AddToWorld() override;
@@ -24,8 +24,8 @@
#include "Player.h"
#include "ScriptMgr.h"
TempSummon::TempSummon(SummonPropertiesEntry const* properties, ObjectGuid owner, bool isWorldObject) :
Creature(isWorldObject), m_Properties(properties), m_type(TEMPSUMMON_MANUAL_DESPAWN),
TempSummon::TempSummon(SummonPropertiesEntry const* properties, ObjectGuid owner) :
Creature(), m_Properties(properties), m_type(TEMPSUMMON_MANUAL_DESPAWN),
m_timer(0), m_lifetime(0), _visibleBySummonerOnly(false)
{
if (owner)
@@ -350,7 +350,7 @@ std::string TempSummon::GetDebugInfo() const
return sstr.str();
}
Minion::Minion(SummonPropertiesEntry const* properties, ObjectGuid owner, bool isWorldObject) : TempSummon(properties, owner, isWorldObject)
Minion::Minion(SummonPropertiesEntry const* properties, ObjectGuid owner) : TempSummon(properties, owner)
, m_owner(owner)
{
ASSERT(m_owner);
@@ -417,7 +417,7 @@ std::string Minion::GetDebugInfo() const
return sstr.str();
}
Guardian::Guardian(SummonPropertiesEntry const* properties, ObjectGuid owner, bool isWorldObject) : Minion(properties, owner, isWorldObject)
Guardian::Guardian(SummonPropertiesEntry const* properties, ObjectGuid owner) : Minion(properties, owner)
{
m_unitTypeMask |= UNIT_MASK_GUARDIAN;
if (properties && (properties->Type == SUMMON_TYPE_PET || properties->Category == SUMMON_CATEGORY_PET))
@@ -462,7 +462,7 @@ std::string Guardian::GetDebugInfo() const
return sstr.str();
}
Puppet::Puppet(SummonPropertiesEntry const* properties, ObjectGuid owner) : Minion(properties, owner, false), m_owner(owner) //maybe true?
Puppet::Puppet(SummonPropertiesEntry const* properties, ObjectGuid owner) : Minion(properties, owner), m_owner(owner)
{
ASSERT(owner.IsPlayer());
m_unitTypeMask |= UNIT_MASK_PUPPET;
@@ -39,7 +39,7 @@ struct TempSummonData
class TempSummon : public Creature
{
public:
explicit TempSummon(SummonPropertiesEntry const* properties, ObjectGuid owner, bool isWorldObject);
explicit TempSummon(SummonPropertiesEntry const* properties, ObjectGuid owner);
~TempSummon() override = default;
void Update(uint32 time) override;
virtual void InitStats(uint32 lifetime);
@@ -76,7 +76,7 @@ private:
class Minion : public TempSummon
{
public:
Minion(SummonPropertiesEntry const* properties, ObjectGuid owner, bool isWorldObject);
Minion(SummonPropertiesEntry const* properties, ObjectGuid owner);
void InitStats(uint32 duration) override;
void RemoveFromWorld() override;
[[nodiscard]] Unit* GetOwner() const;
@@ -95,7 +95,7 @@ protected:
class Guardian : public Minion
{
public:
Guardian(SummonPropertiesEntry const* properties, ObjectGuid owner, bool isWorldObject);
Guardian(SummonPropertiesEntry const* properties, ObjectGuid owner);
void InitStats(uint32 duration) override;
bool InitStatsForLevel(uint8 level);
void InitSummon() override;
@@ -22,7 +22,7 @@
#include "SpellAuraEffects.h"
#include "Transport.h"
DynamicObject::DynamicObject(bool isWorldObject) : WorldObject(isWorldObject), MovableMapObject(),
DynamicObject::DynamicObject() : WorldObject(), MovableMapObject(),
_aura(nullptr), _removedAura(nullptr), _caster(nullptr), _duration(0), _isViewpoint(false), _updateViewerVisibilityTimer(0)
{
m_objectType |= TYPEMASK_DYNAMICOBJECT;
@@ -128,11 +128,6 @@ bool DynamicObject::CreateDynamicObject(ObjectGuid::LowType guidlow, Unit* caste
return false;
}
if (IsWorldObject())
{
setActive(true);
}
return true;
}
@@ -34,7 +34,7 @@ enum DynamicObjectType
class DynamicObject : public WorldObject, public GridObject<DynamicObject>, public MovableMapObject, public UpdatableMapObject
{
public:
DynamicObject(bool isWorldObject);
DynamicObject();
~DynamicObject() override;
void AddToWorld() override;
@@ -38,7 +38,7 @@
#include <G3D/CoordinateFrame.h>
#include <G3D/Quat.h>
GameObject::GameObject() : WorldObject(false), MovableMapObject(),
GameObject::GameObject() : WorldObject(), MovableMapObject(),
m_model(nullptr), m_goValue(), m_AI(nullptr)
{
m_objectType |= TYPEMASK_GAMEOBJECT;
@@ -721,7 +721,7 @@ void GameObject::Update(uint32 diff)
{
Acore::NearestAttackableNoTotemUnitInObjectRangeCheck checker(this, owner, radius);
Acore::UnitSearcher<Acore::NearestAttackableNoTotemUnitInObjectRangeCheck> searcher(this, target, checker);
Cell::VisitAllObjects(this, searcher, radius);
Cell::VisitObjects(this, searcher, radius);
}
else // environmental trap
{
@@ -730,7 +730,7 @@ void GameObject::Update(uint32 diff)
Player* player = nullptr;
Acore::AnyPlayerInObjectRangeCheck checker(this, radius, true, true);
Acore::PlayerSearcher<Acore::AnyPlayerInObjectRangeCheck> searcher(this, player, checker);
Cell::VisitWorldObjects(this, searcher, radius);
Cell::VisitObjects(this, searcher, radius);
target = player;
}
@@ -893,7 +893,7 @@ void GameObject::Update(uint32 diff)
if (!m_spawnedByDefault)
{
m_respawnTime = 0;
DestroyForNearbyPlayers(); // xinef: old UpdateObjectVisibility();
DestroyForVisiblePlayers(); // xinef: old UpdateObjectVisibility();
return;
}
@@ -904,7 +904,7 @@ void GameObject::Update(uint32 diff)
if (GetMap()->IsDungeon())
SaveRespawnTime();
DestroyForNearbyPlayers(); // xinef: old UpdateObjectVisibility();
DestroyForVisiblePlayers(); // xinef: old UpdateObjectVisibility();
break;
}
}
@@ -1397,7 +1397,7 @@ GameObject* GameObject::LookupFishingHoleAround(float range)
Acore::NearestGameObjectFishingHole u_check(*this, range);
Acore::GameObjectSearcher<Acore::NearestGameObjectFishingHole> checker(this, ok, u_check);
Cell::VisitGridObjects(this, checker, range);
Cell::VisitObjects(this, checker, range);
return ok;
}
+1 -1
View File
@@ -1151,7 +1151,7 @@ bool Item::IsBindedNotWith(Player const* player) const
return true;
}
void Item::BuildUpdate(UpdateDataMapType& data_map, UpdatePlayerSet&)
void Item::BuildUpdate(UpdateDataMapType& data_map)
{
if (Player* owner = GetOwner())
BuildFieldsUpdate(owner, data_map);
+1 -1
View File
@@ -357,7 +357,7 @@ public:
void ClearSoulboundTradeable(Player* currentOwner);
bool CheckSoulboundTradeExpire();
void BuildUpdate(UpdateDataMapType& data_map, UpdatePlayerSet&) override;
void BuildUpdate(UpdateDataMapType& data_map) override;
void AddToObjectUpdate() override;
void RemoveFromObjectUpdate() override;
+51 -174
View File
@@ -86,17 +86,6 @@ Object::Object() : m_PackGUID(sizeof(uint64) + 1)
WorldObject::~WorldObject()
{
sScriptMgr->OnWorldObjectDestroy(this);
// this may happen because there are many !create/delete
if (IsWorldObject() && m_currMap)
{
if (IsCorpse())
{
LOG_FATAL("entities.object", "Object::~Object Corpse {}, type={} deleted but still in map!!", GetGUID().ToString(), ((Corpse*)this)->GetType());
ABORT();
}
ResetMap();
}
}
Object::~Object()
@@ -1047,10 +1036,11 @@ void MovementInfo::OutDebug()
LOG_INFO("movement", "splineElevation: {}", splineElevation);
}
WorldObject::WorldObject(bool isWorldObject) : WorldLocation(),
LastUsedScriptID(0), m_name(""), m_isActive(false), m_visibilityDistanceOverride(), m_isWorldObject(isWorldObject), m_zoneScript(nullptr),
WorldObject::WorldObject() : WorldLocation(),
LastUsedScriptID(0), m_name(""), m_isActive(false), m_visibilityDistanceOverride(), m_zoneScript(nullptr),
_zoneId(0), _areaId(0), _floorZ(INVALID_HEIGHT), _outdoors(false), _liquidData(), _updatePositionData(false), m_transport(nullptr),
m_currMap(nullptr), _heartbeatTimer(HEARTBEAT_INTERVAL), m_InstanceId(0), m_phaseMask(PHASEMASK_NORMAL), m_useCombinedPhases(true), m_notifyflags(0), m_executed_notifies(0)
m_currMap(nullptr), _heartbeatTimer(HEARTBEAT_INTERVAL), m_InstanceId(0), m_phaseMask(PHASEMASK_NORMAL), m_useCombinedPhases(true),
m_notifyflags(0), m_executed_notifies(0), _objectVisibilityContainer(this)
{
m_serverSideVisibility.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_ALIVE | GHOST_VISIBILITY_GHOST);
m_serverSideVisibilityDetect.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_ALIVE);
@@ -1082,31 +1072,14 @@ void WorldObject::setActive(bool on)
m_isActive = on;
if (on && !IsInWorld())
if (!on || !IsInWorld())
return;
Map* map = FindMap();
if (!map)
return;
if (on)
{
if (IsCreature())
map->AddToActive(this->ToCreature());
else if (IsDynamicObject())
map->AddToActive((DynamicObject*)this);
else if (IsGameObject())
map->AddToActive((GameObject*)this);
}
else
{
if (IsCreature())
map->RemoveFromActive(this->ToCreature());
else if (IsDynamicObject())
map->RemoveFromActive((DynamicObject*)this);
else if (IsGameObject())
map->RemoveFromActive((GameObject*)this);
}
map->AddObjectToPendingUpdateList(this);
}
void WorldObject::SetVisibilityDistanceOverride(VisibilityDistanceType type)
@@ -1177,7 +1150,9 @@ void WorldObject::RemoveFromWorld()
if (!IsInWorld())
return;
DestroyForNearbyPlayers();
DestroyForVisiblePlayers();
GetObjectVisibilityContainer().CleanVisibilityReferences();
Object::RemoveFromWorld();
}
@@ -2073,19 +2048,19 @@ void Unit::BuildHeartBeatMsg(WorldPacket* data) const
void WorldObject::SendMessageToSet(WorldPacket const* data, bool self) const
{
if (IsInWorld())
SendMessageToSetInRange(data, GetVisibilityRange(), self);
SendMessageToSetInRange(data, 0.0f, self);
}
void WorldObject::SendMessageToSetInRange(WorldPacket const* data, float dist, bool /*self*/) const
{
Acore::MessageDistDeliverer notifier(this, data, dist);
Cell::VisitWorldObjects(this, notifier, dist);
notifier.Visit(GetObjectVisibilityContainer().GetVisiblePlayersMap());
}
void WorldObject::SendMessageToSet(WorldPacket const* data, Player const* skipped_rcvr) const
{
Acore::MessageDistDeliverer notifier(this, data, GetVisibilityRange(), false, skipped_rcvr);
Cell::VisitWorldObjects(this, notifier, GetVisibilityRange());
Acore::MessageDistDeliverer notifier(this, data, 0.0f, false, skipped_rcvr);
notifier.Visit(GetObjectVisibilityContainer().GetVisiblePlayersMap());
}
void WorldObject::SendObjectDeSpawnAnim(ObjectGuid guid)
@@ -2116,9 +2091,6 @@ void WorldObject::SetMap(Map* map)
m_InstanceId = map->GetInstanceId();
sScriptMgr->OnWorldObjectSetMap(this, map);
if (IsWorldObject())
m_currMap->AddWorldObject(this);
}
void WorldObject::ResetMap()
@@ -2126,11 +2098,6 @@ void WorldObject::ResetMap()
ASSERT(m_currMap);
ASSERT(!IsInWorld());
if (IsWorldObject())
{
m_currMap->RemoveWorldObject(this);
}
sScriptMgr->OnWorldObjectResetMap(this);
m_currMap = nullptr;
@@ -2212,10 +2179,10 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert
switch (mask)
{
case UNIT_MASK_SUMMON:
summon = new TempSummon(properties, summoner ? summoner->GetGUID() : ObjectGuid::Empty, false);
summon = new TempSummon(properties, summoner ? summoner->GetGUID() : ObjectGuid::Empty);
break;
case UNIT_MASK_GUARDIAN:
summon = new Guardian(properties, summoner ? summoner->GetGUID() : ObjectGuid::Empty, false);
summon = new Guardian(properties, summoner ? summoner->GetGUID() : ObjectGuid::Empty);
break;
case UNIT_MASK_PUPPET:
summon = new Puppet(properties, summoner ? summoner->GetGUID() : ObjectGuid::Empty);
@@ -2224,7 +2191,7 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert
summon = new Totem(properties, summoner ? summoner->GetGUID() : ObjectGuid::Empty);
break;
case UNIT_MASK_MINION:
summon = new Minion(properties, summoner ? summoner->GetGUID() : ObjectGuid::Empty, false);
summon = new Minion(properties, summoner ? summoner->GetGUID() : ObjectGuid::Empty);
break;
default:
return nullptr;
@@ -2258,7 +2225,7 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert
// call MoveInLineOfSight for nearby creatures
Acore::AIRelocationNotifier notifier(*summon);
Cell::VisitAllObjects(summon, notifier, GetVisibilityRange());
Cell::VisitObjects(summon, notifier, GetVisibilityRange());
return summon;
}
@@ -2443,7 +2410,7 @@ Creature* WorldObject::FindNearestCreature(uint32 entry, float range, bool alive
Creature* creature = nullptr;
Acore::NearestCreatureEntryWithLiveStateInObjectRangeCheck checker(*this, entry, alive, range);
Acore::CreatureLastSearcher<Acore::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(this, creature, checker);
Cell::VisitAllObjects(this, searcher, range);
Cell::VisitObjects(this, searcher, range);
return creature;
}
@@ -2452,7 +2419,7 @@ GameObject* WorldObject::FindNearestGameObject(uint32 entry, float range, bool o
GameObject* go = nullptr;
Acore::NearestGameObjectEntryInObjectRangeCheck checker(*this, entry, range, onlySpawned);
Acore::GameObjectLastSearcher<Acore::NearestGameObjectEntryInObjectRangeCheck> searcher(this, go, checker);
Cell::VisitGridObjects(this, searcher, range);
Cell::VisitObjects(this, searcher, range);
return go;
}
@@ -2461,7 +2428,7 @@ GameObject* WorldObject::FindNearestGameObjectOfType(GameobjectTypes type, float
GameObject* go = nullptr;
Acore::NearestGameObjectTypeInObjectRangeCheck checker(*this, type, range);
Acore::GameObjectLastSearcher<Acore::NearestGameObjectTypeInObjectRangeCheck> searcher(this, go, checker);
Cell::VisitGridObjects(this, searcher, range);
Cell::VisitObjects(this, searcher, range);
return go;
}
@@ -2471,7 +2438,7 @@ Player* WorldObject::SelectNearestPlayer(float distance) const
Acore::NearestPlayerInObjectRangeCheck checker(this, distance);
Acore::PlayerLastSearcher<Acore::NearestPlayerInObjectRangeCheck> searcher(this, target, checker);
Cell::VisitWorldObjects(this, searcher, distance);
Cell::VisitObjects(this, searcher, distance);
return target;
}
@@ -2489,35 +2456,35 @@ void WorldObject::GetGameObjectListWithEntryInGrid(std::list<GameObject*>& gameo
{
Acore::AllGameObjectsWithEntryInRange check(this, entry, maxSearchRange);
Acore::GameObjectListSearcher<Acore::AllGameObjectsWithEntryInRange> searcher(this, gameobjectList, check);
Cell::VisitGridObjects(this, searcher, maxSearchRange);
Cell::VisitObjects(this, searcher, maxSearchRange);
}
void WorldObject::GetGameObjectListWithEntryInGrid(std::list<GameObject*>& gameobjectList, std::vector<uint32> const& entries, float maxSearchRange) const
{
Acore::AllGameObjectsMatchingOneEntryInRange check(this, entries, maxSearchRange);
Acore::GameObjectListSearcher searcher(this, gameobjectList, check);
Cell::VisitGridObjects(this, searcher, maxSearchRange);
Cell::VisitObjects(this, searcher, maxSearchRange);
}
void WorldObject::GetCreatureListWithEntryInGrid(std::list<Creature*>& creatureList, uint32 entry, float maxSearchRange) const
{
Acore::AllCreaturesOfEntryInRange check(this, entry, maxSearchRange);
Acore::CreatureListSearcher<Acore::AllCreaturesOfEntryInRange> searcher(this, creatureList, check);
Cell::VisitGridObjects(this, searcher, maxSearchRange);
Cell::VisitObjects(this, searcher, maxSearchRange);
}
void WorldObject::GetCreatureListWithEntryInGrid(std::list<Creature*>& creatureList, std::vector<uint32> const& entries, float maxSearchRange) const
{
Acore::AllCreaturesMatchingOneEntryInRange check(this, entries, maxSearchRange);
Acore::CreatureListSearcher searcher(this, creatureList, check);
Cell::VisitGridObjects(this, searcher, maxSearchRange);
Cell::VisitObjects(this, searcher, maxSearchRange);
}
void WorldObject::GetDeadCreatureListInGrid(std::list<Creature*>& creaturedeadList, float maxSearchRange, bool alive /*= false*/) const
{
Acore::AllDeadCreaturesInRange check(this, maxSearchRange, alive);
Acore::CreatureListSearcher<Acore::AllDeadCreaturesInRange> searcher(this, creaturedeadList, check);
Cell::VisitGridObjects(this, searcher, maxSearchRange);
Cell::VisitObjects(this, searcher, maxSearchRange);
}
/*
@@ -2906,72 +2873,49 @@ void WorldObject::PlayDirectSound(uint32 sound_id, Player* target /*= nullptr*/)
void WorldObject::PlayRadiusSound(uint32 sound_id, float radius)
{
std::list<Player*> targets;
std::vector<Player*> targets;
Acore::AnyPlayerInObjectRangeCheck check(this, radius, false);
Acore::PlayerListSearcher<Acore::AnyPlayerInObjectRangeCheck> searcher(this, targets, check);
Cell::VisitWorldObjects(this, searcher, radius);
Cell::VisitObjects(this, searcher, radius);
for (Player* player : targets)
{
if (player)
{
player->SendDirectMessage(WorldPackets::Misc::Playsound(sound_id).Write());
}
}
player->SendDirectMessage(WorldPackets::Misc::Playsound(sound_id).Write());
}
void WorldObject::PlayDirectMusic(uint32 music_id, Player* target /*= nullptr*/)
{
if (target)
{
target->SendDirectMessage(WorldPackets::Misc::PlayMusic(music_id).Write());
}
else
{
SendMessageToSet(WorldPackets::Misc::PlayMusic(music_id).Write(), true);
}
}
void WorldObject::PlayRadiusMusic(uint32 music_id, float radius)
{
std::list<Player*> targets;
std::vector<Player*> targets;
Acore::AnyPlayerInObjectRangeCheck check(this, radius, false);
Acore::PlayerListSearcher<Acore::AnyPlayerInObjectRangeCheck> searcher(this, targets, check);
Cell::VisitWorldObjects(this, searcher, radius);
Cell::VisitObjects(this, searcher, radius);
for (Player* player : targets)
{
if (player)
{
player->SendDirectMessage(WorldPackets::Misc::PlayMusic(music_id).Write());
}
}
player->SendDirectMessage(WorldPackets::Misc::PlayMusic(music_id).Write());
}
void WorldObject::DestroyForNearbyPlayers()
// Removes us from visibility for all players who are currently able to see us
void WorldObject::DestroyForVisiblePlayers()
{
if (!IsInWorld())
return;
std::list<Player*> targets;
Acore::AnyPlayerInObjectRangeCheck check(this, GetVisibilityRange() + VISIBILITY_COMPENSATION, false);
Acore::PlayerListSearcherWithSharedVision<Acore::AnyPlayerInObjectRangeCheck> searcher(this, targets, check);
Cell::VisitWorldObjects(this, searcher, GetVisibilityRange());
for (std::list<Player*>::const_iterator iter = targets.begin(); iter != targets.end(); ++iter)
VisiblePlayersMap& visiblePlayerMap = GetObjectVisibilityContainer().GetVisiblePlayersMap();
for (VisiblePlayersMap::iterator itr = visiblePlayerMap.begin(); itr != visiblePlayerMap.end();)
{
Player* player = (*iter);
if (player == this)
continue;
if (!player->HaveAtClient(this))
continue;
if (IsUnit() && ((Unit*)this)->GetCharmerGUID() == player->GetGUID()) /// @todo: this is for puppet
continue;
Player* player = itr->second;
DestroyForPlayer(player);
player->m_clientGUIDs.erase(GetGUID());
// Clean up visibility references now
itr = GetObjectVisibilityContainer().UnlinkVisibilityFromWorldObject(player, itr);
}
}
@@ -2979,7 +2923,7 @@ void WorldObject::UpdateObjectVisibility(bool /*forced*/, bool /*fromUpdate*/)
{
//updates object's visibility for nearby players
Acore::VisibleChangesNotifier notifier(*this);
Cell::VisitWorldObjects(this, notifier, GetVisibilityRange());
Cell::VisitObjects(this, notifier, GetVisibilityRange());
}
void WorldObject::AddToNotify(uint16 f)
@@ -3008,84 +2952,17 @@ void WorldObject::AddToNotify(uint16 f)
}
}
struct WorldObjectChangeAccumulator
void WorldObject::BuildUpdate(UpdateDataMapType& data_map)
{
UpdateDataMapType& i_updateDatas;
UpdatePlayerSet& i_playerSet;
WorldObject& i_object;
WorldObjectChangeAccumulator(WorldObject& obj, UpdateDataMapType& d, UpdatePlayerSet& p) : i_updateDatas(d), i_playerSet(p), i_object(obj)
// Build update for self
if (IsPlayer())
BuildFieldsUpdate(ToPlayer(), data_map);
// Build update for visible players
DoForAllVisiblePlayers([this, &data_map](Player* player)
{
i_playerSet.clear();
}
void Visit(PlayerMapType& m)
{
Player* source = nullptr;
for (PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
{
source = iter->GetSource();
BuildPacket(source);
if (source->HasSharedVision())
{
SharedVisionList::const_iterator it = source->GetSharedVisionList().begin();
for (; it != source->GetSharedVisionList().end(); ++it)
BuildPacket(*it);
}
}
}
void Visit(CreatureMapType& m)
{
Creature* source = nullptr;
for (CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
{
source = iter->GetSource();
if (source->HasSharedVision())
{
SharedVisionList::const_iterator it = source->GetSharedVisionList().begin();
for (; it != source->GetSharedVisionList().end(); ++it)
BuildPacket(*it);
}
}
}
void Visit(DynamicObjectMapType& m)
{
DynamicObject* source = nullptr;
for (DynamicObjectMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
{
source = iter->GetSource();
ObjectGuid guid = source->GetCasterGUID();
if (guid)
{
//Caster may be nullptr if DynObj is in removelist
if (Player* caster = ObjectAccessor::FindPlayer(guid))
if (caster->GetGuidValue(PLAYER_FARSIGHT) == source->GetGUID())
BuildPacket(caster);
}
}
}
void BuildPacket(Player* player)
{
// Only send update once to a player
if (i_playerSet.find(player->GetGUID()) == i_playerSet.end() && player->HaveAtClient(&i_object))
{
i_object.BuildFieldsUpdate(player, i_updateDatas);
i_playerSet.insert(player->GetGUID());
}
}
template<class SKIP> void Visit(GridRefMgr<SKIP>&) {}
};
void WorldObject::BuildUpdate(UpdateDataMapType& data_map, UpdatePlayerSet& player_set)
{
WorldObjectChangeAccumulator notifier(*this, data_map, player_set);
//we must build packets for all visible players
Cell::VisitWorldObjects(this, notifier, GetVisibilityRange());
BuildFieldsUpdate(player, data_map);
});
ClearUpdateMask(false);
}
@@ -3094,7 +2971,7 @@ void WorldObject::GetCreaturesWithEntryInRange(std::list<Creature*>& creatureLis
{
Acore::AllCreaturesOfEntryInRange check(this, entry, radius);
Acore::CreatureListSearcher<Acore::AllCreaturesOfEntryInRange> searcher(this, creatureList, check);
Cell::VisitAllObjects(this, searcher, radius);
Cell::VisitObjects(this, searcher, radius);
}
void WorldObject::AddToObjectUpdate()
+32 -7
View File
@@ -33,6 +33,7 @@
#include "Position.h"
#include "UpdateData.h"
#include "UpdateMask.h"
#include "ObjectVisibilityContainer.h"
#include <memory>
#include <set>
#include <sstream>
@@ -96,7 +97,6 @@ class MotionTransport;
struct PositionFullTerrainStatus;
typedef std::unordered_map<Player*, UpdateData> UpdateDataMapType;
typedef GuidUnorderedSet UpdatePlayerSet;
static constexpr Milliseconds HEARTBEAT_INTERVAL = 5s + 200ms;
@@ -189,7 +189,7 @@ public:
[[nodiscard]] virtual bool hasQuest(uint32 /* quest_id */) const { return false; }
[[nodiscard]] virtual bool hasInvolvedQuest(uint32 /* quest_id */) const { return false; }
virtual void BuildUpdate(UpdateDataMapType&, UpdatePlayerSet&) {}
virtual void BuildUpdate(UpdateDataMapType&) {}
void BuildFieldsUpdate(Player*, UpdateDataMapType&);
void SetFieldNotifyFlag(uint16 flag) { _fieldNotifyFlags |= flag; }
@@ -460,7 +460,7 @@ private:
class WorldObject : public Object, public WorldLocation
{
protected:
explicit WorldObject(bool isWorldObject); //note: here it means if it is in grid object list or world object list
explicit WorldObject();
public:
~WorldObject() override;
@@ -559,6 +559,29 @@ public:
void PlayDirectMusic(uint32 music_id, Player* target = nullptr);
void PlayRadiusMusic(uint32 music_id, float radius);
// Warning: Possible iterator invalidation in uses that may modify visibility map
template<typename Worker>
void DoForAllVisiblePlayers(Worker&& worker)
{
for (auto const& kvPair : GetObjectVisibilityContainer().GetVisiblePlayersMap())
worker(kvPair.second);
}
// Warning: Possible iterator invalidation in uses that may modify visibility map
template<typename Worker>
void DoForAllVisibleWorldObjects(Worker&& worker)
{
// Not a player, no access to this map
VisibleWorldObjectsMap const* visibleWorldObjectsMap = GetObjectVisibilityContainer().GetVisibleWorldObjectsMap();
if (!visibleWorldObjectsMap)
return;
for (auto const& kvPair : *visibleWorldObjectsMap)
worker(kvPair.second);
}
void DestroyForVisiblePlayers();
void SendObjectDeSpawnAnim(ObjectGuid guid);
virtual void SaveRespawnTime() {}
@@ -609,10 +632,9 @@ public:
void GetCreatureListWithEntryInGrid(std::list<Creature*>& creatureList, std::vector<uint32> const& entries, float maxSearchRange) const;
void GetDeadCreatureListInGrid(std::list<Creature*>& lList, float maxSearchRange, bool alive = false) const;
void DestroyForNearbyPlayers();
virtual void UpdateObjectVisibility(bool forced = true, bool fromUpdate = false);
virtual void UpdateObjectVisibilityOnCreate() { UpdateObjectVisibility(true); }
void BuildUpdate(UpdateDataMapType& data_map, UpdatePlayerSet& player_set) override;
void BuildUpdate(UpdateDataMapType& data_map) override;
void GetCreaturesWithEntryInRange(std::list<Creature*>& creatureList, float radius, uint32 entry);
void SetPositionDataUpdate();
@@ -635,7 +657,6 @@ public:
[[nodiscard]] bool IsFarVisible() const { return m_isFarVisible; }
[[nodiscard]] bool IsVisibilityOverridden() const { return m_visibilityDistanceOverride.has_value(); }
void SetVisibilityDistanceOverride(VisibilityDistanceType type);
[[nodiscard]] bool IsWorldObject() const { return m_isWorldObject; }
[[nodiscard]] bool IsInWintergrasp() const
{
@@ -688,6 +709,9 @@ public:
std::string GetDebugInfo() const override;
ObjectVisibilityContainer& GetObjectVisibilityContainer() { return _objectVisibilityContainer; }
ObjectVisibilityContainer const& GetObjectVisibilityContainer() const { return _objectVisibilityContainer; }
// Event handler
ElunaEventProcessor* elunaEvents;
EventProcessor m_Events;
@@ -697,7 +721,6 @@ protected:
bool m_isActive;
bool m_isFarVisible;
Optional<float> m_visibilityDistanceOverride;
const bool m_isWorldObject;
ZoneScript* m_zoneScript;
virtual void ProcessPositionDataChanged(PositionFullTerrainStatus const& data);
@@ -745,6 +768,8 @@ private:
bool CanDetectStealthOf(WorldObject const* obj, bool checkAlert = false) const;
GuidUnorderedSet _allowedLooters;
ObjectVisibilityContainer _objectVisibilityContainer;
};
namespace Acore
@@ -0,0 +1,114 @@
/*
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by the
* Free Software Foundation; either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ObjectVisibilityContainer.h"
#include "Object.h"
#include "Player.h"
/*
* Some implementation notes:
* Non-player worldobjects do not have any concept of 'visibility', thus,
* the most important and mainly used map is 'VisibleWorldObjectsMap'
* which is only accessible for player objects. The 'VisiblePlayersMap'
* map is simply for managing the references so we can use direct pointers.
*/
ObjectVisibilityContainer::ObjectVisibilityContainer(WorldObject* selfObject) :
_selfObject(selfObject)
{
}
ObjectVisibilityContainer::~ObjectVisibilityContainer()
{
ASSERT(_visiblePlayersMap.empty());
if (_visibleWorldObjectsMap)
ASSERT((*_visibleWorldObjectsMap).empty());
}
void ObjectVisibilityContainer::InitForPlayer()
{
_visibleWorldObjectsMap = std::make_unique<VisibleWorldObjectsMap>();
}
void ObjectVisibilityContainer::CleanVisibilityReferences()
{
for (auto const& kvPair : _visiblePlayersMap)
kvPair.second->GetObjectVisibilityContainer().DirectRemoveVisibilityReference(_selfObject->GetGUID());
if (_visibleWorldObjectsMap)
{
for (auto const& kvPair : *_visibleWorldObjectsMap)
kvPair.second->GetObjectVisibilityContainer().DirectRemoveVisiblePlayerReference(_selfObject->GetGUID());
(*_visibleWorldObjectsMap).clear();
}
_visiblePlayersMap.clear();
}
void ObjectVisibilityContainer::LinkWorldObjectVisibility(WorldObject* worldObject)
{
// Do not link self
if (worldObject == _selfObject)
return;
// Only players can link visibility
if (!_visibleWorldObjectsMap)
return;
(*_visibleWorldObjectsMap).insert(std::make_pair(worldObject->GetGUID(), worldObject));
worldObject->GetObjectVisibilityContainer().DirectInsertVisiblePlayerReference(_selfObject->ToPlayer());
}
void ObjectVisibilityContainer::UnlinkWorldObjectVisibility(WorldObject* worldObject)
{
// Only players can unlink visibility
if (!_visibleWorldObjectsMap)
return;
worldObject->GetObjectVisibilityContainer().DirectRemoveVisiblePlayerReference(_selfObject->GetGUID());
(*_visibleWorldObjectsMap).erase(worldObject->GetGUID());
}
VisibleWorldObjectsMap::iterator ObjectVisibilityContainer::UnlinkVisibilityFromPlayer(WorldObject* worldObject, VisibleWorldObjectsMap::iterator itr)
{
ASSERT(_visibleWorldObjectsMap); // Ensure we aren't for some reason calling this as a non-player object
worldObject->GetObjectVisibilityContainer().DirectRemoveVisiblePlayerReference(_selfObject->GetGUID());
return (*_visibleWorldObjectsMap).erase(itr);
}
VisiblePlayersMap::iterator ObjectVisibilityContainer::UnlinkVisibilityFromWorldObject(Player* player, VisiblePlayersMap::iterator itr)
{
player->GetObjectVisibilityContainer().DirectRemoveVisibilityReference(_selfObject->GetGUID());
return _visiblePlayersMap.erase(itr);
}
void ObjectVisibilityContainer::DirectRemoveVisibilityReference(ObjectGuid guid)
{
ASSERT(_visibleWorldObjectsMap);
(*_visibleWorldObjectsMap).erase(guid);
}
void ObjectVisibilityContainer::DirectInsertVisiblePlayerReference(Player* player)
{
_visiblePlayersMap.insert(std::make_pair(player->GetGUID(), player));
}
void ObjectVisibilityContainer::DirectRemoveVisiblePlayerReference(ObjectGuid guid)
{
_visiblePlayersMap.erase(guid);
}
@@ -0,0 +1,101 @@
/*
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by the
* Free Software Foundation; either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _OBJECTVISIBILITYCONTAINER_H
#define _OBJECTVISIBILITYCONTAINER_H
#include "Common.h"
#include "ObjectGuid.h"
#include <memory>
#include <unordered_map>
class Player;
class WorldObject;
typedef std::unordered_map<ObjectGuid, WorldObject*> VisibleWorldObjectsMap;
typedef std::unordered_map<ObjectGuid, Player*> VisiblePlayersMap;
// Class that manages the visibility containers of a worldobject
class ObjectVisibilityContainer
{
public:
ObjectVisibilityContainer(WorldObject* selfObject);
~ObjectVisibilityContainer();
// Creates the _visibleWorldObjectsMap map if we are a player
void InitForPlayer();
// Cleans up all visibility references from other worldobjects,
// this is used before a worldobject is deleted to prevent any dangling references
void CleanVisibilityReferences();
void LinkWorldObjectVisibility(WorldObject* worldObject);
void UnlinkWorldObjectVisibility(WorldObject* worldObject);
// These helpers aren't ideal, but needed in a few spots for cleaning up references
VisibleWorldObjectsMap::iterator UnlinkVisibilityFromPlayer(WorldObject* worldObject, VisibleWorldObjectsMap::iterator itr);
VisiblePlayersMap::iterator UnlinkVisibilityFromWorldObject(Player* player, VisiblePlayersMap::iterator itr);
// Returns a list of all players who can see us
VisiblePlayersMap& GetVisiblePlayersMap() { return _visiblePlayersMap; }
VisiblePlayersMap const& GetVisiblePlayersMap() const { return _visiblePlayersMap; }
// Returns a list of all worldobjects who we can see
// Warning: This is for player objects only, all other objects will return a nullptr
VisibleWorldObjectsMap* GetVisibleWorldObjectsMap()
{
if (!_visibleWorldObjectsMap)
return nullptr;
return _visibleWorldObjectsMap.get();
}
VisibleWorldObjectsMap const* GetVisibleWorldObjectsMap() const
{
if (!_visibleWorldObjectsMap)
return nullptr;
return _visibleWorldObjectsMap.get();
}
private:
// Directly removes visibility reference. This is to be ONLY used as
// a more efficient method for cleaning up visibility references.
// Warning: Improper use will leave dangling references and result in crashes.
void DirectRemoveVisibilityReference(ObjectGuid guid);
// Directly inserts player visibility reference.
// Warning: Improper use will leave dangling references and result in crashes.
void DirectInsertVisiblePlayerReference(Player* player);
// Directly removes player visibility reference.
// Warning: Improper use will leave dangling references and result in crashes.
void DirectRemoveVisiblePlayerReference(ObjectGuid guid);
WorldObject* _selfObject;
// List of all worldobjects that are visible to us (including other players)
// Only players contain this map, thus we will only allocate it as needed.
std::unique_ptr<VisibleWorldObjectsMap> _visibleWorldObjectsMap;
// List of players who are currently able to see this worldobject.
// All worldobjects will contain this map
VisiblePlayersMap _visiblePlayersMap;
};
#endif
+3 -3
View File
@@ -38,7 +38,7 @@
#include "WorldPacket.h"
#include "WorldSession.h"
Pet::Pet(Player* owner, PetType type) : Guardian(nullptr, owner ? owner->GetGUID() : ObjectGuid::Empty, true),
Pet::Pet(Player* owner, PetType type) : Guardian(nullptr, owner ? owner->GetGUID() : ObjectGuid::Empty),
m_usedTalentCount(0),
m_removed(false),
m_owner(owner),
@@ -75,7 +75,7 @@ void Pet::AddToWorld()
if (!IsInWorld())
{
///- Register the pet for guid lookup
GetMap()->GetObjectsStore().Insert<Pet>(GetGUID(), this);
GetMap()->GetObjectsStore().Insert<Creature>(GetGUID(), this);
Unit::AddToWorld();
Motion_Initialize();
AIM_Initialize();
@@ -126,7 +126,7 @@ void Pet::RemoveFromWorld()
{
///- Don't call the function for Creature, normal mobs + totems go in a different storage
Unit::RemoveFromWorld();
GetMap()->GetObjectsStore().Remove<Pet>(GetGUID());
GetMap()->GetObjectsStore().Remove<Creature>(GetGUID());
}
}
+45 -58
View File
@@ -149,7 +149,7 @@ static uint32 copseReclaimDelay[MAX_DEATH_COUNT] = { 30, 60, 120 };
#ifdef _MSC_VER
#pragma warning(disable:4355)
#endif
Player::Player(WorldSession* session): Unit(true), m_mover(this)
Player::Player(WorldSession* session): Unit(), m_mover(this)
{
#ifdef _MSC_VER
#pragma warning(default:4355)
@@ -412,6 +412,9 @@ Player::Player(WorldSession* session): Unit(true), m_mover(this)
m_isInstantFlightOn = true;
_wasOutdoor = true;
GetObjectVisibilityContainer().InitForPlayer();
sScriptMgr->OnConstructPlayer(this);
}
@@ -5718,20 +5721,7 @@ void Player::SendMessageToSetInRange(WorldPacket const* data, float dist, bool s
SendDirectMessage(data);
Acore::MessageDistDeliverer notifier(this, data, dist);
Cell::VisitWorldObjects(this, notifier, dist);
}
void Player::SendMessageToSetInRange(WorldPacket const* data, float dist, bool self, bool includeMargin, bool ownTeamOnly, bool required3dDist) const
{
if (self)
SendDirectMessage(data);
dist += GetObjectSize();
if (includeMargin)
dist += VISIBILITY_COMPENSATION; // pussywizard: to ensure everyone receives all important packets
Acore::MessageDistDeliverer notifier(this, data, dist, ownTeamOnly, nullptr, required3dDist);
Cell::VisitWorldObjects(this, notifier, dist);
notifier.Visit(GetObjectVisibilityContainer().GetVisiblePlayersMap());
}
void Player::SendMessageToSet(WorldPacket const* data, Player const* skipped_rcvr) const
@@ -5739,8 +5729,8 @@ void Player::SendMessageToSet(WorldPacket const* data, Player const* skipped_rcv
if (skipped_rcvr != this)
SendDirectMessage(data);
Acore::MessageDistDeliverer notifier(this, data, GetVisibilityRange(), false, skipped_rcvr);
Cell::VisitWorldObjects(this, notifier, GetVisibilityRange());
Acore::MessageDistDeliverer notifier(this, data, 0.0f, false, skipped_rcvr);
notifier.Visit(GetObjectVisibilityContainer().GetVisiblePlayersMap());
}
void Player::SendDirectMessage(WorldPacket const* data) const
@@ -7722,23 +7712,26 @@ bool Player::CheckAmmoCompatibility(ItemTemplate const* ammo_proto) const
void Player::SendQuestGiverStatusMultiple()
{
if (GetObjectVisibilityContainer().GetVisibleWorldObjectsMap()->empty())
return;
uint32 count = 0;
WorldPacket data(SMSG_QUESTGIVER_STATUS_MULTIPLE, 4);
data << uint32(count); // placeholder
for (GuidUnorderedSet::const_iterator itr = m_clientGUIDs.begin(); itr != m_clientGUIDs.end(); ++itr)
DoForAllVisibleWorldObjects([this, &data, &count](WorldObject* worldObject)
{
uint32 questStatus = DIALOG_STATUS_NONE;
if ((*itr).IsAnyTypeCreature())
if (worldObject->IsCreature())
{
// need also pet quests case support
Creature* questgiver = ObjectAccessor::GetCreatureOrPetOrVehicle(*this, *itr);
Creature* questgiver = worldObject->ToCreature();
if (!questgiver || questgiver->IsHostileTo(this))
continue;
return;
if (!questgiver->HasNpcFlag(UNIT_NPC_FLAG_QUESTGIVER))
continue;
return;
questStatus = GetQuestDialogStatus(questgiver);
@@ -7746,11 +7739,11 @@ void Player::SendQuestGiverStatusMultiple()
data << uint8(questStatus);
++count;
}
else if ((*itr).IsGameObject())
else if (worldObject->IsGameObject())
{
GameObject* questgiver = GetMap()->GetGameObject(*itr);
GameObject* questgiver = worldObject->ToGameObject();
if (!questgiver || questgiver->GetGoType() != GAMEOBJECT_TYPE_QUESTGIVER)
continue;
return;
questStatus = GetQuestDialogStatus(questgiver);
@@ -7758,7 +7751,7 @@ void Player::SendQuestGiverStatusMultiple()
data << uint8(questStatus);
++count;
}
}
});
data.put<uint32>(0, count); // write real count
GetSession()->SendPacket(&data);
@@ -9394,7 +9387,12 @@ void Player::Say(std::string_view text, Language language, WorldObject const* /*
WorldPacket data;
ChatHandler::BuildChatPacket(data, CHAT_MSG_SAY, language, this, this, _text);
SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), true, false, false, true);
SendDirectMessage(&data);
// Special handling for messages, do not use visibility map for stealthed units
Acore::MessageDistDeliverer notifier(this, &data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), false, nullptr, true);
Cell::VisitObjects(this, notifier, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY));
}
void Player::Say(uint32 textId, WorldObject const* target /*= nullptr*/)
@@ -9415,7 +9413,12 @@ void Player::Yell(std::string_view text, Language language, WorldObject const* /
WorldPacket data;
ChatHandler::BuildChatPacket(data, CHAT_MSG_YELL, language, this, this, _text);
SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_YELL), true, false, false, true);
SendDirectMessage(&data);
// Special handling for messages, do not use visibility map for stealthed units
Acore::MessageDistDeliverer notifier(this, &data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_YELL), false, nullptr, true);
Cell::VisitObjects(this, notifier, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_YELL));
}
void Player::Yell(uint32 textId, WorldObject const* target /*= nullptr*/)
@@ -9437,7 +9440,11 @@ void Player::TextEmote(std::string_view text, WorldObject const* /*= nullptr*/,
WorldPacket data;
ChatHandler::BuildChatPacket(data, CHAT_MSG_EMOTE, LANG_UNIVERSAL, this, this, _text);
SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), true, false, !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_EMOTE), true);
SendDirectMessage(&data);
// Special handling for messages, do not use visibility map for stealthed units
Acore::MessageDistDeliverer notifier(this, &data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_EMOTE), nullptr, true);
Cell::VisitObjects(this, notifier, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE));
}
void Player::TextEmote(uint32 textId, WorldObject const* target /*= nullptr*/, bool /*isBossEmote = false*/)
@@ -10498,35 +10505,24 @@ void Player::ContinueTaxiFlight()
void Player::SendTaxiNodeStatusMultiple()
{
for (auto itr = m_clientGUIDs.begin(); itr != m_clientGUIDs.end(); ++itr)
DoForAllVisibleWorldObjects([this](WorldObject* worldObject)
{
if (!itr->IsCreature())
{
continue;
}
Creature* creature = ObjectAccessor::GetCreature(*this, *itr);
Creature* creature = worldObject->ToCreature();
if (!creature || creature->IsHostileTo(this))
{
continue;
}
return;
if (!creature->HasNpcFlag(UNIT_NPC_FLAG_FLIGHTMASTER))
{
continue;
}
return;
uint32 nearestNode = sObjectMgr->GetNearestTaxiNode(creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ(), creature->GetMapId(), GetTeamId());
if (!nearestNode)
{
continue;
}
return;
WorldPacket data(SMSG_TAXINODE_STATUS, 9);
data << *itr;
data << creature->GetGUID();
data << uint8(m_taxi.IsTaximaskNodeKnown(nearestNode) ? 1 : 0);
SendDirectMessage(&data);
}
});
}
void Player::ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs)
@@ -11404,31 +11400,22 @@ WorldLocation Player::GetStartPosition() const
bool Player::HaveAtClient(WorldObject const* u) const
{
if (u == this)
{
return true;
}
// Motion Transports are always present in player's client
if (GameObject const* gameobject = u->ToGameObject())
{
if (gameobject->IsMotionTransport())
{
return true;
}
}
return m_clientGUIDs.find(u->GetGUID()) != m_clientGUIDs.end();
return HaveAtClient(u->GetGUID());
}
bool Player::HaveAtClient(ObjectGuid guid) const
{
if (guid == GetGUID())
{
return true;
}
return m_clientGUIDs.find(guid) != m_clientGUIDs.end();
return GetObjectVisibilityContainer().GetVisibleWorldObjectsMap()->find(guid) != GetObjectVisibilityContainer().GetVisibleWorldObjectsMap()->end();
}
bool Player::IsNeverVisible() const
-2
View File
@@ -2033,7 +2033,6 @@ public:
void SendMessageToSet(WorldPacket const* data, bool self) const override;
void SendMessageToSetInRange(WorldPacket const* data, float dist, bool self) const override;
void SendMessageToSetInRange(WorldPacket const* data, float dist, bool self, bool includeMargin, bool ownTeamOnly, bool required3dDist = false) const;
void SendMessageToSet(WorldPacket const* data, Player const* skipped_rcvr) const override;
void SendTeleportAckPacket();
@@ -2388,7 +2387,6 @@ public:
void SetEntryPoint();
// currently visible objects at player client
GuidUnorderedSet m_clientGUIDs;
std::vector<Unit*> m_newVisible; // pussywizard
[[nodiscard]] bool HaveAtClient(WorldObject const* u) const;
@@ -1602,13 +1602,13 @@ void Player::UpdateVisibilityForPlayer(bool mapChange)
Acore::VisibleNotifier notifierNoLarge(
*this, mapChange,
false); // visit only objects which are not large; default distance
Cell::VisitAllObjects(m_seer, notifierNoLarge,
Cell::VisitObjects(m_seer, notifierNoLarge,
GetSightRange() + VISIBILITY_INC_FOR_GOBJECTS);
notifierNoLarge.SendToSelf();
Acore::VisibleNotifier notifierLarge(
*this, mapChange, true); // visit only large objects; maximum distance
Cell::VisitAllObjects(m_seer, notifierLarge, GetSightRange());
Cell::VisitObjects(m_seer, notifierLarge, GetSightRange());
notifierLarge.SendToSelf();
if (mapChange)
@@ -1636,35 +1636,35 @@ void Player::UpdateObjectVisibility(bool forced, bool fromUpdate)
}
template <class T>
inline void UpdateVisibilityOf_helper(GuidUnorderedSet& s64, T* target,
inline void UpdateVisibilityOf_helper(Player* player, T* target,
std::vector<Unit*>& /*v*/)
{
s64.insert(target->GetGUID());
player->GetObjectVisibilityContainer().LinkWorldObjectVisibility(target);
}
template <>
inline void UpdateVisibilityOf_helper(GuidUnorderedSet& s64, GameObject* target,
inline void UpdateVisibilityOf_helper(Player* player, GameObject* target,
std::vector<Unit*>& /*v*/)
{
// @HACK: This is to prevent objects like deeprun tram from disappearing
// when player moves far from its spawn point while riding it
if ((target->GetGOInfo()->type != GAMEOBJECT_TYPE_TRANSPORT))
s64.insert(target->GetGUID());
player->GetObjectVisibilityContainer().LinkWorldObjectVisibility(target);
}
template <>
inline void UpdateVisibilityOf_helper(GuidUnorderedSet& s64, Creature* target,
inline void UpdateVisibilityOf_helper(Player* player, Creature* target,
std::vector<Unit*>& v)
{
s64.insert(target->GetGUID());
player->GetObjectVisibilityContainer().LinkWorldObjectVisibility(target);
v.push_back(target);
}
template <>
inline void UpdateVisibilityOf_helper(GuidUnorderedSet& s64, Player* target,
inline void UpdateVisibilityOf_helper(Player* player, Player* target,
std::vector<Unit*>& v)
{
s64.insert(target->GetGUID());
player->GetObjectVisibilityContainer().LinkWorldObjectVisibility(target);
v.push_back(target);
}
@@ -1693,7 +1693,7 @@ void Player::UpdateVisibilityOf(T* target, UpdateData& data,
BeforeVisibilityDestroy<T>(target, this);
target->BuildOutOfRangeUpdateBlock(&data);
m_clientGUIDs.erase(target->GetGUID());
GetObjectVisibilityContainer().UnlinkWorldObjectVisibility(target);
}
}
else
@@ -1701,7 +1701,7 @@ void Player::UpdateVisibilityOf(T* target, UpdateData& data,
if (CanSeeOrDetect(target, false, true))
{
target->BuildCreateUpdateBlockForPlayer(&data, this);
UpdateVisibilityOf_helper(m_clientGUIDs, target, visibleNow);
UpdateVisibilityOf_helper(this, target, visibleNow);
}
}
}
@@ -1727,7 +1727,7 @@ void Player::UpdateVisibilityOf(WorldObject* target)
BeforeVisibilityDestroy<Creature>(target->ToCreature(), this);
target->DestroyForPlayer(this);
m_clientGUIDs.erase(target->GetGUID());
GetObjectVisibilityContainer().UnlinkWorldObjectVisibility(target);
}
}
else
@@ -1735,7 +1735,7 @@ void Player::UpdateVisibilityOf(WorldObject* target)
if (CanSeeOrDetect(target, false, true))
{
target->SendUpdateToPlayer(this);
m_clientGUIDs.insert(target->GetGUID());
GetObjectVisibilityContainer().LinkWorldObjectVisibility(target);
// target aura duration for caster show only if target exist at
// caster client send data at target visibility change (adding to
@@ -1748,69 +1748,67 @@ void Player::UpdateVisibilityOf(WorldObject* target)
void Player::UpdateTriggerVisibility()
{
if (m_clientGUIDs.empty())
return;
if (!IsInWorld())
return;
UpdateData udata;
WorldPacket packet;
for (GuidUnorderedSet::iterator itr = m_clientGUIDs.begin();
itr != m_clientGUIDs.end(); ++itr)
if (GetObjectVisibilityContainer().GetVisibleWorldObjectsMap()->empty())
return;
UpdateData udata;
DoForAllVisibleWorldObjects([this, &udata](WorldObject* worldObject)
{
if ((*itr).IsCreatureOrVehicle())
if (worldObject->IsCreature())
{
Creature* creature = GetMap()->GetCreature(*itr);
Creature* creature = worldObject->ToCreature();
// Update fields of triggers, transformed units or unselectable
// units (values dependent on GM state)
if (!creature || (!creature->IsTrigger() &&
!creature->HasTransformAura() &&
!creature->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE)))
continue;
!creature->HasTransformAura() &&
!creature->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE)))
return;
creature->SetFieldNotifyFlag(UF_FLAG_PUBLIC);
creature->BuildValuesUpdateBlockForPlayer(&udata, this);
creature->RemoveFieldNotifyFlag(UF_FLAG_PUBLIC);
}
else if ((*itr).IsGameObject())
else if (worldObject->IsGameObject())
{
GameObject* go = GetMap()->GetGameObject(*itr);
GameObject* go = worldObject->ToGameObject();
if (!go)
continue;
return;
go->SetFieldNotifyFlag(UF_FLAG_PUBLIC);
go->BuildValuesUpdateBlockForPlayer(&udata, this);
go->RemoveFieldNotifyFlag(UF_FLAG_PUBLIC);
}
}
});
if (!udata.HasData())
return;
WorldPacket packet;
udata.BuildPacket(packet);
GetSession()->SendPacket(&packet);
}
void Player::UpdateForQuestWorldObjects()
{
if (m_clientGUIDs.empty())
if (GetObjectVisibilityContainer().GetVisibleWorldObjectsMap()->empty())
return;
UpdateData udata;
WorldPacket packet;
for (GuidUnorderedSet::iterator itr = m_clientGUIDs.begin(); itr != m_clientGUIDs.end(); ++itr)
UpdateData udata;
DoForAllVisibleWorldObjects([this, &udata](WorldObject* worldObject)
{
if ((*itr).IsGameObject())
if (worldObject->IsGameObject())
{
if (GameObject* obj = ObjectAccessor::GetGameObject(*this, *itr))
if (GameObject* obj = worldObject->ToGameObject())
obj->BuildValuesUpdateBlockForPlayer(&udata, this);
}
else if ((*itr).IsCreatureOrVehicle())
else if (worldObject->IsCreature())
{
Creature* obj = ObjectAccessor::GetCreatureOrPetOrVehicle(*this, *itr);
Creature* obj = worldObject->ToCreature();
if (!obj)
continue;
return;
// check if this unit requires quest specific flags
if (obj->HasNpcFlag(UNIT_NPC_FLAG_SPELLCLICK))
@@ -1834,12 +1832,14 @@ void Player::UpdateForQuestWorldObjects()
}
}
else if (obj->HasNpcFlag(UNIT_NPC_FLAG_VENDOR_MASK | UNIT_NPC_FLAG_TRAINER))
{
obj->BuildValuesUpdateBlockForPlayer(&udata, this);
}
}
}
});
if (!udata.HasData())
return;
WorldPacket packet;
udata.BuildPacket(packet);
GetSession()->SendPacket(&packet);
}
+1 -1
View File
@@ -24,7 +24,7 @@
#include "SpellMgr.h"
#include "TotemPackets.h"
Totem::Totem(SummonPropertiesEntry const* properties, ObjectGuid owner) : Minion(properties, owner, false)
Totem::Totem(SummonPropertiesEntry const* properties, ObjectGuid owner) : Minion(properties, owner)
{
m_unitTypeMask |= UNIT_MASK_TOTEM;
m_duration = 0;
@@ -123,7 +123,7 @@ void MotionTransport::CleanupsBeforeDelete(bool finalCleanup /*= true*/)
GameObject::CleanupsBeforeDelete(finalCleanup);
}
void MotionTransport::BuildUpdate(UpdateDataMapType& data_map, UpdatePlayerSet&)
void MotionTransport::BuildUpdate(UpdateDataMapType& data_map)
{
Map::PlayerList const& players = GetMap()->GetPlayers();
if (players.IsEmpty())
@@ -812,7 +812,7 @@ void StaticTransport::CleanupsBeforeDelete(bool finalCleanup /*= true*/)
GameObject::CleanupsBeforeDelete(finalCleanup);
}
void StaticTransport::BuildUpdate(UpdateDataMapType& data_map, UpdatePlayerSet&)
void StaticTransport::BuildUpdate(UpdateDataMapType& data_map)
{
Map::PlayerList const& players = GetMap()->GetPlayers();
if (players.IsEmpty())
@@ -54,7 +54,7 @@ public:
bool CreateMoTrans(ObjectGuid::LowType guidlow, uint32 entry, uint32 mapid, float x, float y, float z, float ang, uint32 animprogress);
void CleanupsBeforeDelete(bool finalCleanup = true) override;
void BuildUpdate(UpdateDataMapType& data_map, UpdatePlayerSet&) override;
void BuildUpdate(UpdateDataMapType& data_map) override;
void Update(uint32 diff) override;
void DelayedUpdate(uint32 diff);
@@ -117,7 +117,7 @@ public:
bool Create(ObjectGuid::LowType guidlow, uint32 name_id, Map* map, uint32 phaseMask, float x, float y, float z, float ang, G3D::Quat const& rotation, uint32 animprogress, GOState go_state, uint32 artKit = 0) override;
void CleanupsBeforeDelete(bool finalCleanup = true) override;
void BuildUpdate(UpdateDataMapType& data_map, UpdatePlayerSet&) override;
void BuildUpdate(UpdateDataMapType& data_map) override;
void Update(uint32 diff) override;
void RelocateToProgress(uint32 progress);
+13 -13
View File
@@ -201,7 +201,7 @@ SpellInfo const* ProcEventInfo::GetSpellInfo() const
#ifdef _MSC_VER
#pragma warning(disable:4355)
#endif
Unit::Unit(bool isWorldObject) : WorldObject(isWorldObject),
Unit::Unit() : WorldObject(),
m_movedByPlayer(nullptr),
m_lastSanctuaryTime(0),
IsAIEnabled(false),
@@ -17077,7 +17077,7 @@ Unit* Unit::SelectNearbyTarget(Unit* exclude, float dist) const
std::list<Unit*> targets;
Acore::AnyUnfriendlyUnitInObjectRangeCheck u_check(this, this, dist);
Acore::UnitListSearcher<Acore::AnyUnfriendlyUnitInObjectRangeCheck> searcher(this, targets, u_check);
Cell::VisitAllObjects(this, searcher, dist);
Cell::VisitObjects(this, searcher, dist);
// remove current target
if (GetVictim())
@@ -17112,7 +17112,7 @@ Unit* Unit::SelectNearbyNoTotemTarget(Unit* exclude, float dist) const
std::list<Unit*> targets;
Acore::AnyUnfriendlyNoTotemUnitInObjectRangeCheck u_check(this, this, dist);
Acore::UnitListSearcher<Acore::AnyUnfriendlyNoTotemUnitInObjectRangeCheck> searcher(this, targets, u_check);
Cell::VisitAllObjects(this, searcher, dist);
Cell::VisitObjects(this, searcher, dist);
// remove current target
if (GetVictim())
@@ -17349,7 +17349,7 @@ void Unit::SetContestedPvP(Player* attackedPlayer, bool lookForNearContestedGuar
std::list<Unit*> targets;
Acore::NearestVisibleDetectableContestedGuardUnitCheck u_check(this);
Acore::UnitListSearcher<Acore::NearestVisibleDetectableContestedGuardUnitCheck> searcher(this, targets, u_check);
Cell::VisitAllObjects(this, searcher, MAX_AGGRO_RADIUS);
Cell::VisitObjects(this, searcher, MAX_AGGRO_RADIUS);
// return if there are no contested guards found
if (!targets.size())
@@ -19255,7 +19255,7 @@ void Unit::UpdateObjectVisibility(bool forced, bool /*fromUpdate*/)
WorldObject::UpdateObjectVisibility(true);
Acore::AIRelocationNotifier notifier(*this);
float radius = 60.0f;
Cell::VisitAllObjects(this, notifier, radius);
Cell::VisitObjects(this, notifier, radius);
}
}
@@ -20306,10 +20306,10 @@ void Unit::ExecuteDelayedUnitRelocationEvent()
}
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::VisitObjects(viewPoint, relocateNoLarge, player->GetSightRange() + VISIBILITY_INC_FOR_GOBJECTS);
relocateNoLarge.SendToSelf();
Acore::PlayerRelocationNotifier relocateLarge(*player, true); // visit only large objects; maximum distance
Cell::VisitAllObjects(viewPoint, relocateLarge, MAX_VISIBILITY_DISTANCE);
Cell::VisitObjects(viewPoint, relocateLarge, MAX_VISIBILITY_DISTANCE);
relocateLarge.SendToSelf();
}
@@ -20345,13 +20345,13 @@ void Unit::ExecuteDelayedUnitRelocationEvent()
GetMap()->LoadGridsInRange(*player, MAX_VISIBILITY_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::VisitObjects(viewPoint, relocateNoLarge, player->GetSightRange() + VISIBILITY_INC_FOR_GOBJECTS);
relocateNoLarge.SendToSelf();
if (!player->GetFarSightDistance())
{
Acore::PlayerRelocationNotifier relocateLarge(*player, true); // visit only large objects; maximum distance
Cell::VisitAllObjects(viewPoint, relocateLarge, MAX_VISIBILITY_DISTANCE);
Cell::VisitObjects(viewPoint, relocateLarge, MAX_VISIBILITY_DISTANCE);
relocateLarge.SendToSelf();
}
@@ -20373,7 +20373,7 @@ void Unit::ExecuteDelayedUnitRelocationEvent()
unit->m_last_notify_position.Relocate(unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ());
Acore::CreatureRelocationNotifier relocate(*unit);
Cell::VisitAllObjects(unit, relocate, unit->GetVisibilityRange() + VISIBILITY_COMPENSATION);
Cell::VisitObjects(unit, relocate, unit->GetVisibilityRange() + VISIBILITY_COMPENSATION);
this->AddToNotify(NOTIFY_AI_RELOCATION);
}
@@ -20387,7 +20387,7 @@ void Unit::ExecuteDelayedUnitAINotifyEvent()
Acore::AIRelocationNotifier notifier(*this);
float radius = 60.0f;
Cell::VisitAllObjects(this, notifier, radius);
Cell::VisitObjects(this, notifier, radius);
}
void Unit::SetInFront(WorldObject const* target)
@@ -21023,7 +21023,7 @@ void Unit::Talk(std::string_view text, ChatMsg msgType, Language language, float
Acore::CustomChatTextBuilder builder(this, msgType, text, language, target);
Acore::LocalizedPacketDo<Acore::CustomChatTextBuilder> localizer(builder);
Acore::PlayerDistWorker<Acore::LocalizedPacketDo<Acore::CustomChatTextBuilder> > worker(this, textRange, localizer);
Cell::VisitWorldObjects(this, worker, textRange);
Cell::VisitObjects(this, worker, textRange);
}
void Unit::Say(std::string_view text, Language language, WorldObject const* target /*= nullptr*/)
@@ -21081,7 +21081,7 @@ void Unit::Talk(uint32 textId, ChatMsg msgType, float textRange, WorldObject con
Acore::BroadcastTextBuilder builder(this, msgType, textId, getGender(), target);
Acore::LocalizedPacketDo<Acore::BroadcastTextBuilder> localizer(builder);
Acore::PlayerDistWorker<Acore::LocalizedPacketDo<Acore::BroadcastTextBuilder> > worker(this, textRange, localizer);
Cell::VisitWorldObjects(this, worker, textRange);
Cell::VisitObjects(this, worker, textRange);
}
void Unit::Say(uint32 textId, WorldObject const* target /*= nullptr*/)
+1 -1
View File
@@ -2035,7 +2035,7 @@ public:
Movement::MoveSpline* movespline;
protected:
explicit Unit (bool isWorldObject);
explicit Unit();
void BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) override;
+2 -7
View File
@@ -103,13 +103,8 @@ struct Cell
static CellArea CalculateCellArea(float x, float y, float radius);
template<class T> static void VisitGridObjects(WorldObject const* obj, T& visitor, float radius);
template<class T> static void VisitWorldObjects(WorldObject const* obj, T& visitor, float radius);
template<class T> static void VisitAllObjects(WorldObject const* obj, T& visitor, float radius);
template<class T> static void VisitGridObjects(float x, float y, Map* map, T& visitor, float radius);
template<class T> static void VisitWorldObjects(float x, float y, Map* map, T& visitor, float radius);
template<class T> static void VisitAllObjects(float x, float y, Map* map, T& visitor, float radius);
template<class T> static void VisitObjects(WorldObject const* obj, T& visitor, float radius);
template<class T> static void VisitObjects(float x, float y, Map* map, T& visitor, float radius);
private:
template<class T, class CONTAINER> void VisitCircle(TypeContainerVisitor<T, CONTAINER>&, Map&, CellCoord const&, CellCoord const&) const;
+2 -46
View File
@@ -162,7 +162,7 @@ inline void Cell::VisitCircle(TypeContainerVisitor<T, CONTAINER>& visitor, Map&
}
template<class T>
inline void Cell::VisitGridObjects(WorldObject const* center_obj, T& visitor, float radius)
inline void Cell::VisitObjects(WorldObject const* center_obj, T& visitor, float radius)
{
CellCoord p(Acore::ComputeCellCoord(center_obj->GetPositionX(), center_obj->GetPositionY()));
Cell cell(p);
@@ -172,29 +172,7 @@ inline void Cell::VisitGridObjects(WorldObject const* center_obj, T& visitor, fl
}
template<class T>
inline void Cell::VisitWorldObjects(WorldObject const* center_obj, T& visitor, float radius)
{
CellCoord p(Acore::ComputeCellCoord(center_obj->GetPositionX(), center_obj->GetPositionY()));
Cell cell(p);
TypeContainerVisitor<T, WorldTypeMapContainer> wnotifier(visitor);
cell.Visit(p, wnotifier, *center_obj->GetMap(), *center_obj, radius);
}
template<class T>
inline void Cell::VisitAllObjects(WorldObject const* center_obj, T& visitor, float radius)
{
CellCoord p(Acore::ComputeCellCoord(center_obj->GetPositionX(), center_obj->GetPositionY()));
Cell cell(p);
TypeContainerVisitor<T, WorldTypeMapContainer> wnotifier(visitor);
cell.Visit(p, wnotifier, *center_obj->GetMap(), *center_obj, radius);
TypeContainerVisitor<T, GridTypeMapContainer> gnotifier(visitor);
cell.Visit(p, gnotifier, *center_obj->GetMap(), *center_obj, radius);
}
template<class T>
inline void Cell::VisitGridObjects(float x, float y, Map* map, T& visitor, float radius)
inline void Cell::VisitObjects(float x, float y, Map* map, T& visitor, float radius)
{
CellCoord p(Acore::ComputeCellCoord(x, y));
Cell cell(p);
@@ -203,26 +181,4 @@ inline void Cell::VisitGridObjects(float x, float y, Map* map, T& visitor, float
cell.Visit(p, gnotifier, *map, x, y, radius);
}
template<class T>
inline void Cell::VisitWorldObjects(float x, float y, Map* map, T& visitor, float radius)
{
CellCoord p(Acore::ComputeCellCoord(x, y));
Cell cell(p);
TypeContainerVisitor<T, WorldTypeMapContainer> wnotifier(visitor);
cell.Visit(p, wnotifier, *map, x, y, radius);
}
template<class T>
inline void Cell::VisitAllObjects(float x, float y, Map* map, T& visitor, float radius)
{
CellCoord p(Acore::ComputeCellCoord(x, y));
Cell cell(p);
TypeContainerVisitor<T, WorldTypeMapContainer> wnotifier(visitor);
cell.Visit(p, wnotifier, *map, x, y, radius);
TypeContainerVisitor<T, GridTypeMapContainer> gnotifier(visitor);
cell.Visit(p, gnotifier, *map, x, y, radius);
}
#endif
-14
View File
@@ -35,7 +35,6 @@
template
<
class WORLD_OBJECT_TYPES,
class GRID_OBJECT_TYPES
>
class GridCell
@@ -43,12 +42,6 @@ class GridCell
public:
~GridCell() = default;
template<class SPECIFIC_OBJECT> void AddWorldObject(SPECIFIC_OBJECT* obj)
{
_worldObjects.template insert<SPECIFIC_OBJECT>(obj);
ASSERT(obj->IsInGrid());
}
template<class SPECIFIC_OBJECT> void AddGridObject(SPECIFIC_OBJECT* obj)
{
_gridObjects.template insert<SPECIFIC_OBJECT>(obj);
@@ -62,14 +55,7 @@ public:
visitor.Visit(_gridObjects);
}
// Visit world objects
template<class T>
void Visit(TypeContainerVisitor<T, TypeMapContainer<WORLD_OBJECT_TYPES> >& visitor)
{
visitor.Visit(_worldObjects);
}
private:
TypeMapContainer<GRID_OBJECT_TYPES> _gridObjects;
TypeMapContainer<WORLD_OBJECT_TYPES> _worldObjects;
};
#endif
+8 -8
View File
@@ -51,10 +51,11 @@ class ObjectGuid;
#define MAP_SIZE (SIZE_OF_GRIDS*MAX_NUMBER_OF_GRIDS)
#define MAP_HALFSIZE (MAP_SIZE/2)
// Creature used instead pet to simplify *::Visit templates (not required duplicate code for Creature->Pet case)
typedef TYPELIST_4(GameObject, Player, Creature/*pets*/, Corpse/*resurrectable*/) AllWorldObjectTypes;
typedef TYPELIST_4(GameObject, Creature/*except pets*/, DynamicObject, Corpse/*Bones*/) AllGridObjectTypes;
typedef TYPELIST_5(Creature, GameObject, DynamicObject, Pet, Corpse) AllMapStoredObjectTypes;
// List of object types stored in a map grid
typedef TYPELIST_5(GameObject, Player, Creature, Corpse, DynamicObject) AllMapGridStoredObjectTypes;
// List of object types stored on map level
typedef TYPELIST_4(Creature, GameObject, DynamicObject, Corpse) AllMapStoredObjectTypes;
typedef GridRefMgr<Corpse> CorpseMapType;
typedef GridRefMgr<Creature> CreatureMapType;
@@ -72,11 +73,10 @@ enum GridMapTypeMask
GRID_MAP_TYPE_MASK_ALL = 0x1F
};
typedef GridCell<AllWorldObjectTypes, AllGridObjectTypes> GridCellType;
typedef MapGrid<AllWorldObjectTypes, AllGridObjectTypes> MapGridType;
typedef GridCell<AllMapGridStoredObjectTypes> GridCellType;
typedef MapGrid<AllMapGridStoredObjectTypes> MapGridType;
typedef TypeMapContainer<AllGridObjectTypes> GridTypeMapContainer;
typedef TypeMapContainer<AllWorldObjectTypes> WorldTypeMapContainer;
typedef TypeMapContainer<AllMapGridStoredObjectTypes> GridTypeMapContainer;
typedef TypeUnorderedMapContainer<AllMapStoredObjectTypes, ObjectGuid> MapStoredObjectTypesContainer;
template<uint32 LIMIT>
+2 -4
View File
@@ -30,10 +30,8 @@ void GridObjectLoader::AddObjectHelper(Map* map, T* obj)
CellCoord cellCoord = Acore::ComputeCellCoord(obj->GetPositionX(), obj->GetPositionY());
Cell cell(cellCoord);
map->AddToGrid(obj, cell);
map->AddToGrid<T>(obj, cell);
obj->AddToWorld();
if (obj->isActiveObject())
map->AddToActive(obj);
}
void GridObjectLoader::LoadCreatures(CellGuidSet const& guid_set, Map* map)
@@ -55,7 +53,7 @@ void GridObjectLoader::LoadCreatures(CellGuidSet const& guid_set, Map* map)
{
// call MoveInLineOfSight for nearby grid creatures
Acore::AIRelocationNotifier notifier(*obj);
Cell::VisitGridObjects(obj, notifier, 60.f);
Cell::VisitObjects(obj, notifier, 60.f);
}
}
}
+2
View File
@@ -47,6 +47,7 @@ class GridObjectCleaner
{
public:
template<class T> void Visit(GridRefMgr<T>&);
void Visit(PlayerMapType&) { }
};
// Delete objects before deleting NGrid
@@ -54,6 +55,7 @@ class GridObjectUnloader
{
public:
void Visit(CorpseMapType&) { } // corpses are deleted with Map
void Visit(PlayerMapType&) { }
template<class T> void Visit(GridRefMgr<T>& m);
};
#endif
+3 -14
View File
@@ -25,13 +25,12 @@ class GridTerrainData;
template
<
class WORLD_OBJECT_TYPES,
class GRID_OBJECT_TYPES
>
class MapGrid
{
public:
typedef GridCell<WORLD_OBJECT_TYPES, GRID_OBJECT_TYPES> GridCellType;
typedef GridCell<GRID_OBJECT_TYPES> GridCellType;
MapGrid(uint16 const x, uint16 const y)
: _x(x), _y(y), _objectDataLoaded(false), _terrainData(nullptr) { }
@@ -45,16 +44,6 @@ public:
bool IsObjectDataLoaded() const { return _objectDataLoaded; }
void SetObjectDataLoaded() { _objectDataLoaded = true; }
template<class SPECIFIC_OBJECT> void AddWorldObject(uint16 const x, uint16 const y, SPECIFIC_OBJECT* obj)
{
GetOrCreateCell(x, y).AddWorldObject(obj);
}
template<class SPECIFIC_OBJECT> void RemoveWorldObject(uint16 const x, uint16 const y, SPECIFIC_OBJECT* obj)
{
GetOrCreateCell(x, y).RemoveWorldObject(obj);
}
template<class SPECIFIC_OBJECT> void AddGridObject(uint16 const x, uint16 const y, SPECIFIC_OBJECT* obj)
{
GetOrCreateCell(x, y).AddGridObject(obj);
@@ -92,7 +81,7 @@ public:
gridCell->Visit(visitor);
}
void link(GridRefMgr<MapGrid<WORLD_OBJECT_TYPES, GRID_OBJECT_TYPES>>* pTo)
void link(GridRefMgr<MapGrid<GRID_OBJECT_TYPES>>* pTo)
{
_gridReference.link(pTo, this);
}
@@ -145,7 +134,7 @@ private:
bool _objectDataLoaded;
std::array<std::array<std::unique_ptr<GridCellType>, MAX_NUMBER_OF_CELLS>, MAX_NUMBER_OF_CELLS> _cells; // N * N array
GridReference<MapGrid<WORLD_OBJECT_TYPES, GRID_OBJECT_TYPES>> _gridReference;
GridReference<MapGrid<GRID_OBJECT_TYPES>> _gridReference;
// Instances will share a copy of the parent maps terrainData
std::shared_ptr<GridTerrainData> _terrainData;
@@ -32,7 +32,6 @@ void VisibleNotifier::Visit(GameObjectMapType& m)
if (i_largeOnly != go->IsVisibilityOverridden())
continue;
vis_guids.erase(go->GetGUID());
i_player.UpdateVisibilityOf(go, i_data, i_visibleNow);
}
}
@@ -42,56 +41,66 @@ void VisibleNotifier::SendToSelf()
// at this moment i_clientGUIDs have guids that not iterate at grid level checks
// but exist one case when this possible and object not out of range: transports
if (Transport* transport = i_player.GetTransport())
{
for (Transport::PassengerSet::const_iterator itr = transport->GetPassengers().begin(); itr != transport->GetPassengers().end(); ++itr)
{
if (i_largeOnly != (*itr)->IsVisibilityOverridden())
continue;
if (vis_guids.find((*itr)->GetGUID()) != vis_guids.end())
switch ((*itr)->GetTypeId())
{
vis_guids.erase((*itr)->GetGUID());
case TYPEID_GAMEOBJECT:
i_player.UpdateVisibilityOf((*itr)->ToGameObject(), i_data, i_visibleNow);
break;
case TYPEID_PLAYER:
i_player.UpdateVisibilityOf((*itr)->ToPlayer(), i_data, i_visibleNow);
(*itr)->ToPlayer()->UpdateVisibilityOf(&i_player);
break;
case TYPEID_UNIT:
i_player.UpdateVisibilityOf((*itr)->ToCreature(), i_data, i_visibleNow);
break;
default:
break;
}
}
}
switch ((*itr)->GetTypeId())
VisibleWorldObjectsMap* visibleWorldObjects = i_player.GetObjectVisibilityContainer().GetVisibleWorldObjectsMap();
for (VisibleWorldObjectsMap::iterator itr = visibleWorldObjects->begin(); itr != visibleWorldObjects->end();)
{
WorldObject* obj = itr->second;
if (i_largeOnly != obj->IsVisibilityOverridden())
{
++itr;
continue;
}
// pussywizard: static transports are removed only in RemovePlayerFromMap and here if can no longer detect (eg. phase changed)
if (itr->first.IsTransport())
{
if (GameObject* staticTrans = obj->ToGameObject())
{
if (i_player.CanSeeOrDetect(staticTrans, false, true))
{
case TYPEID_GAMEOBJECT:
i_player.UpdateVisibilityOf((*itr)->ToGameObject(), i_data, i_visibleNow);
break;
case TYPEID_PLAYER:
i_player.UpdateVisibilityOf((*itr)->ToPlayer(), i_data, i_visibleNow);
(*itr)->ToPlayer()->UpdateVisibilityOf(&i_player);
break;
case TYPEID_UNIT:
i_player.UpdateVisibilityOf((*itr)->ToCreature(), i_data, i_visibleNow);
break;
default:
break;
++itr;
continue;
}
}
}
for (GuidUnorderedSet::const_iterator it = vis_guids.begin(); it != vis_guids.end(); ++it)
{
if (WorldObject* obj = ObjectAccessor::GetWorldObject(i_player, *it))
if (i_player.m_seer->IsWithinDist(obj, i_player.GetSightRange(obj), true))
{
if (i_largeOnly != obj->IsVisibilityOverridden())
continue;
++itr;
continue;
}
// pussywizard: static transports are removed only in RemovePlayerFromMap and here if can no longer detect (eg. phase changed)
if ((*it).IsTransport())
if (GameObject* staticTrans = i_player.GetMap()->GetGameObject(*it))
if (i_player.CanSeeOrDetect(staticTrans, false, true))
continue;
i_data.AddOutOfRangeGUID(obj->GetGUID());
i_player.m_clientGUIDs.erase(*it);
i_data.AddOutOfRangeGUID(*it);
if (Player* objPlayer = obj->ToPlayer())
objPlayer->UpdateVisibilityOf(&i_player);
if ((*it).IsPlayer())
{
Player* player = ObjectAccessor::FindPlayer(*it);
if (player && player->IsInMap(&i_player))
player->UpdateVisibilityOf(&i_player);
}
// Clean up references
itr = i_player.GetObjectVisibilityContainer().UnlinkVisibilityFromPlayer(obj, itr);
}
if (!i_data.HasData())
@@ -170,7 +179,6 @@ void PlayerRelocationNotifier::Visit(PlayerMapType& m)
for (PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
{
Player* player = iter->GetSource();
vis_guids.erase(player->GetGUID());
i_player.UpdateVisibilityOf(player, i_data, i_visibleNow);
player->UpdateVisibilityOf(&i_player); // this notifier with different Visit(PlayerMapType&) than VisibleNotifier is needed to update visibility of self for other players when we move (eg. stealth detection changes)
}
@@ -208,6 +216,23 @@ void AIRelocationNotifier::Visit(CreatureMapType& m)
}
}
// Uses visibility map
void MessageDistDeliverer::Visit(VisiblePlayersMap const& m)
{
for (auto const& kvPair : m)
{
Player const* target = kvPair.second;
if (i_distSq != 0.0f && target->m_seer->GetExactDist2dSq(i_source) > i_distSq)
continue;
// @todo: Might not need this check anymore
if (skipped_receiver == target)
continue;
target->SendDirectMessage(i_message);
}
}
void MessageDistDeliverer::Visit(PlayerMapType& m)
{
for (PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
@@ -43,14 +43,13 @@ namespace Acore
struct VisibleNotifier
{
Player& i_player;
GuidUnorderedSet vis_guids;
std::vector<Unit*>& i_visibleNow;
bool i_gobjOnly;
bool i_largeOnly;
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)
i_player(player), i_visibleNow(player.m_newVisible), i_gobjOnly(gobjOnly), i_largeOnly(largeOnly)
{
i_visibleNow.clear();
}
@@ -111,6 +110,7 @@ namespace Acore
, skipped_receiver(skipped), required3dDist(req3dDist)
{
}
void Visit(VisiblePlayersMap const& m);
void Visit(PlayerMapType& m);
void Visit(CreatureMapType& m);
void Visit(DynamicObjectMapType& m);
@@ -37,7 +37,6 @@ inline void Acore::VisibleNotifier::Visit(GridRefMgr<T>& m)
if (i_largeOnly != iter->GetSource()->IsVisibilityOverridden())
continue;
vis_guids.erase(iter->GetSource()->GetGUID());
i_player.UpdateVisibilityOf(iter->GetSource(), i_data, i_visibleNow);
}
}
@@ -1175,7 +1175,6 @@ void WorldSession::HandlePlayerLoginToCharInWorld(Player* pCurrChar)
pCurrChar->GetMap()->SendInitTransports(pCurrChar);
pCurrChar->GetMap()->SendInitSelf(pCurrChar);
pCurrChar->GetMap()->SendZoneDynamicInfo(pCurrChar);
pCurrChar->m_clientGUIDs.clear();
pCurrChar->UpdateObjectVisibility(false);
pCurrChar->CleanupChannels();
+1 -1
View File
@@ -796,7 +796,7 @@ void WorldSession::HandleTextEmoteOpcode(WorldPacket& recvData)
Acore::EmoteChatBuilder emote_builder(*GetPlayer(), text_emote, emoteNum, unit);
Acore::LocalizedPacketDo<Acore::EmoteChatBuilder > emote_do(emote_builder);
Acore::PlayerDistWorker<Acore::LocalizedPacketDo<Acore::EmoteChatBuilder > > emote_worker(GetPlayer(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), emote_do);
Cell::VisitWorldObjects(GetPlayer(), emote_worker, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE));
Cell::VisitObjects(GetPlayer(), emote_worker, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE));
GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE, text_emote, 0, unit);
+19 -126
View File
@@ -55,16 +55,6 @@ Map::~Map()
sScriptMgr->OnDestroyMap(this);
while (!i_worldObjects.empty())
{
WorldObject* obj = *i_worldObjects.begin();
ASSERT(obj->IsWorldObject());
LOG_DEBUG("maps", "Map::~Map: WorldObject TypeId is not a corpse! ({})", static_cast<uint8>(obj->GetTypeId()));
//ASSERT(obj->IsCorpse());
obj->RemoveFromWorld();
obj->ResetMap();
}
if (!m_scriptSchedule.empty())
sScriptMgr->DecreaseScheduledScriptCount(m_scriptSchedule.size());
@@ -73,8 +63,7 @@ Map::~Map()
Map::Map(uint32 id, uint32 InstanceId, uint8 SpawnMode, Map* _parent) :
_mapGridManager(this), i_mapEntry(sMapStore.LookupEntry(id)), i_spawnMode(SpawnMode), i_InstanceId(InstanceId),
m_unloadTimer(0), m_VisibleDistance(DEFAULT_VISIBILITY_DISTANCE),
_instanceResetPeriod(0), m_activeNonPlayersIter(m_activeNonPlayers.end()),
m_unloadTimer(0), m_VisibleDistance(DEFAULT_VISIBILITY_DISTANCE), _instanceResetPeriod(0),
_transportsUpdateIter(_transports.end()), i_scriptLock(false), _defaultLight(GetDefaultMapLight(id))
{
m_parentMap = (_parent ? _parent : this);
@@ -117,20 +106,16 @@ template<class T>
void Map::AddToGrid(T* obj, Cell const& cell)
{
MapGridType* grid = GetMapGrid(cell.GridX(), cell.GridY());
if (obj->IsWorldObject())
grid->AddWorldObject<T>(cell.CellX(), cell.CellY(), obj);
else
grid->AddGridObject<T>(cell.CellX(), cell.CellY(), obj);
grid->AddGridObject<T>(cell.CellX(), cell.CellY(), obj);
obj->SetCurrentCell(cell);
}
template<>
void Map::AddToGrid(Creature* obj, Cell const& cell)
{
MapGridType* grid = GetMapGrid(cell.GridX(), cell.GridY());
if (obj->IsWorldObject())
grid->AddWorldObject(cell.CellX(), cell.CellY(), obj);
else
grid->AddGridObject(cell.CellX(), cell.CellY(), obj);
grid->AddGridObject(cell.CellX(), cell.CellY(), obj);
obj->SetCurrentCell(cell);
}
@@ -145,15 +130,10 @@ void Map::AddToGrid(GameObject* obj, Cell const& cell)
}
template<>
void Map::AddToGrid(DynamicObject* obj, Cell const& cell)
void Map::AddToGrid(Player* obj, Cell const& cell)
{
MapGridType* grid = GetMapGrid(cell.GridX(), cell.GridY());
if (obj->IsWorldObject())
grid->AddWorldObject(cell.CellX(), cell.CellY(), obj);
else
grid->AddGridObject(cell.CellX(), cell.CellY(), obj);
obj->SetCurrentCell(cell);
grid->AddGridObject(cell.CellX(), cell.CellY(), obj);
}
template<>
@@ -167,12 +147,7 @@ void Map::AddToGrid(Corpse* obj, Cell const& cell)
// so we need to explicitly check it here (Map::AddToGrid is only called from Player::BuildPlayerRepop, not from ObjectGridLoader)
// to avoid failing an assertion in GridObject::AddToGrid
if (grid->IsObjectDataLoaded())
{
if (obj->IsWorldObject())
grid->AddWorldObject(cell.CellX(), cell.CellY(), obj);
else
grid->AddGridObject(cell.CellX(), cell.CellY(), obj);
}
grid->AddGridObject(cell.CellX(), cell.CellY(), obj);
}
template<class T>
@@ -289,7 +264,6 @@ bool Map::AddPlayerToMap(Player* player)
SendInitSelf(player);
SendZoneDynamicInfo(player);
player->m_clientGUIDs.clear();
player->UpdateObjectVisibility(false);
if (player->IsAlive())
@@ -358,9 +332,6 @@ bool Map::AddToMap(T* obj, bool checkTransport)
InitializeObject(obj);
if (obj->isActiveObject())
AddToActive(obj);
//something, such as vehicle, needs to be update immediately
//also, trigger needs to cast spell, if not update, cannot see visual
obj->UpdateObjectVisibility(true);
@@ -394,9 +365,6 @@ bool Map::AddToMap(MotionTransport* obj, bool /*checkTransport*/)
obj->AddToWorld();
if (obj->isActiveObject())
AddToActive(obj);
_transports.insert(obj);
// Broadcast creation to players
@@ -512,19 +480,6 @@ void Map::Update(const uint32 t_diff, const uint32 s_diff, bool /*thread*/)
}
}
if (_updatableObjectListRecheckTimer.Passed())
{
// Mark all cells near active objects
for (m_activeNonPlayersIter = m_activeNonPlayers.begin(); m_activeNonPlayersIter != m_activeNonPlayers.end(); ++m_activeNonPlayersIter)
{
WorldObject* obj = *m_activeNonPlayersIter;
if (!obj || !obj->IsInWorld())
continue;
MarkNearbyCellsOf(obj);
}
}
UpdateNonPlayerObjects(t_diff);
SendObjectUpdates();
@@ -676,13 +631,9 @@ void Map::RemovePlayerFromMap(Player* player, bool remove)
player->UpdateZone(MAP_INVALID_ZONE, 0);
player->getHostileRefMgr().deleteReferences(true); // pussywizard: multithreading crashfix
bool inWorld = player->IsInWorld();
player->RemoveFromWorld();
SendRemoveTransports(player);
if (!inWorld) // pussywizard: if was in world, RemoveFromWorld() called DestroyForNearbyPlayers()
player->DestroyForNearbyPlayers(); // pussywizard: previous player->UpdateObjectVisibility(true)
if (player->IsInGrid())
player->RemoveFromGrid();
else
@@ -702,15 +653,8 @@ void Map::AfterPlayerUnlinkFromMap()
template<class T>
void Map::RemoveFromMap(T* obj, bool remove)
{
bool inWorld = obj->IsInWorld() && obj->GetTypeId() >= TYPEID_UNIT && obj->GetTypeId() <= TYPEID_GAMEOBJECT;
obj->RemoveFromWorld();
if (obj->isActiveObject())
RemoveFromActive(obj);
if (!inWorld) // pussywizard: if was in world, RemoveFromWorld() called DestroyForNearbyPlayers()
obj->DestroyForNearbyPlayers(); // pussywizard: previous player->UpdateObjectVisibility()
obj->RemoveFromGrid();
obj->ResetMap();
@@ -726,8 +670,6 @@ template<>
void Map::RemoveFromMap(MotionTransport* obj, bool remove)
{
obj->RemoveFromWorld();
if (obj->isActiveObject())
RemoveFromActive(obj);
Map::PlayerList const& players = GetPlayers();
if (!players.IsEmpty())
@@ -1653,6 +1595,9 @@ void Map::SendInitTransports(Player* player)
if (*itr != player->GetTransport())
(*itr)->BuildCreateUpdateBlockForPlayer(&transData, player);
if (!transData.HasData())
return;
WorldPacket packet;
transData.BuildPacket(packet);
player->GetSession()->SendPacket(&packet);
@@ -1667,7 +1612,7 @@ void Map::SendRemoveTransports(Player* player)
(*itr)->BuildOutOfRangeUpdateBlock(&transData);
// pussywizard: remove static transports from client
for (GuidUnorderedSet::const_iterator it = player->m_clientGUIDs.begin(); it != player->m_clientGUIDs.end(); )
/*for (GuidUnorderedSet::const_iterator it = player->m_clientGUIDs.begin(); it != player->m_clientGUIDs.end(); )
{
if ((*it).IsTransport())
{
@@ -1676,7 +1621,10 @@ void Map::SendRemoveTransports(Player* player)
}
else
++it;
}
}*/
if (!transData.HasData())
return;
WorldPacket packet;
transData.BuildPacket(packet);
@@ -1686,7 +1634,6 @@ void Map::SendRemoveTransports(Player* player)
void Map::SendObjectUpdates()
{
UpdateDataMapType update_players;
UpdatePlayerSet player_set;
while (!_updateObjects.empty())
{
@@ -1694,7 +1641,7 @@ void Map::SendObjectUpdates()
ASSERT(obj->IsInWorld());
_updateObjects.erase(_updateObjects.begin());
obj->BuildUpdate(update_players, player_set);
obj->BuildUpdate(update_players);
}
WorldPacket packet; // here we allocate a std::vector with a size of 0x10000
@@ -1830,60 +1777,6 @@ void Map::SendToPlayers(WorldPacket const* data) const
itr->GetSource()->GetSession()->SendPacket(data);
}
template<class T>
void Map::AddToActive(T* obj)
{
AddToActiveHelper(obj);
}
template <>
void Map::AddToActive(Creature* c)
{
AddToActiveHelper(c);
}
template<>
void Map::AddToActive(DynamicObject* d)
{
AddToActiveHelper(d);
}
template<>
void Map::AddToActive(GameObject* d)
{
AddToActiveHelper(d);
}
template<>
void Map::AddToActive(Corpse* /*c*/)
{
// do nothing for corpses
}
template<class T>
void Map::RemoveFromActive(T* obj)
{
RemoveFromActiveHelper(obj);
}
template <>
void Map::RemoveFromActive(Creature* c)
{
RemoveFromActiveHelper(c);
}
template<>
void Map::RemoveFromActive(DynamicObject* obj)
{
RemoveFromActiveHelper(obj);
}
template<>
void Map::RemoveFromActive(GameObject* obj)
{
RemoveFromActiveHelper(obj);
}
template bool Map::AddToMap(Corpse*, bool);
template bool Map::AddToMap(Creature*, bool);
template bool Map::AddToMap(GameObject*, bool);
@@ -2404,7 +2297,7 @@ GameObject* Map::GetGameObject(ObjectGuid const guid)
Pet* Map::GetPet(ObjectGuid const guid)
{
return _objectsStore.Find<Pet>(guid);
return dynamic_cast<Pet*>(_objectsStore.Find<Creature>(guid));
}
Transport* Map::GetTransport(ObjectGuid guid)
@@ -2692,7 +2585,7 @@ void Map::RemoveCorpse(Corpse* corpse)
ASSERT(corpse);
GridCoord const gridCoord = Acore::ComputeGridCoord(corpse->GetPositionX(), corpse->GetPositionY());
corpse->DestroyForNearbyPlayers();
corpse->DestroyForVisiblePlayers();
if (corpse->IsInGrid())
RemoveFromMap(corpse, false);
else
+1 -41
View File
@@ -315,9 +315,6 @@ public:
[[nodiscard]] bool HavePlayers() const { return !m_mapRefMgr.IsEmpty(); }
[[nodiscard]] uint32 GetPlayersCountExceptGMs() const;
void AddWorldObject(WorldObject* obj) { i_worldObjects.insert(obj); }
void RemoveWorldObject(WorldObject* obj) { i_worldObjects.erase(obj); }
void SendToPlayers(WorldPacket const* data) const;
typedef MapRefMgr PlayerList;
@@ -327,14 +324,6 @@ public:
void ScriptsStart(std::map<uint32, std::multimap<uint32, ScriptInfo> > const& scripts, uint32 id, Object* source, Object* target);
void ScriptCommandStart(ScriptInfo const& script, uint32 delay, Object* source, Object* target);
// must called with AddToWorld
template<class T>
void AddToActive(T* obj);
// must called with RemoveFromWorld
template<class T>
void RemoveFromActive(T* obj);
CreatureGroupHolderType CreatureGroupHolder;
void UpdateIteratorBack(Player* player);
@@ -490,10 +479,7 @@ public:
_updateObjects.erase(obj);
}
std::size_t GetActiveNonPlayersCount() const
{
return m_activeNonPlayers.size();
}
size_t GetUpdateObjectsCount() const { return _updateObjects.size(); }
virtual std::string GetDebugInfo() const;
@@ -549,10 +535,6 @@ protected:
MapRefMgr m_mapRefMgr;
MapRefMgr::iterator m_mapRefIter;
typedef std::set<WorldObject*> ActiveNonPlayers;
ActiveNonPlayers m_activeNonPlayers;
ActiveNonPlayers::iterator m_activeNonPlayersIter;
// Objects that must update even in inactive grids without activating them
TransportsContainer _transports;
TransportsContainer::iterator _transportsUpdateIter;
@@ -575,7 +557,6 @@ private:
bool i_scriptLock;
std::unordered_set<WorldObject*> i_objectsToRemove;
std::unordered_set<WorldObject*> i_worldObjects;
typedef std::multimap<time_t, ScriptAction> ScriptScheduleMap;
ScriptScheduleMap m_scriptSchedule;
@@ -583,27 +564,6 @@ private:
template<class T>
void DeleteFromWorld(T*);
void AddToActiveHelper(WorldObject* obj)
{
m_activeNonPlayers.insert(obj);
}
void RemoveFromActiveHelper(WorldObject* obj)
{
// Map::Update for active object in proccess
if (m_activeNonPlayersIter != m_activeNonPlayers.end())
{
ActiveNonPlayers::iterator itr = m_activeNonPlayers.find(obj);
if (itr == m_activeNonPlayers.end())
return;
if (itr == m_activeNonPlayersIter)
++m_activeNonPlayersIter;
m_activeNonPlayers.erase(itr);
}
else
m_activeNonPlayers.erase(obj);
}
void UpdateNonPlayerObjects(uint32 const diff);
void _AddObjectToUpdateList(WorldObject* obj);
+1 -1
View File
@@ -336,7 +336,7 @@ bool OPvPCapturePoint::Update(uint32 diff)
std::list<Player*> players;
Acore::AnyPlayerInObjectRangeCheck checker(_capturePoint, radius);
Acore::PlayerListSearcher<Acore::AnyPlayerInObjectRangeCheck> searcher(_capturePoint, players, checker);
Cell::VisitWorldObjects(_capturePoint, searcher, radius);
Cell::VisitObjects(_capturePoint, searcher, radius);
for (auto& itr : players)
{
@@ -2838,7 +2838,7 @@ void AuraEffect::HandleFeignDeath(AuraApplication const* aurApp, uint8 mode, boo
UnitList targets;
Acore::AnyUnfriendlyUnitInObjectRangeCheck u_check(target, target, target->GetVisibilityRange()); // no VISIBILITY_COMPENSATION, distance is enough
Acore::UnitListSearcher<Acore::AnyUnfriendlyUnitInObjectRangeCheck> searcher(target, targets, u_check);
Cell::VisitAllObjects(target, searcher, target->GetMap()->GetVisibilityRange());
Cell::VisitObjects(target, searcher, target->GetMap()->GetVisibilityRange());
for (UnitList::iterator iter = targets.begin(); iter != targets.end(); ++iter)
{
if (!(*iter)->HasUnitState(UNIT_STATE_CASTING))
@@ -5631,7 +5631,7 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool
Player* player = nullptr;
Acore::AnyPlayerInObjectRangeCheck checker(target, 10.0f);
Acore::PlayerSearcher<Acore::AnyPlayerInObjectRangeCheck> searcher(target, player, checker);
Cell::VisitWorldObjects(target, searcher, 10.0f);
Cell::VisitObjects(target, searcher, 10.0f);
if (player && player->GetGUID() != target->GetGUID())
target->CastSpell(player, 52921, true);
@@ -7365,7 +7365,7 @@ void AuraEffect::HandleRaidProcFromChargeWithValueAuraProc(AuraApplication* aurA
Unit* triggerTarget = nullptr;
Acore::MostHPMissingGroupInRange u_check(target, radius, 0);
Acore::UnitLastSearcher<Acore::MostHPMissingGroupInRange> searcher(target, triggerTarget, u_check);
Cell::VisitAllObjects(target, searcher, radius);
Cell::VisitObjects(target, searcher, radius);
if (triggerTarget)
{
+6 -6
View File
@@ -2823,7 +2823,7 @@ void UnitAura::FillTargetMap(std::map<Unit*, uint8>& targets, Unit* caster)
targetList.push_back(GetUnitOwner());
Acore::AnyGroupedUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius, GetSpellInfo()->Effects[effIndex].Effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID);
Acore::UnitListSearcher<Acore::AnyGroupedUnitInObjectRangeCheck> searcher(GetUnitOwner(), targetList, u_check);
Cell::VisitAllObjects(GetUnitOwner(), searcher, radius);
Cell::VisitObjects(GetUnitOwner(), searcher, radius);
break;
}
case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND:
@@ -2831,14 +2831,14 @@ void UnitAura::FillTargetMap(std::map<Unit*, uint8>& targets, Unit* caster)
targetList.push_back(GetUnitOwner());
Acore::AnyFriendlyUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius);
Acore::UnitListSearcher<Acore::AnyFriendlyUnitInObjectRangeCheck> searcher(GetUnitOwner(), targetList, u_check);
Cell::VisitAllObjects(GetUnitOwner(), searcher, radius);
Cell::VisitObjects(GetUnitOwner(), searcher, radius);
break;
}
case SPELL_EFFECT_APPLY_AREA_AURA_ENEMY:
{
Acore::AnyAoETargetUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius); // No GetCharmer in searcher
Acore::UnitListSearcher<Acore::AnyAoETargetUnitInObjectRangeCheck> searcher(GetUnitOwner(), targetList, u_check);
Cell::VisitAllObjects(GetUnitOwner(), searcher, radius);
Cell::VisitObjects(GetUnitOwner(), searcher, radius);
break;
}
case SPELL_EFFECT_APPLY_AREA_AURA_PET:
@@ -2900,7 +2900,7 @@ void DynObjAura::FillTargetMap(std::map<Unit*, uint8>& targets, Unit* /*caster*/
{
Acore::AnyFriendlyUnitInObjectRangeCheck u_check(GetDynobjOwner(), dynObjOwnerCaster, radius);
Acore::UnitListSearcher<Acore::AnyFriendlyUnitInObjectRangeCheck> searcher(GetDynobjOwner(), targetList, u_check);
Cell::VisitAllObjects(GetDynobjOwner(), searcher, radius);
Cell::VisitObjects(GetDynobjOwner(), searcher, radius);
}
// pussywizard: TARGET_DEST_DYNOBJ_NONE is supposed to search for both friendly and unfriendly targets, so for any unit
// what about EffectImplicitTargetA?
@@ -2908,13 +2908,13 @@ void DynObjAura::FillTargetMap(std::map<Unit*, uint8>& targets, Unit* /*caster*/
{
Acore::AnyAttackableUnitExceptForOriginalCasterInObjectRangeCheck u_check(GetDynobjOwner(), dynObjOwnerCaster, radius);
Acore::UnitListSearcher<Acore::AnyAttackableUnitExceptForOriginalCasterInObjectRangeCheck> searcher(GetDynobjOwner(), targetList, u_check);
Cell::VisitAllObjects(GetDynobjOwner(), searcher, radius);
Cell::VisitObjects(GetDynobjOwner(), searcher, radius);
}
else
{
Acore::AnyAoETargetUnitInObjectRangeCheck u_check(GetDynobjOwner(), dynObjOwnerCaster, radius);
Acore::UnitListSearcher<Acore::AnyAoETargetUnitInObjectRangeCheck> searcher(GetDynobjOwner(), targetList, u_check);
Cell::VisitAllObjects(GetDynobjOwner(), searcher, radius);
Cell::VisitObjects(GetDynobjOwner(), searcher, radius);
}
for (UnitList::iterator itr = targetList.begin(); itr != targetList.end(); ++itr)
+1 -18
View File
@@ -2161,24 +2161,7 @@ void Spell::SearchTargets(SEARCHER& searcher, uint32 containerMask, Unit* refere
if (!containerMask)
return;
// search world and grid for possible targets
bool searchInGrid = containerMask & (GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_GAMEOBJECT);
bool searchInWorld = containerMask & (GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER | GRID_MAP_TYPE_MASK_CORPSE);
if (searchInGrid || searchInWorld)
{
float x, y;
x = pos->GetPositionX();
y = pos->GetPositionY();
Map* map = referer->GetMap();
if (searchInWorld)
Cell::VisitWorldObjects(x, y, map, searcher, radius);
if (searchInGrid)
Cell::VisitGridObjects(x, y, map, searcher, radius);
}
Cell::VisitObjects(pos->GetPositionX(), pos->GetPositionY(), referer->GetMap(), searcher, radius);
}
WorldObject* Spell::SearchNearbyTarget(float range, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList* condList)
+5 -5
View File
@@ -1854,7 +1854,7 @@ void Spell::EffectPersistentAA(SpellEffIndex effIndex)
// Caster not in world, might be spell triggered from aura removal
if (!caster->IsInWorld() || !caster->FindMap() || !ObjectAccessor::GetUnit(*caster, caster->GetGUID())) // pussywizard: temporary crash fix (FindMap and GetUnit are mine)
return;
DynamicObject* dynObj = new DynamicObject(false);
DynamicObject* dynObj = new DynamicObject();
if (!dynObj->CreateDynamicObject(caster->GetMap()->GenerateLowGuid<HighGuid::DynamicObject>(), caster, m_spellInfo->Id, *destTarget, radius, DYNAMIC_OBJECT_AREA_SPELL))
{
delete dynObj;
@@ -2731,7 +2731,7 @@ void Spell::EffectAddFarsight(SpellEffIndex effIndex)
// Remove old farsight if exist
bool updateViewerVisibility = m_caster->RemoveDynObject(m_spellInfo->Id);
DynamicObject* dynObj = new DynamicObject(false);
DynamicObject* dynObj = new DynamicObject();
if (!dynObj->CreateDynamicObject(m_caster->GetMap()->GenerateLowGuid<HighGuid::DynamicObject>(), m_caster, m_spellInfo->Id, *destTarget, radius, DYNAMIC_OBJECT_FARSIGHT_FOCUS))
{
delete dynObj;
@@ -4043,7 +4043,7 @@ void Spell::EffectSanctuary(SpellEffIndex /*effIndex*/)
UnitList targets;
Acore::AnyUnfriendlyUnitInObjectRangeCheck u_check(unitTarget, unitTarget, unitTarget->GetVisibilityRange()); // no VISIBILITY_COMPENSATION, distance is enough
Acore::UnitListSearcher<Acore::AnyUnfriendlyUnitInObjectRangeCheck> searcher(unitTarget, targets, u_check);
Cell::VisitAllObjects(unitTarget, searcher, unitTarget->GetVisibilityRange());
Cell::VisitObjects(unitTarget, searcher, unitTarget->GetVisibilityRange());
for (UnitList::iterator iter = targets.begin(); iter != targets.end(); ++iter)
{
if (!(*iter)->HasUnitState(UNIT_STATE_CASTING))
@@ -4778,7 +4778,7 @@ void Spell::EffectForceDeselect(SpellEffIndex /*effIndex*/)
float dist = m_caster->GetVisibilityRange() + VISIBILITY_COMPENSATION;
Acore::MessageDistDelivererToHostile notifier(m_caster, &data, dist);
Cell::VisitWorldObjects(m_caster, notifier, dist);
Cell::VisitObjects(m_caster, notifier, dist);
// xinef: we should also force pets to remove us from current target
Unit::AttackerSet attackerSet;
@@ -4803,7 +4803,7 @@ void Spell::EffectForceDeselect(SpellEffIndex /*effIndex*/)
UnitList targets;
Acore::AnyUnfriendlyUnitInObjectRangeCheck u_check(m_caster, m_caster, m_caster->GetVisibilityRange()); // no VISIBILITY_COMPENSATION, distance is enough
Acore::UnitListSearcher<Acore::AnyUnfriendlyUnitInObjectRangeCheck> searcher(m_caster, targets, u_check);
Cell::VisitAllObjects(m_caster, searcher, m_caster->GetVisibilityRange());
Cell::VisitObjects(m_caster, searcher, m_caster->GetVisibilityRange());
for (UnitList::iterator iter = targets.begin(); iter != targets.end(); ++iter)
{
if (!(*iter)->HasUnitState(UNIT_STATE_CASTING))
+1 -1
View File
@@ -251,7 +251,7 @@ void CreatureTextMgr::SendChatPacket(WorldObject* source, Builder const& builder
dist = 250.0f;
Acore::PlayerDistWorker<CreatureTextLocalizer<Builder> > worker(source, dist, localizer);
Cell::VisitWorldObjects(source, worker, dist);
Cell::VisitObjects(source, worker, dist);
}
#endif