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.cpp4
-rw-r--r--src/server/game/Entities/GameObject/GameObjectData.h16
-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.h37
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp46
-rw-r--r--src/server/worldserver/worldserver.conf.dist6
10 files changed, 117 insertions, 31 deletions
diff --git a/src/common/Utilities/Util.h b/src/common/Utilities/Util.h
index f378d457648..78019885d99 100644
--- a/src/common/Utilities/Util.h
+++ b/src/common/Utilities/Util.h
@@ -503,7 +503,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 371b588e5e8..06a74ea1c79 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -2478,6 +2478,10 @@ bool Creature::LoadCreaturesAddon()
if (cainfo->emote != 0)
SetUInt32Value(UNIT_NPC_EMOTESTATE, cainfo->emote);
+ // Check if visibility distance different
+ if (cainfo->visibilityDistanceType != VisibilityDistanceType::Normal)
+ SetVisibilityDistanceOverride(cainfo->visibilityDistanceType);
+
// Load Path
if (cainfo->path_id != 0)
_waypointPathId = cainfo->path_id;
diff --git a/src/server/game/Entities/Creature/CreatureData.h b/src/server/game/Entities/Creature/CreatureData.h
index dae19fbf326..c08b2ae86a6 100644
--- a/src/server/game/Entities/Creature/CreatureData.h
+++ b/src/server/game/Entities/Creature/CreatureData.h
@@ -29,6 +29,7 @@
#include <cmath>
struct ItemTemplate;
+enum class VisibilityDistanceType : uint8;
// EnumUtils: DESCRIBE THIS
enum CreatureFlagsExtra : uint32
@@ -312,6 +313,7 @@ struct CreatureAddon
uint32 bytes2;
uint32 emote;
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 8ae536497f4..bae468c329c 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -399,6 +399,10 @@ bool GameObject::Create(ObjectGuid::LowType guidlow, uint32 name_id, Map* map, u
delete linkedGO;
}
+ // 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 b27e004289b..ecb5ba8e684 100644
--- a/src/server/game/Entities/GameObject/GameObjectData.h
+++ b/src/server/game/Entities/GameObject/GameObjectData.h
@@ -571,6 +571,22 @@ struct GameObjectTemplate
}
}
+ bool IsLargeGameObject() const
+ {
+ switch (type)
+ {
+ case GAMEOBJECT_TYPE_BUTTON: return button.large != 0;
+ case GAMEOBJECT_TYPE_QUESTGIVER: return questgiver.large != 0;
+ case GAMEOBJECT_TYPE_GENERIC: return _generic.large != 0;
+ case GAMEOBJECT_TYPE_TRAP: return trap.large != 0;
+ case GAMEOBJECT_TYPE_SPELL_FOCUS: return spellFocus.large != 0;
+ case GAMEOBJECT_TYPE_GOOBER: return goober.large != 0;
+ case GAMEOBJECT_TYPE_SPELLCASTER: return spellcaster.large != 0;
+ case GAMEOBJECT_TYPE_CAPTURE_POINT: return capturePoint.large != 0;
+ default: return false;
+ }
+ }
+
void InitializeQueryData();
WorldPacket BuildQueryData(LocaleConstant loc) const;
};
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index 3909f76cd67..5087279adc0 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -47,6 +47,16 @@
#include "World.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_PackGUID(sizeof(uint64)+1)
{
m_objectTypeId = TYPEID_OBJECT;
@@ -1022,6 +1032,15 @@ void WorldObject::SetFarVisible(bool on)
m_isFarVisible = 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())
@@ -1459,7 +1478,9 @@ float WorldObject::GetGridActivationRange() const
float WorldObject::GetVisibilityRange() const
{
- if (IsFarVisible() && !ToPlayer())
+ if (IsVisibilityOverridden() && !ToPlayer())
+ return *m_visibilityDistanceOverride;
+ else if (IsFarVisible() && !ToPlayer())
return MAX_VISIBILITY_DISTANCE;
else
return GetMap()->GetVisibilityRange();
@@ -1471,7 +1492,9 @@ float WorldObject::GetSightRange(WorldObject const* target) const
{
if (ToPlayer())
{
- if (target && target->IsFarVisible() && !target->ToPlayer())
+ if (target && target->IsVisibilityOverridden() && !target->ToPlayer())
+ return *target->m_visibilityDistanceOverride;
+ else if (target && target->IsFarVisible() && !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 db707fac897..7b13276a7f8 100644
--- a/src/server/game/Entities/Object/Object.h
+++ b/src/server/game/Entities/Object/Object.h
@@ -28,6 +28,7 @@
#include "MovementInfo.h"
#include "ObjectDefines.h"
#include "ObjectGuid.h"
+#include "Optional.h"
#include "Position.h"
#include "SharedDefines.h"
#include "SpellDefines.h"
@@ -479,6 +480,8 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation
void setActive(bool isActiveObject);
bool IsFarVisible() const { return m_isFarVisible; }
void SetFarVisible(bool on);
+ 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;
@@ -519,6 +522,7 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation
std::string m_name;
bool m_isActive;
bool m_isFarVisible;
+ Optional<float> m_visibilityDistanceOverride;
bool const m_isWorldObject;
ZoneScript* m_zoneScript;
diff --git a/src/server/game/Entities/Object/ObjectDefines.h b/src/server/game/Entities/Object/ObjectDefines.h
index ca6a55913e2..0a4faeb1281 100644
--- a/src/server/game/Entities/Object/ObjectDefines.h
+++ b/src/server/game/Entities/Object/ObjectDefines.h
@@ -21,16 +21,21 @@
#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 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_PLAYER_BOUNDING_RADIUS 0.388999998569489f // player size, also currently used (correctly?) for any non Unit world objects
#define DEFAULT_PLAYER_COMBAT_REACH 1.5f
@@ -38,6 +43,18 @@
#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
{
TEMPSUMMON_TIMED_OR_DEAD_DESPAWN = 1, // despawns after a specified time OR when the creature disappears
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index df4cdc346c2..b267c52aa32 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -487,8 +487,8 @@ void ObjectMgr::LoadCreatureTemplateAddons()
{
uint32 oldMSTime = getMSTime();
- // 0 1 2 3 4 5 6
- QueryResult result = WorldDatabase.Query("SELECT entry, path_id, mount, bytes1, bytes2, emote, auras FROM creature_template_addon");
+ // 0 1 2 3 4 5 6 7
+ QueryResult result = WorldDatabase.Query("SELECT entry, path_id, mount, bytes1, bytes2, emote, visibilityDistanceType, auras FROM creature_template_addon");
if (!result)
{
@@ -511,13 +511,14 @@ 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.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.visibilityDistanceType = VisibilityDistanceType(fields[6].GetUInt8());
- Tokenizer tokens(fields[6].GetString(), ' ');
+ Tokenizer tokens(fields[7].GetString(), ' ');
uint8 i = 0;
creatureAddon.auras.resize(tokens.size());
for (Tokenizer::const_iterator itr = tokens.begin(); itr != tokens.end(); ++itr)
@@ -556,6 +557,13 @@ void ObjectMgr::LoadCreatureTemplateAddons()
creatureAddon.emote = 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());
@@ -983,8 +991,8 @@ void ObjectMgr::LoadCreatureAddons()
{
uint32 oldMSTime = getMSTime();
- // 0 1 2 3 4 5 6
- QueryResult result = WorldDatabase.Query("SELECT guid, path_id, mount, bytes1, bytes2, emote, auras FROM creature_addon");
+ // 0 1 2 3 4 5 6 7
+ QueryResult result = WorldDatabase.Query("SELECT guid, path_id, mount, bytes1, bytes2, emote, visibilityDistanceType, auras FROM creature_addon");
if (!result)
{
@@ -1015,12 +1023,13 @@ void ObjectMgr::LoadCreatureAddons()
TC_LOG_ERROR("sql.sql", "Creature (GUID %u) 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.mount = fields[2].GetUInt32();
+ creatureAddon.bytes1 = fields[3].GetUInt32();
+ creatureAddon.bytes2 = fields[4].GetUInt32();
+ creatureAddon.emote = fields[5].GetUInt32();
+ creatureAddon.visibilityDistanceType = VisibilityDistanceType(fields[6].GetUInt8());
- Tokenizer tokens(fields[6].GetString(), ' ');
+ Tokenizer tokens(fields[7].GetString(), ' ');
uint8 i = 0;
creatureAddon.auras.resize(tokens.size());
for (Tokenizer::const_iterator itr = tokens.begin(); itr != tokens.end(); ++itr)
@@ -1059,6 +1068,13 @@ void ObjectMgr::LoadCreatureAddons()
creatureAddon.emote = 0;
}
+ if (creatureAddon.visibilityDistanceType >= VisibilityDistanceType::Max)
+ {
+ TC_LOG_ERROR("sql.sql", "Creature (GUID: %u) 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 99b888c9ff2..eb31fc4da9a 100644
--- a/src/server/worldserver/worldserver.conf.dist
+++ b/src/server/worldserver/worldserver.conf.dist
@@ -2117,15 +2117,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