Rename to Construct

This commit is contained in:
ForestOfLight
2025-04-19 14:15:19 -07:00
Unverified
parent 53438f3c60
commit 5e2da6e3ab
46 changed files with 102 additions and 57 deletions

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 64 KiB

@@ -1,5 +1,5 @@
import { structureCollection } from './StructureCollection'; import { structureCollection } from './StructureCollection';
import { MenuForm } from '../classes/MenuForm'; import { MenuForm } from './MenuForm';
import { forceShow } from '../utils'; import { forceShow } from '../utils';
import { InstanceEditButtons } from './enums/InstanceEditButtons'; import { InstanceEditButtons } from './enums/InstanceEditButtons';
import { InstanceEditFormBuilder } from './InstanceEditFormBuilder'; import { InstanceEditFormBuilder } from './InstanceEditFormBuilder';
@@ -1,38 +1,43 @@
import { structureCollection } from '../classes/StructureCollection';
class MaterialCounter { class MaterialCounter {
static getAll(name) { instance
const structure = structureCollection.get(name); materials;
const materials = {};
for (const block of structure.getAllBlocks()) { constructor(instance) {
const typeId = block?.getItemStack()?.typeId.replace('minecraft:', ''); this.instance = instance;
if (!typeId) continue; this.materials = {};
if (!materials[typeId]) {
materials[typeId] = 0;
}
materials[typeId]++;
}
return materials;
} }
static getLayer(name, layer) { populateAll() {
const structure = structureCollection.get(name); for (const layer = 0; layer < this.instance.getMaxLayer(); layer++)
const materials = {}; this.getLayer(layer)
for (const block of structure.getLayerBlocks(layer)) {
const typeId = block?.getItemStack()?.typeId.replace('minecraft:', '');
if (!typeId) continue;
if (!materials[typeId]) {
materials[typeId] = 0;
}
materials[typeId]++;
}
return materials;
} }
static getPrintable(name) { populateLayer(layer) {
const structure = structureCollection.get(name); for (const block of this.instance.getLayerBlocks(layer))
this.countBlock(block)
}
populateActive() {
for (const block of this.instance.getActiveBlocks())
this.countBlock(block)
}
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() {
this.materials = {}; // does this leak memory??
}
toString() {
const materials = {}; const materials = {};
for (const block of structure.getAllBlocks()) { for (const block of this.instance.getAllBlocks()) {
const itemStack = block?.getItemStack(); const itemStack = block?.getItemStack();
const typeId = itemStack?.typeId.replace('minecraft:', ''); const typeId = itemStack?.typeId.replace('minecraft:', '');
if (!typeId) continue; if (!typeId) continue;
@@ -4,16 +4,16 @@ import { MenuFormBuilder } from './MenuFormBuilder';
import { InstanceEditForm } from './InstanceEditForm'; import { InstanceEditForm } from './InstanceEditForm';
export class MenuForm { export class MenuForm {
constructor(player, { jumpToInstance = true } = {}) { constructor(player, { jumpToInstance = false, instanceName = void 0 } = {}) {
this.player = player; this.player = player;
this.show(jumpToInstance); this.show(jumpToInstance, instanceName);
} }
async show(jumpToInstance = true) { async show(jumpToInstance = false, instanceName = void 0) {
let instanceName;
if (jumpToInstance) { if (jumpToInstance) {
if (!instanceName)
instanceName = structureCollection.getStructure(this.player.dimension.id, this.player.location, { useActiveLayer: false })?.getName(); instanceName = structureCollection.getStructure(this.player.dimension.id, this.player.location, { useActiveLayer: false })?.getName();
if (instanceName) { if (structureCollection.get(instanceName)) {
new InstanceEditForm(this.player, instanceName); new InstanceEditForm(this.player, instanceName);
return; return;
} }
@@ -53,14 +53,14 @@ export class StructureInstance {
return this.options.getDimension(); return this.options.getDimension();
} }
getMaxLayer() {
return this.structure.getHeight();
}
getLayer() { getLayer() {
return this.options.currentLayer; return this.options.currentLayer;
} }
getMaxLayer() {
return this.structure.getHeight();
}
getBounds() { getBounds() {
return { return {
min: this.structure.getMin(), min: this.structure.getMin(),
@@ -72,18 +72,18 @@ export class StructureInstance {
if (!this.options.isEnabled) if (!this.options.isEnabled)
throw new Error(`[StrucTool] Instance '${this.options.instanceName}' is not placed.`); throw new Error(`[StrucTool] Instance '${this.options.instanceName}' is not placed.`);
if (this.hasLayerSelected()) if (this.hasLayerSelected())
return this.getLayeredBounds(); return this.getLayerBounds(this.getLayer());
return this.getBounds(); return this.getBounds();
} }
getLayeredBounds() { getLayerBounds(layer) {
if (!this.options.isEnabled) if (!this.options.isEnabled)
throw new Error(`[StrucTool] Instance '${this.options.instanceName}' is not placed.`); throw new Error(`[StrucTool] Instance '${this.options.instanceName}' is not placed.`);
const min = this.structure.getMin(); const min = this.structure.getMin();
const max = this.structure.getMax(); const max = this.structure.getMax();
return { return {
min: new Vector(min.x, this.options.currentLayer - 1, min.z), min: new Vector(min.x, layer - 1, min.z),
max: new Vector(max.x, this.options.currentLayer, max.z) max: new Vector(max.x, layer, max.z)
}; };
} }
@@ -103,6 +103,14 @@ export class StructureInstance {
return this.structure.getAllBlocks(); return this.structure.getAllBlocks();
} }
getActiveBlocks() {
if (!this.options.isEnabled)
throw new Error(`[StrucTool] Instance '${this.options.instanceName}' is not placed.`);
if (this.hasLayerSelected())
return this.getLayerBlocks(this.getLayer());
return this.getAllBlocks();
}
isLocationActive(dimensionId, structureLocation, { useActiveLayer = true } = {}) { isLocationActive(dimensionId, structureLocation, { useActiveLayer = true } = {}) {
if (!this.options.isEnabled || this.options.dimensionId !== dimensionId) if (!this.options.isEnabled || this.options.dimensionId !== dimensionId)
return false; return false;
@@ -1,4 +1,4 @@
import { Outliner } from '../classes/Outliner'; import { Outliner } from './Outliner';
export class StructureOutliner { export class StructureOutliner {
constructor(instance) { constructor(instance) {
@@ -5,16 +5,23 @@ import { MenuForm } from '../classes/MenuForm';
const ACTION_ITEM = 'minecraft:paper'; const ACTION_ITEM = 'minecraft:paper';
const structoolCmd = new Command({ const menuCmd = new Command({
name: 'structool', name: 'structool',
description: { text: 'Opens the StrucTool Menu. Using a paper will also open the menu.' }, description: { text: 'Opens the StrucTool Menu. Using a paper will also open the menu.' },
usage: 'structool', usage: 'structool',
callback: (sender) => new MenuForm(sender) callback: (sender) => openMenu(sender)
}); });
extension.addCommand(structoolCmd); extension.addCommand(menuCmd);
world.beforeEvents.itemUse.subscribe((event) => { world.beforeEvents.itemUse.subscribe((event) => {
if (!event.source || event.itemStack?.typeId !== ACTION_ITEM) return; if (!event.source || event.itemStack?.typeId !== ACTION_ITEM) return;
event.cancel = true; event.cancel = true;
system.run(() => structoolCmd.getCallback()(event.source)); system.run(() => openMenu(event.source, event));
}); });
function openMenu(sender, event = void 0) {
const options = { jumpToInstance: true }
if (event)
options.instanceName = event.itemStack?.typeId;
new MenuForm(sender, options);
}
@@ -23,7 +23,7 @@
* SOFTWARE. * SOFTWARE.
*/ */
import { world } from '@minecraft/server'; import { world } from '@minecraft/server';
import IPC from '../../lib/ipc/ipc'; import IPC from '../ipc/ipc';
import Command from './Command'; import Command from './Command';
import Rule from './Rule'; import Rule from './Rule';
import { CommandCallbackRequest, CommandPrefixRequest, Ready, RegisterCommand, RegisterExtension, RegisterRule, RuleValueRequest, RuleValueSet, CommandPrefixResponse, RuleValueResponse } from './extension.ipc'; import { CommandCallbackRequest, CommandPrefixRequest, Ready, RegisterCommand, RegisterExtension, RegisterRule, RuleValueRequest, RuleValueSet, CommandPrefixResponse, RuleValueResponse } from './extension.ipc';
@@ -1,9 +1,10 @@
// Rules // Rules
import './rules/easyPlace'; import './rules/easyPlace';
import './rules/fastEasyPlace'; import './rules/fastEasyPlace';
import './rules/materialGrabber';
// Commands // Commands
import './commands/structool'; import './commands/construct';
// Other // Other
import './classes/BlockInfo'; import './classes/BlockInfo';
@@ -0,0 +1,24 @@
import { Rule } from '../lib/canopy/CanopyExtension';
import { extension } from '../config';
import { world } from '@minecraft/server';
const easyPlace = new Rule({
identifier: 'materialGrabber',
description: { text: "Automatically grabs structure materials out of inventories. Use a paper named 'materialGrabber' to get started." },
onEnableCallback: () => {
world.beforeEvents.playerInteractWithBlock.subscribe(onPlayerInteract);
world.beforeEvents.playerInteractWithEntity.subscribe(onPlayerInteract);
},
onDisableCallback: () => {
world.beforeEvents.playerInteractWithBlock.unsubscribe(onPlayerInteract);
world.beforeEvents.playerInteractWithEntity.unsubscribe(onPlayerInteract);
}
})
extension.addRule(easyPlace);
function onPlayerInteract(event) {
// get inventory
// analyze active structure items if not analyzed -- there needs to be a way to refresh this that is efficient
// find items in inventory that match items in structure
// transfer to player
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Before

Width:  |  Height:  |  Size: 83 B

After

Width:  |  Height:  |  Size: 83 B

+5 -5
View File
@@ -1,12 +1,12 @@
<div align="center"> <div align="center">
<a href="./pack_icon.png"> <a href="./Construct [BP]/pack_icon.png">
<img src="./pack_icon.png" alt="Canopy Extension Example Icon" width="100" height="100"> <img src="./Construct [BP]/pack_icon.png" alt="Construct Icon" width="100" height="100">
</a> </a>
<p><b>StrucTool</b></p> <p><b>Construct</b></p>
[![Codacy Quality](https://app.codacy.com/project/badge/Grade/10040a714ad84a2f912d4dae9d3f6e57)](https://app.codacy.com/gh/ForestOfLight/StrucTool/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade) [![Codacy Quality](https://app.codacy.com/project/badge/Grade/10040a714ad84a2f912d4dae9d3f6e57)](https://app.codacy.com/gh/ForestOfLight/Construct/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)
[![Minecraft - Version](https://img.shields.io/badge/Minecraft-v1.21.60_(Bedrock)-brightgreen)](https://feedback.minecraft.net/hc/en-us/sections/360001186971-Release-Changelogs) [![Minecraft - Version](https://img.shields.io/badge/Minecraft-v1.21.60_(Bedrock)-brightgreen)](https://feedback.minecraft.net/hc/en-us/sections/360001186971-Release-Changelogs)
[![GitHub License](https://img.shields.io/github/license/forestoflight/structool)](LICENSE) [![GitHub License](https://img.shields.io/github/license/forestoflight/construct)](LICENSE)
[![Discord](https://badgen.net/discord/members/9KGche8fxm?icon=discord&label=Discord&list=what)](https://discord.gg/9KGche8fxm) [![Discord](https://badgen.net/discord/members/9KGche8fxm?icon=discord&label=Discord&list=what)](https://discord.gg/9KGche8fxm)
</div> </div>