import { Vector } from "../../lib/Vector"; import { StructureOutliner } from "../Structure/StructureOutliner"; import { StructureVerifier } from "../Verifier/StructureVerifier"; import { Structure } from "../Structure/Structure"; import { InstanceOptions } from "./InstanceOptions"; import { TicksPerSecond } from "@minecraft/server"; export class StructureInstance { options; structure = void 0; verifier = void 0; outliner = void 0; constructor(instanceName, structureId) { this.structure = new Structure(structureId); this.options = new InstanceOptions(instanceName, structureId); this.refreshBox(); } delete() { this.disable(); this.options.clear(); delete this.options; delete this.structure; delete this.outliner; delete this.verifier; } refreshBox() { if (!this.hasLocation()) return; if (!this.outliner) this.outliner = new StructureOutliner(this); if (!this.verifier) this.verifier = new StructureVerifier(this, { isEnabled: this.options.verifier.isEnabled, trackPlayerDistance: this.options.verifier.trackPlayerDistance }); this.outliner.refresh(); this.verifier.refresh(); } getName() { return this.options.instanceName; } getStructureId() { return this.options.structureId; } getLocation() { return { dimensionId: this.options.dimensionId, location: this.options.worldLocation }; } getDimension() { return this.options.getDimension(); } getLayer() { return this.options.currentLayer; } getMaxLayer() { return this.structure.getHeight(); } getBounds() { return { min: this.structure.getMin(), max: this.structure.getMax() } } getActiveBounds() { if (!this.options.isEnabled) throw new Error(`[Construct] Instance '${this.options.instanceName}' is not placed.`); if (this.hasLayerSelected()) return this.getLayerBounds(this.getLayer()); return this.getBounds(); } getLayerBounds(layer) { if (!this.options.isEnabled) throw new Error(`[Construct] Instance '${this.options.instanceName}' is not placed.`); const min = this.structure.getMin(); const max = this.structure.getMax(); return { min: new Vector(min.x, layer - 1, min.z), max: new Vector(max.x, layer, max.z) }; } getBlock(structureLocation) { return this.structure.getBlock(structureLocation); } getBlocks(structureLocations) { return this.structure.getBlocks(structureLocations); } getLayerBlocks(layer) { return this.structure.getLayerBlocks(layer); } getAllBlocks() { return this.structure.getAllBlocks(); } getActiveBlocks() { if (!this.options.isEnabled) throw new Error(`[Construct] Instance '${this.options.instanceName}' is not placed.`); if (this.hasLayerSelected()) return this.getLayerBlocks(this.getLayer()); return this.getAllBlocks(); } isLocationActive(dimensionId, structureLocation, { useActiveLayer = true } = {}) { if (!this.options.isEnabled || this.options.dimensionId !== dimensionId) return false; let bounds; if (useActiveLayer) bounds = this.getActiveBounds(); else bounds = this.getBounds(); return structureLocation.x >= bounds.min.x && structureLocation.x < bounds.max.x && structureLocation.y >= bounds.min.y && structureLocation.y < bounds.max.y && structureLocation.z >= bounds.min.z && structureLocation.z < bounds.max.z; } getAllActiveLocations() { if (!this.options.isEnabled) throw new Error(`[Construct] Instance '${this.options.instanceName}' is not placed.`); if (this.hasLayerSelected()) return this.structure.getLayerLocations(this.getLayer()-1); else return this.structure.getAllLocations(); } isEnabled() { return this.options.isEnabled; } hasLocation() { return this.options.dimensionId && this.options.worldLocation.x !== 0 && this.options.worldLocation.y !== 0 && this.options.worldLocation.z !== 0; } hasLayers() { return this.getMaxLayer() > 1; } hasLayerSelected() { return this.hasLayers() && this.options.currentLayer !== 0; } hasWholeStructureSelected() { return this.hasLocation() && this.options.currentLayer === 0; } isAtMaxLayer() { return !this.hasLayers || this.options.currentLayer >= this.getMaxLayer(); } isAtMinLayer() { return !this.hasLayers || this.options.currentLayer <= 0; } enable() { this.options.enable(); this.refreshBox(); } disable() { this.options.disable(); this.refreshBox(); } rename(newName) { this.options.rename(newName); } place(dimensionId, worldLocation) { this.move(dimensionId, worldLocation); this.enable(); } move(dimensionId, worldLocation) { this.options.move(dimensionId, worldLocation); this.refreshBox(); } setLayer(layer) { if (layer < 0 || layer > this.getMaxLayer()) throw new Error(`[Construct] Layer ${layer} is out of bounds.`); this.options.setLayer(layer); this.refreshBox(); } setVerifierEnabled(enable) { this.options.setVerifierEnabled(enable); this.verifier.refresh(); } setVerifierDistance(distance) { this.options.setVerifierDistance(distance); if (this.options.verifier.trackPlayerDistance === 0) { const bounds = this.getBounds(); this.options.verifier.intervalOrLifetime = Math.max(bounds.min.volume(bounds.max) / TicksPerSecond, 2*TicksPerSecond); } else { this.options.verifier.intervalOrLifetime = 10; } this.verifier.refresh(); } increaseLayer() { if (this.isAtMaxLayer()) this.setLayer(0); else this.setLayer(this.options.currentLayer + 1); } decreaseLayer() { if (this.isAtMinLayer()) this.setLayer(this.getMaxLayer()); else this.setLayer(this.options.currentLayer - 1); } toGlobalCoords(structureLocation) { return Vector.from(structureLocation).add(this.options.worldLocation); } toStructureCoords(worldLocation) { return Vector.from(worldLocation).subtract(this.options.worldLocation); } }