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,37 @@
import { MaterialGrabberFormBuilder } from './MaterialGrabberFormBuilder';
import { forceShow } from '../../utils';
import { Builders } from '../Builder/Builders';
import { structureCollection } from '../Structure/StructureCollection';
export class MaterialGrabberForm {
constructor(player) {
this.player = player;
this.show();
}
show() {
try {
return forceShow(this.player, MaterialGrabberFormBuilder.buildInstanceSelector(this.player)).then((response) => {
if (response.canceled)
return;
const selectedInstanceName = structureCollection.getInstanceNames()[response.selection];
if (selectedInstanceName) {
this.setActiveInstance(selectedInstanceName);
this.player.sendMessage(`§7Selected instance for material grabber: §2${selectedInstanceName}`);
return;
}
});
} catch (e) {
if (e.message === 'Menu timed out.') {
this.player.sendMessage('§8Menu timed out.');
return;
}
throw e;
}
}
setActiveInstance(instanceName) {
const builder = Builders.get(this.player.id);
builder.materialInstanceName = instanceName;
}
}
@@ -0,0 +1,25 @@
import { ActionFormData } from "@minecraft/server-ui";
import { MenuFormBuilder } from "../MenuFormBuilder";
import { structureCollection } from "../Structure/StructureCollection";
import { Builders } from "../Builder/Builders";
export class MaterialGrabberFormBuilder {
static menuTitle = MenuFormBuilder.menuTitle + ' Material Grabber';
static buildInstanceSelector(player) {
const allInstanceNameForm = new ActionFormData()
.title(this.menuTitle);
const currInstanceName = Builders.get(player.id).materialInstanceName;
let body = '§7Current instance: ';
if (currInstanceName)
body += `§2${currInstanceName}`;
else
body += '§7None';
body += '\n§7Select an instance:';
allInstanceNameForm.body(body);
structureCollection.getInstanceNames().forEach(instanceName => {
allInstanceNameForm.button(`§2${instanceName}`);
});
return allInstanceNameForm;
}
}
@@ -0,0 +1,140 @@
import { ItemStack, system } from "@minecraft/server";
import { Vector } from "../../lib/Vector";
class StructureMaterials {
instance;
materials;
constructor(instance) {
this.instance = instance;
this.materials = {};
}
refresh() {
this.clear();
this.populateInstance();
}
populateInstance() {
try {
if (this.instance.hasLocation() && this.instance.isEnabled())
system.runJob(this.populateActive());
else
system.runJob(this.populateAll());
} catch (e) {
if (e.name === 'InstanceNotPlacedError')
this.clear();
else
throw e;
}
}
get(itemType) {
return this.materials[itemType];
}
isEmpty() {
return Object.keys(this.materials).length === 0;
}
has(itemType) {
return this.materials[itemType] !== undefined;
}
remove(itemType, amount) {
if (!this.materials[itemType]) return;
this.materials[itemType].count -= amount;
if (this.materials[itemType].count <= 0)
delete this.materials[itemType];
}
*populateAll() {
for (let layer = 0; layer < this.instance.getMaxLayer(); layer++) {
for (const block of this.instance.getLayerBlocks(layer)) {
this.countBlock(block)
yield void 0;
}
}
}
*populateActive() {
const bounds = this.instance.getActiveBounds();
for (let y = bounds.min.y; y < bounds.max.y; y++) {
for (let z = bounds.min.z; z < bounds.max.z; z++) {
for (let x = bounds.min.x; x < bounds.max.x; x++) {
const location = new Vector(x, y, z);
const block = this.instance.getBlock(location);
if (!block) continue;
this.countBlock(block);
yield void 0;
}
}
}
}
countBlock(block) {
const itemStack = block?.getItemStack();
const typeId = itemStack?.typeId;
if (!typeId) return;
if (!this.materials[typeId])
this.materials[typeId] = { count: 0, stackSize: itemStack.maxAmount };
this.materials[typeId].count++;
}
clear() {
for (const key in this.materials)
delete this.materials[key];
}
formatString(otherMaterials = void 0) {
const materials = otherMaterials || this.materials;
let message = { rawtext: [] };
const sortedTypes = Object.keys(materials).sort(
(a, b) => materials[b].count - materials[a].count
);
for (const blockType of sortedTypes) {
let count = materials[blockType].count;
let countStr = '';
const stackSize = materials[blockType].stackSize;
const fullShulker = 27 * stackSize;
if (count >= fullShulker)
countStr = `${Math.floor(count / fullShulker)}\uE200`;
if (count > fullShulker && count % fullShulker > 0)
countStr += ' + ';
count %= fullShulker;
if (count >= stackSize) {
const numStacks = Math.floor(count / stackSize);
countStr += `${numStacks} stack`;
if (numStacks > 1)
countStr += 's';
}
if (count > stackSize && count % stackSize > 0)
countStr += ' + ';
count %= stackSize;
if (count > 0)
countStr += count;
message.rawtext.push({ text: '§3' });
message.rawtext.push({ translate: new ItemStack(blockType).localizationKey })
message.rawtext.push({ text: `§f: ${countStr}\n` });
}
return message;
}
getMaterialsDifference(container) {
const missingMaterials = JSON.parse(JSON.stringify(this.materials));
for (let slotIndex = 0; slotIndex < container.size; slotIndex++) {
const slot = container.getSlot(slotIndex);
if (slot.hasItem()) {
const itemType = slot.getItem().typeId;
if (!missingMaterials[itemType])
continue;
missingMaterials[itemType].count -= slot.amount;
if (missingMaterials[itemType].count <= 0)
delete missingMaterials[itemType];
}
}
return missingMaterials;
}
}
export { StructureMaterials };