Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Core/Pathfinding] Some improvements... hopefully... #3658

Merged
merged 16 commits into from
Dec 1, 2020
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/server/game/AI/CreatureAI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ bool CreatureAI::_EnterEvadeMode()
me->SetLootRecipient(nullptr);
me->ResetPlayerDamageReq();
me->SetLastDamagedTime(0);
me->SetCannotReachTarget(false);

if (me->IsInEvadeMode())
return false;
Expand Down
7 changes: 1 addition & 6 deletions src/server/game/AI/SmartScripts/SmartAI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -626,12 +626,7 @@ void SmartAI::EnterEvadeMode()
me->RemoveEvadeAuras();

me->AddUnitState(UNIT_STATE_EVADE);
me->DeleteThreatList();
me->CombatStop(true);
me->LoadCreaturesAddon(true);
me->SetLootRecipient(nullptr);
me->ResetPlayerDamageReq();
me->SetLastDamagedTime(0);
_EnterEvadeMode();

GetScript()->ProcessEventsFor(SMART_EVENT_EVADE);//must be after aura clear so we can cast spells from db

Expand Down
12 changes: 11 additions & 1 deletion src/server/game/Entities/Creature/Creature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@
#include "LuaEngine.h"
#endif

uint32 DEF_CANNOT_REACH = 5 * IN_MILLISECONDS; // 5s ok?
FALL1N1 marked this conversation as resolved.
Show resolved Hide resolved

TrainerSpell const* TrainerSpellData::Find(uint32 spell_id) const
{
TrainerSpellMap::const_iterator itr = spellList.find(spell_id);
Expand Down Expand Up @@ -164,7 +166,7 @@ Creature::Creature(bool isWorldObject): Unit(isWorldObject), MovableMapObject(),
m_transportCheckTimer(1000), lootPickPocketRestoreTime(0), m_reactState(REACT_AGGRESSIVE), m_defaultMovementType(IDLE_MOTION_TYPE),
m_DBTableGuid(0), m_equipmentId(0), m_originalEquipmentId(0), m_AlreadyCallAssistance(false),
m_AlreadySearchedAssistance(false), m_regenHealth(true), m_AI_locked(false), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL), m_originalEntry(0), m_moveInLineOfSightDisabled(false), m_moveInLineOfSightStrictlyDisabled(false),
m_homePosition(), m_transportHomePosition(), m_creatureInfo(nullptr), m_creatureData(nullptr), m_waypointID(0), m_path_id(0), m_formation(nullptr), _lastDamagedTime(0)
m_homePosition(), m_transportHomePosition(), m_creatureInfo(nullptr), m_creatureData(nullptr), m_waypointID(0), m_path_id(0), m_formation(nullptr), _lastDamagedTime(0), m_cannotReachTarget(false), m_cannotReachTimer(0)
{
m_regenTimer = CREATURE_REGEN_INTERVAL;
m_valuesCount = UNIT_END;
Expand Down Expand Up @@ -610,6 +612,14 @@ void Creature::Update(uint32 diff)

m_regenTimer += CREATURE_REGEN_INTERVAL;
}

if (CanNotReachTarget() && !IsInEvadeMode() && !GetMap()->IsRaid())
{
m_cannotReachTimer += diff;
if (m_cannotReachTimer >= DEF_CANNOT_REACH && IsAIEnabled)
AI()->EnterEvadeMode();
FALL1N1 marked this conversation as resolved.
Show resolved Hide resolved
}

FALL1N1 marked this conversation as resolved.
Show resolved Hide resolved
break;
}
default:
Expand Down
6 changes: 6 additions & 0 deletions src/server/game/Entities/Creature/Creature.h
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,7 @@ class Creature : public Unit, public GridObject<Creature>, public MovableMapObje
uint8 getLevelForTarget(WorldObject const* target) const override; // overwrite Unit::getLevelForTarget for boss level support

bool IsInEvadeMode() const { return HasUnitState(UNIT_STATE_EVADE); }
bool IsEvadingAttacks() const { return IsInEvadeMode() || CanNotReachTarget(); }

bool AIM_Initialize(CreatureAI* ai = nullptr);
void Motion_Initialize();
Expand Down Expand Up @@ -664,6 +665,9 @@ class Creature : public Unit, public GridObject<Creature>, public MovableMapObje
return m_charmInfo->GetCharmSpell(pos)->GetAction();
}

void SetCannotReachTarget(bool cannotReach) { if (cannotReach == m_cannotReachTarget) return; m_cannotReachTarget = cannotReach; m_cannotReachTimer = 0; }
bool CanNotReachTarget() const { return m_cannotReachTarget; }

void SetPosition(float x, float y, float z, float o);
void SetPosition(const Position& pos) { SetPosition(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation()); }

Expand Down Expand Up @@ -751,6 +755,8 @@ class Creature : public Unit, public GridObject<Creature>, public MovableMapObje
bool m_AlreadySearchedAssistance;
bool m_regenHealth;
bool m_AI_locked;
bool m_cannotReachTarget;
uint32 m_cannotReachTimer;

SpellSchoolMask m_meleeDamageSchoolMask;
uint32 m_originalEntry;
Expand Down
12 changes: 6 additions & 6 deletions src/server/game/Entities/Unit/Unit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -665,7 +665,7 @@ bool Unit::HasBreakableByDamageCrowdControlAura(Unit* excludeCasterChannel) cons

void Unit::DealDamageMods(Unit const* victim, uint32& damage, uint32* absorb)
{
if (!victim || !victim->IsAlive() || victim->IsInFlight() || (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsInEvadeMode()))
if (!victim || !victim->IsAlive() || victim->IsInFlight() || (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsEvadingAttacks()))
{
if (absorb)
*absorb += damage;
Expand Down Expand Up @@ -1231,7 +1231,7 @@ void Unit::DealSpellDamage(SpellNonMeleeDamage* damageInfo, bool durabilityLoss)
if (!victim)
return;

if (!victim->IsAlive() || victim->IsInFlight() || (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsInEvadeMode()))
if (!victim->IsAlive() || victim->IsInFlight() || (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsEvadingAttacks()))
return;

SpellInfo const* spellProto = sSpellMgr->GetSpellInfo(damageInfo->SpellID);
Expand Down Expand Up @@ -1462,7 +1462,7 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss)
{
Unit* victim = damageInfo->target;

if (!victim->IsAlive() || victim->IsInFlight() || (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsInEvadeMode()))
if (!victim->IsAlive() || victim->IsInFlight() || (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsEvadingAttacks()))
return;

// Hmmmm dont like this emotes client must by self do all animations
Expand Down Expand Up @@ -2218,7 +2218,7 @@ MeleeHitOutcome Unit::RollMeleeOutcomeAgainst(const Unit* victim, WeaponAttackTy
MeleeHitOutcome Unit::RollMeleeOutcomeAgainst(const Unit* victim, WeaponAttackType attType, int32 crit_chance, int32 miss_chance, int32 dodge_chance, int32 parry_chance, int32 block_chance) const
{

if (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsInEvadeMode())
if (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsEvadingAttacks())
return MELEE_HIT_EVADE;

int32 attackerMaxSkillValueForLevel = GetMaxSkillValueForLevel(victim);
Expand Down Expand Up @@ -2891,7 +2891,7 @@ SpellMissInfo Unit::SpellHitResult(Unit* victim, SpellInfo const* spell, bool Ca
return SPELL_MISS_NONE;

// Return evade for units in evade mode
if (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsInEvadeMode() && !spell->HasAura(SPELL_AURA_CONTROL_VEHICLE))
if (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsEvadingAttacks() && !spell->HasAura(SPELL_AURA_CONTROL_VEHICLE))
return SPELL_MISS_EVADE;

// Try victim reflect spell
Expand Down Expand Up @@ -9580,7 +9580,7 @@ bool Unit::Attack(Unit* victim, bool meleeAttack)
}
else
{
if (victim->ToCreature()->IsInEvadeMode())
if (victim->ToCreature()->IsEvadingAttacks())
return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ void FleeingMovementGenerator<T>::_setTargetLocation(T* owner)

if (!isInLOS)
{
i_nextCheckTime.Reset(500);
i_nextCheckTime.Reset(100);
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ void PointMovementGenerator<T>::DoInitialize(T* unit)
i_y += 0.2f * sin(unit->GetOrientation());
}

init.MoveTo(i_x, i_y, i_z);
init.MoveTo(i_x, i_y, i_z, true);
}
}
else
Expand All @@ -55,7 +55,7 @@ void PointMovementGenerator<T>::DoInitialize(T* unit)
i_y += 0.2f * sin(unit->GetOrientation());
}

init.MoveTo(i_x, i_y, i_z);
init.MoveTo(i_x, i_y, i_z, true);
}
if (speed > 0.0f)
init.SetVelocity(speed);
Expand Down Expand Up @@ -101,10 +101,10 @@ bool PointMovementGenerator<T>::DoUpdate(T* unit, uint32 /*diff*/)
if (m_precomputedPath.size() > 2)
init.MovebyPath(m_precomputedPath);
else if (m_precomputedPath.size() == 2)
init.MoveTo(m_precomputedPath[1].x, m_precomputedPath[1].y, m_precomputedPath[1].z);
init.MoveTo(m_precomputedPath[1].x, m_precomputedPath[1].y, m_precomputedPath[1].z, true);
}
else
init.MoveTo(i_x, i_y, i_z);
init.MoveTo(i_x, i_y, i_z, true);
if (speed > 0.0f) // Default value for point motion type is 0.0, if 0.0 spline will use GetSpeed on unit
init.SetVelocity(speed);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,21 @@ void TargetedMovementGeneratorMedium<T, D>::_setTargetLocation(T* owner, bool in
if (owner->GetMapId() == 631 && owner->GetTransport() && owner->GetTransport()->IsMotionTransport() && i_target->GetTransport() && i_target->GetTransport()->IsMotionTransport()) // for ICC, if both on a motion transport => don't use mmaps
sameTransport = owner->GetTypeId() == TYPEID_UNIT && i_target->isInAccessiblePlaceFor(owner->ToCreature());
bool useMMaps = MMAP::MMapFactory::IsPathfindingEnabled(owner->FindMap()) && !sameTransport;
bool forceDest = (owner->FindMap() && owner->FindMap()->IsDungeon() && !isPlayerPet) || // force in instances to prevent exploiting
(owner->GetTypeId() == TYPEID_UNIT && ((owner->IsPet() && owner->HasUnitState(UNIT_STATE_FOLLOW)) || // allow pets following their master to cheat while generating paths
((Creature*)owner)->isWorldBoss() || ((Creature*)owner)->IsDungeonBoss())) || // force for all bosses, even not in instances
bool forceDest =
// (owner->FindMap() && owner->FindMap()->IsDungeon() && !isPlayerPet) || // force in instances to prevent exploiting
(owner->GetTypeId() == TYPEID_UNIT && ((owner->IsPet() && owner->HasUnitState(UNIT_STATE_FOLLOW)))) || // allow pets following their master to cheat while generating paths
// ((Creature*)owner)->isWorldBoss() || ((Creature*)owner)->IsDungeonBoss())) || // force for all bosses, even not in instances
FALL1N1 marked this conversation as resolved.
Show resolved Hide resolved
(owner->GetMapId() == 572 && (owner->GetPositionX() < 1275.0f || i_target->GetPositionX() < 1275.0f)) || // pussywizard: Ruins of Lordaeron - special case (acid)
sameTransport || // nothing to comment, can't find path on transports so allow it
(i_target->GetTypeId() == TYPEID_PLAYER && i_target->ToPlayer()->IsGameMaster()); // for .npc follow
(i_target->GetTypeId() == TYPEID_PLAYER && i_target->ToPlayer()->IsGameMaster()) // for .npc follow*/
; // closes "bool forceDest", that way it is more appropriate, so we can comment out crap whenever we need to
bool forcePoint = ((!isPlayerPet || owner->GetMapId() == 618) && (forceDest || !useMMaps)) || sameTransport;

if (owner->GetTypeId() == TYPEID_UNIT && !i_target->isInAccessiblePlaceFor(owner->ToCreature()) && !sameTransport && !forceDest && !forcePoint)
{
owner->ToCreature()->SetCannotReachTarget(true);
return;
}

lastOwnerXYZ.Relocate(owner->GetPositionX(), owner->GetPositionY(), owner->GetPositionZ());
lastTargetXYZ.Relocate(i_target->GetPositionX(), i_target->GetPositionY(), i_target->GetPositionZ());
Expand Down Expand Up @@ -186,6 +191,10 @@ void TargetedMovementGeneratorMedium<T, D>::_setTargetLocation(T* owner, bool in
float maxDist = MELEE_RANGE + owner->GetMeleeReach() + i_target->GetMeleeReach();
if (!forceDest && (i_path->GetPathType() & PATHFIND_NOPATH || (!i_offset && !isPlayerPet && i_target->GetExactDistSq(i_path->GetActualEndPosition().x, i_path->GetActualEndPosition().y, i_path->GetActualEndPosition().z) > maxDist * maxDist)))
{
// unsure, @todo
if (owner->GetTypeId() == TYPEID_UNIT)
owner->ToCreature()->SetCannotReachTarget(false);
FALL1N1 marked this conversation as resolved.
Show resolved Hide resolved

lastPathingFailMSTime = World::GetGameTimeMS();
owner->m_targetsNotAcceptable[i_target->GetGUID()] = MMapTargetData(sWorld->GetGameTime() + DISALLOW_TIME_AFTER_FAIL, owner, i_target.getTarget());
return;
Expand All @@ -203,8 +212,13 @@ void TargetedMovementGeneratorMedium<T, D>::_setTargetLocation(T* owner, bool in
return;
}
}

// if failed to generate, just use normal MoveTo
else
{
// evade first
if (owner->GetTypeId() == TYPEID_UNIT)
owner->ToCreature()->SetCannotReachTarget(true);
FALL1N1 marked this conversation as resolved.
Show resolved Hide resolved
// then use normal MoveTo - if we have to
}
}

owner->AddUnitState(UNIT_STATE_CHASE);
Expand Down
5 changes: 3 additions & 2 deletions src/tools/mmaps_generator/MapBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -602,10 +602,11 @@ namespace MMAP
config.walkableRadius = m_bigBaseUnit ? 1 : 2;
config.borderSize = config.walkableRadius + 3;
config.maxEdgeLen = VERTEX_PER_TILE + 1; // anything bigger than tileSize
config.walkableHeight = m_bigBaseUnit ? 3 : 6;
// a value >= 3|6 allows npcs to walk over some fences
// a value >= 4|8 allows npcs to walk over all fences
config.walkableClimb = m_bigBaseUnit ? 4 : 8;
// we prefer 3 and 6 for both Height/Climb as it's closer to be like retail
config.walkableHeight = m_bigBaseUnit ? 3 : 6;
config.walkableClimb = m_bigBaseUnit ? 3 : 6;
FALL1N1 marked this conversation as resolved.
Show resolved Hide resolved
config.minRegionArea = rcSqr(60);
config.mergeRegionArea = rcSqr(50);
config.maxSimplificationError = 1.8f; // eliminates most jagged edges (tiny polygons)
Expand Down
2 changes: 1 addition & 1 deletion src/tools/mmaps_generator/MapBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ namespace MMAP
class MapBuilder
{
public:
MapBuilder(float maxWalkableAngle = 70.f,
MapBuilder(float maxWalkableAngle = 60.f,
bool skipLiquid = false,
bool skipContinents = false,
bool skipJunkMaps = true,
Expand Down
2 changes: 1 addition & 1 deletion src/tools/mmaps_generator/PathGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ int main(int argc, char** argv)
{
unsigned int threads = std::thread::hardware_concurrency();
int mapnum = -1;
float maxAngle = 70.0f;
float maxAngle = 60.0f;
int tileX = -1, tileY = -1;
bool skipLiquid = false,
skipContinents = false,
Expand Down