diff --git a/src/server/apps/worldserver/worldserver.conf.dist b/src/server/apps/worldserver/worldserver.conf.dist index da92ec010..0b7a9beb5 100644 --- a/src/server/apps/worldserver/worldserver.conf.dist +++ b/src/server/apps/worldserver/worldserver.conf.dist @@ -2824,6 +2824,14 @@ Rate.Creature.Aggro = 1 CreatureFamilyFleeAssistanceRadius = 30 +# +# CreatureLeashRadius +# Description: Distance (in yards) for default leash due to being too far from pulled position. +# Default: 30 - (Enabled) +# 0 - (Disabled) + +CreatureLeashRadius = 30 + # # CreatureFamilyAssistanceRadius # Description: Distance for creatures calling for assistance from other creatures without diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 4398579f9..c2209bc5b 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -2671,29 +2671,28 @@ bool Creature::CanCreatureAttack(Unit const* victim, bool skipDistCheck) const // pussywizard: don't check distance to home position if recently damaged (allow kiting away from spawnpoint!) // xinef: this should include taunt auras - if (!isWorldBoss() && (GetLastLeashExtensionTime() + 12 > GameTime::GetGameTime().count() || HasTauntAura())) + if (!isWorldBoss() && (GetLastLeashExtensionTime() + GetLeashTimer() > GameTime::GetGameTime().count() || HasTauntAura())) return true; } if (skipDistCheck) return true; - // xinef: added size factor for huge npcs - float dist = std::min(GetDetectionRange() + GetObjectSize() * 2, 150.0f); + float dist = sWorld->getFloatConfig(CONFIG_CREATURE_LEASH_RADIUS); - if (Unit* unit = GetCharmerOrOwner()) + if (GetCharmerOrOwner()) { dist = std::min(GetMap()->GetVisibilityRange() + GetObjectSize() * 2, 150.0f); - return victim->IsWithinDist(unit, dist); - } - else - { - // to prevent creatures in air ignore attacks because distance is already too high... - if (GetMovementTemplate().IsFlightAllowed()) - return victim->IsInDist2d(&m_homePosition, dist); - else - return victim->IsInDist(&m_homePosition, dist); + return IsWithinDist(victim, dist); } + + if (!dist) + return true; + + float x, y, z; + GetMotionMaster()->GetMotionSlot(MOTION_SLOT_IDLE)->GetResetPosition(x, y, z); + + return IsInDist2d(x, y, dist); } CreatureAddon const* Creature::GetCreatureAddon() const @@ -3729,6 +3728,16 @@ void Creature::UpdateLeashExtensionTime() (*GetLastLeashExtensionTimePtr()) = GameTime::GetGameTime().count(); } +uint8 Creature::GetLeashTimer() const +{ // Based on testing on Classic, seems to range from ~11s for low level mobs (1-5) to ~16s for high level mobs (70+) + uint8 timerOffset = 11; + + uint8 timerModifier = uint8(GetLevel() / 10) - 2; + + // Formula is likely not quite correct, but better than flat timer + return std::max(timerOffset, timerOffset + timerModifier); +} + bool Creature::CanPeriodicallyCallForAssistance() const { if (!IsInCombat()) diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 6b861f17e..092cec299 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -391,6 +391,7 @@ public: void ClearLastLeashExtensionTimePtr(); time_t GetLastLeashExtensionTime() const; void UpdateLeashExtensionTime(); + uint8 GetLeashTimer() const; bool IsFreeToMove(); static constexpr uint32 MOVE_CIRCLE_CHECK_INTERVAL = 3000; diff --git a/src/server/game/World/IWorld.h b/src/server/game/World/IWorld.h index 112d593a8..018626bfa 100644 --- a/src/server/game/World/IWorld.h +++ b/src/server/game/World/IWorld.h @@ -192,6 +192,7 @@ enum WorldFloatConfigs CONFIG_LISTEN_RANGE_SAY, CONFIG_LISTEN_RANGE_TEXTEMOTE, CONFIG_LISTEN_RANGE_YELL, + CONFIG_CREATURE_LEASH_RADIUS, CONFIG_CREATURE_FAMILY_FLEE_ASSISTANCE_RADIUS, CONFIG_CREATURE_FAMILY_ASSISTANCE_RADIUS, CONFIG_CHANCE_OF_GM_SURVEY, diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index edccd7b66..47a8de9e5 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -793,6 +793,7 @@ void World::LoadConfigSettings(bool reload) _int_configs[CONFIG_EVENT_ANNOUNCE] = sConfigMgr->GetOption("Event.Announce", 0); + _float_configs[CONFIG_CREATURE_LEASH_RADIUS] = sConfigMgr->GetOption("CreatureLeashRadius", 30.0f); _float_configs[CONFIG_CREATURE_FAMILY_FLEE_ASSISTANCE_RADIUS] = sConfigMgr->GetOption("CreatureFamilyFleeAssistanceRadius", 30.0f); _float_configs[CONFIG_CREATURE_FAMILY_ASSISTANCE_RADIUS] = sConfigMgr->GetOption("CreatureFamilyAssistanceRadius", 10.0f); _int_configs[CONFIG_CREATURE_FAMILY_ASSISTANCE_DELAY] = sConfigMgr->GetOption("CreatureFamilyAssistanceDelay", 2000);