From 5880593cb1242f4be858dba13de6aac4670f6011 Mon Sep 17 00:00:00 2001 From: Paul Coene Date: Fri, 17 Nov 2017 13:12:26 -0500 Subject: [PATCH] MoveTo while saving guard position no longer hops. --- zone/mob.cpp | 15 ++++++-- zone/mob.h | 6 ++-- zone/mob_ai.cpp | 18 ++++++---- zone/waypoints.cpp | 86 ++++++++++++++++++++++++++++------------------ 4 files changed, 79 insertions(+), 46 deletions(-) diff --git a/zone/mob.cpp b/zone/mob.cpp index efb2922f0..28ee296ee 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -123,8 +123,6 @@ Mob::Mob(const char* in_name, tar_vector=0; currently_fleeing = false; - last_z = 0; - last_major_update_position = m_Position; AI_Init(); @@ -3439,6 +3437,19 @@ void Mob::SetTarget(Mob* mob) { this->GetTarget()->SendHPUpdate(false, true); } +// For when we want a Ground Z at a location we are not at yet +// Like MoveTo. +float Mob::FindDestGroundZ(glm::vec3 dest, float z_offset) +{ + float best_z = BEST_Z_INVALID; + if (zone->zonemap != nullptr) + { + dest.z += z_offset; + best_z = zone->zonemap->FindBestZ(dest, nullptr); + } + return best_z; +} + float Mob::FindGroundZ(float new_x, float new_y, float z_offset) { float ret = BEST_Z_INVALID; diff --git a/zone/mob.h b/zone/mob.h index 058774c54..812f54ca1 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -954,7 +954,8 @@ public: void SendTo(float new_x, float new_y, float new_z); void SendToFixZ(float new_x, float new_y, float new_z); float GetZOffset() const; - void FixZ(int32 z_find_offset = 5); + void FixZ(int32 z_find_offset = 5); + float GetFixedZ(glm::vec3 position, int32 z_find_offset = 5); void NPCSpecialAttacks(const char* parse, int permtag, bool reset = true, bool remove = false); inline uint32 DontHealMeBefore() const { return pDontHealMeBefore; } inline uint32 DontBuffMeBefore() const { return pDontBuffMeBefore; } @@ -1108,8 +1109,6 @@ public: int GetWeaponDamage(Mob *against, const EQEmu::ItemData *weapon_item); int GetWeaponDamage(Mob *against, const EQEmu::ItemInstance *weapon_item, uint32 *hate = nullptr); - float last_z; - // Bots HealRotation methods #ifdef BOTS bool IsHealRotationTarget() { return (m_target_of_heal_rotation.use_count() && m_target_of_heal_rotation.get()); } @@ -1267,6 +1266,7 @@ protected: virtual int16 GetFocusEffect(focusType type, uint16 spell_id) { return 0; } void CalculateNewFearpoint(); float FindGroundZ(float new_x, float new_y, float z_offset=0.0); + float FindDestGroundZ(glm::vec3 dest, float z_offset=0.0); glm::vec3 UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &WaypointChange, bool &NodeReached); void PrintRoute(); diff --git a/zone/mob_ai.cpp b/zone/mob_ai.cpp index 72c81d374..eb045488d 100644 --- a/zone/mob_ai.cpp +++ b/zone/mob_ai.cpp @@ -503,7 +503,7 @@ void NPC::AI_Start(uint32 iMoveDelay) { AIautocastspell_timer->Disable(); } else { AIautocastspell_timer = std::unique_ptr(new Timer(750)); - AIautocastspell_timer->Start(RandomTimer(0, 15000), false); + AIautocastspell_timer->Start(RandomTimer(0, 300), false); } if (NPCTypedata) { @@ -1582,18 +1582,22 @@ void NPC::AI_DoMovement() { } this->FixZ(); - SendPosition(); //kick off event_waypoint arrive char temp[16]; sprintf(temp, "%d", cur_wp); parse->EventNPC(EVENT_WAYPOINT_ARRIVE, CastToNPC(), nullptr, temp, 0); - // start moving directly to next waypoint if we're at a 0 pause waypoint and we didn't get quest halted. - if (!AI_walking_timer->Enabled()) + // No need to move as we are there. Next loop will + // take care of normal grids, even at pause 0. + // We do need to call and setup a wp if we're cur_wp=-2 + // as that is where roamer is unset and we don't want + // the next trip through to move again based on grid stuff. + doMove = false; + if (cur_wp == -2) { AI_SetupNextWaypoint(); - else - doMove = false; + } + // wipe feign memory since we reached our first waypoint if(cur_wp == 1) ClearFeignMemory(); @@ -2593,7 +2597,7 @@ void NPC::AddSpellToNPCList(int16 iPriority, int16 iSpellID, uint32 iType, // If we're going from an empty list, we need to start the timer if (AIspells.size() == 1) - AIautocastspell_timer->Start(RandomTimer(0, 15000), false); + AIautocastspell_timer->Start(RandomTimer(0, 300), false); } void NPC::RemoveSpellFromNPCList(int16 spell_id) diff --git a/zone/waypoints.cpp b/zone/waypoints.cpp index ca0d24175..967325fd8 100644 --- a/zone/waypoints.cpp +++ b/zone/waypoints.cpp @@ -176,9 +176,15 @@ void NPC::MoveTo(const glm::vec4& position, bool saveguardspot) cur_wp = -2; // flag as quest controlled w/no grid Log(Logs::Detail, Logs::AI, "MoveTo %s without a grid.", to_string(static_cast(position)).c_str()); } + + glm::vec3 dest(position); + + m_CurrentWayPoint = position; + m_CurrentWayPoint.z = GetFixedZ(dest); + if (saveguardspot) { - m_GuardPoint = position; + m_GuardPoint = m_CurrentWayPoint; if (m_GuardPoint.w == 0) m_GuardPoint.w = 0.0001; //hack to make IsGuarding simpler @@ -189,7 +195,6 @@ void NPC::MoveTo(const glm::vec4& position, bool saveguardspot) Log(Logs::Detail, Logs::AI, "Setting guard position to %s", to_string(static_cast(m_GuardPoint)).c_str()); } - m_CurrentWayPoint = position; cur_wp_pause = 0; pLastFightingDelayMoving = 0; if (AI_walking_timer->Enabled()) @@ -838,49 +843,62 @@ void Mob::SendToFixZ(float new_x, float new_y, float new_z) { } } -void Mob::FixZ(int32 z_find_offset /*= 5*/) +float Mob::GetFixedZ(glm::vec3 dest, int32 z_find_offset) { - BenchTimer timer; timer.reset(); + float new_z = dest.z; - if (zone->HasMap() && RuleB(Map, FixZWhenMoving) && (flymode != 1 && flymode != 2)) + if (zone->HasMap() && RuleB(Map, FixZWhenMoving) && + (flymode != 1 && flymode != 2)) { - if (!RuleB(Watermap, CheckForWaterWhenMoving) || !zone->HasWaterMap() || - (zone->HasWaterMap() && !zone->watermap->InWater(glm::vec3(m_Position)))) + if (!RuleB(Watermap, CheckForWaterWhenMoving) || !zone->HasWaterMap() + || (zone->HasWaterMap() && + !zone->watermap->InWater(glm::vec3(m_Position)))) { /* Any more than 5 in the offset makes NPC's hop/snap to ceiling in small corridors */ - float new_z = this->FindGroundZ(m_Position.x, m_Position.y, z_find_offset); - new_z += this->GetZOffset(); + new_z = this->FindDestGroundZ(dest,z_find_offset); + if (new_z != BEST_Z_INVALID) + { + new_z += this->GetZOffset(); - auto duration = timer.elapsed(); - - Log( - Logs::Moderate, - Logs::FixZ, - "Mob::FixZ() (%s) returned %4.3f at %4.3f, %4.3f, %4.3f - Took %lf", - this->GetCleanName(), - new_z, - m_Position.x, - m_Position.y, - m_Position.z, - duration - ); - - if ((new_z > -2000) && new_z != BEST_Z_INVALID) { - if (RuleB(Map, MobZVisualDebug)) - this->SendAppearanceEffect(78, 0, 0, 0, 0); - - m_Position.z = new_z; + // If bad new Z restore old one + if (new_z < -2000) { + new_z = m_Position.z; + } } - else { - if (RuleB(Map, MobZVisualDebug)) - this->SendAppearanceEffect(103, 0, 0, 0, 0); + } - Log(Logs::General, Logs::FixZ, "%s is failing to find Z %f", this->GetCleanName(), std::abs(m_Position.z - new_z)); - } + auto duration = timer.elapsed(); - last_z = m_Position.z; + Log(Logs::Moderate, Logs::FixZ, + "Mob::FixZ() (%s) returned %4.3f at %4.3f, %4.3f, %4.3f - Took %lf", + this->GetCleanName(), new_z, m_Position.x, m_Position.y, + m_Position.z, duration); + } + + return new_z; +} + +void Mob::FixZ(int32 z_find_offset /*= 5*/) +{ + glm::vec3 current_loc(m_Position); + float new_z=GetFixedZ(current_loc, z_find_offset); + + if (new_z != m_Position.z) + { + if ((new_z > -2000) && new_z != BEST_Z_INVALID) { + if (RuleB(Map, MobZVisualDebug)) + this->SendAppearanceEffect(78, 0, 0, 0, 0); + + m_Position.z = new_z; + } + else { + if (RuleB(Map, MobZVisualDebug)) + this->SendAppearanceEffect(103, 0, 0, 0, 0); + + Log(Logs::General, Logs::FixZ, "%s is failing to find Z %f", + this->GetCleanName(), std::abs(m_Position.z - new_z)); } } }