fix(Core/CreatureAI): revert NPC repositioning and path system (temporarily) (#4274)

This commit is contained in:
Stefano Borzì
2021-01-14 19:17:34 +01:00
committed by GitHub
parent b42f2386c2
commit df600f9946
22 changed files with 773 additions and 1418 deletions

View File

@@ -153,28 +153,9 @@ ProcEventInfo::ProcEventInfo(Unit* actor, Unit* actionTarget, Unit* procTarget,
#pragma warning(disable:4355)
#endif
Unit::Unit(bool isWorldObject) : WorldObject(isWorldObject),
m_movedByPlayer(nullptr),
m_lastSanctuaryTime(0),
IsAIEnabled(false),
NeedChangeAI(false),
m_ControlledByPlayer(false),
m_CreatedByPlayer(false),
movespline(new Movement::MoveSpline()),
i_AI(nullptr),
i_disabledAI(nullptr),
m_realRace(0),
m_race(0),
m_AutoRepeatFirstCast(false),
m_procDeep(0),
m_removedAurasCount(0),
i_motionMaster(new MotionMaster(this)),
m_regenTimer(0),
m_ThreatManager(this),
m_vehicle(nullptr),
m_vehicleKit(nullptr),
m_unitTypeMask(UNIT_MASK_NONE),
m_HostileRefManager(this),
m_comboTarget(nullptr)
m_movedByPlayer(nullptr), m_lastSanctuaryTime(0), IsAIEnabled(false), NeedChangeAI(false),
m_ControlledByPlayer(false), m_CreatedByPlayer(false), movespline(new Movement::MoveSpline()), i_AI(nullptr), i_disabledAI(nullptr), m_realRace(0), m_race(0), m_AutoRepeatFirstCast(false), m_procDeep(0), m_removedAurasCount(0),
i_motionMaster(new MotionMaster(this)), m_regenTimer(0), m_ThreatManager(this), m_vehicle(nullptr), m_vehicleKit(nullptr), m_unitTypeMask(UNIT_MASK_NONE), m_HostileRefManager(this)
{
#ifdef _MSC_VER
#pragma warning(default:4355)
@@ -596,21 +577,6 @@ bool Unit::IsWithinMeleeRange(const Unit* obj, float dist) const
return distsq < maxdist * maxdist;
}
bool Unit::IsWithinRange(Unit const* obj, float dist) const
{
if (!obj || !IsInMap(obj) || !InSamePhase(obj))
{
return false;
}
auto dx = GetPositionX() - obj->GetPositionX();
auto dy = GetPositionY() - obj->GetPositionY();
auto dz = GetPositionZ() - obj->GetPositionZ();
auto distsq = dx * dx + dy * dy + dz * dz;
return distsq <= dist * dist;
}
bool Unit::GetRandomContactPoint(const Unit* obj, float& x, float& y, float& z, bool force) const
{
float combat_reach = GetCombatReach();
@@ -2222,125 +2188,6 @@ void Unit::AttackerStateUpdate (Unit* victim, WeaponAttackType attType, bool ext
}
}
Position* Unit::GetMeleeAttackPoint(Unit* attacker)
{
if (!attacker) // only player & pets to save CPU
{
return nullptr;
}
AttackerSet attackers = getAttackers();
if (attackers.size() <= 1) // if the attackers are not more than one
{
return nullptr;
}
float meleeReach = attacker->GetMeleeReach();
if (meleeReach <= 0)
{
return nullptr;
}
float currentAngle, minDistance = 0;
Unit *refUnit = nullptr;
uint32 validAttackers=0;
for (const auto& otherAttacker: attackers)
{
// if the otherAttacker is not valid, skip
if (!otherAttacker ||
otherAttacker->GetGUID() == attacker->GetGUID() ||
!otherAttacker->IsWithinMeleeRange(this) ||
otherAttacker->isMoving()
)
{
continue;
}
float tempDist = attacker->GetExactDist2d(otherAttacker) - (attacker->GetObjectSize()/2) - (otherAttacker->GetObjectSize()/2);
if (tempDist == 0 || minDistance == 0 || tempDist < minDistance)
{
minDistance = tempDist;
currentAngle = GetAngle(otherAttacker);
refUnit = otherAttacker;
}
validAttackers++;
}
auto attackerSize = attacker->GetObjectSize();
// in instance: the more attacker there are, the higher will be the tollerance
// outside: creatures should not intersecate
float distanceTollerance = attacker->GetMap()->IsDungeon() ? -attackerSize * tanh(validAttackers / 5.0f) : 0.0f;
if (!refUnit || minDistance > distanceTollerance)
{
return nullptr;
}
double ray = attackerSize > refUnit->GetObjectSize() ? attackerSize / 2.0f : refUnit->GetObjectSize() / 2.0f;
double angle = 0;
// Equation of tangent point to get the ideal angle to
// move away from collisions with another unit during combat
// NOTE: it works only when there's enough space between the
// attacker and the victim. We use a simpler one otherwise.
if (GetExactDist2d(refUnit) > ray)
{
double refUnitX = refUnit->GetPositionX();
double refUnitY = refUnit->GetPositionY();
double victimX = GetPositionX();
double victimY = GetPositionY();
// calculate tangent star
double a = 4.0f * ( pow(ray,2.0f) - pow(refUnitX,2.0f) + (2.0f * refUnitX * victimX) - pow(victimX,2.0f) );
double b = 8.0f * ( (refUnitX * refUnitY) + (victimX * victimY) - (victimX * refUnitY) - (refUnitX * victimY) );
double c = 4.0f * (- pow(victimY,2.0f) - pow(refUnitY,2.0f) + (2.0f*victimY*refUnitY) + pow(ray,2.0f));
double sq = sqrt(pow(b,2.0f)-4.0f*a*c);
double m1 = (-b + sq) / (2.0f*a);
double m2 = (-b - sq) / (2.0f*a);
// tangents
double xT1 = ((-1.0f) * (m1*(victimY - m1*victimX - refUnitY) - refUnitX) ) / (1.0f + pow(m1,2.0f));
double xT2 = ((-1.0f) * (m2*(victimY - m2*victimX - refUnitY) - refUnitX) ) / (1.0f + pow(m2,2.0f));
double yT1 = m1*(xT1 - victimX) + victimY;
double yT2 = m2*(xT2 - victimX) + victimY;
double distance = sqrt(pow(yT2-yT1,2.0f) + pow(xT2-xT1,2.0f));
double exactDist = GetExactDist2d(xT1, yT1);
double ortDist = sqrt(pow(exactDist,2.0f) - pow(distance/2.0f,2.0f));
angle = 2.0f * atan(distance / (2.0f * ortDist));
}
int8 direction = (urand(0, 1) ? -1 : 1);
angle = frand(0.1f,0.3f) + (angle && !isnan(angle) ? angle : atan(attackerSize / (meleeReach))); // or fallback to the simpler method
float x, y, z;
GetNearPoint(attacker, x, y, z, attackerSize, 0.0f, currentAngle + angle * direction);
if (!GetMap()->CanReachPositionAndGetCoords(this, x, y, z))
{
GetNearPoint(attacker, x, y, z, attackerSize, 0.0f, currentAngle + angle * (direction * -1)); // try the other side
if (!GetMap()->CanReachPositionAndGetCoords(this, x, y, z))
{
return nullptr;
}
}
return new Position(x,y,z);
}
void Unit::HandleProcExtraAttackFor(Unit* victim)
{
while (m_extraAttacks)
@@ -12699,7 +12546,7 @@ void Unit::Mount(uint32 mount, uint32 VehicleId, uint32 creatureEntry)
WorldPacket data(SMSG_MOVE_SET_COLLISION_HGT, GetPackGUID().size() + 4 + 4);
data.append(GetPackGUID());
data << uint32(sWorld->GetGameTime()); // Packet counter
data << player->GetCollisionHeight();
data << player->GetCollisionHeight(true);
player->GetSession()->SendPacket(&data);
}
@@ -12719,7 +12566,7 @@ void Unit::Dismount()
WorldPacket data(SMSG_MOVE_SET_COLLISION_HGT, GetPackGUID().size() + 4 + 4);
data.append(GetPackGUID());
data << uint32(sWorld->GetGameTime()); // Packet counter
data << thisPlayer->GetCollisionHeight();
data << thisPlayer->GetCollisionHeight(false);
thisPlayer->GetSession()->SendPacket(&data);
}
@@ -19988,32 +19835,3 @@ bool Unit::IsInCombatWith(Unit const* who) const
// Nothing found, false.
return false;
}
//! Return collision height sent to client
float Unit::GetCollisionHeight() const
{
uint32 nativeDisplayId = GetNativeDisplayId();
if (IsMounted())
{
if (CreatureDisplayInfoEntry const* mountDisplayInfo = sCreatureDisplayInfoStore.LookupEntry(GetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID));
CreatureModelDataEntry const* mountModelData = sCreatureModelDataStore.LookupEntry(mountDisplayInfo->ModelId))
{
CreatureDisplayInfoEntry const* displayInfo = sCreatureDisplayInfoStore.LookupEntry(nativeDisplayId);
ASSERT(displayInfo);
CreatureModelDataEntry const* modelData = sCreatureModelDataStore.LookupEntry(displayInfo->ModelId);
ASSERT(modelData);
float scaleMod = GetFloatValue(OBJECT_FIELD_SCALE_X); // 99% sure about this
return scaleMod * mountModelData->MountHeight + modelData->CollisionHeight * 0.5f;
}
}
//! Dismounting case - use basic default model data
CreatureDisplayInfoEntry const* displayInfo = sCreatureDisplayInfoStore.LookupEntry(nativeDisplayId);
ASSERT(displayInfo);
CreatureModelDataEntry const* modelData = sCreatureModelDataStore.LookupEntry(displayInfo->ModelId);
ASSERT(modelData);
return modelData->CollisionHeight;
}