aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/Utilities/Util.h2
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp4
-rw-r--r--src/server/game/Entities/Creature/CreatureData.h2
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp12
-rw-r--r--src/server/game/Entities/GameObject/GameObjectData.h54
-rw-r--r--src/server/game/Entities/Object/Object.cpp27
-rw-r--r--src/server/game/Entities/Object/Object.h4
-rw-r--r--src/server/game/Entities/Object/ObjectDefines.h49
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp60
-rw-r--r--src/server/worldserver/worldserver.conf.dist6
10 files changed, 176 insertions, 44 deletions
diff --git a/src/common/Utilities/Util.h b/src/common/Utilities/Util.h
index d17e8b83c92..4438bf1863d 100644
--- a/src/common/Utilities/Util.h
+++ b/src/common/Utilities/Util.h
@@ -538,7 +538,7 @@ bool CompareValues(ComparisionType type, T val1, T val2)
}
template<typename E>
-typename std::underlying_type<E>::type AsUnderlyingType(E enumValue)
+constexpr typename std::underlying_type<E>::type AsUnderlyingType(E enumValue)
{
static_assert(std::is_enum<E>::value, "AsUnderlyingType can only be used with enums");
return static_cast<typename std::underlying_type<E>::type>(enumValue);
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index 2f0df09d488..55e93719dc1 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -2360,6 +2360,10 @@ bool Creature::LoadCreaturesAddon()
SetMovementAnimKitId(cainfo->movementAnimKit);
SetMeleeAnimKitId(cainfo->meleeAnimKit);
+ // Check if visibility distance different
+ if (cainfo->visibilityDistanceType != VisibilityDistanceType::Normal)
+ SetVisibilityDistanceOverride(cainfo->visibilityDistanceType);
+
//Load Path
if (cainfo->path_id != 0)
m_path_id = cainfo->path_id;
diff --git a/src/server/game/Entities/Creature/CreatureData.h b/src/server/game/Entities/Creature/CreatureData.h
index d53f59c0273..36715732e48 100644
--- a/src/server/game/Entities/Creature/CreatureData.h
+++ b/src/server/game/Entities/Creature/CreatureData.h
@@ -28,6 +28,7 @@
#include <cmath>
struct ItemTemplate;
+enum class VisibilityDistanceType : uint8;
enum CreatureDifficultyFlags
{
@@ -578,6 +579,7 @@ struct CreatureAddon
uint16 movementAnimKit;
uint16 meleeAnimKit;
std::vector<uint32> auras;
+ VisibilityDistanceType visibilityDistanceType;
};
// Vendors
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index 2e15c25baa5..7f07e5f2930 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -400,6 +400,18 @@ bool GameObject::Create(uint32 entry, Map* map, Position const& pos, QuaternionD
}
}
+ // Check if GameObject is Infinite
+ if (goInfo->IsInfiniteGameObject())
+ SetVisibilityDistanceOverride(VisibilityDistanceType::Infinite);
+
+ // Check if GameObject is Gigantic
+ if (goInfo->IsGiganticGameObject())
+ SetVisibilityDistanceOverride(VisibilityDistanceType::Gigantic);
+
+ // Check if GameObject is Large
+ if (goInfo->IsLargeGameObject())
+ SetVisibilityDistanceOverride(VisibilityDistanceType::Large);
+
return true;
}
diff --git a/src/server/game/Entities/GameObject/GameObjectData.h b/src/server/game/Entities/GameObject/GameObjectData.h
index 873e2076ea2..5944f07654a 100644
--- a/src/server/game/Entities/GameObject/GameObjectData.h
+++ b/src/server/game/Entities/GameObject/GameObjectData.h
@@ -850,6 +850,60 @@ struct GameObjectTemplate
default: return 0;
}
}
+
+ bool IsInfiniteGameObject() const
+ {
+ switch (type)
+ {
+ case GAMEOBJECT_TYPE_DOOR: return door.InfiniteAOI != 0;
+ case GAMEOBJECT_TYPE_FLAGSTAND: return flagStand.InfiniteAOI != 0;
+ case GAMEOBJECT_TYPE_FLAGDROP: return flagDrop.InfiniteAOI != 0;
+ case GAMEOBJECT_TYPE_TRAPDOOR: return trapdoor.InfiniteAOI != 0;
+ case GAMEOBJECT_TYPE_NEW_FLAG: return newflag.InfiniteAOI != 0;
+ default: return false;
+ }
+ }
+
+ bool IsGiganticGameObject() const
+ {
+ switch (type)
+ {
+ case GAMEOBJECT_TYPE_DOOR: return door.GiganticAOI != 0;
+ case GAMEOBJECT_TYPE_BUTTON: return button.GiganticAOI != 0;
+ case GAMEOBJECT_TYPE_QUESTGIVER: return questgiver.GiganticAOI != 0;
+ case GAMEOBJECT_TYPE_CHEST: return chest.GiganticAOI != 0;
+ case GAMEOBJECT_TYPE_GENERIC: return generic.GiganticAOI != 0;
+ case GAMEOBJECT_TYPE_TRAP: return trap.GiganticAOI != 0;
+ case GAMEOBJECT_TYPE_SPELL_FOCUS: return spellFocus.GiganticAOI != 0;
+ case GAMEOBJECT_TYPE_GOOBER: return goober.GiganticAOI != 0;
+ case GAMEOBJECT_TYPE_SPELLCASTER: return spellCaster.GiganticAOI != 0;
+ case GAMEOBJECT_TYPE_FLAGSTAND: return flagStand.GiganticAOI != 0;
+ case GAMEOBJECT_TYPE_FLAGDROP: return flagDrop.GiganticAOI != 0;
+ case GAMEOBJECT_TYPE_CONTROL_ZONE: return controlZone.GiganticAOI != 0;
+ case GAMEOBJECT_TYPE_DUNGEON_DIFFICULTY: return dungeonDifficulty.GiganticAOI != 0;
+ case GAMEOBJECT_TYPE_TRAPDOOR: return trapdoor.GiganticAOI != 0;
+ case GAMEOBJECT_TYPE_NEW_FLAG: return newflag.GiganticAOI != 0;
+ case GAMEOBJECT_TYPE_CAPTURE_POINT: return capturePoint.GiganticAOI != 0;
+ case GAMEOBJECT_TYPE_GARRISON_SHIPMENT: return garrisonShipment.GiganticAOI != 0;
+ case GAMEOBJECT_TYPE_UI_LINK: return UILink.GiganticAOI != 0;
+ case GAMEOBJECT_TYPE_GATHERING_NODE: return gatheringNode.GiganticAOI != 0;
+ default: return false;
+ }
+ }
+
+ bool IsLargeGameObject() const
+ {
+ switch (type)
+ {
+ case GAMEOBJECT_TYPE_CHEST: return chest.LargeAOI != 0;
+ case GAMEOBJECT_TYPE_GENERIC: return generic.LargeAOI != 0;
+ case GAMEOBJECT_TYPE_DUNGEON_DIFFICULTY: return dungeonDifficulty.LargeAOI != 0;
+ case GAMEOBJECT_TYPE_GARRISON_SHIPMENT: return garrisonShipment.LargeAOI != 0;
+ case GAMEOBJECT_TYPE_ARTIFACT_FORGE: return artifactForge.LargeAOI != 0;
+ case GAMEOBJECT_TYPE_GATHERING_NODE: return gatheringNode.LargeAOI != 0;
+ default: return false;
+ }
+ }
};
// From `gameobject_template_addon`
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index 9d0645842d4..392d418a3e7 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -51,6 +51,16 @@
#include "WorldSession.h"
#include <G3D/Vector3.h>
+constexpr float VisibilityDistances[AsUnderlyingType(VisibilityDistanceType::Max)] =
+{
+ DEFAULT_VISIBILITY_DISTANCE,
+ VISIBILITY_DISTANCE_TINY,
+ VISIBILITY_DISTANCE_SMALL,
+ VISIBILITY_DISTANCE_LARGE,
+ VISIBILITY_DISTANCE_GIGANTIC,
+ MAX_VISIBILITY_DISTANCE
+};
+
Object::Object()
{
m_objectTypeId = TYPEID_OBJECT;
@@ -1615,6 +1625,15 @@ void WorldObject::setActive(bool on)
}
}
+void WorldObject::SetVisibilityDistanceOverride(VisibilityDistanceType type)
+{
+ ASSERT(type < VisibilityDistanceType::Max);
+ if (GetTypeId() == TYPEID_PLAYER)
+ return;
+
+ m_visibilityDistanceOverride = VisibilityDistances[AsUnderlyingType(type)];
+}
+
void WorldObject::CleanupsBeforeDelete(bool /*finalCleanup*/)
{
if (IsInWorld())
@@ -2061,7 +2080,9 @@ float WorldObject::GetGridActivationRange() const
float WorldObject::GetVisibilityRange() const
{
- if (isActiveObject() && !ToPlayer())
+ if (IsVisibilityOverridden() && !ToPlayer())
+ return *m_visibilityDistanceOverride;
+ else if (isActiveObject() && !ToPlayer())
return MAX_VISIBILITY_DISTANCE;
else
return GetMap()->GetVisibilityRange();
@@ -2073,7 +2094,9 @@ float WorldObject::GetSightRange(const WorldObject* target) const
{
if (ToPlayer())
{
- if (target && target->isActiveObject() && !target->ToPlayer())
+ if (target && target->IsVisibilityOverridden() && !target->ToPlayer())
+ return *target->m_visibilityDistanceOverride;
+ else if (target && target->isActiveObject() && !target->ToPlayer())
return MAX_VISIBILITY_DISTANCE;
else if (ToPlayer()->GetCinematicMgr()->IsOnCinematic())
return DEFAULT_VISIBILITY_INSTANCE;
diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h
index fb05d7cc747..211cb5e221c 100644
--- a/src/server/game/Entities/Object/Object.h
+++ b/src/server/game/Entities/Object/Object.h
@@ -26,6 +26,7 @@
#include "MovementInfo.h"
#include "ObjectDefines.h"
#include "ObjectGuid.h"
+#include "Optional.h"
#include "PhaseShift.h"
#include "Position.h"
#include "SharedDefines.h"
@@ -572,6 +573,8 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation
bool isActiveObject() const { return m_isActive; }
void setActive(bool isActiveObject);
+ bool IsVisibilityOverridden() const { return m_visibilityDistanceOverride.is_initialized(); }
+ void SetVisibilityDistanceOverride(VisibilityDistanceType type);
void SetWorldObject(bool apply);
bool IsPermanentWorldObject() const { return m_isWorldObject; }
bool IsWorldObject() const;
@@ -604,6 +607,7 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation
protected:
std::string m_name;
bool m_isActive;
+ Optional<float> m_visibilityDistanceOverride;
const bool m_isWorldObject;
ZoneScript* m_zoneScript;
diff --git a/src/server/game/Entities/Object/ObjectDefines.h b/src/server/game/Entities/Object/ObjectDefines.h
index 34bfdd036a3..00b7557c120 100644
--- a/src/server/game/Entities/Object/ObjectDefines.h
+++ b/src/server/game/Entities/Object/ObjectDefines.h
@@ -21,22 +21,39 @@
#include "Define.h"
-#define CONTACT_DISTANCE 0.5f
-#define INTERACTION_DISTANCE 5.0f
-#define ATTACK_DISTANCE 5.0f
-#define INSPECT_DISTANCE 28.0f
-#define TRADE_DISTANCE 11.11f
-#define MAX_VISIBILITY_DISTANCE SIZE_OF_GRIDS // max distance for visible objects
-#define SIGHT_RANGE_UNIT 50.0f
-#define DEFAULT_VISIBILITY_DISTANCE 90.0f // default visible distance, 90 yards on continents
-#define DEFAULT_VISIBILITY_INSTANCE 170.0f // default visible distance in instances, 170 yards
-#define DEFAULT_VISIBILITY_BGARENAS 533.0f // default visible distance in BG/Arenas, roughly 533 yards
-
-#define DEFAULT_WORLD_OBJECT_SIZE 0.388999998569489f // player size, also currently used (correctly?) for any non Unit world objects
-#define DEFAULT_COMBAT_REACH 1.5f
-#define MIN_MELEE_REACH 2.0f
-#define NOMINAL_MELEE_RANGE 5.0f
-#define MELEE_RANGE (NOMINAL_MELEE_RANGE - MIN_MELEE_REACH * 2) //center to center for players
+#define CONTACT_DISTANCE 0.5f
+#define INTERACTION_DISTANCE 5.0f
+#define ATTACK_DISTANCE 5.0f
+#define INSPECT_DISTANCE 28.0f
+#define TRADE_DISTANCE 11.11f
+#define MAX_VISIBILITY_DISTANCE SIZE_OF_GRIDS // max distance for visible objects
+#define SIGHT_RANGE_UNIT 50.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 VISIBILITY_DISTANCE_NORMAL // default visible distance, 100 yards on continents
+#define DEFAULT_VISIBILITY_INSTANCE 170.0f // default visible distance in instances, 170 yards
+#define DEFAULT_VISIBILITY_BGARENAS 533.0f // default visible distance in BG/Arenas, roughly 533 yards
+
+#define DEFAULT_WORLD_OBJECT_SIZE 0.388999998569489f // player size, also currently used (correctly?) for any non Unit world objects
+#define DEFAULT_COMBAT_REACH 1.5f
+#define MIN_MELEE_REACH 2.0f
+#define NOMINAL_MELEE_RANGE 5.0f
+#define MELEE_RANGE (NOMINAL_MELEE_RANGE - MIN_MELEE_REACH * 2) //center to center for players
+
+enum class VisibilityDistanceType : uint8
+{
+ Normal = 0,
+ Tiny = 1,
+ Small = 2,
+ Large = 3,
+ Gigantic = 4,
+ Infinite = 5,
+
+ Max
+};
enum TempSummonType
{
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index db98243a5f1..8ad7d0b14ae 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -588,8 +588,8 @@ void ObjectMgr::LoadCreatureTemplateAddons()
{
uint32 oldMSTime = getMSTime();
- // 0 1 2 3 4 5 6 7 8 9
- QueryResult result = WorldDatabase.Query("SELECT entry, path_id, mount, bytes1, bytes2, emote, aiAnimKit, movementAnimKit, meleeAnimKit, auras FROM creature_template_addon");
+ // 0 1 2 3 4 5 6 7 8 9 10
+ QueryResult result = WorldDatabase.Query("SELECT entry, path_id, mount, bytes1, bytes2, emote, aiAnimKit, movementAnimKit, meleeAnimKit, visibilityDistanceType, auras FROM creature_template_addon");
if (!result)
{
@@ -612,16 +612,17 @@ void ObjectMgr::LoadCreatureTemplateAddons()
CreatureAddon& creatureAddon = _creatureTemplateAddonStore[entry];
- creatureAddon.path_id = fields[1].GetUInt32();
- creatureAddon.mount = fields[2].GetUInt32();
- creatureAddon.bytes1 = fields[3].GetUInt32();
- creatureAddon.bytes2 = fields[4].GetUInt32();
- creatureAddon.emote = fields[5].GetUInt32();
- creatureAddon.aiAnimKit = fields[6].GetUInt16();
- creatureAddon.movementAnimKit = fields[7].GetUInt16();
- creatureAddon.meleeAnimKit = fields[8].GetUInt16();
-
- Tokenizer tokens(fields[9].GetString(), ' ');
+ creatureAddon.path_id = fields[1].GetUInt32();
+ creatureAddon.mount = fields[2].GetUInt32();
+ creatureAddon.bytes1 = fields[3].GetUInt32();
+ creatureAddon.bytes2 = fields[4].GetUInt32();
+ creatureAddon.emote = fields[5].GetUInt32();
+ creatureAddon.aiAnimKit = fields[6].GetUInt16();
+ creatureAddon.movementAnimKit = fields[7].GetUInt16();
+ creatureAddon.meleeAnimKit = fields[8].GetUInt16();
+ creatureAddon.visibilityDistanceType = VisibilityDistanceType(fields[9].GetUInt8());
+
+ Tokenizer tokens(fields[10].GetString(), ' ');
uint8 i = 0;
creatureAddon.auras.resize(tokens.size());
for (Tokenizer::const_iterator itr = tokens.begin(); itr != tokens.end(); ++itr)
@@ -679,6 +680,13 @@ void ObjectMgr::LoadCreatureTemplateAddons()
creatureAddon.meleeAnimKit = 0;
}
+ if (creatureAddon.visibilityDistanceType >= VisibilityDistanceType::Max)
+ {
+ TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has invalid visibilityDistanceType (%u) defined in `creature_template_addon`.",
+ entry, AsUnderlyingType(creatureAddon.visibilityDistanceType));
+ creatureAddon.visibilityDistanceType = VisibilityDistanceType::Normal;
+ }
+
++count;
}
while (result->NextRow());
@@ -1064,8 +1072,8 @@ void ObjectMgr::LoadCreatureAddons()
{
uint32 oldMSTime = getMSTime();
- // 0 1 2 3 4 5 6 7 8 9
- QueryResult result = WorldDatabase.Query("SELECT guid, path_id, mount, bytes1, bytes2, emote, aiAnimKit, movementAnimKit, meleeAnimKit, auras FROM creature_addon");
+ // 0 1 2 3 4 5 6 7 8 9 10
+ QueryResult result = WorldDatabase.Query("SELECT guid, path_id, mount, bytes1, bytes2, emote, aiAnimKit, movementAnimKit, meleeAnimKit, visibilityDistanceType, auras FROM creature_addon");
if (!result)
{
@@ -1096,15 +1104,16 @@ void ObjectMgr::LoadCreatureAddons()
TC_LOG_ERROR("sql.sql", "Creature (GUID " UI64FMTD ") has movement type set to WAYPOINT_MOTION_TYPE but no path assigned", guid);
}
- creatureAddon.mount = fields[2].GetUInt32();
- creatureAddon.bytes1 = fields[3].GetUInt32();
- creatureAddon.bytes2 = fields[4].GetUInt32();
- creatureAddon.emote = fields[5].GetUInt32();
- creatureAddon.aiAnimKit = fields[6].GetUInt16();
- creatureAddon.movementAnimKit = fields[7].GetUInt16();
- creatureAddon.meleeAnimKit = fields[8].GetUInt16();
+ creatureAddon.mount = fields[2].GetUInt32();
+ creatureAddon.bytes1 = fields[3].GetUInt32();
+ creatureAddon.bytes2 = fields[4].GetUInt32();
+ creatureAddon.emote = fields[5].GetUInt32();
+ creatureAddon.aiAnimKit = fields[6].GetUInt16();
+ creatureAddon.movementAnimKit = fields[7].GetUInt16();
+ creatureAddon.meleeAnimKit = fields[8].GetUInt16();
+ creatureAddon.visibilityDistanceType = VisibilityDistanceType(fields[9].GetUInt8());
- Tokenizer tokens(fields[9].GetString(), ' ');
+ Tokenizer tokens(fields[10].GetString(), ' ');
uint8 i = 0;
creatureAddon.auras.resize(tokens.size());
for (Tokenizer::const_iterator itr = tokens.begin(); itr != tokens.end(); ++itr)
@@ -1162,6 +1171,13 @@ void ObjectMgr::LoadCreatureAddons()
creatureAddon.meleeAnimKit = 0;
}
+ if (creatureAddon.visibilityDistanceType >= VisibilityDistanceType::Max)
+ {
+ TC_LOG_ERROR("sql.sql", "Creature (GUID: " UI64FMTD ") has invalid visibilityDistanceType (%u) defined in `creature_addon`.",
+ guid, AsUnderlyingType(creatureAddon.visibilityDistanceType));
+ creatureAddon.visibilityDistanceType = VisibilityDistanceType::Normal;
+ }
+
++count;
}
while (result->NextRow());
diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
index cfcde52c061..65c386abd66 100644
--- a/src/server/worldserver/worldserver.conf.dist
+++ b/src/server/worldserver/worldserver.conf.dist
@@ -2022,15 +2022,15 @@ 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 ~533.
+# 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)
+# Default: 100 - (Visibility.Distance.Continents)
# 170 - (Visibility.Distance.Instances)
# 533 - (Visibility.Distance.BGArenas)
-Visibility.Distance.Continents = 90
+Visibility.Distance.Continents = 100
Visibility.Distance.Instances = 170
Visibility.Distance.BGArenas = 533