import type { Ped } from '../classes/Ped'; import type { Vehicle } from '../classes/Vehicle'; import type { Volume } from '../classes/Volume'; import { Vector2 } from '../types/Vector2'; import { Vector3 } from '../types/Vector3'; import { Vector4 } from '../types/Vector4'; import { Color } from '../types/Color'; import { createFromHandle } from '../types/HandleRegistry'; import { inv, rai, raf, ras, rav, pvi, pvf, pvv, pvii, pvfi, _h, f, int, uint, float, Hash, u8, u16, u32, u64, i8, i16, i32, i64 } from '../types/NativeAliases'; export class Pathfind { /** * Returns true if a path of waypoints was found. Waypoints can be retrieved with _NAVMESH_REQUESTED_PATH_NUM_WAYPOINTS and _NAVMESH_REQUESTED_PATH_WAYPOINT_BY_INDEX * * @param path * @returns */ static navmeshRequestedPathWaypointsFound(path: int): boolean { return !!inv('0x8800776E410EB669', path, rai()); } /** * @param p0 * @returns */ static N_0xEFC535C9FAF563B3(p0: any): any { return inv('0xEFC535C9FAF563B3', p0); } /** * @param p0 * @returns */ static simulatedRouteExists(p0: any): any { return inv('0x65A8196B8D7F5E0B', p0); } /** * @param min * @param max * @param p6 * @param p7 */ static setRoadsBackToOriginal(min: Vector3, max: Vector3, p6: any, p7: any): void { inv('0x1EE7063B80FFC77C', f(min.x), f(min.y), f(min.z), f(max.x), f(max.y), f(max.z), p6, p7); } /** * Gets a value indicating whether the specified position is on a road. * * @param pos * @param vehicle * @returns */ static isPointOnRoad(pos: Vector3, vehicle: Vehicle): boolean { return !!inv('0x125BF4ABFC536B09', f(pos.x), f(pos.y), f(pos.z), vehicle.handle, rai()); } /** * @param name * @returns */ static navmeshDeactivateSwap(name: string): any { return inv('0x527B97C203BB8606', name); } /** * @param multiplier */ static setAmbientPedRangeMultiplierThisFrame(multiplier: float): void { inv('0x0B919E1FB47CC4E0', f(multiplier)); } /** * Returns true if the id is non zero. * * @param vehicleNodeId * @returns */ static isVehicleNodeIdValid(vehicleNodeId: int): boolean { return !!inv('0x5829A02AF4F0B3CB', vehicleNodeId, rai()); } /** * @param p0 * @param p1 * @param p2 */ static simulatedRouteTravelToPoint(p0: any, p1: float, p2: float): void { inv('0xA1A3DE1C215C7394', p0, f(p1), f(p2)); } /** * @param p0 * @param p1 * @param p2 */ static N_0x5A4E1A41E3A02AD0(p0: any, p1: any, p2: any): void { inv('0x5A4E1A41E3A02AD0', p0, p1, p2); } /** * @param volume * @returns */ static doesNavmeshBlockingVolumeExist(volume: Volume): boolean { return !!inv('0xDE0EA444735C1368', volume.handle, rai()); } /** * @param nodeId * @param pos * @returns outCoords; heading */ static getSpawnDataForRoadNode(nodeId: int, pos: Vector3): [Vector3, number] { const result = inv<[number[], number]>('0xA3791B915B8B84C6', nodeId, f(pos.x), f(pos.y), f(pos.z), pvv(), pvf()); return [Vector3.fromArray(result[0]), result[1]]; } /** * @param min * @param max * @param p6 * @param p7 */ static N_0xAFE2AE66F6251C66(min: Vector3, max: Vector3, p6: int, p7: any): void { inv('0xAFE2AE66F6251C66', f(min.x), f(min.y), f(min.z), f(max.x), f(max.y), f(max.z), p6, p7); } /** * @param p0 */ static simulatedRouteDelete(p0: any): void { inv('0x4907D0E4FB26EE65', p0); } /** * @returns */ static getGpsBlipRouteFound(): boolean { return !!inv('0x869DAACBBE9FA006', rai()); } /** * @param vehicle * @param navMeshName * @returns */ static navmeshAssignNavmeshToVehicle(vehicle: Vehicle, navMeshName: string): any { return inv('0x44026E3DB3CED602', vehicle.handle, navMeshName); } /** * @param volume * @param p1 * @param p2 * @param p3 */ static setRoadsInVolume(volume: Volume, p1: boolean, p2: boolean, p3: boolean): void { inv('0xC1799FAFD2FDF52B', volume.handle, p1, p2, p3); } /** * @param p0 */ static N_0x264E9A5CD78C338F(p0: any): void { inv('0x264E9A5CD78C338F', p0); } /** * @param p0 * @returns */ static simulatedRouteIsLoaded(p0: any): any { return inv('0x240915043CB799D7', p0); } /** * @param volume * @param p1 */ static resetRoadsInVolume(volume: Volume, p1: boolean): void { inv('0xD17672447692478E', volume.handle, p1); } /** * @param p0 * @param p1 * @param p2 * @param p3 * @param p4 * @param p5 * @param p6 * @returns */ static N_0xCA27A86CAA4E98ED(p0: any, p1: any, p2: any, p3: any, p4: any, p5: any, p6: any): any { return inv('0xCA27A86CAA4E98ED', p0, p1, p2, p3, p4, p5, p6); } /** * Returns a vector3 waypoint at the specified index for a path. Use _NAVMESH_REQUESTED_PATH_NUM_WAYPOINTS to get available indexes. * * @param path * @param waypointIndex * @returns */ static navmeshRequestedPathWaypointByIndex(path: int, waypointIndex: int): Vector3 { return Vector3.fromArray(inv('0x430F8319AE56C8A9', path, waypointIndex, rav())); } /** * @param pos * @param nthClosest * @param unknown1 * @param unknown2 * @param unknown3 * @returns outPosition */ static getNthClosestVehicleNode(pos: Vector3, nthClosest: int, unknown1: int, unknown2: float, unknown3: any): [boolean, Vector3] { const result = inv<[boolean, number[]]>('0x5A6D8DF6FBC5D0C4', f(pos.x), f(pos.y), f(pos.z), nthClosest, pvv(), unknown1, f(unknown2), unknown3, rai()); return [!!result[0], Vector3.fromArray(result[1])]; } /** * @param pos * @param desiredX * @param desiredY * @param desiredZ * @param nthClosest * @param nodetype * @param p10 * @param p11 * @returns outPosition; outHeading */ static getNthClosestVehicleNodeFavourDirection(pos: Vector3, desiredX: float, desiredY: float, desiredZ: float, nthClosest: int, nodetype: int, p10: any, p11: any): [boolean, Vector3, number] { const result = inv<[boolean, number[], number]>('0x2FAC235A6062F14A', f(pos.x), f(pos.y), f(pos.z), f(desiredX), f(desiredY), f(desiredZ), nthClosest, pvv(), pvf(), nodetype, p10, p11, rai()); return [!!result[0], Vector3.fromArray(result[1]), result[2]]; } /** * @param name * @returns */ static navmeshActivateSwap(name: string): any { return inv('0x7C334FF4D9215912', name); } /** * @param p0 * @param p1 * @param p2 */ static N_0xCF213A5FC3ABFC08(p0: any, p1: any, p2: any): void { inv('0xCF213A5FC3ABFC08', p0, p1, p2); } /** * @param pos * @param onGround * @param flags * @returns outPosition */ static getSafeCoordForPed(pos: Vector3, onGround: boolean, flags: int): [boolean, Vector3] { const result = inv<[boolean, number[]]>('0xB61C8E878A4199CA', f(pos.x), f(pos.y), f(pos.z), onGround, pvv(), flags, rai()); return [!!result[0], Vector3.fromArray(result[1])]; } /** * Old name: REQUEST_PATHS_PREFER_ACCURATE_BOUNDINGSTRUCT * * @param pos1 * @param pos2 * @returns */ static requestPathNodesInAreaThisFrame(pos1: Vector2, pos2: Vector2): boolean { return !!inv('0x07FB139B592FA687', f(pos1.x), f(pos1.y), f(pos2.x), f(pos2.y), rai()); } /** * @param p0 * @param p1 */ static N_0x6DAD6630AE4A74CB(p0: any, p1: any): void { inv('0x6DAD6630AE4A74CB', p0, p1); } /** * @param min * @param max * @param p6 * @param p7 */ static N_0x6C3F12ECEB6D2E2A(min: Vector3, max: Vector3, p6: any, p7: any): void { inv('0x6C3F12ECEB6D2E2A', f(min.x), f(min.y), f(min.z), f(max.x), f(max.y), f(max.z), p6, p7); } /** * @param p0 * @param p1 * @param p2 * @param p3 * @param p4 * @param p5 * @param p6 * @param p7 * @param p8 */ static setRoadsBackToOriginalInAngledArea(p0: any, p1: any, p2: any, p3: any, p4: any, p5: any, p6: any, p7: any, p8: any): void { inv('0x0027501B9F3B407E', p0, p1, p2, p3, p4, p5, p6, p7, p8); } /** * Returns whether navmesh for the region is loaded. * * @param pos1 * @param pos2 * @returns */ static isNavmeshLoadedInArea(pos1: Vector3, pos2: Vector3): boolean { return !!inv('0xF813C7E63F9062A5', f(pos1.x), f(pos1.y), f(pos1.z), f(pos2.x), f(pos2.y), f(pos2.z), rai()); } /** * @param p0 * @param p1 * @param p2 * @param p3 * @param p4 * @param p5 * @returns */ static getNumNavmeshesExistingInArea(p0: float, p1: float, p2: float, p3: float, p4: float, p5: float): int { return inv('0x01708E8DD3FF8C65', f(p0), f(p1), f(p2), f(p3), f(p4), f(p5), rai()); } /** * @returns */ static getGpsBlipRouteLength(): int { return inv('0xBBB45C3CF5C8AA85', rai()); } /** * @param p0 * @returns */ static N_0x5A3B54ADDF5472A3(p0: string): int { return inv('0x5A3B54ADDF5472A3', p0, rai()); } /** * Returns CGameWorldHeightMap's minimum Z value at specified point (grid node). * * @param pos * @returns */ static getApproxFloorForPoint(pos: Vector2): float { return inv('0x336511A34F2E5185', f(pos.x), f(pos.y), raf()); } /** * @param p0 * @returns */ static simulatedRouteGetEta(p0: any): float { return inv('0x2DD5F78D73B24172', p0, raf()); } /** * @param pos * @param nodeType * @param p6 * @param p7 * @returns outPosition; outHeading */ static getClosestVehicleNodeWithHeading(pos: Vector3, nodeType: int, p6: float, p7: float): [boolean, Vector3, number] { const result = inv<[boolean, number[], number]>('0x23CFFD4CCB243354', f(pos.x), f(pos.y), f(pos.z), pvv(), pvf(), nodeType, f(p6), f(p7), rai()); return [!!result[0], Vector3.fromArray(result[1]), result[2]]; } /** * @param p0 * @param p1 * @param p2 * @param p3 * @param p4 * @param p5 * @param p6 */ static setPedPathsBackToOriginal(p0: any, p1: any, p2: any, p3: any, p4: any, p5: any, p6: any): void { inv('0xE04B48F2CC926253', p0, p1, p2, p3, p4, p5, p6); } /** * @param x * @param y * @param radius */ static addNavmeshRequiredRegion(x: float, y: float, radius: float): void { inv('0x387EAD7EE42F6685', f(x), f(y), f(radius)); } /** * @param pos * @param radius * @param minLanes * @param avoidDeadEnds * @param avoidHighways * @returns outPosition; nodeId */ static getRandomVehicleNode(pos: Vector3, radius: float, minLanes: int, avoidDeadEnds: boolean, avoidHighways: boolean): [boolean, Vector3, number] { const result = inv<[boolean, number[], number]>('0x93E0DB8440B73A7D', f(pos.x), f(pos.y), f(pos.z), f(radius), minLanes, avoidDeadEnds, avoidHighways, pvv(), pvi(), rai()); return [!!result[0], Vector3.fromArray(result[1]), result[2]]; } /** * @param pos * @param nth * @param nodetype * @param p5 * @param p6 * @returns */ static getNthClosestVehicleNodeId(pos: Vector3, nth: int, nodetype: int, p5: float, p6: float): int { return inv('0x116443008E5CEFC3', f(pos.x), f(pos.y), f(pos.z), nth, nodetype, f(p5), f(p6), rai()); } /** * @param p0 */ static N_0x34C9AF25649172D0(p0: any): void { inv('0x34C9AF25649172D0', p0); } /** * @param name * @returns */ static navmeshDoesSwapExist(name: string): any { return inv('0x495CFAB2924237C7', name); } /** * @param p0 * @param p1 * @param p2 */ static N_0xB03944057FD735BA(p0: any, p1: any, p2: any): void { inv('0xB03944057FD735BA', p0, p1, p2); } /** * @param pos1 * @param pos2 * @returns */ static areNodesLoadedForArea(pos1: Vector2, pos2: Vector2): boolean { return !!inv('0xF7B79A50B905A30D', f(pos1.x), f(pos1.y), f(pos2.x), f(pos2.y), rai()); } /** * @param p0 * @param p1 * @param p2 * @param p3 * @param p4 * @param p5 */ static N_0x4BDEBEA5702B97A9(p0: any, p1: any, p2: any, p3: any, p4: any, p5: any): void { inv('0x4BDEBEA5702B97A9', p0, p1, p2, p3, p4, p5); } /** * @param pos * @param p3 * @param p4 * @param p10 * @returns p5; p6; p7; p8; p9 */ static getClosestRoad(pos: Vector3, p3: float, p4: int, p10: boolean): [any, Vector3, Vector3, number, number, number] { const result = inv<[number, number[], number[], number, number, number]>('0x132F52BBA570FE92', f(pos.x), f(pos.y), f(pos.z), f(p3), p4, pvv(), pvv(), pvi(), pvi(), pvf(), p10); return [result[0], Vector3.fromArray(result[1]), Vector3.fromArray(result[2]), result[3], result[4], result[5]]; } /** * nullsub, doesn't do anything * * @param toggle */ static setIgnoreNoGpsFlag(toggle: boolean): void { inv('0x72751156E7678833', toggle); } /** * @param p0 */ static N_0x869A7015BD4606E9(p0: any): void { inv('0x869A7015BD4606E9', p0); } /** * Called in scripts after finished with requested pathes. Immediately resets all values connected to the path handle except query status, which changes from 1 to 2 before eventually becoming fully invalidated to 0. * * @param path * @returns */ static navmeshClearRequestedPath(path: int): boolean { return !!inv('0x661BB1E1FF77742D', path, rai()); } /** * @param pos * @param nodeType * @param p5 * @param p6 * @returns outPosition */ static getClosestVehicleNode(pos: Vector3, nodeType: int, p5: float, p6: float): [boolean, Vector3] { const result = inv<[boolean, number[]]>('0x240A18690AE96513', f(pos.x), f(pos.y), f(pos.z), pvv(), nodeType, f(p5), f(p6), rai()); return [!!result[0], Vector3.fromArray(result[1])]; } /** * @param p0 */ static removeNavmeshBlockingObject(p0: any): void { inv('0x46399A7895957C0E', p0); } /** * @param p0 * @returns */ static doesNavmeshBlockingObjectExist(p0: any): boolean { return !!inv('0x0EAEB0DB4B132399', p0, rai()); } /** * @param p0 * @param p1 * @param p2 * @param p3 * @param p4 * @param p5 * @param p6 * @param p7 * @param p8 * @param p9 * @param p10 */ static setRoadsInAngledArea(p0: any, p1: any, p2: any, p3: any, p4: any, p5: any, p6: any, p7: any, p8: any, p9: any, p10: any): void { inv('0x1A5AA1208AF5DB59', p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); } /** * @param p0 * @param p1 * @returns */ static N_0xA33914B00CA55756(p0: string, p1: int): number { return inv('0xA33914B00CA55756', p0, p1); } /** * @param pos1 * @param pos2 * @param unknown * @param p7 */ static setPedPathsInArea(pos1: Vector3, pos2: Vector3, unknown: boolean, p7: any): void { inv('0x34F060F4BF92E018', f(pos1.x), f(pos1.y), f(pos1.z), f(pos2.x), f(pos2.y), f(pos2.z), unknown, p7); } /** * @param volume */ static removeNavmeshBlockingVolume(volume: Volume): void { inv('0x2C87C3E1C7B96EE2', volume.handle); } /** * @param pos1 * @param pos2 * @param p6 * @returns */ static simulatedRouteCreate(pos1: Vector3, pos2: Vector3, p6: int): any { return inv('0xFD5BB35AAB83FD48', f(pos1.x), f(pos1.y), f(pos1.z), f(pos2.x), f(pos2.y), f(pos2.z), p6); } /** * @param p0 * @param p1 * @param p2 * @param p3 * @param p4 * @returns */ static N_0x54F4D7B6670FBB5A(p0: any, p1: any, p2: any, p3: any, p4: any): any { return inv('0x54F4D7B6670FBB5A', p0, p1, p2, p3, p4); } /** * @param name * @returns */ static navmeshIsSwapActive(name: string): any { return inv('0x5AC0944C156E5F44', name); } /** * Returns the nth closest vehicle node with a heading to a coord * * @param pos * @param nthClosest * @param nodeFlags * @param zMeasureMult * @param zTolerance * @returns returnHeading; returnNumLanes */ static getNthClosestVehicleNodeIdWithHeading(pos: Vector3, nthClosest: int, nodeFlags: int, zMeasureMult: float, zTolerance: float): [int, number, number] { const result = inv<[number, number, number]>('0x4114EAA8A7F7766D', f(pos.x), f(pos.y), f(pos.z), nthClosest, pvf(), pvi(), nodeFlags, f(zMeasureMult), f(zTolerance), rai()); return [result[0], result[1], result[2]]; } /** * @param volume * @param flags * @returns */ static addNavmeshBlockingVolume(volume: Volume, flags: int): any { return inv('0x19C7567D2F2287D6', volume.handle, flags); } /** * @param pos * @param nthClosest * @param unknown2 * @param unknown3 * @param unknown4 * @returns outPosition; heading; unknown1 */ static getNthClosestVehicleNodeWithHeading(pos: Vector3, nthClosest: int, unknown2: int, unknown3: float, unknown4: float): [boolean, Vector3, number, number] { const result = inv<[boolean, number[], number, number]>('0x591B40D4390DB54A', f(pos.x), f(pos.y), f(pos.z), nthClosest, pvv(), pvf(), pvi(), unknown2, f(unknown3), f(unknown4), rai()); return [!!result[0], Vector3.fromArray(result[1]), result[2], result[3]]; } /** * @param p0 * @param p1 * @param p2 * @param p3 * @param p4 * @param p5 * @param p6 * @param p7 * @param p8 * @returns */ static addNavmeshBlockingObject(p0: float, p1: float, p2: float, p3: float, p4: float, p5: float, p6: float, p7: boolean, p8: any): any { return inv('0xFCD5C8E06E502F5A', f(p0), f(p1), f(p2), f(p3), f(p4), f(p5), f(p6), p7, p8); } /** * Returns eNavMeshQueryStatus * enum eNavMeshQueryStatus * { * QS_NOT_FOUND, * QS_COMPLETE, * QS_PENDING * }; It appears that the pending state of 2 is at least also used when cleaning up a request (_NAVMESH_CLEAR_REQUESTED_PATH) or if a request never completes. Eventually queries are invalidated and return 0. Old name: _NAVMESH_QUERY_STATUS * * @param path * @returns */ static navmeshRequestedQueryStatus(path: int): int { return inv('0x3A0F82F6EE2291C8', path, rai()); } /** * Returns the number of waypoints for a requested path (NAVMESH_REQUEST_PATH) if the query is completed (_NAVMESH_REQUESTED_QUERY_STATUS). For use with _NAVMESH_REQUESTED_PATH_WAYPOINT_BY_INDEX * * @param path * @returns */ static navmeshRequestedPathNumWaypoints(path: int): int { return inv('0xD470725E0703D22F', path, rai()); } /** * @param nodeID * @returns */ static getVehicleNodeIsSwitchedOff(nodeID: int): boolean { return !!inv('0x28533DBDDF7C2C97', nodeID, rai()); } /** * @param p0 * @param p1 * @param p2 * @param p3 * @param p4 * @param p5 * @param p6 * @param p7 * @param p8 * @param p9 */ static N_0x4358BCF14C91761C(p0: any, p1: any, p2: any, p3: any, p4: any, p5: any, p6: any, p7: any, p8: any, p9: any): void { inv('0x4358BCF14C91761C', p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); } /** * @param nodeId * @returns outPosition */ static getVehicleNodePosition(nodeId: int): Vector3 { const result = inv('0x8E8D72FF24DEE1FB', nodeId, pvv()); return Vector3.fromArray(result); } /** * @param p0 * @param p1 * @param p2 * @returns */ static N_0x665B21666351CB37(p0: any, p1: any, p2: any): any { return inv('0x665B21666351CB37', p0, p1, p2); } /** * GPS disabled zone: p1 = 0 * Clearing GPS disabled zone: p1 = 1 * * @param volume * @param p1 * @param p2 */ static N_0xF2A2177AC848B3A8(volume: Volume, p1: int, p2: int): void { inv('0xF2A2177AC848B3A8', volume.handle, p1, p2); } /** * Starts a nav mesh query for a path between coordinates with a given ped and returns a handle to be validated by _NAVMESH_REQUESTED_QUERY_STATUS and then _NAVMESH_REQUESTED_PATH_WAYPOINTS_FOUND Only bit flag values used in scripts are 0, 23, and 29. 23 is used with dogs and horses. 29 with legendary animals. * * @param ped * @param pos1 * @param pos2 * @param bitFlag * @returns */ static navmeshRequestPath(ped: Ped, pos1: Vector3, pos2: Vector3, bitFlag: int): int { return inv('0x348F211CA2404039', ped.handle, f(pos1.x), f(pos1.y), f(pos1.z), f(pos2.x), f(pos2.y), f(pos2.z), bitFlag, rai()); } /** * @param min * @param max * @param p6 * @param p7 * @param p8 */ static setRoadsInArea(min: Vector3, max: Vector3, p6: any, p7: any, p8: any): void { inv('0xBF1A602B5BA52FEE', f(min.x), f(min.y), f(min.z), f(max.x), f(max.y), f(max.z), p6, p7, p8); } /** * @param p0 * @param p1 * @param p2 */ static N_0xE5EF9DE716FF737E(p0: any, p1: any, p2: any): void { inv('0xE5EF9DE716FF737E', p0, p1, p2); } /** * Returns a bit flag for seemingly terrain within the waypoints in the path. Checked against bit value 2 to match water in the path, seems to always contain at least 1 though regardless of location/ped. * * @param path * @returns */ static navmeshRequestedPathWaypointsTerrain(path: int): int { return inv('0xF61CFEDEAB627BFA', path, rai()); } }