configure for regolith

This commit is contained in:
ForestOfLight
2025-07-02 20:02:17 -07:00
Unverified
parent b92cdd269c
commit 657467f49d
69 changed files with 29 additions and 1 deletions
@@ -0,0 +1,78 @@
import { world } from "@minecraft/server";
import { Vector } from "../../lib/Vector";
import { InvalidStructureError } from "../Errors/InvalidStructureError";
export class Structure {
structureId;
#structure;
constructor(structureId) {
this.structureId = structureId;
this.#structure = world.structureManager.get(structureId);
if (!this.#structure)
throw new InvalidStructureError(`[Construct] Structure '${structureId}' not found on world.`);
this.#structure.saveToWorld();
}
getHeight() {
return this.#structure.size.y;
}
getMin() {
return new Vector(0, 0, 0);
}
getMax() {
return Vector.from(this.#structure.size);
}
getBlock(structureLocation) {
const blockPermutation = this.#structure.getBlockPermutation(structureLocation);
if (!blockPermutation)
return void 0;
blockPermutation.location = structureLocation;
return blockPermutation;
}
*getBlocks(locations) {
for (const location of locations) {
yield this.getBlock(location);
}
}
*getLayerBlocks(layer) {
for (let x = 0; x < this.#structure.size.x; x++) {
for (let z = 0; z < this.#structure.size.z; z++) {
yield this.getBlock({ x, y: layer, z });
}
}
}
*getAllBlocks() {
for (let y = 0; y < this.#structure.size.y; y++) {
yield * this.getLayerBlocks(y);
}
}
getLayerLocations(layer) {
const locations = new Set();
for (let x = 0; x < this.#structure.size.x; x++) {
for (let z = 0; z < this.#structure.size.z; z++) {
locations.add(new Vector(x, layer, z));
}
}
return locations;
}
getAllLocations() {
const locations = new Set();
for (let y = 0; y < this.#structure.size.y; y++) {
const layerLocations = this.getLayerLocations(y);
for (const location of layerLocations) {
locations.add(location);
}
}
return locations;
}
}
@@ -0,0 +1,100 @@
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;
}
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() {
return world.structureManager.getWorldStructureIds()
.filter(id => id.startsWith('mystructure:'))
.map(id => id.replace('mystructure:', ''));
}
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();
});
@@ -0,0 +1,64 @@
import { BlockVerificationLevel } from '../Enums/BlockVerificationLevel.js';
export class StructureStatistics {
constructor(instance, verification) {
this.instance = instance;
this.verification = verification;
this.parse();
}
init() {
this.statistics = {};
for (const verificationLevel of Object.values(BlockVerificationLevel))
this.statistics[verificationLevel] = 0;
this.statistics.correctlyAir = 0;
}
parse() {
this.init();
for (const blockVerificationLevel of Object.values(BlockVerificationLevel))
this.parseStatistic(blockVerificationLevel);
}
parseStatistic(blockVerificationLevel) {
for (const [location, verificationLevel] of Object.entries(this.verification)) {
if (location === 'correctlyAir')
continue;
if (blockVerificationLevel === verificationLevel)
this.statistics[verificationLevel]++;
}
}
getNonAirBlocks() {
const activeBounds = this.instance.getActiveBounds();
return activeBounds.min.volume(activeBounds.max) - this.verification.correctlyAir;
}
getStat(blockVerificationLevel) {
return { num: this.statistics[blockVerificationLevel], percent: this.statistics[blockVerificationLevel] / (this.getNonAirBlocks()) * 100 };
}
getSkipped() {
return this.statistics[BlockVerificationLevel.Skipped] || 0;
}
getMessage() {
let message = '';
message += `§fStatistics for §a${this.instance.getName()}§f:`;
if (this.instance.hasLayerSelected())
message += ` §7(layer ${this.instance.getLayer()})`;
message += `\n§7Blocks: §2${this.getNonAirBlocks()}\n`;
const skipped = this.getSkipped();
if (skipped > 0)
message += `§c[!] This analysis skipped ${skipped} blocks.\n`;
message += `§7Correct: §a${this.formatStat(this.getStat(BlockVerificationLevel.Match))}\n`;
message += `§7Block State Incorrect: §e${this.formatStat(this.getStat(BlockVerificationLevel.TypeMatch))}\n`;
message += `§7Incorrect: §c${this.formatStat(this.getStat(BlockVerificationLevel.NoMatch))}\n`;
message += `§7Missing: §3${this.formatStat(this.getStat(BlockVerificationLevel.Missing))}\n`;
return message;
}
formatStat(stat) {
return `${stat.num} (${stat.percent.toFixed(2)}%%)`;
}
}