Files
Construct-CN/packs/BP/scripts/classes/Structure/StructureCollection.js
T
2026-05-07 16:22:44 -07:00

116 lines
4.0 KiB
JavaScript

import { InvalidInstanceError } from '../Errors/InvalidInstanceError';
import { InstanceOptions } from '../Instance/InstanceOptions';
import { StructureInstance } from '../Instance/StructureInstance';
import { world } from '@minecraft/server';
class StructureCollection {
structures;
constructor() {
this.structures = {};
}
loadExistingInstances() {
world.getDynamicPropertyIds().filter(id => id.startsWith('instanceOptions:')).forEach(id => {
const instanceName = id.replace('instanceOptions:', '');
let structureId;
try {
structureId = InstanceOptions.getInstanceStructureId(instanceName);
this.structures[instanceName] = new StructureInstance(instanceName, structureId);
} catch (e) {
world.sendMessage(`§c[Construct] Error loading structure instance '${instanceName}'. It will be removed.`);
world.setDynamicProperty(id, void 0);
throw e;
}
});
}
add(instanceName, structureId) {
if (this.structures[instanceName])
throw new InvalidInstanceError(`Instance ${instanceName} already exists.`);
const structure = new StructureInstance(instanceName, structureId);
this.structures[instanceName] = structure;
return structure;
}
get(instanceName) {
const structure = this.structures[instanceName];
if (!structure)
throw new InvalidInstanceError(`Instance ${instanceName} not found.`);
return structure;
}
has(instanceName) {
return Boolean(this.structures[instanceName]);
}
delete(instanceName) {
const struct = this.get(instanceName);
struct.delete();
delete this.structures[instanceName];
}
getInstanceNames() {
return Object.keys(this.structures);
}
getStructures(dimensionId, location, options = {}) {
return Object.values(this.structures).filter(structure => {
try {
return structure.isLocationActive(dimensionId, structure.toStructureCoords(location), options)
} catch (e) {
if (e.name === 'InvalidStructureError') {
structureCollection.delete(structure.name);
return false;
} else {
throw e;
}
}
});
}
getStructure(dimensionId, location, options = {}) {
return this.getStructures(dimensionId, location, options)[0];
}
fetchStructureBlock(dimensionId, location) {
const structure = this.getStructure(dimensionId, location);
if (!structure)
return void 0;
return structure.getBlock(structure.toStructureCoords(location));
}
getWorldStructureIds() {
const structureManager = world.structureManager;
const packIds = [...new Set(structureManager.getPackStructureIds()
.map(id => id.replace('mystructure:', '')))
];
const packIdSet = new Set(packIds);
let worldStructureIds = [];
try {
worldStructureIds = structureManager.getWorldStructureIds()
.filter(id => id.startsWith('mystructure:'))
.map(id => id.replace('mystructure:', ''))
.filter(id => !packIdSet.has(id));
} catch (error) {
console.warn('Failed to fetch world structure IDs. They will be ignored. Error:', error);
}
return [...packIds, ...worldStructureIds];
}
rename(instanceName, newName) {
const structure = this.get(instanceName);
if (this.structures[newName])
throw new Error(`Instance '${newName}' already exists.`);
structure.rename(newName);
this.structures[newName] = structure;
delete this.structures[instanceName];
structure.name = newName;
}
}
export const structureCollection = new StructureCollection();
world.afterEvents.worldLoad.subscribe(() => {
structureCollection.loadExistingInstances();
});