@duydang2311/ragemp-utils
Version:
A collection of utilities for RAGE Multiplayer JavaScript module.
405 lines (401 loc) • 10.4 kB
JavaScript
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var index_exports = {};
__export(index_exports, {
RageMpLocalMarker: () => RageMpLocalMarker,
SpatialGrid2D: () => SpatialGrid2D,
distanceSquared: () => distanceSquared
});
module.exports = __toCommonJS(index_exports);
// src/lib/vector.ts
var distanceSquared = (a, b) => {
const dx = a.x - b.x;
const dy = a.y - b.y;
if ("z" in a && "z" in b) {
const dz = a.z - b.z;
return dx * dx + dy * dy + dz * dz;
}
return dx * dx + dy * dy;
};
// src/lib/spatial-grid.ts
var SpatialGrid2D = class _SpatialGrid2D {
static DEFAULT_MIN_X = -4e3;
static DEFAULT_MAX_X = 4e3;
static DEFAULT_MIN_Y = -4e3;
static DEFAULT_MAX_Y = 8e3;
static DEFAULT_CELL_SIZE = 128;
#idCounter;
#min;
#max;
#rows;
#columns;
#cells;
#cellSize;
#idLookup = /* @__PURE__ */ new Map();
constructor(options) {
this.#idCounter = 0;
this.#min = options?.min ?? {
x: _SpatialGrid2D.DEFAULT_MIN_X,
y: _SpatialGrid2D.DEFAULT_MIN_Y
};
this.#max = options?.max ?? {
x: _SpatialGrid2D.DEFAULT_MAX_X,
y: _SpatialGrid2D.DEFAULT_MAX_Y
};
this.#cellSize = options?.cellSize ?? _SpatialGrid2D.DEFAULT_CELL_SIZE;
this.#rows = Math.ceil((this.#max.y - this.#min.y) / this.#cellSize);
this.#columns = Math.ceil((this.#max.x - this.#min.x) / this.#cellSize);
this.#cells = new Array(this.#rows * this.#columns).fill(0).map(() => []);
}
get min() {
return this.#min;
}
get max() {
return this.#max;
}
get cellSize() {
return this.#cellSize;
}
get rows() {
return this.#rows;
}
get columns() {
return this.#columns;
}
cellAt(coords) {
this.#assertInBounds(coords);
return this.#safeCellAt(coords);
}
nearbyCells(coords, radius) {
this.#assertInBounds(coords);
const minCol = Math.max(
0,
Math.floor((coords.x - radius - this.#min.x) / this.#cellSize)
);
const maxCol = Math.min(
this.#columns - 1,
Math.floor((coords.x + radius - this.#min.x) / this.#cellSize)
);
const minRow = Math.max(
0,
Math.floor((coords.y - radius - this.#min.y) / this.#cellSize)
);
const maxRow = Math.min(
this.#rows - 1,
Math.floor((coords.y + radius - this.#min.y) / this.#cellSize)
);
const cells = new Array(
(maxRow - minRow + 1) * (maxCol - minCol + 1)
);
let index = 0;
for (let row = minRow; row <= maxRow; ++row) {
for (let col = minCol; col <= maxCol; ++col) {
cells[index++] = row * this.#columns + col;
}
}
return cells;
}
add(item, coords, radius) {
this.#assertInBounds(coords);
const id = ++this.#idCounter;
if (radius == null) {
const cellIndex = this.#safeCellAt(coords);
this.#cells[cellIndex].push([id, item]);
this.#idLookup.set(id, [[cellIndex]]);
return id;
}
const minCol = Math.max(
0,
Math.floor(
(coords.x - (radius ?? 0) - this.#min.x) / this.#cellSize
)
);
const maxCol = Math.min(
this.#columns - 1,
Math.floor(
(coords.x + (radius ?? 0) - this.#min.x) / this.#cellSize
)
);
const minRow = Math.max(
0,
Math.floor(
(coords.y - (radius ?? 0) - this.#min.y) / this.#cellSize
)
);
const maxRow = Math.min(
this.#rows - 1,
Math.floor(
(coords.y + (radius ?? 0) - this.#min.y) / this.#cellSize
)
);
const cells = [];
for (let row = minRow; row <= maxRow; ++row) {
for (let col = minCol; col <= maxCol; ++col) {
const cellIndex = row * this.#columns + col;
cells.push(cellIndex);
this.#cells[cellIndex].push([id, item, radius]);
}
}
this.#idLookup.set(id, [cells]);
return id;
}
update(id, coords, radius) {
const itemLookup = this.#idLookup.get(id);
if (!itemLookup) {
return false;
}
const [lookUpCells] = itemLookup;
let item;
for (const cell of lookUpCells) {
item = this.#cells[cell].find(
(cellItem) => cellItem[0] === id
)?.[1];
if (item) {
break;
}
}
if (!item || !this.remove(id)) {
return false;
}
if (radius == null) {
const cellIndex = this.#safeCellAt(coords);
this.#cells[cellIndex].push([id, item]);
this.#idLookup.set(id, [[cellIndex]]);
return true;
}
const minCol = Math.max(
0,
Math.floor(
(coords.x - (radius ?? 0) - this.#min.x) / this.#cellSize
)
);
const maxCol = Math.min(
this.#columns - 1,
Math.floor(
(coords.x + (radius ?? 0) - this.#min.x) / this.#cellSize
)
);
const minRow = Math.max(
0,
Math.floor(
(coords.y - (radius ?? 0) - this.#min.y) / this.#cellSize
)
);
const maxRow = Math.min(
this.#rows - 1,
Math.floor(
(coords.y + (radius ?? 0) - this.#min.y) / this.#cellSize
)
);
const cells = [];
for (let row = minRow; row <= maxRow; ++row) {
for (let col = minCol; col <= maxCol; ++col) {
const cellIndex = row * this.#columns + col;
cells.push(cellIndex);
this.#cells[cellIndex].push([id, item, radius]);
}
}
this.#idLookup.set(id, [cells]);
return true;
}
remove(id) {
const itemLookup = this.#idLookup.get(id);
if (!itemLookup) {
return false;
}
const [cells] = itemLookup;
for (const cellIndex of cells) {
const cellItems = this.#cells[cellIndex];
const itemIndex = cellItems.findIndex(
(cellItem) => cellItem[0] === id
);
if (itemIndex !== -1) {
cellItems.splice(itemIndex, 1);
}
}
return this.#idLookup.delete(id);
}
#safeCellAt(coords) {
const col = Math.floor((coords.x - this.#min.x) / this.#cellSize);
const row = Math.floor((coords.y - this.#min.y) / this.#cellSize);
return row * this.#columns + col;
}
#assertInBounds(coords) {
if (coords.x < this.#min.x || coords.x >= this.#max.x || coords.y < this.#min.y || coords.y >= this.#max.y) {
throw new Error(
`Coordinates (${coords.x}, ${coords.y}) are out of bounds for the grid.`
);
}
}
};
// src/lib/local-marker.ts
var RageMpLocalMarker = class {
#type;
#position;
#destination;
#direction;
#rotation;
#scale;
#radius;
#color;
#bobUpAndDown;
#faceCamera;
#rotate;
#textureDict;
#textureName;
#drawOnEnts;
constructor(type, position, destination, rotation, scale, radius, color, bobUpAndDown = false, faceCamera = false, rotate = false, textureDict = null, textureName = null, drawOnEnts = false) {
this.#type = type;
this.#position = position;
this.#destination = destination;
this.#rotation = rotation;
this.#scale = scale;
this.#radius = radius;
this.#color = color;
this.#bobUpAndDown = bobUpAndDown;
this.#faceCamera = faceCamera;
this.#rotate = rotate;
this.#textureDict = textureDict;
this.#textureName = textureName;
this.#drawOnEnts = drawOnEnts;
this.#direction = this.#getDirectionVector();
}
get type() {
return this.#type;
}
get position() {
return this.#position;
}
get destination() {
return this.#destination;
}
get rotation() {
return this.#rotation;
}
get scale() {
return this.#scale;
}
get radius() {
return this.#radius;
}
get color() {
return this.#color;
}
get bobUpAndDown() {
return this.#bobUpAndDown;
}
get faceCamera() {
return this.#faceCamera;
}
get rotate() {
return this.#rotate;
}
get textureDict() {
return this.#textureDict;
}
get textureName() {
return this.#textureName;
}
get drawOnEnts() {
return this.#drawOnEnts;
}
set type(value) {
this.#type = value;
}
set position(value) {
this.#position = value;
}
set destination(value) {
this.#destination = value;
this.#direction = this.#getDirectionVector();
}
set rotation(value) {
this.#rotation = value;
}
set scale(value) {
this.#scale = value;
}
set radius(value) {
this.#radius = value;
}
set color(value) {
this.#color = value;
}
set bobUpAndDown(value) {
this.#bobUpAndDown = value;
}
set faceCamera(value) {
this.#faceCamera = value;
}
set rotate(value) {
this.#rotate = value;
}
set textureDict(value) {
this.#textureDict = value;
}
set textureName(value) {
this.#textureName = value;
}
set drawOnEnts(value) {
this.#drawOnEnts = value;
}
render() {
mp.game.graphics.drawMarker(
this.#type,
this.#position.x,
this.#position.y,
this.#position.z,
this.#direction.x,
this.#direction.y,
this.#direction.z,
this.#rotation.x,
this.#rotation.y,
this.#rotation.z,
this.#scale.x,
this.#scale.y,
this.#scale.z,
this.#color[0],
this.#color[1],
this.#color[2],
this.#color[3],
this.#bobUpAndDown,
this.#faceCamera,
2,
this.#rotate,
this.#textureDict,
this.#textureName,
this.#drawOnEnts
);
}
#getDirectionVector() {
return new mp.Vector3(
this.#destination.x - this.#position.x,
this.#destination.y - this.#position.y,
this.#destination.z - this.#position.z
);
}
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
RageMpLocalMarker,
SpatialGrid2D,
distanceSquared
});
//# sourceMappingURL=index.cjs.map