@runejs/filestore
Version:
Tools for managing the RuneJS filestore.
162 lines (161 loc) • 6.41 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.RegionStore = exports.maxRegions = void 0;
const tslib_1 = require("tslib");
const common_1 = require("@runejs/common");
const node_fs_1 = require("node:fs");
const node_path_1 = tslib_1.__importDefault(require("node:path"));
exports.maxRegions = 32768;
class RegionStore {
fileStore;
xteas = {};
regionIndex;
constructor(fileStore, xteas) {
this.fileStore = fileStore;
this.regionIndex = this.fileStore.getIndex('regions');
if (xteas) {
this.xteas = xteas;
}
else {
const array = JSON.parse((0, node_fs_1.readFileSync)(node_path_1.default.join(this.fileStore.configDir, 'map-keys.json'), 'utf8'));
for (let i = 0; i < array.length; i++) {
const object = array[i];
this.xteas[object.name] = object;
}
}
}
getMapKeys(regionX, regionY) {
return this.xteas[`l${regionX}_${regionY}`]?.key || [0, 0, 0, 0];
}
getRegion(regionX, regionY) {
const mapFile = this.getMapFile(regionX, regionY);
if (!mapFile) {
return null;
}
const landscapeFile = this.getLandscapeFile(regionX, regionY) || null;
return { regionX, regionY, mapFile, landscapeFile };
}
getLandscapeFile(regionX, regionY) {
const keys = this.getMapKeys(regionX, regionY);
const landscapeFile = this.regionIndex.getFile(`l${regionX}_${regionY}`, keys);
if (!landscapeFile) {
common_1.logger.warn(`Landscape file not found for region ${regionX},${regionY}`);
return null;
}
const landscapeObjects = [];
let objectId = -1;
landscapeFile.content.readerIndex = 0;
let objectLoop = true;
while (objectLoop) {
const objectIdOffset = landscapeFile.content.get('SMART_SHORT');
if (objectIdOffset === 0) {
objectLoop = false;
break;
}
objectId += objectIdOffset;
let objectPositionInfo = 0;
let positionLoop = true;
while (positionLoop) {
const objectPositionInfoOffset = landscapeFile.content.get('SMART_SHORT');
if (objectPositionInfoOffset === 0) {
positionLoop = false;
break;
}
objectPositionInfo += objectPositionInfoOffset - 1;
const worldX = (regionX & 0xff) * 64;
const worldY = regionY * 64;
const x = ((objectPositionInfo >> 6) & 0x3f) + worldX;
const y = (objectPositionInfo & 0x3f) + worldY;
const level = (objectPositionInfo >> 12) & 0x3;
const objectMetadata = landscapeFile.content.get('BYTE', 'UNSIGNED');
const type = objectMetadata >> 2;
const orientation = objectMetadata & 0x3;
landscapeObjects.push({
objectId,
x,
y,
level,
type,
orientation,
});
}
}
return {
fileId: landscapeFile.fileId,
regionX,
regionY,
landscapeObjects,
};
}
getMapFile(regionX, regionY) {
const mapFile = this.regionIndex.getFile(`m${regionX}_${regionY}`);
if (!mapFile) {
common_1.logger.warn(`Map file not found for region ${regionX},${regionY}`);
return null;
}
const tileHeights = new Array(4);
const tileSettings = new Array(4);
const tileOverlayIds = new Array(4);
const tileOverlayPaths = new Array(4);
const tileOverlayOrientations = new Array(4);
const tileUnderlayIds = new Array(4);
const buffer = mapFile.content;
buffer.readerIndex = 0;
for (let level = 0; level < 4; level++) {
tileHeights[level] = new Array(64);
tileSettings[level] = new Array(64);
tileOverlayIds[level] = new Array(64);
tileOverlayPaths[level] = new Array(64);
tileOverlayOrientations[level] = new Array(64);
tileUnderlayIds[level] = new Array(64);
for (let x = 0; x < 64; x++) {
tileHeights[level][x] = new Array(64);
tileSettings[level][x] = new Uint8Array(64);
tileOverlayIds[level][x] = new Uint8Array(64);
tileOverlayPaths[level][x] = new Uint8Array(64);
tileOverlayOrientations[level][x] = new Uint8Array(64);
tileUnderlayIds[level][x] = new Uint8Array(64);
for (let y = 0; y < 64; y++) {
tileSettings[level][x][y] = 0;
let run = true;
while (run) {
const opcode = buffer.get('BYTE', 'UNSIGNED');
if (opcode === 0) {
run = false;
break;
}
if (opcode === 1) {
tileHeights[level][x][y] = buffer.get('BYTE', 'UNSIGNED');
run = false;
break;
}
if (opcode <= 49) {
tileOverlayIds[level][x][y] = buffer.get('BYTE');
tileOverlayPaths[level][x][y] = (opcode - 2) / 4;
tileOverlayOrientations[level][x][y] =
(opcode - 2) & 3;
}
else if (opcode <= 81) {
tileSettings[level][x][y] = opcode - 49;
}
else {
tileUnderlayIds[level][x][y] = opcode - 81;
}
}
}
}
}
return {
fileId: mapFile.fileId,
regionX,
regionY,
tileHeights,
tileOverlayIds,
tileOverlayOrientations,
tileOverlayPaths,
tileSettings,
tileUnderlayIds,
};
}
}
exports.RegionStore = RegionStore;