Skip to content

Commit

Permalink
feat(Core/Grids): Implement visibility notifier (azerothcore#15919)
Browse files Browse the repository at this point in the history
* Cherry-picked from TrinityCore (unable to find author)
  • Loading branch information
AGandrup authored Sep 28, 2023
1 parent 29af6cc commit 2779833
Show file tree
Hide file tree
Showing 33 changed files with 1,249 additions and 505 deletions.
25 changes: 16 additions & 9 deletions src/server/apps/worldserver/worldserver.conf.dist
Original file line number Diff line number Diff line change
Expand Up @@ -939,6 +939,13 @@ ClientCacheVersion = 0

SessionAddDelay = 10000

#
# GridCleanUpDelay
# Description: Time (in milliseconds) grid clean up delay.
# Default: 300000 - (5 minutes)

GridCleanUpDelay = 300000

#
# CloseIdleConnections
# Description: Automatically close idle connections.
Expand Down Expand Up @@ -1244,17 +1251,17 @@ Visibility.GroupMode = 1
# Visibility.Distance.Instances
# Visibility.Distance.BGArenas
# Description: Visibility distance to see other players or gameobjects.
# Visibility on continents on retail ~90 yards. In BG/Arenas ~180.
# For instances default ~120.
# Max limited by active player zone: ~ 333
# Visibility on continents on retail ~100 yards. In BG/Arenas ~533.
# For instances default ~170.
# Max limited by grid size: 533.33333
# Min limit is max aggro radius (45) * Rate.Creature.Aggro
# Default: 90 - (Visibility.Distance.Continents)
# 120 - (Visibility.Distance.Instances)
# 180 - (Visibility.Distance.BGArenas)
# Default: 100 - (Visibility.Distance.Continents)
# 170 - (Visibility.Distance.Instances)
# 533 - (Visibility.Distance.BGArenas)

Visibility.Distance.Continents = 90
Visibility.Distance.Instances = 120
Visibility.Distance.BGArenas = 180
Visibility.Distance.Continents = 100
Visibility.Distance.Instances = 170
Visibility.Distance.BGArenas = 533

#
# Visibility.Notify.Period.OnContinents
Expand Down
2 changes: 1 addition & 1 deletion src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,6 @@ void BattlegroundAB::ApplyPhaseMask()
for (auto const& itr : bgPlayerMap)
{
itr.second->SetPhaseMask(phaseMask, false);
itr.second->UpdateObjectVisibility(true, false);
itr.second->UpdateObjectVisibility(true);
}
}
18 changes: 7 additions & 11 deletions src/server/game/Entities/Creature/Creature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -365,17 +365,15 @@ void Creature::RemoveCorpse(bool setSpawnTime, bool skipVisibility)
//SaveRespawnTime();
}

float x, y, z, o;
GetRespawnPosition(x, y, z, &o);
SetHomePosition(x, y, z, o);
SetPosition(x, y, z, o);

// xinef: relocate notifier
m_last_notify_position.Relocate(-5000.0f, -5000.0f, -5000.0f, 0.0f);

// pussywizard: if corpse was removed during falling then the falling will continue after respawn, so stop falling is such case
if (IsFalling())
StopMoving();

float x, y, z, o;
GetRespawnPosition(x, y, z, &o);
UpdateAllowedPositionZ(x, y, z);
SetHomePosition(x, y, z, o);
GetMap()->CreatureRelocation(this, x, y, z, o);
}

/**
Expand Down Expand Up @@ -2077,9 +2075,7 @@ void Creature::Respawn(bool force)
m_respawnedTime = GameTime::GetGameTime().count();
}
m_respawnedTime = GameTime::GetGameTime().count();
// xinef: relocate notifier, fixes npc appearing in corpse position after forced respawn (instead of spawn)
m_last_notify_position.Relocate(-5000.0f, -5000.0f, -5000.0f, 0.0f);
UpdateObjectVisibility(false);
UpdateObjectVisibility();
}

void Creature::ForcedDespawn(uint32 timeMSToDespawn, Seconds forceRespawnTimer)
Expand Down
27 changes: 3 additions & 24 deletions src/server/game/Entities/Object/Object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ constexpr float VisibilityDistances[AsUnderlyingType(VisibilityDistanceType::Max
VISIBILITY_DISTANCE_SMALL,
VISIBILITY_DISTANCE_LARGE,
VISIBILITY_DISTANCE_GIGANTIC,
VISIBILITY_DISTANCE_INFINITE
MAX_VISIBILITY_DISTANCE
};

Object::Object() : m_PackGUID(sizeof(uint64) + 1)
Expand Down Expand Up @@ -2922,7 +2922,7 @@ void WorldObject::DestroyForNearbyPlayers()
}
}

void WorldObject::UpdateObjectVisibility(bool /*forced*/, bool /*fromUpdate*/)
void WorldObject::UpdateObjectVisibility(bool /*forced*/)
{
//updates object's visibility for nearby players
Acore::VisibleChangesNotifier notifier(*this);
Expand All @@ -2931,28 +2931,7 @@ void WorldObject::UpdateObjectVisibility(bool /*forced*/, bool /*fromUpdate*/)

void WorldObject::AddToNotify(uint16 f)
{
if (!(m_notifyflags & f))
if (Unit* u = ToUnit())
{
if (f & NOTIFY_VISIBILITY_CHANGED)
{
uint32 EVENT_VISIBILITY_DELAY = u->FindMap() ? DynamicVisibilityMgr::GetVisibilityNotifyDelay(u->FindMap()->GetEntry()->map_type) : 1000;

uint32 diff = getMSTimeDiff(u->m_last_notify_mstime, GameTime::GetGameTimeMS().count());
if (diff >= EVENT_VISIBILITY_DELAY / 2)
EVENT_VISIBILITY_DELAY /= 2;
else
EVENT_VISIBILITY_DELAY -= diff;
u->m_delayed_unit_relocation_timer = EVENT_VISIBILITY_DELAY;
u->m_last_notify_mstime = GameTime::GetGameTimeMS().count() + EVENT_VISIBILITY_DELAY - 1;
}
else if (f & NOTIFY_AI_RELOCATION)
{
u->m_delayed_unit_ai_notify_timer = u->FindMap() ? DynamicVisibilityMgr::GetAINotifyDelay(u->FindMap()->GetEntry()->map_type) : 500;
}

m_notifyflags |= f;
}
m_notifyflags |= f;
}

struct WorldObjectChangeAccumulator
Expand Down
17 changes: 13 additions & 4 deletions src/server/game/Entities/Object/Object.h
Original file line number Diff line number Diff line change
Expand Up @@ -379,14 +379,23 @@ class MovableMapObject
template<class T> friend class RandomMovementGenerator;

protected:
MovableMapObject() = default;
MovableMapObject() : _moveState(MAP_OBJECT_CELL_MOVE_NONE)
{
_newPosition.Relocate(0.0f, 0.0f, 0.0f, 0.0f);
}

private:
Cell _currentCell;
[[nodiscard]] Cell const& GetCurrentCell() const { return _currentCell; }
void SetCurrentCell(Cell const& cell) { _currentCell = cell; }

Cell _currentCell;
MapObjectCellMoveState _moveState{MAP_OBJECT_CELL_MOVE_NONE};
MapObjectCellMoveState _moveState;
Position _newPosition;
void SetNewCellPosition(float x, float y, float z, float o)
{
_moveState = MAP_OBJECT_CELL_MOVE_ACTIVE;
_newPosition.Relocate(x, y, z, o);
}
};

class WorldObject : public Object, public WorldLocation
Expand Down Expand Up @@ -538,7 +547,7 @@ class WorldObject : public Object, public WorldLocation
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 UpdateObjectVisibility(bool forced = true);
void BuildUpdate(UpdateDataMapType& data_map, UpdatePlayerSet& player_set) override;
void GetCreaturesWithEntryInRange(std::list<Creature*>& creatureList, float radius, uint32 entry);

Expand Down
5 changes: 2 additions & 3 deletions src/server/game/Entities/Object/ObjectDefines.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,15 @@
#define VISIBILITY_INC_FOR_GOBJECTS 30.0f // pussywizard
#define SPELL_SEARCHER_COMPENSATION 30.0f // increase searchers size in case we have large npc near cell border
#define TRADE_DISTANCE 11.11f
#define MAX_VISIBILITY_DISTANCE 250.0f // max distance for visible objects, experimental
#define MAX_VISIBILITY_DISTANCE SIZE_OF_GRIDS // max distance for visible objects, experimental
#define SIGHT_RANGE_UNIT 50.0f
#define MAX_SEARCHER_DISTANCE 150.0f // pussywizard: replace the use of MAX_VISIBILITY_DISTANCE in searchers, because MAX_VISIBILITY_DISTANCE is quite too big for this purpose
#define VISIBILITY_DISTANCE_INFINITE 533.0f
#define VISIBILITY_DISTANCE_GIGANTIC 400.0f
#define VISIBILITY_DISTANCE_LARGE 200.0f
#define VISIBILITY_DISTANCE_NORMAL 100.0f
#define VISIBILITY_DISTANCE_SMALL 50.0f
#define VISIBILITY_DISTANCE_TINY 25.0f
#define DEFAULT_VISIBILITY_DISTANCE 100.0f // default visible distance, 100 yards on continents
#define DEFAULT_VISIBILITY_DISTANCE VISIBILITY_DISTANCE_NORMAL // default visible distance, 100 yards on continents
#define DEFAULT_VISIBILITY_INSTANCE 170.0f // default visible distance in instances, 170 yards
#define VISIBILITY_DIST_WINTERGRASP 175.0f
#define DEFAULT_VISIBILITY_BGARENAS 533.0f // default visible distance in BG/Arenas, roughly 533 yards
Expand Down
2 changes: 1 addition & 1 deletion src/server/game/Entities/Player/Player.h
Original file line number Diff line number Diff line change
Expand Up @@ -2349,7 +2349,7 @@ class Player : public Unit, public GridObject<Player>
bool IsVisibleGloballyFor(Player const* player) const;

void GetInitialVisiblePackets(Unit* target);
void UpdateObjectVisibility(bool forced = true, bool fromUpdate = false) override;
void UpdateObjectVisibility(bool forced = true) override;
void UpdateVisibilityForPlayer(bool mapChange = false);
void UpdateVisibilityOf(WorldObject* target);
void UpdateTriggerVisibility();
Expand Down
33 changes: 5 additions & 28 deletions src/server/game/Entities/Player/PlayerUpdates.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -412,14 +412,6 @@ void Player::Update(uint32 p_time)
SetHasDelayedTeleport(false);
TeleportTo(teleportStore_dest, teleportStore_options);
}

if (!IsBeingTeleported() && bRequestForcedVisibilityUpdate)
{
bRequestForcedVisibilityUpdate = false;
UpdateObjectVisibility(true, true);
m_delayed_unit_relocation_timer = 0;
RemoveFromNotify(NOTIFY_VISIBILITY_CHANGED);
}
}

void Player::UpdateMirrorTimers()
Expand Down Expand Up @@ -1550,23 +1542,13 @@ void Player::UpdateVisibilityForPlayer(bool mapChange)
m_seer = this;
}

Acore::VisibleNotifier notifierNoLarge(
*this, mapChange,
false); // visit only objects which are not large; default distance
Cell::VisitAllObjects(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());
notifierLarge.SendToSelf();

if (mapChange)
m_last_notify_position.Relocate(-5000.0f, -5000.0f, -5000.0f, 0.0f);
// updates visibility of all objects around point of view for current player
Acore::VisibleNotifier notifier(*this, mapChange);
Cell::VisitAllObjects(m_seer, notifier, GetSightRange());
notifier.SendToSelf(); // send gathered data
}

void Player::UpdateObjectVisibility(bool forced, bool fromUpdate)
void Player::UpdateObjectVisibility(bool forced)
{
// Prevent updating visibility if player is not in world (example: LoadFromDB sets drunkstate which updates invisibility while player is not in map)
if (!IsInWorld())
Expand All @@ -1576,11 +1558,6 @@ void Player::UpdateObjectVisibility(bool forced, bool fromUpdate)
AddToNotify(NOTIFY_VISIBILITY_CHANGED);
else if (!isBeingLoaded())
{
if (!fromUpdate) // pussywizard:
{
bRequestForcedVisibilityUpdate = true;
return;
}
Unit::UpdateObjectVisibility(true);
UpdateVisibilityForPlayer();
}
Expand Down
Loading

0 comments on commit 2779833

Please sign in to comment.