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,86 @@
import { MolangVariableMap } from "@minecraft/server";
import { BlockVerificationLevel } from "../Enums/BlockVerificationLevel";
import { Vector } from "../../lib/Vector";
export class BlockVerificationLevelRender {
opacity = 0.2;
lifetimeSeconds = 0;
constructor(dimensionLocation, verificationLevel, lifetimeSeconds = 5) {
this.dimension = dimensionLocation.dimension;
this.location = Vector.from(dimensionLocation.location);
this.verificationLevel = verificationLevel;
this.lifetimeSeconds = lifetimeSeconds;
this.renderBlock();
}
renderBlock() {
const sizeScalar = this.verificationLevelToSizeScalar();
for (const particle of this.getBlockParticles(sizeScalar)) {
const color = this.getRGBAMolang();
if (!color)
return;
color.setFloat("lifetime", this.lifetimeSeconds);
color.setFloat("width", 0.5*sizeScalar);
color.setFloat("height", 0.5*sizeScalar);
try {
this.dimension.spawnParticle(particle.particleType, particle.location, color);
} catch {
/* pass */
}
}
}
getBlockParticles(sizeScalar = 1) {
const bottomFace = new Vector(0.5, 0, 0.5);
const topFace = new Vector(0.5, 1, 0.5);
const leftFace = new Vector(1, 0.5, 0.5);
const rightFace = new Vector(0, 0.5, 0.5);
const frontFace = new Vector(0.5, 0.5, 1);
const backFace = new Vector(0.5, 0.5, 0);
const center = new Vector(0.5, 0.5, 0.5);
return [
{ particleType: "construct:blockoverlay_xz", location: this.location.add(center).add(topFace.subtract(center).multiply(sizeScalar)) },
{ particleType: "construct:blockoverlay_xz", location: this.location.add(center).add(bottomFace.subtract(center).multiply(sizeScalar)) },
{ particleType: "construct:blockoverlay_yz", location: this.location.add(center).add(leftFace.subtract(center).multiply(sizeScalar)) },
{ particleType: "construct:blockoverlay_yz", location: this.location.add(center).add(rightFace.subtract(center).multiply(sizeScalar)) },
{ particleType: "construct:blockoverlay_xy", location: this.location.add(center).add(frontFace.subtract(center).multiply(sizeScalar)) },
{ particleType: "construct:blockoverlay_xy", location: this.location.add(center).add(backFace.subtract(center).multiply(sizeScalar)) }
];
}
getRGBAMolang() {
const rgb = this.verificationLevelToRGB();
if (!rgb) return;
rgb.alpha = this.opacity;
const molang = new MolangVariableMap();
molang.setColorRGBA("face_color", rgb);
return molang;
}
verificationLevelToRGB() {
switch (this.verificationLevel) {
case BlockVerificationLevel.NoMatch:
return { red: 1, green: 0, blue: 0};
case BlockVerificationLevel.TypeMatch:
return { red: 1, green: 1, blue: 0};
case BlockVerificationLevel.Missing:
return { red: 0, green: 0, blue: 1};
default:
return void 0;
}
}
verificationLevelToSizeScalar() {
switch (this.verificationLevel) {
case BlockVerificationLevel.NoMatch:
return 1.01;
case BlockVerificationLevel.TypeMatch:
return 1.01;
case BlockVerificationLevel.Missing:
return 0.90;
default:
return 1.00;
}
}
}
@@ -0,0 +1,53 @@
import { Outliner } from '../Outliner';
export class StructureOutliner {
constructor(instance) {
this.instance = instance;
this.pullInstanceData();
this.outliner = new Outliner(this.dimension, this.bounds.min, this.bounds.max);
}
pullInstanceData() {
try {
this.dimension = this.instance.getDimension();
this.bounds = this.instance.getBounds();
this.bounds.min = this.instance.toGlobalCoords(this.bounds.min);
this.bounds.max = this.instance.toGlobalCoords(this.bounds.max);
} catch (e) {
if (e.name === 'InvalidStructureError')
this.outliner.stopDraw();
else
throw e;
}
}
refresh() {
this.pullInstanceData();
this.refreshDraw();
}
refreshDraw() {
this.outliner.stopDraw();
if (!this.instance.isEnabled())
return;
if (this.instance.hasLayerSelected())
this.layeredDraw();
else
this.boxDraw();
this.outliner.startDraw();
}
boxDraw() {
this.outliner.setVertices(this.dimension, this.bounds.min, this.bounds.max);
}
layeredDraw() {
const { min, max } = this.instance.getLayerBounds(this.instance.getLayer());
this.outliner.setVertices(this.dimension, this.instance.toGlobalCoords(min), this.instance.toGlobalCoords(max));
this.outliner.addStandaloneParticles(this.getCornerVertices());
}
getCornerVertices() {
return this.outliner.getVertices(this.bounds.min, this.bounds.max);
}
}
@@ -0,0 +1,117 @@
import { TicksPerSecond } from "@minecraft/server";
import { BlockVerificationLevelRender } from "./BlockVerificationLevelRender";
import { system } from "@minecraft/server";
const RENDER_LIFETIME_FACTOR_TICKS = 1;
export class VerificationRenderer {
instance;
lastRenderedChunk;
bounds;
shortestDimension;
#runner;
#renderQueue = [];
constructor(instance) {
this.instance = instance;
this.lastRenderedChunk = 0;
}
startContinuousRendering() {
this.#runner = system.runInterval(() => {
if (this.#renderQueue.length === 0)
this.prepareRenderQueue();
this.renderNextChunk();
}, RENDER_LIFETIME_FACTOR_TICKS);
}
stopContinuousRendering() {
if (!this.#runner)
return;
system.clearRun(this.#runner);
this.#runner = void 0;
this.#renderQueue = [];
}
refresh() {
this.stopContinuousRendering();
if (!this.instance.isEnabled() || !this.instance.options.verifier.isEnabled)
return;
this.startContinuousRendering();
}
prepareRenderQueue() {
this.#renderQueue = [];
const bounds = this.instance.getActiveBounds();
for (let y = bounds.min.y; y < bounds.max.y; y++) {
this.prepareRenderQueueLayer(bounds, y);
}
this.lastRenderedChunk = 0;
}
prepareRenderQueueLayer(bounds, y) {
if (bounds.max.x < bounds.max.z) {
for (let z = bounds.min.z; z < bounds.max.z; z++) {
for (let x = bounds.min.x; x < bounds.max.x; x++) {
this.#renderQueue.push({ x, y, z });
}
}
} else {
for (let x = bounds.min.x; x < bounds.max.x; x++) {
for (let z = bounds.min.z; z < bounds.max.z; z++) {
this.#renderQueue.push({ x, y, z });
}
}
}
}
renderNextChunk() {
if (this.shouldUseLargeStructureRendering())
this.renderNextChunkForLargeStructure();
else
this.renderNextChunkForSmallStructure();
}
renderNextChunkForLargeStructure() {
const bounds = this.instance.getActiveBounds();
const shortestSideLength = Math.min(bounds.max.x, bounds.max.z);
const maxChunk = (bounds.min.volume(bounds.max) / shortestSideLength) / (bounds.max.y - bounds.min.y);
const lifetime = (maxChunk * RENDER_LIFETIME_FACTOR_TICKS) / TicksPerSecond;
const verificationLevels = this.instance.verifier.getLastVerificationLevels();
const dimension = this.instance.getDimension();
const chunk = this.#renderQueue.splice(0, shortestSideLength);
for (const location of chunk) {
const verificationLevel = verificationLevels[JSON.stringify(location)];
if (!verificationLevel)
continue;
const dimensionLocation = {
dimension: dimension,
location: this.instance.toGlobalCoords(location)
};
new BlockVerificationLevelRender(dimensionLocation, verificationLevel, lifetime);
}
}
renderNextChunkForSmallStructure() {
const bounds = this.instance.getActiveBounds();
const lifetime = (bounds.max.x * (bounds.max.y - bounds.min.y) * bounds.max.z * RENDER_LIFETIME_FACTOR_TICKS) / TicksPerSecond;
const verificationLevels = this.instance.verifier.getLastVerificationLevels();
const dimension = this.instance.getDimension();
for (const location of this.#renderQueue.splice(0, 1)) {
const verificationLevel = verificationLevels[JSON.stringify(location)];
if (!verificationLevel)
continue;
const dimensionLocation = {
dimension: dimension,
location: this.instance.toGlobalCoords(location)
};
new BlockVerificationLevelRender(dimensionLocation, verificationLevel, lifetime);
}
}
shouldUseLargeStructureRendering() {
const bounds = this.instance.getActiveBounds();
const maxVolume = 343;
return this.instance.hasLayerSelected() || bounds.min.volume(bounds.max) > maxVolume;
}
}