diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/common/Utilities/Util.h | 2 | ||||
-rw-r--r-- | src/server/game/Entities/Creature/Creature.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Entities/Creature/CreatureData.h | 2 | ||||
-rw-r--r-- | src/server/game/Entities/GameObject/GameObject.cpp | 12 | ||||
-rw-r--r-- | src/server/game/Entities/GameObject/GameObjectData.h | 54 | ||||
-rw-r--r-- | src/server/game/Entities/Object/Object.cpp | 27 | ||||
-rw-r--r-- | src/server/game/Entities/Object/Object.h | 4 | ||||
-rw-r--r-- | src/server/game/Entities/Object/ObjectDefines.h | 49 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.cpp | 60 | ||||
-rw-r--r-- | src/server/worldserver/worldserver.conf.dist | 6 |
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 |