Files
Construct-CN/packs/BP/scripts/classes/Instance/InstanceCollection.js
T
wed150 136d5ffa3b
/ build (push) Has been cancelled
Start working at 1.2.0
2026-08-26 09:54:39 +08:00

130 lines
4.6 KiB
JavaScript

import { InstanceExistsError } from '../Errors/InstanceExistsError';
import { InstanceNotFoundError } from '../Errors/InstanceNotFoundError';
import { StructureNotFoundError } from '../Errors/StructureNotFoundError';
import { InstanceOptions } from './InstanceOptions';
import { StructureInstance } from './StructureInstance';
import { InvalidStructureError, world } from '@minecraft/server';
class InstanceCollection {
instances;
constructor() {
this.instances = {};
}
loadExistingInstances() {
world.getDynamicPropertyIds().filter(id => id.startsWith('instanceOptions:')).forEach(id => {
const instanceName = id.replace('instanceOptions:', '');
let structureId;
try {
structureId = InstanceOptions.getInstanceStructureId(instanceName);
this.instances[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, defaults = {}) {
if (this.instances[instanceName])
throw new InstanceExistsError(instanceName);
const instance = new StructureInstance(instanceName, structureId, defaults);
this.instances[instanceName] = instance;
return instance;
}
get(instanceName) {
const instance = this.instances[instanceName];
if (!instance)
throw new InstanceNotFoundError(instanceName);
return instance;
}
has(instanceName) {
return Boolean(this.instances[instanceName]);
}
delete(instanceName) {
const instance = this.get(instanceName);
instance.delete();
delete this.instances[instanceName];
}
getInstanceNames() {
return Object.keys(this.instances).sort((a, b) => a.localeCompare(b));
}
getInstanceNamesSortedByEnabled() {
const instanceNames = this.getInstanceNames();
instanceNames.sort((a, b) => {
const aEnabled = this.get(a).isEnabled();
const bEnabled = this.get(b).isEnabled();
if (aEnabled === bEnabled)
return a.localeCompare(b);
return bEnabled ? 1 : -1;
});
return instanceNames;
}
getInstancesAt(dimensionId, location, options = {}) {
return Object.values(this.instances).filter(instance => {
try {
return instance.isLocationActive(dimensionId, instance.toStructureCoords(location), options)
} catch (error) {
if (error instanceof StructureNotFoundError || error instanceof InvalidStructureError) {
this.delete(instance.name);
return false;
} else {
throw error;
}
}
});
}
getInstanceAt(dimensionId, location, options = {}) {
return this.getInstancesAt(dimensionId, location, options)[0];
}
fetchStructureBlock(dimensionId, location) {
const instance = this.getInstanceAt(dimensionId, location);
if (!instance)
return void 0;
return instance.getBlock(instance.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.instances[newName])
throw new InstanceExistsError(newName);
structure.rename(newName);
this.instances[newName] = structure;
delete this.instances[instanceName];
structure.name = newName;
}
}
export const instanceCollection = new InstanceCollection();
world.afterEvents.worldLoad.subscribe(() => {
instanceCollection.loadExistingInstances();
});