diff options
| author | Treeston <treeston.mmoc@gmail.com> | 2018-04-06 18:09:55 +0200 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2021-09-24 23:37:43 +0200 |
| commit | 14939204955d1a24fe465cdfcbf307daf3ce4f09 (patch) | |
| tree | 18e2bc2c0fa726bdcea65384c99742805e6d0cdf /src/server/game/Entities | |
| parent | 27fa6f3e341bb5a52b8c9b37b5a018d40b8e88a5 (diff) | |
Core/Movement: Replace old TargetedMovementGenerator into ChaseMovementGenerator and FollowMovementGenerator, full rewrite for both.
- Chase to angle is now functional. Pets use this to chase behind the target. Closes #19925.
- Chase to arbitrary range interval works. Not used anywhere, but you can technically make hunter-like mobs.
- Pets now follow the hunter cleanly and without stutter stepping. Also fix some other things. Closes #8924.
(cherry picked from commit 2a84562dc85516f432bb1e5de9add23c28b26ce4)
Diffstat (limited to 'src/server/game/Entities')
| -rw-r--r-- | src/server/game/Entities/Object/G3DPosition.hpp | 29 | ||||
| -rw-r--r-- | src/server/game/Entities/Pet/PetDefines.h | 2 | ||||
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 59 | ||||
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 13 |
4 files changed, 70 insertions, 33 deletions
diff --git a/src/server/game/Entities/Object/G3DPosition.hpp b/src/server/game/Entities/Object/G3DPosition.hpp new file mode 100644 index 00000000000..413072fc811 --- /dev/null +++ b/src/server/game/Entities/Object/G3DPosition.hpp @@ -0,0 +1,29 @@ +/* + * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef TRINITY_G3DPOSITION_HPP +#define TRINITY_G3DPOSITION_HPP + +#include "Position.h" +#include <G3D/Vector3.h> +#include "Errors.h" + +inline G3D::Vector3 PositionToVector3(Position p) { return { p.m_positionX, p.m_positionY, p.m_positionZ }; } +inline G3D::Vector3 PositionToVector3(Position const* p) { return { ASSERT_NOTNULL(p)->m_positionX, p->m_positionY, p->m_positionZ }; } +inline Position Vector3ToPosition(G3D::Vector3 v) { return { v.x, v.y, v.z }; } + +#endif diff --git a/src/server/game/Entities/Pet/PetDefines.h b/src/server/game/Entities/Pet/PetDefines.h index dfee8719e75..266c6f1e15a 100644 --- a/src/server/game/Entities/Pet/PetDefines.h +++ b/src/server/game/Entities/Pet/PetDefines.h @@ -77,6 +77,6 @@ enum PetTalk }; #define PET_FOLLOW_DIST 1.0f -#define PET_FOLLOW_ANGLE float(M_PI/2) +#define PET_FOLLOW_ANGLE float(M_PI) #endif diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 3fb1be9ca38..390d9855ce1 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -16,6 +16,7 @@ */ #include "Unit.h" +#include "AbstractFollower.h" #include "Battlefield.h" #include "BattlefieldMgr.h" #include "Battleground.h" @@ -559,14 +560,14 @@ bool Unit::IsWithinCombatRange(Unit const* obj, float dist2compare) const return distsq < maxdist * maxdist; } -bool Unit::IsWithinMeleeRange(Unit const* obj) const +bool Unit::IsWithinMeleeRangeAt(Position const& pos, Unit const* obj) const { if (!obj || !IsInMap(obj) || !IsInPhase(obj)) return false; - float dx = GetPositionX() - obj->GetPositionX(); - float dy = GetPositionY() - obj->GetPositionY(); - float dz = GetPositionZ() - obj->GetPositionZ(); + float dx = pos.GetPositionX() - obj->GetPositionX(); + float dy = pos.GetPositionY() - obj->GetPositionY(); + float dz = pos.GetPositionZ() - obj->GetPositionZ(); float distsq = dx*dx + dy*dy + dz*dz; float maxdist = GetMeleeRange(obj) + GetTotalAuraModifier(SPELL_AURA_MOD_AUTOATTACK_RANGE); @@ -8020,25 +8021,7 @@ void Unit::UpdateSpeed(UnitMoveType mtype) { // Set creature speed rate if (GetTypeId() == TYPEID_UNIT) - { - Unit* pOwner = GetCharmerOrOwner(); - if ((IsPet() || IsGuardian()) && !IsInCombat() && pOwner) // Must check for owner or crash on "Tame Beast" - { - // For every yard over 5, increase speed by 0.01 - // to help prevent pet from lagging behind and despawning - float dist = GetDistance(pOwner); - float base_rate = 1.00f; // base speed is 100% of owner speed - - if (dist < 5) - dist = 5; - - float mult = base_rate + ((dist - 5) * 0.01f); - - speed *= pOwner->GetSpeedRate(mtype) * mult; // pets derive speed from owner when not in combat - } - else - speed *= ToCreature()->GetCreatureTemplate()->speed_run; // at this point, MOVE_WALK is never reached - } + speed *= ToCreature()->GetCreatureTemplate()->speed_run; // at this point, MOVE_WALK is never reached // Normalize speed by 191 aura SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED if need /// @todo possible affect only on MOVE_RUN @@ -8073,11 +8056,27 @@ void Unit::UpdateSpeed(UnitMoveType mtype) break; } - // for creature case, we check explicit if mob searched for assistance - if (GetTypeId() == TYPEID_UNIT) + if (Creature* creature = ToCreature()) { - if (ToCreature()->HasSearchedAssistance()) + // for creature case, we check explicit if mob searched for assistance + if (creature->HasSearchedAssistance()) speed *= 0.66f; // best guessed value, so this will be 33% reduction. Based off initial speed, mob can then "run", "walk fast" or "walk". + + if (creature->HasUnitTypeMask(UNIT_MASK_MINION) && !creature->IsInCombat()) + { + MovementGenerator* top = creature->GetMotionMaster()->top(); + if (top && top->GetMovementGeneratorType() == FOLLOW_MOTION_TYPE) + { + Unit* followed = ASSERT_NOTNULL(dynamic_cast<AbstractFollower*>(top))->GetTarget(); + if (followed && followed->GetGUID() == GetOwnerGUID() && !followed->IsInCombat()) + { + float ownerSpeed = followed->GetSpeedRate(mtype); + if (speed < ownerSpeed || creature->IsWithinDist3d(followed, 10.0f)) + speed = ownerSpeed; + speed *= std::min(std::max(1.0f, 0.75f + (GetDistance(followed) - PET_FOLLOW_DIST) * 0.05f), 1.3f); + } + } + } } // Apply strongest slow aura mod to speed @@ -8170,6 +8169,12 @@ void Unit::SetSpeedRate(UnitMoveType mtype, float rate) } } +void Unit::RemoveAllFollowers() +{ + while (!m_followingMe.empty()) + (*m_followingMe.begin())->SetTarget(nullptr); +} + void Unit::setDeathState(DeathState s) { // Death state needs to be updated before RemoveAllAurasOnDeath() is called, to prevent entering combat @@ -9076,6 +9081,8 @@ void Unit::RemoveFromWorld() RemoveAreaAurasDueToLeaveWorld(); + RemoveAllFollowers(); + if (!GetCharmerGUID().IsEmpty()) { TC_LOG_FATAL("entities.unit", "Unit %u has charmer guid when removed from world", GetEntry()); diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 161ab077283..25e694d758c 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -19,8 +19,6 @@ #define __UNIT_H #include "Object.h" -#include "FollowerReference.h" -#include "FollowerRefManager.h" #include "CombatManager.h" #include "OptionalFwd.h" #include "SpellAuraDefines.h" @@ -65,6 +63,7 @@ enum InventorySlot NULL_SLOT = 255 }; +struct AbstractFollower; struct FactionTemplateEntry; struct LiquidData; struct LiquidTypeEntry; @@ -793,7 +792,8 @@ class TC_GAME_API Unit : public WorldObject float GetBoundingRadius() const { return m_unitData->BoundingRadius; } void SetBoundingRadius(float boundingRadius) { SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::BoundingRadius), boundingRadius); } bool IsWithinCombatRange(Unit const* obj, float dist2compare) const; - bool IsWithinMeleeRange(Unit const* obj) const; + bool IsWithinMeleeRange(Unit const* obj) const { return IsWithinMeleeRangeAt(GetPosition(), obj); } + bool IsWithinMeleeRangeAt(Position const& pos, Unit const* obj) const; float GetMeleeRange(Unit const* target) const; virtual SpellSchoolMask GetMeleeDamageSchoolMask(WeaponAttackType attackType = BASE_ATTACK) const = 0; bool IsWithinBoundaryRadius(const Unit* obj) const; @@ -1684,8 +1684,9 @@ class TC_GAME_API Unit : public WorldObject void SetSpeed(UnitMoveType mtype, float newValue); void SetSpeedRate(UnitMoveType mtype, float rate); - void addFollower(FollowerReference* pRef) { m_FollowingRefManager.insertFirst(pRef); } - void removeFollower(FollowerReference* /*pRef*/) { /* nothing to do yet */ } + void FollowerAdded(AbstractFollower* f) { m_followingMe.insert(f); } + void FollowerRemoved(AbstractFollower* f) { m_followingMe.erase(f); } + void RemoveAllFollowers(); MotionMaster* GetMotionMaster() { return i_motionMaster; } MotionMaster const* GetMotionMaster() const { return i_motionMaster; } @@ -1953,7 +1954,7 @@ class TC_GAME_API Unit : public WorldObject friend class ThreatManager; ThreatManager m_threatManager; - FollowerRefManager m_FollowingRefManager; + std::unordered_set<AbstractFollower*> m_followingMe; bool m_cleanupDone; // lock made to not add stuff after cleanup before delete bool m_duringRemoveFromWorld; // lock made to not add stuff after begining removing from world |
