107 lines
3.2 KiB
C++
107 lines
3.2 KiB
C++
![]() |
#pragma once
|
||
|
|
||
|
#include "natives.hpp"
|
||
|
#include "pointers.hpp"
|
||
|
#include "math.hpp"
|
||
|
#include "script.hpp"
|
||
|
#include "gta/enums.hpp"
|
||
|
|
||
|
|
||
|
namespace big::pathfind
|
||
|
{
|
||
|
|
||
|
inline bool load_path_nodes(Vector3 coords)
|
||
|
{
|
||
|
if(PATHFIND::ARE_NODES_LOADED_FOR_AREA(coords.x, coords.y, coords.z, coords.y)) return true;
|
||
|
|
||
|
PATHFIND::REQUEST_PATH_NODES_IN_AREA_THIS_FRAME(coords.x, coords.y, coords.z, coords.y);
|
||
|
|
||
|
for (int i = 0; i < 35 && !PATHFIND::ARE_NODES_LOADED_FOR_AREA(coords.x, coords.y, coords.z, coords.y); i++)
|
||
|
{
|
||
|
PATHFIND::REQUEST_PATH_NODES_IN_AREA_THIS_FRAME(coords.x, coords.y, coords.z, coords.y);
|
||
|
script::get_current()->yield(10ms);
|
||
|
}
|
||
|
|
||
|
return PATHFIND::ARE_NODES_LOADED_FOR_AREA(coords.x, coords.y, coords.z, coords.y);
|
||
|
}
|
||
|
|
||
|
inline bool load_navmesh_area(Vector3 coords, float radius)
|
||
|
{
|
||
|
if(PATHFIND::ARE_ALL_NAVMESH_REGIONS_LOADED()) return true;
|
||
|
|
||
|
PATHFIND::ADD_NAVMESH_REQUIRED_REGION(coords.x, coords.z, radius);
|
||
|
|
||
|
for (int i = 0; i < 35 && !PATHFIND::ARE_ALL_NAVMESH_REGIONS_LOADED(); i++)
|
||
|
{
|
||
|
script::get_current()->yield(10ms);
|
||
|
}
|
||
|
|
||
|
return PATHFIND::ARE_ALL_NAVMESH_REGIONS_LOADED();
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
Be sure to call this after having added a required region to free up memory since the game files suggest it is rather demanding to load navmesh
|
||
|
*/
|
||
|
inline void remove_navmesh_required_areas()
|
||
|
{
|
||
|
PATHFIND::REMOVE_NAVMESH_REQUIRED_REGIONS();
|
||
|
}
|
||
|
|
||
|
inline bool find_safe_pos_ped(Vector3 coords, Vector3& outcoords, bool onGround, int flag)
|
||
|
{
|
||
|
if (load_path_nodes(coords))
|
||
|
return PATHFIND::GET_SAFE_COORD_FOR_PED(coords.x, coords.y, coords.z, onGround, &outcoords, flag);
|
||
|
else
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
zMeasureMult: how strongly should the difference in Z direction be weighted?
|
||
|
0.0 = ignored completely, 1.0 = the same as 2d distance. Default is 3.0 since we tend to care about
|
||
|
height differences more than 2d distance.
|
||
|
zTolerance: how far apart to the Z coords have to be before zMeasureMult kicks in?
|
||
|
nth: Which coords are returned, 1 being closest, 2 being second closesst and so on
|
||
|
*/
|
||
|
inline bool find_closest_vehicle_node(Vector3 coords, Vector3& outcoords, float& outheading, int flag, int nth = 1, float zMeasureMult = 3.f, float zTolerance = 0.f)
|
||
|
{
|
||
|
int lanes;
|
||
|
if (load_path_nodes(coords))
|
||
|
return PATHFIND::GET_NTH_CLOSEST_VEHICLE_NODE_WITH_HEADING(coords.x, coords.y, coords.z, nth, &outcoords, &outheading, &lanes, flag, zMeasureMult, zTolerance);
|
||
|
else
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
inline bool find_random_location_in_vicinity(Vector3 coords, Vector3& outcoords, float& outheading, int flag, int vicinity)
|
||
|
{
|
||
|
|
||
|
int rand1 = rand() % 4;
|
||
|
Vector3 changedcoords = coords;
|
||
|
|
||
|
switch (rand1)
|
||
|
{
|
||
|
case 1: changedcoords.x += rand() % vicinity + vicinity / 2; break;
|
||
|
case 2: changedcoords.x -= rand() % vicinity + vicinity / 2; break;
|
||
|
case 3: changedcoords.y += rand() % vicinity + vicinity / 2; break;
|
||
|
case 4: changedcoords.y -= rand() % vicinity + vicinity / 2; break;
|
||
|
}
|
||
|
|
||
|
find_closest_vehicle_node(changedcoords, outcoords, outheading, flag);
|
||
|
|
||
|
if (math::distance_between_vectors(outcoords, changedcoords) > vicinity)
|
||
|
{
|
||
|
if (find_safe_pos_ped(changedcoords, outcoords, true, flag))
|
||
|
return true;
|
||
|
else
|
||
|
{
|
||
|
outcoords = coords;
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
else
|
||
|
return true;
|
||
|
|
||
|
return false;
|
||
|
|
||
|
}
|
||
|
}
|