fix(Core/Movement): Rewritten follow movement generator for pets (#7324)

- Closes #7296
This commit is contained in:
UltraNix
2021-08-24 11:08:50 +02:00
committed by GitHub
parent bbc071aa57
commit 1becd73f09
6 changed files with 209 additions and 150 deletions

View File

@@ -2539,7 +2539,7 @@ namespace Acore
//===================================================================================================
void WorldObject::GetNearPoint2D(WorldObject const* searcher, float& x, float& y, float distance2d, float absAngle) const
void WorldObject::GetNearPoint2D(WorldObject const* searcher, float& x, float& y, float distance2d, float absAngle, Position const* startPos) const
{
float effectiveReach = GetCombatReach();
@@ -2561,24 +2561,28 @@ void WorldObject::GetNearPoint2D(WorldObject const* searcher, float& x, float& y
}
}
x = GetPositionX() + (effectiveReach + distance2d) * std::cos(absAngle);
y = GetPositionY() + (effectiveReach + distance2d) * std::sin(absAngle);
float positionX = startPos ? startPos->GetPositionX() : GetPositionX();
float positionY = startPos ? startPos->GetPositionY() : GetPositionY();
x = positionX + (effectiveReach + distance2d) * std::cos(absAngle);
y = positionY + (effectiveReach + distance2d) * std::sin(absAngle);
Acore::NormalizeMapCoord(x);
Acore::NormalizeMapCoord(y);
}
void WorldObject::GetNearPoint2D(float& x, float& y, float distance2d, float absAngle) const
void WorldObject::GetNearPoint2D(float& x, float& y, float distance2d, float absAngle, Position const* startPos) const
{
GetNearPoint2D(nullptr, x, y, distance2d, absAngle);
GetNearPoint2D(nullptr, x, y, distance2d, absAngle, startPos);
}
void WorldObject::GetNearPoint(WorldObject const* searcher, float& x, float& y, float& z, float searcher_size, float distance2d, float absAngle, float controlZ) const
void WorldObject::GetNearPoint(WorldObject const* searcher, float& x, float& y, float& z, float searcher_size, float distance2d, float absAngle, float controlZ, Position const* startPos) const
{
GetNearPoint2D(x, y, distance2d + searcher_size, absAngle);
GetNearPoint2D(x, y, distance2d + searcher_size, absAngle, startPos);
z = GetPositionZ();
if (searcher) {
if (searcher)
{
if (Unit const* unit = searcher->ToUnit(); Unit const* target = ToUnit())
{
if (unit && target && unit->IsInWater() && target->IsInWater())
@@ -2614,7 +2618,7 @@ void WorldObject::GetNearPoint(WorldObject const* searcher, float& x, float& y,
// loop in a circle to look for a point in LoS using small steps
for (float angle = float(M_PI) / 8; angle < float(M_PI) * 2; angle += float(M_PI) / 8)
{
GetNearPoint2D(x, y, distance2d + searcher_size, absAngle + angle);
GetNearPoint2D(x, y, distance2d + searcher_size, absAngle + angle, startPos);
z = GetPositionZ();
UpdateAllowedPositionZ(x, y, z);
if (controlZ && fabsf(GetPositionZ() - z) > controlZ)

View File

@@ -19,6 +19,7 @@
#include <set>
#include <string>
#include <sstream>
#include "G3D/Vector3.h"
#ifdef ELUNA
class ElunaEventProcessor;
@@ -376,6 +377,11 @@ struct Position
return !(operator==(a));
}
operator G3D::Vector3() const
{
return { m_positionX, m_positionY, m_positionZ };
}
void Relocate(float x, float y)
{
m_positionX = x;
@@ -758,9 +764,9 @@ public:
ElunaEventProcessor* elunaEvents;
#endif
void GetNearPoint2D(WorldObject const* searcher, float& x, float& y, float distance, float absAngle) const;
void GetNearPoint2D(float& x, float& y, float distance, float absAngle) const;
void GetNearPoint(WorldObject const* searcher, float& x, float& y, float& z, float searcher_size, float distance2d, float absAngle, float controlZ = 0) const;
void GetNearPoint2D(WorldObject const* searcher, float& x, float& y, float distance, float absAngle, Position const* startPos = nullptr) const;
void GetNearPoint2D(float& x, float& y, float distance, float absAngle, Position const* startPos = nullptr) const;
void GetNearPoint(WorldObject const* searcher, float& x, float& y, float& z, float searcher_size, float distance2d, float absAngle, float controlZ = 0, Position const* startPos = nullptr) const;
void GetVoidClosePoint(float& x, float& y, float& z, float size, float distance2d = 0, float relAngle = 0, float controlZ = 0) const;
bool GetClosePoint(float& x, float& y, float& z, float size, float distance2d = 0, float angle = 0, const WorldObject* forWho = nullptr, bool force = false) const;
void MovePosition(Position& pos, float dist, float angle);

View File

@@ -13579,29 +13579,7 @@ void Unit::UpdateSpeed(UnitMoveType mtype, bool forced)
{
if (GetTypeId() == TYPEID_UNIT)
{
Unit* followed = nullptr;
if (GetMotionMaster()->GetCurrentMovementGeneratorType() == FOLLOW_MOTION_TYPE)
{
followed = static_cast<FollowMovementGenerator<Creature>const*>(GetMotionMaster()->top())->GetTarget();
}
if (followed && !IsInCombat() && !IsVehicle() && !HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_POSSESSED) && (IsPet() || IsGuardian() || GetGUID() == followed->GetCritterGUID() || GetCharmerOrOwnerGUID() == followed->GetGUID()))
{
if (followed->GetTypeId() != TYPEID_PLAYER)
{
if (speed < followed->GetSpeedRate(mtype) + 0.1f)
speed = followed->GetSpeedRate(mtype) + 0.1f; // pets derive speed from owner when not in combat
}
else
{
float ownerSpeed = followed->GetSpeedRate(mtype);
if (speed < ownerSpeed || IsWithinDist3d(followed, 10.0f))
speed = ownerSpeed;
speed *= std::min(std::max(1.0f, 0.75f + (GetDistance(followed) - PET_FOLLOW_DIST) * 0.05f), 1.3f);
}
}
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