mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-24 21:31:28 +00:00
90 lines
2.3 KiB
C++
90 lines
2.3 KiB
C++
#include "../common/global_define.h"
|
|
|
|
#include "client.h"
|
|
#include "doors.h"
|
|
#include "water_map.h"
|
|
#include "zone.h"
|
|
#include <math.h>
|
|
|
|
glm::vec3 Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &WaypointChanged)
|
|
{
|
|
WaypointChanged = false;
|
|
|
|
glm::vec3 from(GetX(), GetY(), GetZ());
|
|
glm::vec3 to(ToX, ToY, ToZ);
|
|
|
|
if (Speed <= 0)
|
|
return to;
|
|
|
|
if (to == from)
|
|
return to;
|
|
|
|
//if from is swimming and has los to target then just swim toward them don't bother with pathing.
|
|
if (zone->HasMap() && zone->HasWaterMap() && zone->watermap->InLiquid(from) && zone->zonemap->CheckLoS(from, to) ) {
|
|
return to;
|
|
}
|
|
|
|
if (!m_pathing_route.Active() || !m_pathing_route.DestinationValid(to)) {
|
|
if (zone->HasMap()) {
|
|
auto best_z_src = zone->zonemap->FindBestZ(from, nullptr);
|
|
if (best_z_src != BEST_Z_INVALID) {
|
|
from.z = best_z_src;
|
|
}
|
|
auto best_z_dest = zone->zonemap->FindBestZ(to, nullptr);
|
|
if (best_z_dest != BEST_Z_INVALID) {
|
|
to.z = best_z_dest;
|
|
}
|
|
}
|
|
|
|
m_pathing_route = zone->pathing.FindRoute(from, to);
|
|
|
|
if (m_pathing_route.GetStatus() == PathBroken) {
|
|
auto &nodes = m_pathing_route.GetNodesEdit();
|
|
auto &last_node = nodes[nodes.size() - 1];
|
|
auto flag_temp = last_node.flag;
|
|
last_node.flag = NavigationPolyFlagPortal;
|
|
|
|
PathfindingNode end;
|
|
end.position.x = ToX;
|
|
end.position.y = ToY;
|
|
end.position.z = ToZ;
|
|
end.flag = flag_temp;
|
|
nodes.push_back(end);
|
|
}
|
|
}
|
|
|
|
m_pathing_route.CalcCurrentNode(from, WaypointChanged);
|
|
auto ¤t = m_pathing_route.GetCurrentNode();
|
|
|
|
//We reached a wp and rolled over to a new wp dest and it was a portal wp so we portal to the next spot
|
|
if (WaypointChanged) {
|
|
if (m_pathing_route.GetPreviousNodeFlag() & NavigationPolyFlagPortal) {
|
|
Teleport(current.position);
|
|
}
|
|
|
|
TrySnapToMap();
|
|
}
|
|
|
|
return current.position;
|
|
}
|
|
|
|
void Mob::TrySnapToMap() {
|
|
bool snap = true;
|
|
if (IsNPC()) {
|
|
auto npc = CastToNPC();
|
|
if (npc->GetFlyMode() == 1 || npc->GetFlyMode() == 2) {
|
|
snap = false;
|
|
}
|
|
}
|
|
|
|
if (snap && zone->HasMap()) {
|
|
if (!RuleB(Watermap, CheckForWaterWhenMoving) ||
|
|
!zone->HasWaterMap() ||
|
|
(zone->HasWaterMap() && !zone->watermap->InLiquid(glm::vec3(m_Position)))) {
|
|
glm::vec3 dest(m_Position);
|
|
float newz = zone->zonemap->FindBestZ(dest, nullptr) + 3.5f;
|
|
m_Position.z = newz;
|
|
}
|
|
}
|
|
}
|