Core/Movement: ported and merged Follow and Chase movement generator rewrite
This commit is contained in:
1 parent
33566426aa
commit
7edabcbd88
25 files changed
+666
-725
No files matched your search
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
|
||||
#include "Unit.h"
|
||||
#include "AbstractFollower.h"
|
||||
#include "Battlefield.h"
|
||||
#include "BattlefieldMgr.h"
|
||||
#include "Battleground.h"
|
||||
@@ -623,14 +624,19 @@ 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 = GetPositionZMinusOffset() - obj->GetPositionZMinusOffset();
|
||||
float dx = pos.GetPositionX() - obj->GetPositionX();
|
||||
float dy = pos.GetPositionY() - obj->GetPositionY();
|
||||
|
||||
float z = pos.GetPositionZ();
|
||||
if (HasUnitMovementFlag(MOVEMENTFLAG_HOVER))
|
||||
z -= GetFloatValue(UNIT_FIELD_HOVERHEIGHT);
|
||||
|
||||
float dz = z - obj->GetPositionZMinusOffset();
|
||||
float distsq = dx*dx + dy*dy + dz*dz;
|
||||
|
||||
float maxdist = GetMeleeRange(obj);
|
||||
@@ -9008,25 +9014,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
|
||||
@@ -9050,11 +9038,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()->topOrNull();
|
||||
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
|
||||
@@ -9130,6 +9134,12 @@ void Unit::SetSpeedRate(UnitMoveType mtype, float rate)
|
||||
Movement::PacketSender(this, moveTypeToOpcode[mtype][0], moveTypeToOpcode[mtype][1], moveTypeToOpcode[mtype][2], &extra).Send();
|
||||
}
|
||||
|
||||
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
|
||||
@@ -10274,6 +10284,8 @@ void Unit::RemoveFromWorld()
|
||||
|
||||
RemoveAreaAurasDueToLeaveWorld();
|
||||
|
||||
RemoveAllFollowers();
|
||||
|
||||
if (GetCharmerGUID())
|
||||
{
|
||||
TC_LOG_FATAL("entities.unit", "Unit %u has charmer guid when removed from world", GetEntry());
|
||||
|
||||
Reference in new issue
Block a user