From d0685556e8e092d04806f6e4f15ef0b40d60b297 Mon Sep 17 00:00:00 2001 From: KimLS Date: Sat, 13 Oct 2018 23:53:16 -0700 Subject: [PATCH] Bunch of bug fixes, guard behavior works again --- zone/bot.cpp | 6 ++-- zone/client_packet.cpp | 6 ++-- zone/command.cpp | 41 ++----------------------- zone/merc.cpp | 6 ++-- zone/mob.cpp | 24 ++++----------- zone/mob.h | 4 ++- zone/mob_ai.cpp | 53 +++++++++++---------------------- zone/mob_movement_manager.cpp | 56 ++++++++++++++++++++++++++++------- zone/mob_movement_manager.h | 7 ++--- zone/npc.cpp | 5 ++-- zone/position.cpp | 5 ++++ zone/position.h | 2 ++ zone/spells.cpp | 3 +- zone/waypoints.cpp | 31 +++++++++++++++---- 14 files changed, 120 insertions(+), 129 deletions(-) diff --git a/zone/bot.cpp b/zone/bot.cpp index 3cb75187d..712d572b5 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -280,7 +280,7 @@ void Bot::ChangeBotArcherWeapons(bool isArcher) { void Bot::Sit() { if(IsMoving()) { moved = false; - SetCurrentSpeed(0); + StopNavigation(); } SetAppearance(eaSitting); @@ -2999,7 +2999,7 @@ void Bot::PetAIProcess() { botPet->SetHeading(botPet->GetTarget()->GetHeading()); if(moved) { moved = false; - SetCurrentSpeed(0); + StopNavigation(); botPet->SendPosition(); botPet->SetMoving(false); } @@ -3027,7 +3027,7 @@ void Bot::PetAIProcess() { botPet->SetHeading(botPet->GetTarget()->GetHeading()); if(moved) { moved = false; - SetCurrentSpeed(0); + StopNavigation(); botPet->SendPosition(); botPet->SetMoving(false); } diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 0cd405765..cb5d7ede6 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -10041,7 +10041,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) mypet->SetPetOrder(SPO_Guard); mypet->CastToNPC()->SaveGuardSpot(); if (!mypet->GetTarget()) // want them to not twitch if they're chasing something down - mypet->SetCurrentSpeed(0); + mypet->StopNavigation(); if (mypet->IsPetStop()) { mypet->SetPetStop(false); SetPetCommandState(PET_BUTTON_STOP, 0); @@ -10343,7 +10343,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) mypet->SetPetStop(false); } else { mypet->SetPetStop(true); - mypet->SetCurrentSpeed(0); + mypet->StopNavigation(); mypet->SetTarget(nullptr); if (mypet->IsPetRegroup()) { mypet->SetPetRegroup(false); @@ -10359,7 +10359,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) { mypet->SetPetStop(true); - mypet->SetCurrentSpeed(0); + mypet->StopNavigation(); mypet->SetTarget(nullptr); mypet->SayTo_StringID(this, MT_PetResponse, PET_GETLOST_STRING); if (mypet->IsPetRegroup()) { diff --git a/zone/command.cpp b/zone/command.cpp index 6d9d875b1..5ea4f5c85 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -1271,48 +1271,11 @@ void command_movement(Client *c, const Seperator *sep) if (strcasecmp(sep->arg[1], "stats") == 0) { - //mgr.DumpStats(c); + mgr.DumpStats(c); } else if (strcasecmp(sep->arg[1], "clearstats") == 0) { - //mgr.ClearStats(); - } - if (strcasecmp(sep->arg[1], "test") == 0) - { - auto target = c->GetTarget(); - if (!target) { - c->Message(0, "Requires target"); - } - - mgr.NavigateTo(target, c->GetX(), c->GetY(), c->GetZ(), false, MovementRunning); - - //auto heading = target->CalculateHeadingToTarget(c->GetX(), c->GetY()); - //mgr.SendCommandToClients(target, 0.0f, 0.0f, 0.0f, atof(sep->arg[2]), 0, ClientRangeAny); - //mgr.RotateTo(target, heading); - - //double a1 = atof(sep->arg[2]); - //double a2 = atof(sep->arg[3]); - //double a3 = atof(sep->arg[4]); - //double a4 = atof(sep->arg[5]); - //int a5 = atoi(sep->arg[6]); - // - ////PlayerPositionUpdateServer_Struct - //EQApplicationPacket outapp(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct)); - //PlayerPositionUpdateServer_Struct *spu = (PlayerPositionUpdateServer_Struct*)outapp.pBuffer; - // - //memset(spu, 0x00, sizeof(PlayerPositionUpdateServer_Struct)); - //spu->spawn_id = target->GetID(); - //spu->x_pos = FloatToEQ19(target->GetX()); - //spu->y_pos = FloatToEQ19(target->GetY()); - //spu->z_pos = FloatToEQ19(target->GetZ()); - //spu->heading = FloatToEQ12(target->GetHeading()); - //spu->delta_x = FloatToEQ13(a1); - //spu->delta_y = FloatToEQ13(a2); - //spu->delta_z = FloatToEQ13(a3); - //spu->delta_heading = FloatToEQ10(a4); - //spu->animation = a5; - // - //c->QueuePacket(&outapp); + mgr.ClearStats(); } else { c->Message(0, "Usage: #movement stats/clearstats"); diff --git a/zone/merc.cpp b/zone/merc.cpp index bfa4a7233..b03042f5a 100644 --- a/zone/merc.cpp +++ b/zone/merc.cpp @@ -1471,7 +1471,7 @@ void Merc::AI_Process() { if(moved) { moved = false; - SetCurrentSpeed(0); + StopNavigation(); } } @@ -1513,7 +1513,7 @@ void Merc::AI_Process() { SetRunAnimSpeed(0); if(moved) { - SetCurrentSpeed(0); + StopNavigation(); } } @@ -1771,7 +1771,7 @@ void Merc::AI_Process() { else { if (moved) { moved = false; - SetCurrentSpeed(0); + StopNavigation(); } } } diff --git a/zone/mob.cpp b/zone/mob.cpp index 6df25048b..99ef689fe 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -1434,16 +1434,14 @@ void Mob::SendHPUpdate(bool skip_self /*= false*/, bool force_update_all /*= fal } void Mob::StopMoving() { - FixZ(); - SetCurrentSpeed(0); + StopNavigation(); if (moved) moved = false; } void Mob::StopMoving(float new_heading) { - SetHeading(new_heading); - FixZ(); - SetCurrentSpeed(0); + StopNavigation(); + RotateTo(new_heading); if (moved) moved = false; } @@ -2706,10 +2704,10 @@ void Mob::FaceTarget(Mob* mob_to_face /*= 0*/) { float new_heading = CalculateHeadingToTarget(faced_mob->GetX(), faced_mob->GetY()); if(current_heading != new_heading) { if (IsEngaged() || IsRunning()) { - mMovementManager->RotateTo(this, new_heading); + RotateToRunning(new_heading); } else { - mMovementManager->RotateTo(this, new_heading, MovementWalking); + RotateToWalking(new_heading); } } @@ -5765,18 +5763,6 @@ void Mob::SendRemovePlayerState(PlayerState old_state) safe_delete(app); } -void Mob::SetCurrentSpeed(int in){ - if (current_speed != in) - { - current_speed = in; - if (in == 0) { - SetRunAnimSpeed(0); - SetMoving(false); - SendPosition(); - } - } -} - int32 Mob::GetMeleeMitigation() { int32 mitigation = 0; mitigation += spellbonuses.MeleeMitigationEffect; diff --git a/zone/mob.h b/zone/mob.h index 35ebaf87c..f6e110353 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -549,7 +549,6 @@ public: virtual void Gate(uint8 bindnum = 0); int GetWalkspeed() const { return(_GetWalkSpeed()); } int GetRunspeed() const { return(_GetRunSpeed()); } - void SetCurrentSpeed(int in); int GetBaseRunspeed() const { return base_runspeed; } int GetBaseWalkspeed() const { return base_walkspeed; } int GetBaseFearSpeed() const { return base_fearspeed; } @@ -972,6 +971,9 @@ public: void WalkTo(float x, float y, float z); void RunTo(float x, float y, float z); void NavigateTo(float x, float y, float z); + void RotateTo(float new_heading); + void RotateToWalking(float new_heading); + void RotateToRunning(float new_heading); void StopNavigation(); float CalculateDistance(float x, float y, float z); float GetGroundZ(float new_x, float new_y, float z_offset=0.0); diff --git a/zone/mob_ai.cpp b/zone/mob_ai.cpp index 750f5c792..12360f4e7 100644 --- a/zone/mob_ai.cpp +++ b/zone/mob_ai.cpp @@ -372,7 +372,7 @@ bool NPC::AIDoSpellCast(uint8 i, Mob* tar, int32 mana_cost, uint32* oDontDoAgain //stop moving if were casting a spell and were not a bard... if(!IsBardSong(AIspells[i].spellid)) { - SetCurrentSpeed(0); + StopNavigation(); } return CastSpell(AIspells[i].spellid, tar->GetID(), EQEmu::CastingSlot::Gem2, AIspells[i].manacost == -2 ? 0 : -1, mana_cost, oDontDoAgainBefore, -1, -1, 0, &(AIspells[i].resist_adjust)); @@ -715,7 +715,7 @@ void Client::AI_SpellCast() { if(!IsBardSong(spell_to_cast)) { - SetCurrentSpeed(0); + StopNavigation(); } CastSpell(spell_to_cast, tar->GetID(), slot_to_use); return; @@ -729,7 +729,7 @@ void Client::AI_SpellCast() { if(!IsBardSong(spell_to_cast)) { - SetCurrentSpeed(0); + StopNavigation(); } CastSpell(spell_to_cast, tar->GetID(), slot_to_use); return; @@ -787,9 +787,8 @@ void Client::AI_Process() if (IsRooted()) { //make sure everybody knows were not moving, for appearance sake if (IsMoving()) { - if (GetTarget()) - SetHeading(CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY())); - SetCurrentSpeed(0); + FaceTarget(); + StopNavigation(); } //continue on to attack code, ensuring that we execute the engaged code engaged = true; @@ -797,7 +796,7 @@ void Client::AI_Process() else { if (AI_movement_timer->Check()) { // Check if we have reached the last fear point - if(IsPositionEqual(glm::vec3(GetX(), GetY(), GetZ()), m_FearWalkTarget)) { + if(IsPositionEqualWithinCertainZ(glm::vec3(GetX(), GetY(), GetZ()), m_FearWalkTarget, 5.0f)) { CalculateNewFearpoint(); } @@ -844,10 +843,8 @@ void Client::AI_Process() if (AI_movement_timer->Check()) { if (CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY()) != m_Position.w) { - SetHeading(CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY())); - SendPosition(); + FaceTarget(); } - SetCurrentSpeed(0); } if (GetTarget() && !IsStunned() && !IsMezzed() && !GetFeigned()) { if (attack_timer.Check()) { @@ -874,8 +871,7 @@ void Client::AI_Process() } else if(IsMoving()) { - SetHeading(CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY())); - SetCurrentSpeed(0); + FaceTarget(); } } AI_SpellCast(); @@ -1070,9 +1066,8 @@ void Mob::AI_Process() { !IsPetRegroup()) { //make sure everybody knows were not moving, for appearance sake if (IsMoving()) { - if (target) - SetHeading(CalculateHeadingToTarget(target->GetX(), target->GetY())); - SetCurrentSpeed(0); + FaceTarget(); + StopNavigation(); moved = false; } //continue on to attack code, ensuring that we execute the engaged code @@ -1081,7 +1076,7 @@ void Mob::AI_Process() { else { if (AI_movement_timer->Check()) { // Check if we have reached the last fear point - if (IsPositionEqual(glm::vec3(GetX(), GetY(), GetZ()), m_FearWalkTarget)) { + if (IsPositionEqualWithinCertainZ(glm::vec3(GetX(), GetY(), GetZ()), m_FearWalkTarget, 5.0f)) { // Calculate a new point to run to CalculateNewFearpoint(); } @@ -1403,8 +1398,7 @@ void Mob::AI_Process() { } else if (IsMoving()) { - SetHeading(CalculateHeadingToTarget(target->GetX(), target->GetY())); - SetCurrentSpeed(0); + FaceTarget(); } } } @@ -1490,9 +1484,7 @@ void Mob::AI_Process() { * Distance: >= 450 (Snap to owner) */ if (distance_to_owner >= 202500 || z_distance > 100) { - m_Position = pet_owner_position; - SendPositionUpdate(); - moved = true; + Teleport(pet_owner_position); } else { @@ -1562,7 +1554,7 @@ void Mob::AI_Process() { } else { moved = false; - SetCurrentSpeed(0); + StopNavigation(); } } } @@ -1688,9 +1680,6 @@ void NPC::AI_DoMovement() { if (m_Position.x == roambox_destination_x && m_Position.y == roambox_destination_y) { time_until_can_move = Timer::GetCurrentTime() + RandomTimer(roambox_min_delay, roambox_delay); - SetMoving(false); - this->FixZ(); - SendPosition(); } return; @@ -1721,14 +1710,10 @@ void NPC::AI_DoMovement() { SetWaypointPause(); SetAppearance(eaStanding, false); - SetMoving(false); if (m_CurrentWayPoint.w >= 0.0) { - SetHeading(m_CurrentWayPoint.w); + RotateTo(m_CurrentWayPoint.w); } - this->FixZ(); - SendPosition(); - //kick off event_waypoint arrive char temp[16]; sprintf(temp, "%d", cur_wp); @@ -1771,7 +1756,7 @@ void NPC::AI_DoMovement() { } else if (IsGuarding()) { - bool at_gp = IsPositionEqual(m_Position, m_GuardPoint); + bool at_gp = IsPositionEqualWithinCertainZ(m_Position, m_GuardPoint, 5.0f); if (at_gp) { @@ -1786,12 +1771,11 @@ void NPC::AI_DoMovement() { ClearFeignMemory(); moved = false; if (GetTarget() == nullptr || DistanceSquared(m_Position, GetTarget()->GetPosition()) >= 5 * 5) { - SetHeading(m_GuardPoint.w); + RotateTo(m_GuardPoint.w); } else { FaceTarget(GetTarget()); } - SetCurrentSpeed(0); SetAppearance(GetGuardPointAnim()); } } @@ -1925,8 +1909,7 @@ void Mob::AI_Event_NoLongerEngaged() { // except if we're a pet, then we might run into some issues with pets backing off when they should immediately be moving if(!IsPet()) { - SetRunAnimSpeed(0); - SendPosition(); + StopNavigation(); } ClearRampage(); diff --git a/zone/mob_movement_manager.cpp b/zone/mob_movement_manager.cpp index 616ef42cc..d826ed0f0 100644 --- a/zone/mob_movement_manager.cpp +++ b/zone/mob_movement_manager.cpp @@ -48,6 +48,7 @@ public: if (!m_started) { m_started = true; + m->SetMoving(true); if (rotate_to_speed > 0.0 && rotate_to_speed <= 25.0) { //send basic rotation mgr->SendCommandToClients(m, 0.0, 0.0, 0.0, m_rotate_to_dir * rotate_to_speed, 0, ClientRangeClose); @@ -71,7 +72,8 @@ public: if (td >= dist) { m->SetHeading(to); - mgr->SendCommandToClients(m, 0.0, 0.0, 0.0, 0.0, 0, ClientRangeAny); + m->SetMoving(false); + mgr->SendCommandToClients(m, 0.0, 0.0, 0.0, 0.0, 0, ClientRangeCloseMedium); return true; } @@ -129,6 +131,7 @@ public: if (!m_started) { m_started = true; //rotate to the point + m->SetMoving(true); m->SetHeading(m->CalculateHeadingToTarget(m_move_to_x, m_move_to_y)); m->TryFixZ(); @@ -165,6 +168,7 @@ public: glm::vec2 pos(p.x, p.y); double len = glm::distance(pos, tar); if (len == 0) { + m->SetMoving(false); return true; } @@ -172,7 +176,7 @@ public: glm::vec2 dir = tar - pos; glm::vec2 ndir = glm::normalize(dir); - double distance_moved = frame_time * current_speed * 0.4f * 1.4f; + double distance_moved = frame_time * current_speed * 0.4f * 1.45f; if (distance_moved > len) { m->SetPosition(m_move_to_x, m_move_to_y, m_move_to_z); @@ -182,6 +186,7 @@ public: } m->TryFixZ(); + m->SetMoving(false); return true; } else { @@ -272,7 +277,7 @@ public: return true; } - mgr->SendCommandToClients(m, 0.0, 0.0, 0.0, 0.0, 0, ClientRangeAny); + mgr->SendCommandToClients(m, 0.0, 0.0, 0.0, 0.0, 0, ClientRangeCloseMedium); return true; } @@ -284,12 +289,14 @@ public: struct MovementStats { MovementStats() { + LastResetTime = static_cast(Timer::GetCurrentTime()) / 1000.0; TotalSent = 0ULL; TotalSentMovement = 0ULL; TotalSentPosition = 0ULL; TotalSentHeading = 0ULL; } + double LastResetTime; uint64_t TotalSent; uint64_t TotalSentMovement; uint64_t TotalSentPosition; @@ -302,12 +309,14 @@ struct NavigateTo navigate_to_x = 0.0; navigate_to_y = 0.0; navigate_to_z = 0.0; + navigate_to_heading = 0.0; last_set_time = 0.0; } double navigate_to_x; double navigate_to_y; double navigate_to_z; + double navigate_to_heading; double last_set_time; }; @@ -417,24 +426,28 @@ void MobMovementManager::Teleport(Mob *who, float x, float y, float z, float hea PushTeleportTo(ent.second, x, y, z, heading); } -void MobMovementManager::NavigateTo(Mob *who, float x, float y, float z, bool force, MobMovementMode mode) +void MobMovementManager::NavigateTo(Mob *who, float x, float y, float z, MobMovementMode mode) { auto iter = _impl->Entries.find(who); auto &ent = (*iter); auto &nav = ent.second.NavigateTo; double current_time = static_cast(Timer::GetCurrentTime()) / 1000.0; - if (force || (current_time - nav.last_set_time) > 0.5) { + if ((current_time - nav.last_set_time) > 0.5) { //Can potentially recalc auto within = IsPositionWithinSimpleCylinder(glm::vec3(x, y, z), glm::vec3(nav.navigate_to_x, nav.navigate_to_y, nav.navigate_to_z), 1.5f, 6.0f); - - if (false == within) { + auto heading_match = IsHeadingEqual(0.0, nav.navigate_to_heading); + + if (false == within || false == heading_match) { + ent.second.Commands.clear(); + //Path is no longer valid, calculate a new path UpdatePath(who, x, y, z, mode); nav.navigate_to_x = x; nav.navigate_to_y = y; nav.navigate_to_z = z; + nav.navigate_to_heading = 0.0; nav.last_set_time = current_time; } } @@ -455,7 +468,7 @@ void MobMovementManager::StopNavigation(Mob *who) { } who->TryFixZ(); - SendCommandToClients(who, 0.0, 0.0, 0.0, 0.0, 0, ClientRangeAny); + SendCommandToClients(who, 0.0, 0.0, 0.0, 0.0, 0, ClientRangeCloseMedium); ent.second.Commands.clear(); } @@ -492,19 +505,19 @@ void MobMovementManager::SendCommandToClients(Mob *m, float dx, float dy, float bool match = false; if (range & ClientRangeClose) { - if (dist < 200.0f) { + if (dist < 250.0f) { match = true; } } if (!match && range & ClientRangeMedium) { - if (dist >= 200.0f && dist < 1000.0f) { + if (dist >= 250.0f && dist < 1500.0f) { match = true; } } if (!match && range & ClientRangeLong) { - if (dist >= 1000.0f) { + if (dist >= 1500.0f) { match = true; } } @@ -542,6 +555,27 @@ float MobMovementManager::FixHeading(float in) return h; } +void MobMovementManager::DumpStats(Client *to) +{ + auto current_time = static_cast(Timer::GetCurrentTime()) / 1000.0; + auto total_time = current_time - _impl->Stats.LastResetTime; + + to->Message(MT_System, "Dumping Movement Stats:"); + to->Message(MT_System, "Total Sent: %u (%.2f / sec)", _impl->Stats.TotalSent, static_cast(_impl->Stats.TotalSent) / total_time); + to->Message(MT_System, "Total Heading: %u (%.2f / sec)", _impl->Stats.TotalSentHeading, static_cast(_impl->Stats.TotalSentHeading) / total_time); + to->Message(MT_System, "Total Movement: %u (%.2f / sec)", _impl->Stats.TotalSentMovement, static_cast(_impl->Stats.TotalSentMovement) / total_time); + to->Message(MT_System, "Total Position: %u (%.2f / sec)", _impl->Stats.TotalSentPosition, static_cast(_impl->Stats.TotalSentPosition) / total_time); +} + +void MobMovementManager::ClearStats() +{ + _impl->Stats.LastResetTime = static_cast(Timer::GetCurrentTime()) / 1000.0; + _impl->Stats.TotalSent = 0; + _impl->Stats.TotalSentHeading = 0; + _impl->Stats.TotalSentMovement = 0; + _impl->Stats.TotalSentPosition = 0; +} + void MobMovementManager::FillCommandStruct(PlayerPositionUpdateServer_Struct *spu, Mob *m, float dx, float dy, float dz, float dh, int anim) { memset(spu, 0x00, sizeof(PlayerPositionUpdateServer_Struct)); diff --git a/zone/mob_movement_manager.h b/zone/mob_movement_manager.h index 6d04ea323..4e8d73451 100644 --- a/zone/mob_movement_manager.h +++ b/zone/mob_movement_manager.h @@ -39,13 +39,12 @@ public: void RotateTo(Mob *who, float to, MobMovementMode mode = MovementRunning); void Teleport(Mob *who, float x, float y, float z, float heading); - void NavigateTo(Mob *who, float x, float y, float z, bool force = false, MobMovementMode mode = MovementRunning); + void NavigateTo(Mob *who, float x, float y, float z, MobMovementMode mode = MovementRunning); void StopNavigation(Mob *who); void SendCommandToClients(Mob *m, float dx, float dy, float dz, float dh, int anim, ClientRange range); float FixHeading(float in); - //void Dump(Mob *m, Client *to); - //void DumpStats(Client *to); - //void ClearStats(); + void DumpStats(Client *to); + void ClearStats(); static MobMovementManager &Get() { static MobMovementManager inst; diff --git a/zone/npc.cpp b/zone/npc.cpp index 0bb1bc10d..a0e510a43 100644 --- a/zone/npc.cpp +++ b/zone/npc.cpp @@ -772,9 +772,8 @@ bool NPC::Process() DoGravityEffect(); } - if(reface_timer->Check() && !IsEngaged() && (m_GuardPoint.x == GetX() && m_GuardPoint.y == GetY() && m_GuardPoint.z == GetZ())) { - SetHeading(m_GuardPoint.w); - SendPosition(); + if(reface_timer->Check() && !IsEngaged() && IsPositionEqualWithinCertainZ(m_Position, m_GuardPoint, 5.0f)) { + RotateTo(m_GuardPoint.w); reface_timer->Disable(); } diff --git a/zone/position.cpp b/zone/position.cpp index 9f9e36fc2..cc4317e0e 100644 --- a/zone/position.cpp +++ b/zone/position.cpp @@ -163,6 +163,11 @@ float GetReciprocalHeading(const float heading) return result; } +bool IsHeadingEqual(const float h1, const float h2) +{ + return std::abs(h2 - h1) < 0.01f; +} + bool IsPositionEqual(const glm::vec2 &p1, const glm::vec2 &p2) { return std::abs(p1.x - p2.x) < position_eps && std::abs(p1.y - p2.y) < position_eps; diff --git a/zone/position.h b/zone/position.h index ccccfb857..8dcf42c3c 100644 --- a/zone/position.h +++ b/zone/position.h @@ -50,6 +50,8 @@ float DistanceSquaredNoZ(const glm::vec4& point1, const glm::vec4& point2); float GetReciprocalHeading(const glm::vec4& point1); float GetReciprocalHeading(const float heading); +bool IsHeadingEqual(const float h1, const float h2); + bool IsPositionEqual(const glm::vec2 &p1, const glm::vec2 &p2); bool IsPositionEqual(const glm::vec3 &p1, const glm::vec3 &p2); bool IsPositionEqual(const glm::vec4 &p1, const glm::vec4 &p2); diff --git a/zone/spells.cpp b/zone/spells.cpp index 56f992dbe..0b705717d 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -4898,12 +4898,11 @@ void Client::UnStun() { void NPC::Stun(int duration) { Mob::Stun(duration); - SetCurrentSpeed(0); + StopNavigation(); } void NPC::UnStun() { Mob::UnStun(); - SetCurrentSpeed(GetRunspeed()); } void Mob::Mesmerize() diff --git a/zone/waypoints.cpp b/zone/waypoints.cpp index 79806ac3a..8e5402895 100644 --- a/zone/waypoints.cpp +++ b/zone/waypoints.cpp @@ -428,12 +428,11 @@ void NPC::SaveGuardSpot(bool iClearGuardSpot) { void NPC::NextGuardPosition() { NavigateTo(m_GuardPoint.x, m_GuardPoint.y, m_GuardPoint.z); - if ((m_Position.x == m_GuardPoint.x) && (m_Position.y == m_GuardPoint.y) && (m_Position.z == m_GuardPoint.z)) + if (IsPositionEqualWithinCertainZ(m_Position, m_GuardPoint, 5.0f)) { if (moved) { moved = false; - SetCurrentSpeed(0); } } } @@ -444,24 +443,44 @@ float Mob::CalculateDistance(float x, float y, float z) { void Mob::WalkTo(float x, float y, float z) { - mMovementManager->NavigateTo(this, x, y, z, false, MovementWalking); + mMovementManager->NavigateTo(this, x, y, z, MovementWalking); } void Mob::RunTo(float x, float y, float z) { - mMovementManager->NavigateTo(this, x, y, z, false, MovementRunning); + mMovementManager->NavigateTo(this, x, y, z, MovementRunning); } void Mob::NavigateTo(float x, float y, float z) { if (IsRunning()) { - mMovementManager->NavigateTo(this, x, y, z, false, MovementRunning); + RunTo(x, y, z); } else { - mMovementManager->NavigateTo(this, x, y, z, false, MovementWalking); + WalkTo(x, y, z); } } +void Mob::RotateTo(float new_heading) +{ + if (IsRunning()) { + RotateToRunning(new_heading); + } + else { + RotateToWalking(new_heading); + } +} + +void Mob::RotateToWalking(float new_heading) +{ + mMovementManager->RotateTo(this, new_heading, MovementWalking); +} + +void Mob::RotateToRunning(float new_heading) +{ + mMovementManager->RotateTo(this, new_heading, MovementRunning); +} + void Mob::StopNavigation() { mMovementManager->StopNavigation(this); }