Files
ox_lib/package/client/resource/points/index.ts

131 lines
3.3 KiB
TypeScript
Raw Normal View History

import { Vector3 } from '@nativewrappers/fivem';
import { cache } from '../cache';
2023-02-19 22:40:16 +01:00
let points: Point[] = [];
let nearbyPoints: Point[] = [];
let nearbyCount: number = 0;
let closestPoint: Point | undefined;
let tick: number | undefined;
let pointsInterval: CitizenTimer;
2023-02-19 22:40:16 +01:00
interface LibPoint<T = unknown> {
2023-02-19 22:40:16 +01:00
coords: number[];
distance: number;
onEnter?: () => void;
onExit?: () => void;
nearby?: () => void;
args?: T;
2023-02-19 22:40:16 +01:00
}
export class Point<T = unknown> {
2023-02-19 22:40:16 +01:00
id: number = 0;
coords: Vector3;
distance: number = 0;
onEnter?: () => void;
onExit?: () => void;
nearby?: () => void;
args?: T;
2023-02-19 22:40:16 +01:00
inside: boolean = false;
currentDistance?: number;
isClosest: boolean = false;
constructor(point: LibPoint<T>) {
2023-02-19 22:40:16 +01:00
this.id = points.length + 1;
this.coords = Vector3.fromArray(point.coords);
this.distance = point.distance;
this.onEnter = point.onEnter;
this.onExit = point.onExit;
this.nearby = point.nearby;
this.args = point.args;
2023-02-19 22:40:16 +01:00
points.push(this);
if (points.length === 1) {
startPointsInterval();
}
2023-02-19 22:40:16 +01:00
}
remove = () => {
const coords = Vector3.fromArray(GetEntityCoords(cache.ped, false));
const distance = coords.distance(this.coords);
if (distance < this.distance) {
nearbyCount -= 1;
nearbyPoints = nearbyPoints.filter((point) => point.id !== this.id);
if (nearbyCount === 0 && tick) {
clearTick(tick);
tick = undefined;
}
}
2023-02-19 22:40:16 +01:00
points = points.filter((point) => point.id !== this.id);
if (points.length === 0) {
clearInterval(pointsInterval);
}
2023-02-19 22:40:16 +01:00
};
}
const startPointsInterval = () => {
pointsInterval = setInterval(() => {
if (points.length < 1) return;
if (nearbyCount !== 0) {
nearbyPoints = [];
nearbyCount = 0;
}
2023-02-19 22:40:16 +01:00
const coords = Vector3.fromArray(GetEntityCoords(cache.ped, false));
2023-02-19 22:40:16 +01:00
if (closestPoint && coords.distance(closestPoint.coords) > closestPoint.distance) {
closestPoint = undefined;
}
2023-02-19 22:40:16 +01:00
for (let i = 0; i < points.length; i++) {
const point = points[i];
const distance = coords.distance(point.coords);
2023-02-19 22:40:16 +01:00
if (distance <= point.distance) {
point.currentDistance = distance;
2023-02-19 22:40:16 +01:00
if (closestPoint && closestPoint.currentDistance) {
if (distance < closestPoint.currentDistance) {
closestPoint.isClosest = false;
point.isClosest = true;
closestPoint = point;
}
} else if (distance < point.distance) {
2023-02-19 22:40:16 +01:00
point.isClosest = true;
closestPoint = point;
}
if (point.nearby) {
nearbyCount++;
nearbyPoints[nearbyCount - 1] = point;
}
2023-02-19 22:40:16 +01:00
if (point.onEnter && !point.inside) {
point.inside = true;
point.onEnter();
}
} else if (point.currentDistance) {
if (point.onExit) point.onExit();
point.inside = false;
point.currentDistance = undefined;
2023-02-19 22:40:16 +01:00
}
}
if (!tick) {
if (nearbyCount !== 0) {
tick = setTick(() => {
for (let i = 0; i < nearbyCount; i++) {
const point = nearbyPoints[i];
2023-02-19 22:40:16 +01:00
if (point && point.nearby) {
point.nearby();
}
2023-02-19 22:40:16 +01:00
}
});
}
} else if (nearbyCount === 0) {
clearTick(tick);
tick = undefined;
2023-02-19 22:40:16 +01:00
}
}, 300);
};