@overextended/ox_lib
Version:
JS/TS wrapper for ox_lib exports
127 lines (126 loc) • 5.03 kB
JavaScript
console.warn(`The ox_lib zones module is experimental and may change in future versions.`);
import { Grid } from '@overextended/core/grid';
import { Prism, Sphere } from '@overextended/core/geometry';
import { Vector3 } from '@overextended/core/vector';
import { cache } from '../cache';
export class Zone {
static nextId = 1;
static map = new Map();
static grid = new Grid();
static Prism(...args) {
return new Zone(new Prism(...args));
}
static Cuboid(...args) {
return new Zone(Prism.createCuboid(...args));
}
static Sphere(...args) {
return new Zone(new Sphere(...args));
}
static delete(id) {
const zone = Zone.map.get(id);
if (zone) {
Zone.map.delete(id);
Zone.grid.remove(zone);
}
}
static getNearby(point) {
return Zone.grid.getEntries(point.x, point.y);
}
static has(id) {
return Zone.map.has(id);
}
shouldDraw = false;
constructor(shape) {
this.shape = shape;
this.x = shape.centroid.x;
this.y = shape.centroid.y;
this.id = `zone:${Zone.nextId++}`;
if (shape instanceof Prism) {
const bounds = shape.bounds;
this.width = Math.abs(bounds.maxX - bounds.minX);
this.height = Math.abs(bounds.maxY - bounds.minY);
}
else {
const diametre = ('circle' in shape ? shape.circle.radius : shape.radius) * 2;
this.width = diametre;
this.height = diametre;
}
Zone.grid.add(this);
Zone.map.set(this.id, this);
}
draw(red = 255, green = 42, blue = 24, alpha = 100) {
if (cache.game === 'fxserver')
return;
if (this.shape instanceof Sphere) {
const { x, y, z } = this.shape.coords;
const radius = this.shape.radius;
return DrawMarker(28, x, y, z, 0, 0, 0, 0, 0, 0, radius, radius, radius, red, green, blue, alpha, false, false, 0, false, null, null, false);
}
if (this.shape instanceof Prism) {
const polygon = this.shape.polygon;
const half = this.shape.height / 2;
const minZ = this.shape.z - half;
const maxZ = this.shape.z + half;
for (let i = 0; i < polygon.vertices.length; i++) {
const curr = polygon.vertices[i];
const next = (polygon.vertices[i + 1] || polygon.vertices[0]);
DrawLine(curr.x, curr.y, minZ, curr.x, curr.y, maxZ, red, green, blue, 225);
DrawLine(curr.x, curr.y, maxZ, next.x, next.y, maxZ, red, green, blue, 225);
DrawLine(curr.x, curr.y, minZ, next.x, next.y, minZ, red, green, blue, 225);
DrawPoly(curr.x, curr.y, minZ, curr.x, curr.y, maxZ, next.x, next.y, maxZ, red, green, blue, alpha);
DrawPoly(curr.x, curr.y, minZ, next.x, next.y, maxZ, next.x, next.y, minZ, red, green, blue, alpha);
DrawPoly(curr.x, curr.y, minZ, next.x, next.y, maxZ, curr.x, curr.y, maxZ, red, green, blue, alpha);
DrawPoly(curr.x, curr.y, minZ, next.x, next.y, minZ, next.x, next.y, maxZ, red, green, blue, alpha);
}
for (let i = 0; i < polygon.triangles.length; i++) {
const [a, b, c] = polygon.triangles[i];
DrawPoly(a.x, a.y, minZ, b.x, b.y, minZ, c.x, c.y, minZ, red, green, blue, alpha);
DrawPoly(a.x, a.y, maxZ, b.x, b.y, maxZ, c.x, c.y, maxZ, red, green, blue, alpha);
DrawPoly(b.x, b.y, minZ, a.x, a.y, minZ, c.x, c.y, minZ, red, green, blue, alpha);
DrawPoly(b.x, b.y, maxZ, a.x, a.y, maxZ, c.x, c.y, maxZ, red, green, blue, alpha);
}
return;
}
}
}
function startPolling() {
if (cache.game === 'fxserver')
return;
let nearbyZones = new Set();
let insideZones = new Set();
let lastZones = new Set();
setInterval(() => {
const coords = Vector3.fromArray(GetEntityCoords(cache.ped, true));
cache.coords = coords;
nearbyZones = Zone.getNearby(coords);
[lastZones, insideZones] = [insideZones, lastZones];
insideZones.clear();
for (const zone of nearbyZones) {
if (zone.shape.contains(coords.x, coords.y, coords.z)) {
insideZones.add(zone);
if (!lastZones.has(zone)) {
if (zone.onEnter)
zone.onEnter();
}
else {
lastZones.delete(zone);
}
}
}
for (const zone of lastZones) {
if (zone.onExit)
zone.onExit();
}
}, 300);
setTick(() => {
for (const zone of nearbyZones) {
if (zone.shouldDraw)
zone.draw();
}
for (const zone of insideZones) {
if (zone.inside)
zone.inside();
}
});
}
startPolling();