diff --git a/zone/lua_mob.cpp b/zone/lua_mob.cpp index 4a5932db2..67784eb57 100644 --- a/zone/lua_mob.cpp +++ b/zone/lua_mob.cpp @@ -1124,9 +1124,14 @@ double Lua_Mob::CalculateHeadingToTarget(double in_x, double in_y) { return self->CalculateHeadingToTarget(static_cast(in_x), static_cast(in_y)); } -void Lua_Mob::CalculateNewPosition(double x, double y, double z, double speed) { +void Lua_Mob::NavigateTo(double x, double y, double z, double speed) { Lua_Safe_Call_Void(); - self->CalculateNewPosition(static_cast(x), static_cast(y), static_cast(z), static_cast(speed)); + self->NavigateTo(static_cast(x), static_cast(y), static_cast(z), static_cast(speed)); +} + +void Lua_Mob::StopNavigation() { + Lua_Safe_Call_Void(); + self->StopNavigation(); } float Lua_Mob::CalculateDistance(double x, double y, double z) { @@ -2355,7 +2360,8 @@ luabind::scope lua_register_mob() { .def("FaceTarget", (void(Lua_Mob::*)(Lua_Mob))&Lua_Mob::FaceTarget) .def("SetHeading", (void(Lua_Mob::*)(double))&Lua_Mob::SetHeading) .def("CalculateHeadingToTarget", (double(Lua_Mob::*)(double,double))&Lua_Mob::CalculateHeadingToTarget) - .def("CalculateNewPosition", (void(Lua_Mob::*)(double,double,double,double))&Lua_Mob::CalculateNewPosition) + .def("NavigateTo", (void(Lua_Mob::*)(double,double,double,double))&Lua_Mob::NavigateTo) + .def("StopNavigation", (void(Lua_Mob::*)(void))&Lua_Mob::StopNavigation) .def("CalculateDistance", (float(Lua_Mob::*)(double,double,double))&Lua_Mob::CalculateDistance) .def("SendTo", (void(Lua_Mob::*)(double,double,double))&Lua_Mob::SendTo) .def("SendToFixZ", (void(Lua_Mob::*)(double,double,double))&Lua_Mob::SendToFixZ) diff --git a/zone/lua_mob.h b/zone/lua_mob.h index ed3f869ed..7300e3085 100644 --- a/zone/lua_mob.h +++ b/zone/lua_mob.h @@ -240,7 +240,8 @@ public: void FaceTarget(Lua_Mob target); void SetHeading(double in); double CalculateHeadingToTarget(double in_x, double in_y); - void CalculateNewPosition(double x, double y, double z, double speed); + void NavigateTo(double x, double y, double z, double speed); + void StopNavigation(); float CalculateDistance(double x, double y, double z); void SendTo(double x, double y, double z); void SendToFixZ(double x, double y, double z); diff --git a/zone/merc.cpp b/zone/merc.cpp index 09bd78622..2a1e581d9 100644 --- a/zone/merc.cpp +++ b/zone/merc.cpp @@ -1479,7 +1479,7 @@ void Merc::AI_Process() { } else if (!CheckLosFN(GetTarget())) { auto Goal = GetTarget()->GetPosition(); - CalculateNewPosition(Goal.x, Goal.y, Goal.z, GetRunspeed()); + NavigateTo(Goal.x, Goal.y, Goal.z, GetRunspeed()); return; } @@ -1545,7 +1545,7 @@ void Merc::AI_Process() { float newZ = 0; FaceTarget(GetTarget()); if (PlotPositionAroundTarget(this, newX, newY, newZ)) { - CalculateNewPosition(newX, newY, newZ, GetRunspeed()); + NavigateTo(newX, newY, newZ, GetRunspeed()); return; } } @@ -1557,7 +1557,7 @@ void Merc::AI_Process() { float newY = 0; float newZ = 0; if (PlotPositionAroundTarget(GetTarget(), newX, newY, newZ)) { - CalculateNewPosition(newX, newY, newZ, GetRunspeed()); + NavigateTo(newX, newY, newZ, GetRunspeed()); return; } } @@ -1568,7 +1568,7 @@ void Merc::AI_Process() { float newY = 0; float newZ = 0; if (PlotPositionAroundTarget(GetTarget(), newX, newY, newZ, false) && GetArchetype() != ARCHETYPE_CASTER) { - CalculateNewPosition(newX, newY, newZ, GetRunspeed()); + NavigateTo(newX, newY, newZ, GetRunspeed()); return; } } @@ -1695,7 +1695,7 @@ void Merc::AI_Process() { { if(!IsRooted()) { Log(Logs::Detail, Logs::AI, "Pursuing %s while engaged.", GetTarget()->GetCleanName()); - CalculateNewPosition(GetTarget()->GetX(), GetTarget()->GetY(), GetTarget()->GetZ(), GetRunspeed()); + NavigateTo(GetTarget()->GetX(), GetTarget()->GetY(), GetTarget()->GetZ(), GetRunspeed()); return; } @@ -1758,7 +1758,7 @@ void Merc::AI_Process() { SetRunAnimSpeed(0); if (dist > GetFollowDistance()) { - CalculateNewPosition(follow->GetX(), follow->GetY(), follow->GetZ(), speed); + NavigateTo(follow->GetX(), follow->GetY(), follow->GetZ(), speed); if (rest_timer.Enabled()) rest_timer.Disable(); diff --git a/zone/mob.h b/zone/mob.h index 14cb3c3a6..d9f180626 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -602,7 +602,7 @@ public: void SetAssistAggro(bool value) { AssistAggro = value; if (PrimaryAggro) AssistAggro = false; } bool HateSummon(); void FaceTarget(Mob* mob_to_face = 0); - void SetHeading(float iHeading) { if(m_Position.w != iHeading) { m_Position.w = iHeading; } } + void SetHeading(float iHeading) { m_Position.w = iHeading; } void WipeHateList(); void AddFeignMemory(Client* attacker); void RemoveFromFeignMemory(Client* attacker); @@ -969,7 +969,8 @@ public: inline bool CheckAggro(Mob* other) {return hate_list.IsEntOnHateList(other);} float CalculateHeadingToTarget(float in_x, float in_y) { return HeadingAngleToMob(in_x, in_y); } - void CalculateNewPosition(float x, float y, float z, float speed, bool check_z = true, bool calculate_heading = true); + void NavigateTo(float x, float y, float z, float speed); + void StopNavigation(); float CalculateDistance(float x, float y, float z); float GetGroundZ(float new_x, float new_y, float z_offset=0.0); void SendTo(float new_x, float new_y, float new_z); diff --git a/zone/mob_ai.cpp b/zone/mob_ai.cpp index b9582d712..9a0ffb8b7 100644 --- a/zone/mob_ai.cpp +++ b/zone/mob_ai.cpp @@ -801,13 +801,11 @@ void Client::AI_Process() speed *= 2; SetCurrentSpeed(speed); // Check if we have reached the last fear point - if ((std::abs(GetX() - m_FearWalkTarget.x) < 0.1) && - (std::abs(GetY() - m_FearWalkTarget.y) < 0.1)) { - // Calculate a new point to run to + if(IsPositionEqual(GetX(), GetY(), GetZ(), m_FearWalkTarget.x, m_FearWalkTarget.y, m_FearWalkTarget.z)) { CalculateNewFearpoint(); } - CalculateNewPosition(m_FearWalkTarget.x, m_FearWalkTarget.y, m_FearWalkTarget.z, speed, true); + NavigateTo(m_FearWalkTarget.x, m_FearWalkTarget.y, m_FearWalkTarget.z, speed); } return; } @@ -841,6 +839,8 @@ void Client::AI_Process() bool is_combat_range = CombatRange(GetTarget()); if (is_combat_range) { + StopNavigation(); + if (charm_class_attacks_timer.Check()) { DoClassAttacks(GetTarget()); } @@ -877,7 +877,7 @@ void Client::AI_Process() animation = newspeed; newspeed *= 2; SetCurrentSpeed(newspeed); - CalculateNewPosition(GetTarget()->GetX(), GetTarget()->GetY(), GetTarget()->GetZ(), newspeed); + NavigateTo(GetTarget()->GetX(), GetTarget()->GetY(), GetTarget()->GetZ(), newspeed); } } else if(IsMoving()) @@ -925,13 +925,10 @@ void Client::AI_Process() nspeed *= 2; SetCurrentSpeed(nspeed); - CalculateNewPosition(owner->GetX(), owner->GetY(), owner->GetZ(), nspeed); + NavigateTo(owner->GetX(), owner->GetY(), owner->GetZ(), nspeed); } } else { - if (moved) { - SetCurrentSpeed(0); - moved = false; - } + StopNavigation(); } } } @@ -1092,17 +1089,15 @@ void Mob::AI_Process() { else { if (AI_movement_timer->Check()) { // Check if we have reached the last fear point - if ((std::abs(GetX() - m_FearWalkTarget.x) < 0.1) && - (std::abs(GetY() - m_FearWalkTarget.y) < 0.1)) { + if (IsPositionEqual(GetX(), GetY(), GetZ(), m_FearWalkTarget.x, m_FearWalkTarget.y, m_FearWalkTarget.z)) { // Calculate a new point to run to CalculateNewFearpoint(); } - CalculateNewPosition( + NavigateTo( m_FearWalkTarget.x, m_FearWalkTarget.y, m_FearWalkTarget.z, - GetFearSpeed(), - true + GetFearSpeed() ); } return; @@ -1218,6 +1213,8 @@ void Mob::AI_Process() { bool is_combat_range = CombatRange(target); if (is_combat_range) { + StopNavigation(); + if (AI_movement_timer->Check()) { if (CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY()) != m_Position.w) { SetHeading(CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY())); @@ -1422,13 +1419,12 @@ void Mob::AI_Process() { else if (AI_movement_timer->Check() && target) { if (!IsRooted()) { Log(Logs::Detail, Logs::AI, "Pursuing %s while engaged.", target->GetName()); - CalculateNewPosition(target->GetX(), target->GetY(), target->GetZ(), GetRunspeed()); + NavigateTo(target->GetX(), target->GetY(), target->GetZ(), GetRunspeed()); } else if (IsMoving()) { SetHeading(CalculateHeadingToTarget(target->GetX(), target->GetY())); SetCurrentSpeed(0); - } } } @@ -1522,15 +1518,11 @@ void Mob::AI_Process() { auto &Goal = owner->GetPosition(); - CalculateNewPosition(Goal.x, Goal.y, Goal.z, pet_speed, true); + NavigateTo(Goal.x, Goal.y, Goal.z, pet_speed); } } else { - if (moved) { - this->FixZ(); - SetCurrentSpeed(0); - moved = false; - } + StopNavigation(); } break; @@ -1576,7 +1568,7 @@ void Mob::AI_Process() { auto &Goal = follow->GetPosition(); - CalculateNewPosition(Goal.x, Goal.y, Goal.z, speed, true); + NavigateTo(Goal.x, Goal.y, Goal.z, speed); } else { moved = false; @@ -1702,7 +1694,7 @@ void NPC::AI_DoMovement() { roambox_destination_y); } - CalculateNewPosition(roambox_destination_x, roambox_destination_y, roambox_destination_z, move_speed, true); + NavigateTo(roambox_destination_x, roambox_destination_y, roambox_destination_z, move_speed); 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); @@ -1766,12 +1758,11 @@ void NPC::AI_DoMovement() { ClearFeignMemory(); } if (doMove) { // not at waypoint yet or at 0 pause WP, so keep moving - CalculateNewPosition( + NavigateTo( m_CurrentWayPoint.x, m_CurrentWayPoint.y, m_CurrentWayPoint.z, - move_speed, - true + move_speed ); } @@ -1790,14 +1781,12 @@ void NPC::AI_DoMovement() { } } - else if (IsGuarding()) { - CalculateNewPosition(m_GuardPoint.x, m_GuardPoint.y, m_GuardPoint.z, move_speed); - - //if(Distance(m_GuardPoint, m_Position)) - - bool at_gp = CalculateDistance(m_GuardPoint.x, m_GuardPoint.y, m_GuardPoint.z) < 0.1f; + else if (IsGuarding()) { + bool at_gp = IsPositionEqual(GetX(), GetY(), GetZ(), m_GuardPoint.x, m_GuardPoint.y, m_GuardPoint.z); if (at_gp) { + StopNavigation(); + if (moved) { Log(Logs::Detail, Logs::AI, @@ -1818,6 +1807,9 @@ void NPC::AI_DoMovement() { SetAppearance(GetGuardPointAnim()); } } + else { + NavigateTo(m_GuardPoint.x, m_GuardPoint.y, m_GuardPoint.z, move_speed); + } } } diff --git a/zone/mob_movement_manager.cpp b/zone/mob_movement_manager.cpp index 76f71663b..b87e4f740 100644 --- a/zone/mob_movement_manager.cpp +++ b/zone/mob_movement_manager.cpp @@ -124,7 +124,6 @@ void MobMovementManager::RemoveClient(Client *c) ++iter; } - } void MobMovementManager::SendPosition(Mob *who) @@ -327,7 +326,6 @@ void MobMovementManager::ProcessMovement(Mob *who, float x, float y, float z, fl return; } - bool calculate_heading = false; bool WaypointChanged = false; bool NodeReached = false; glm::vec3 Goal = who->UpdatePath( @@ -335,7 +333,6 @@ void MobMovementManager::ProcessMovement(Mob *who, float x, float y, float z, fl ); if (WaypointChanged || NodeReached) { - calculate_heading = true; entity_list.OpenDoorsNear(who); } @@ -374,7 +371,6 @@ void MobMovementManager::ProcessMovement(Mob *who, float x, float y, float z, fl } who->TryFixZ(); - return; } else { @@ -386,9 +382,8 @@ void MobMovementManager::ProcessMovement(Mob *who, float x, float y, float z, fl } } - if (calculate_heading) { - who->SetHeading(who->CalculateHeadingToTarget(Goal.x, Goal.y)); - } + who->SetHeading(who->CalculateHeadingToTarget(Goal.x, Goal.y)); + SendPositionUpdate(who, false); who->TryFixZ(); diff --git a/zone/pathing.cpp b/zone/pathing.cpp index f835bfe67..49e84f72a 100644 --- a/zone/pathing.cpp +++ b/zone/pathing.cpp @@ -7,6 +7,21 @@ extern Zone *zone; +void AdjustRoute(std::list &nodes, int flymode, float offset) { + if (!zone->HasMap() || !zone->HasWaterMap()) { + return; + } + + for (auto &node : nodes) { + if (flymode == GravityBehavior::Ground || !zone->watermap->InLiquid(node.pos)) { + auto best_z = zone->zonemap->FindBestZ(node.pos, nullptr); + if (best_z != BEST_Z_INVALID) { + node.pos.z = best_z + offset; + } + } + } +} + glm::vec3 Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &WaypointChanged, bool &NodeReached) { glm::vec3 To(ToX, ToY, ToZ); @@ -27,6 +42,7 @@ glm::vec3 Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &Wa bool partial = false; bool stuck = false; Route = zone->pathing->FindRoute(From, To, partial, stuck); + AdjustRoute(Route, flymode, GetZOffset()); PathingDestination = To; WaypointChanged = true; @@ -50,6 +66,7 @@ glm::vec3 Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &Wa bool partial = false; bool stuck = false; Route = zone->pathing->FindRoute(From, To, partial, stuck); + AdjustRoute(Route, flymode, GetZOffset()); PathingDestination = To; WaypointChanged = true; @@ -116,6 +133,8 @@ glm::vec3 Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &Wa bool partial = false; bool stuck = false; Route = zone->pathing->FindRoute(From, To, partial, stuck); + AdjustRoute(Route, flymode, GetZOffset()); + PathingDestination = To; WaypointChanged = true; diff --git a/zone/perl_mob.cpp b/zone/perl_mob.cpp index 2e2c9a6cb..ba0fe9b57 100644 --- a/zone/perl_mob.cpp +++ b/zone/perl_mob.cpp @@ -5526,12 +5526,12 @@ XS(XS_Mob_CalculateHeadingToTarget) { XSRETURN(1); } -XS(XS_Mob_CalculateNewPosition); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_CalculateNewPosition) { +XS(XS_Mob_NavigateTo); /* prototype to pass -Wmissing-prototypes */ +XS(XS_Mob_NavigateTo) { dXSARGS; if (items < 5 || items > 6) Perl_croak(aTHX_ - "Usage: Mob::CalculateNewPosition(THIS, float x, float y, float z, float speed)"); + "Usage: Mob::NavigateTo(THIS, float x, float y, float z, float speed)"); { Mob *THIS; float x = (float) SvNV(ST(1)); @@ -5548,7 +5548,31 @@ XS(XS_Mob_CalculateNewPosition) { Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - THIS->CalculateNewPosition(x, y, z, speed); + THIS->NavigateTo(x, y, z, speed); + } + XSRETURN_EMPTY; +} + +XS(XS_Mob_StopNavigation); /* prototype to pass -Wmissing-prototypes */ +XS(XS_Mob_StopNavigation) { + dXSARGS; + if (items < 5 || items > 6) + Perl_croak(aTHX_ + "Usage: Mob::StopNavigation(THIS)"); + { + Mob *THIS; + + if (sv_derived_from(ST(0), "Mob")) { + IV tmp = SvIV((SV *)SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } + else + Perl_croak(aTHX_ "THIS is not of type Mob"); + if (THIS == nullptr) + Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); + + + THIS->StopNavigation(); } XSRETURN_EMPTY; } @@ -8687,7 +8711,8 @@ XS(boot_Mob) { newXSproto(strcpy(buf, "WipeHateList"), XS_Mob_WipeHateList, file, "$"); newXSproto(strcpy(buf, "CheckAggro"), XS_Mob_CheckAggro, file, "$$"); newXSproto(strcpy(buf, "CalculateHeadingToTarget"), XS_Mob_CalculateHeadingToTarget, file, "$$$"); - newXSproto(strcpy(buf, "CalculateNewPosition"), XS_Mob_CalculateNewPosition, file, "$$$$$"); + newXSproto(strcpy(buf, "NavigateTo"), XS_Mob_NavigateTo, file, "$$$$$"); + newXSproto(strcpy(buf, "StopNavigation"), XS_Mob_StopNavigation, file, "$"); newXSproto(strcpy(buf, "CalculateDistance"), XS_Mob_CalculateDistance, file, "$$$$"); newXSproto(strcpy(buf, "SendTo"), XS_Mob_SendTo, file, "$$$$"); newXSproto(strcpy(buf, "SendToFixZ"), XS_Mob_SendToFixZ, file, "$$$$"); diff --git a/zone/waypoints.cpp b/zone/waypoints.cpp index 76680e0fb..2295cfd08 100644 --- a/zone/waypoints.cpp +++ b/zone/waypoints.cpp @@ -427,7 +427,7 @@ void NPC::SaveGuardSpot(bool iClearGuardSpot) { } void NPC::NextGuardPosition() { - CalculateNewPosition(m_GuardPoint.x, m_GuardPoint.y, m_GuardPoint.z, GetMovespeed()); + NavigateTo(m_GuardPoint.x, m_GuardPoint.y, m_GuardPoint.z, GetMovespeed()); if ((m_Position.x == m_GuardPoint.x) && (m_Position.y == m_GuardPoint.y) && (m_Position.z == m_GuardPoint.z)) { if (moved) @@ -442,10 +442,14 @@ float Mob::CalculateDistance(float x, float y, float z) { return (float)sqrtf(((m_Position.x - x)*(m_Position.x - x)) + ((m_Position.y - y)*(m_Position.y - y)) + ((m_Position.z - z)*(m_Position.z - z))); } -void Mob::CalculateNewPosition(float x, float y, float z, float speed, bool check_z, bool calculate_heading) { +void Mob::NavigateTo(float x, float y, float z, float speed) { mMovementManager->NavigateTo(this, x, y, z, speed); } +void Mob::StopNavigation() { + mMovementManager->StopNavigation(this); +} + void NPC::AssignWaypoints(int32 grid) { if (grid == 0)