form start
This commit is contained in:
@@ -30,13 +30,12 @@ Removes a structure.
|
|||||||
|
|
||||||
## Roadmap
|
## Roadmap
|
||||||
|
|
||||||
- [ ] place structure **(in progress)**
|
- [ ] place structure using form **(in progress)**
|
||||||
- [x] easyPlace rule
|
- [x] easyPlace rule
|
||||||
- [x] Make a viewable material list
|
- [x] Make a viewable material list
|
||||||
- [ ] Make automatic material gathering from inventories
|
- [ ] Make automatic material gathering from inventories
|
||||||
- [ ] structure movement & rotation
|
- [ ] structure movement & rotation
|
||||||
- [ ] structuraMode & holoprintMode rules for ease of use
|
- [ ] structuraMode & holoprintMode rules for ease of use
|
||||||
- [ ] send structure as a scriptevent so that other addons can use it
|
|
||||||
- [ ] more litematica features!
|
- [ ] more litematica features!
|
||||||
|
|
||||||
## Issues & Suggestions
|
## Issues & Suggestions
|
||||||
|
|||||||
@@ -0,0 +1,116 @@
|
|||||||
|
import { structureCollection } from './StructureCollection';
|
||||||
|
import { MenuForm } from '../classes/MenuForm';
|
||||||
|
import { ActionFormData } from '@minecraft/server-ui';
|
||||||
|
import { InstanceEditOptions } from './InstanceEditOptions';
|
||||||
|
|
||||||
|
export class InstanceEditForm {
|
||||||
|
instanceName;
|
||||||
|
options = {
|
||||||
|
isPlaced: [
|
||||||
|
InstanceEditOptions.NextLayer,
|
||||||
|
InstanceEditOptions.PreviousLayer,
|
||||||
|
InstanceEditOptions.SetLayer,
|
||||||
|
InstanceEditOptions.Move,
|
||||||
|
InstanceEditOptions.Rotate,
|
||||||
|
InstanceEditOptions.Mirror,
|
||||||
|
InstanceEditOptions.RemovePlacement,
|
||||||
|
],
|
||||||
|
notPlaced: [
|
||||||
|
InstanceEditOptions.PlaceInstance
|
||||||
|
],
|
||||||
|
common: [
|
||||||
|
InstanceEditOptions.MaterialsList,
|
||||||
|
InstanceEditOptions.RenameInstance,
|
||||||
|
InstanceEditOptions.DeleteInstance,
|
||||||
|
InstanceEditOptions.MainMenu
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(player, instanceName) {
|
||||||
|
this.player = player;
|
||||||
|
this.instanceName = instanceName;
|
||||||
|
this.instance = structureCollection.get(this.instanceName);
|
||||||
|
this.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
show() {
|
||||||
|
const form = this.buildInstanceForm();
|
||||||
|
form.show(this.player).then((response) => {
|
||||||
|
if (response.canceled) return;
|
||||||
|
let selectedOption;
|
||||||
|
if (this.instance.isPlaced())
|
||||||
|
selectedOption = this.options.isPlaced[response.selection] || this.options.common[response.selection-this.options.isPlaced.length];
|
||||||
|
else
|
||||||
|
selectedOption = this.options.notPlaced[response.selection] || this.options.common[response.selection-this.options.notPlaced.length];
|
||||||
|
this.handleOption(selectedOption);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
buildInstanceForm() {
|
||||||
|
const instanceOptions = this.instance.isPlaced() ? this.options.isPlaced : this.options.notPlaced;
|
||||||
|
const form = new ActionFormData()
|
||||||
|
.title('§l§2StrucTool §8Menu')
|
||||||
|
.body(`Instance: §2${this.instanceName}`)
|
||||||
|
instanceOptions.forEach(option => {
|
||||||
|
form.button(`${option}`);
|
||||||
|
});
|
||||||
|
this.options.common.forEach(option => {
|
||||||
|
form.button(`${option}`);
|
||||||
|
});
|
||||||
|
return form;
|
||||||
|
}
|
||||||
|
|
||||||
|
handleOption(option) {
|
||||||
|
switch (option) {
|
||||||
|
case InstanceEditOptions.PlaceInstance:
|
||||||
|
this.instance.place(this.player.dimension.id, this.player.location);
|
||||||
|
break;
|
||||||
|
case InstanceEditOptions.RemovePlacement:
|
||||||
|
this.instance.removePlacement();
|
||||||
|
break;
|
||||||
|
case InstanceEditOptions.RenameInstance:
|
||||||
|
this.renameInstanceForm();
|
||||||
|
break;
|
||||||
|
case InstanceEditOptions.DeleteInstance:
|
||||||
|
this.structureCollection.remove(this.instanceName);
|
||||||
|
break;
|
||||||
|
case InstanceEditOptions.NextLayer:
|
||||||
|
this.instance.setLayer(this.instance.getLayer() + 1);
|
||||||
|
new InstanceEditForm(this.player, this.instanceName);
|
||||||
|
break;
|
||||||
|
case InstanceEditOptions.PreviousLayer:
|
||||||
|
this.instance.setLayer(this.instance.getLayer() - 1);
|
||||||
|
new InstanceEditForm(this.player, this.instanceName);
|
||||||
|
break;
|
||||||
|
case InstanceEditOptions.SetLayer:
|
||||||
|
this.setLayerForm();
|
||||||
|
break;
|
||||||
|
case InstanceEditOptions.Rotate:
|
||||||
|
this.player.sendMessage('§cRotating not implemented yet.');
|
||||||
|
break;
|
||||||
|
case InstanceEditOptions.Mirror:
|
||||||
|
this.player.sendMessage('§cMirroring not implemented yet.');
|
||||||
|
break;
|
||||||
|
case InstanceEditOptions.Move:
|
||||||
|
this.instance.move(this.player.dimension.id, this.player.location);
|
||||||
|
break;
|
||||||
|
case InstanceEditOptions.MaterialsList:
|
||||||
|
this.player.sendMessage('§cMaterial list not implemented yet.');
|
||||||
|
break;
|
||||||
|
case InstanceEditOptions.MainMenu:
|
||||||
|
new MenuForm(this.player);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this.player.sendMessage(`§cUnknown option: ${option}`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
renameInstanceForm() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
setLayerForm() {
|
||||||
|
// should have a toggle for if it should layer the structure or notw
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import { ActionFormData, ModalFormData } from '@minecraft/server-ui';
|
||||||
|
|
||||||
|
export class InstanceEditFormBuilder {
|
||||||
|
static buildRenameInstance() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
export const InstanceEditOptions = Object.freeze({
|
||||||
|
Unknown: "unknown",
|
||||||
|
MainMenu: 'Back to Main Menu',
|
||||||
|
PlaceInstance: 'Place Instance',
|
||||||
|
RemovePlacement: 'Remove Placement',
|
||||||
|
RenameInstance: 'Rename Instance',
|
||||||
|
DeleteInstance: '§cDelete Instance',
|
||||||
|
NextLayer: 'Increase Layer',
|
||||||
|
PreviousLayer: 'Decrease Layer',
|
||||||
|
SetLayer: 'Set Layer',
|
||||||
|
Move: 'Move Here',
|
||||||
|
Rotate: 'Rotate',
|
||||||
|
Mirror: 'Mirror',
|
||||||
|
MaterialsList: 'Get Materials List',
|
||||||
|
});
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
import { forceShow } from '../utils';
|
||||||
|
import { structureCollection } from './StructureCollection';
|
||||||
|
import { MenuFormBuilder } from './MenuFormBuilder';
|
||||||
|
import { InstanceEditForm } from './InstanceEditForm';
|
||||||
|
|
||||||
|
export class MenuForm {
|
||||||
|
constructor(player) {
|
||||||
|
this.player = player;
|
||||||
|
this.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
async show() {
|
||||||
|
let instanceName = this.getInstanceFromLocation();
|
||||||
|
if (!instanceName)
|
||||||
|
instanceName = await this.getInstanceNameFromForm();
|
||||||
|
if (!instanceName)
|
||||||
|
return;
|
||||||
|
new InstanceEditForm(this.player, instanceName);
|
||||||
|
}
|
||||||
|
|
||||||
|
getInstanceFromLocation() {
|
||||||
|
const locatedStructures = structureCollection.getStructuresAtLocation(this.player.location);
|
||||||
|
if (locatedStructures.length === 0)
|
||||||
|
return void 0;
|
||||||
|
const structure = locatedStructures[0];
|
||||||
|
return structure.instanceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
async getInstanceNameFromForm() {
|
||||||
|
try {
|
||||||
|
return forceShow(this.player, MenuFormBuilder.buildAllInstanceNameForm()).then((response) => {
|
||||||
|
if (response.canceled) return;
|
||||||
|
const selectedInstanceName = structureCollection.getInstanceNames()[response.selection];
|
||||||
|
return selectedInstanceName || this.createNewInstance();
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
if (e.message === 'Menu timed out.') {
|
||||||
|
this.player.sendMessage('§8Menu timed out.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async createNewInstance() {
|
||||||
|
return MenuFormBuilder.buildNewInstanceForm().show(this.player).then(async (response) => {
|
||||||
|
if (response.canceled)
|
||||||
|
return;
|
||||||
|
const instanceName = response.formValues[0];
|
||||||
|
if (instanceName === '')
|
||||||
|
return void 0;
|
||||||
|
const structureId = await this.getStructureId();
|
||||||
|
if (!structureId)
|
||||||
|
return;
|
||||||
|
structureCollection.add(instanceName, structureId);
|
||||||
|
return instanceName;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async getStructureId() {
|
||||||
|
return MenuFormBuilder.buildAllStructuresForm().show(this.player).then((response) => {
|
||||||
|
if (response.canceled)
|
||||||
|
return;
|
||||||
|
const selectedStructureId = structureCollection.getWorldStructureIds()[response.selection];
|
||||||
|
return selectedStructureId || this.getOtherStructureId();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getOtherStructureId() {
|
||||||
|
return MenuFormBuilder.buildOtherStructureForm().show(this.player).then((response) => {
|
||||||
|
if (response.canceled)
|
||||||
|
return;
|
||||||
|
const structureId = response.formValues[0];
|
||||||
|
if (structureId === '')
|
||||||
|
return void 0;
|
||||||
|
return structureId;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
import { ActionFormData, ModalFormData } from '@minecraft/server-ui';
|
||||||
|
import { structureCollection } from './StructureCollection';
|
||||||
|
|
||||||
|
export class MenuFormBuilder {
|
||||||
|
static menuTitle = '§l§2StrucTool §8Menu';
|
||||||
|
|
||||||
|
static buildAllInstanceNameForm() {
|
||||||
|
const allInstanceNameForm = new ActionFormData()
|
||||||
|
.title(this.menuTitle)
|
||||||
|
.body('Select an instance:');
|
||||||
|
structureCollection.getInstanceNames().forEach(instanceName => {
|
||||||
|
allInstanceNameForm.button(`§2${instanceName}`);
|
||||||
|
});
|
||||||
|
allInstanceNameForm.button('Create New Instance');
|
||||||
|
return allInstanceNameForm;
|
||||||
|
}
|
||||||
|
|
||||||
|
static buildNewInstanceForm() {
|
||||||
|
return new ModalFormData()
|
||||||
|
.title(this.menuTitle)
|
||||||
|
.textField('Enter a name for the new instance:', 'example_instance')
|
||||||
|
.submitButton('Submit');
|
||||||
|
}
|
||||||
|
|
||||||
|
static buildAllStructuresForm() {
|
||||||
|
const allStructuresForm = new ActionFormData()
|
||||||
|
.title(this.menuTitle)
|
||||||
|
.body('Select a structure:');
|
||||||
|
structureCollection.getWorldStructureIds().forEach(structureId => {
|
||||||
|
const structureName = structureId.replace('mystructure:', '');
|
||||||
|
allStructuresForm.button(`§2${structureName}`);
|
||||||
|
});
|
||||||
|
allStructuresForm.button('Other');
|
||||||
|
return allStructuresForm;
|
||||||
|
}
|
||||||
|
|
||||||
|
static buildOtherStructureForm() {
|
||||||
|
return new ModalFormData()
|
||||||
|
.title(this.menuTitle)
|
||||||
|
.textField('Enter the Structure ID:', 'example_structure')
|
||||||
|
.submitButton('Submit');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
import { world } from "@minecraft/server";
|
|
||||||
import { structureCollection } from "./StructureCollection";
|
import { structureCollection } from "./StructureCollection";
|
||||||
|
|
||||||
export class Raycaster {
|
export class Raycaster {
|
||||||
|
|||||||
@@ -1,37 +1,41 @@
|
|||||||
import { Structure } from './Structure';
|
import { StructureInstance } from './StructureInstance';
|
||||||
|
import { world } from '@minecraft/server';
|
||||||
|
|
||||||
class StructureCollection {
|
class StructureCollection {
|
||||||
#structures;
|
structures;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.#structures = {};
|
this.structures = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
add(name) {
|
add(instanceName, structureId) {
|
||||||
if (this.#structures[name]) {
|
if (this.structures[instanceName])
|
||||||
throw new Error(`Structure ${name} already exists.`);
|
throw new Error(`Instance ${instanceName} already exists.`);
|
||||||
}
|
const structure = new StructureInstance(instanceName, structureId);
|
||||||
const structure = new Structure(name);
|
this.structures[instanceName] = structure;
|
||||||
this.#structures[name] = structure;
|
|
||||||
return structure;
|
return structure;
|
||||||
}
|
}
|
||||||
|
|
||||||
get(name) {
|
get(instanceName) {
|
||||||
const structure = this.#structures[name];
|
const structure = this.structures[instanceName];
|
||||||
if (!structure) {
|
if (!structure) {
|
||||||
throw new Error(`Structure ${name} not found.`);
|
throw new Error(`Instance ${instanceName} not found.`);
|
||||||
}
|
}
|
||||||
return structure;
|
return structure;
|
||||||
}
|
}
|
||||||
|
|
||||||
remove(name) {
|
remove(instanceName) {
|
||||||
const struct = this.get(name);
|
const struct = this.get(instanceName);
|
||||||
struct.remove();
|
struct.removePlacement();
|
||||||
delete this.#structures[name];
|
delete this.structures[instanceName];
|
||||||
|
}
|
||||||
|
|
||||||
|
getInstanceNames() {
|
||||||
|
return Object.keys(this.structures);
|
||||||
}
|
}
|
||||||
|
|
||||||
getStructuresAtLocation(location) {
|
getStructuresAtLocation(location) {
|
||||||
return Object.values(this.#structures).filter(structure => structure.isLocationActive(structure.toStructureCoords(location)));
|
return Object.values(this.structures).filter(structure => structure.isLocationActive(structure.toStructureCoords(location)));
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchStructureBlock(location) {
|
fetchStructureBlock(location) {
|
||||||
@@ -41,6 +45,21 @@ class StructureCollection {
|
|||||||
const structure = locatedStructures[0];
|
const structure = locatedStructures[0];
|
||||||
return structure.getBlock(structure.toStructureCoords(location));
|
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.`);
|
||||||
|
this.structures[newName] = structure;
|
||||||
|
delete this.structures[instanceName];
|
||||||
|
structure.name = newName;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const structureCollection = new StructureCollection();
|
export const structureCollection = new StructureCollection();
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import { world } from "@minecraft/server";
|
import { world } from "@minecraft/server";
|
||||||
import { Outliner } from "./Outliner";
|
import { Outliner } from "./Outliner";
|
||||||
|
|
||||||
export class Structure {
|
export class StructureInstance {
|
||||||
#structure;
|
#structure;
|
||||||
#options = {
|
#options = {
|
||||||
isPlaced: false,
|
isPlaced: false,
|
||||||
@@ -12,13 +12,15 @@ export class Structure {
|
|||||||
currentLayer: 0
|
currentLayer: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(structureName) {
|
constructor(instanceName, structureId) {
|
||||||
this.name = structureName;
|
this.name = instanceName;
|
||||||
this.#structure = world.structureManager.get(structureName);
|
this.structureId = structureId;
|
||||||
|
this.#structure = world.structureManager.get(structureId);
|
||||||
if (!this.#structure) {
|
if (!this.#structure) {
|
||||||
throw new Error(`[StrucTool] Structure '${structureName}' not found.`);
|
throw new Error(`[StrucTool] Structure '${this.structureId}' not found.`);
|
||||||
}
|
}
|
||||||
this.#options = this.loadOptions();
|
this.#options = this.loadOptions();
|
||||||
|
this.#options.isPlaced = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
loadOptions() {
|
loadOptions() {
|
||||||
@@ -39,7 +41,7 @@ export class Structure {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getLocation() {
|
getLocation() {
|
||||||
return this.#options.worldLocation;
|
return { dimensionId: this.#options.dimensionId, location: this.#options.worldLocation };
|
||||||
}
|
}
|
||||||
|
|
||||||
getHeight() {
|
getHeight() {
|
||||||
@@ -47,7 +49,7 @@ export class Structure {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getLayer() {
|
getLayer() {
|
||||||
return this.#options.currentLayer;
|
return this.#options.currentLayer || 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
*getBlocks() {
|
*getBlocks() {
|
||||||
@@ -83,7 +85,7 @@ export class Structure {
|
|||||||
|
|
||||||
getLayeredBounds() {
|
getLayeredBounds() {
|
||||||
if (!this.#options.isPlaced)
|
if (!this.#options.isPlaced)
|
||||||
throw new Error(`[StrucTool] Structure '${this.name}' is not placed.`);
|
throw new Error(`[StrucTool] Instance '${this.name}' is not placed.`);
|
||||||
return {
|
return {
|
||||||
min: { x: 0, y: this.#options.currentLayer - 1, z: 0 },
|
min: { x: 0, y: this.#options.currentLayer - 1, z: 0 },
|
||||||
max: { x: this.#structure.size.x, y: this.#options.currentLayer, z: this.#structure.size.z }
|
max: { x: this.#structure.size.x, y: this.#options.currentLayer, z: this.#structure.size.z }
|
||||||
@@ -91,31 +93,44 @@ export class Structure {
|
|||||||
}
|
}
|
||||||
|
|
||||||
place(dimensionId, worldLocation) {
|
place(dimensionId, worldLocation) {
|
||||||
this.#options = {
|
this.#options.isPlaced = true;
|
||||||
isPlaced: true,
|
this.move(dimensionId, worldLocation);
|
||||||
dimensionId,
|
|
||||||
worldLocation: { x: Math.floor(worldLocation.x), y: Math.floor(worldLocation.y), z: Math.floor(worldLocation.z) },
|
|
||||||
};
|
|
||||||
this.updateOptions();
|
|
||||||
this.outliner = new Outliner(dimensionId, this.toGlobalCoords(this.getBounds().min), this.toGlobalCoords(this.getBounds().max));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
remove() {
|
removePlacement() {
|
||||||
if (!this.#options.isPlaced)
|
if (!this.#options.isPlaced)
|
||||||
throw new Error(`[StrucTool] Structure '${this.name}' is not placed.`);
|
throw new Error(`[StrucTool] Instance '${this.name}' is not placed.`);
|
||||||
this.#options.isPlaced = false;
|
this.#options.isPlaced = false;
|
||||||
this.updateOptions();
|
this.updateOptions();
|
||||||
this.outliner.stopDraw();
|
this.outliner.stopDraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
move(dimensionId, location) {
|
||||||
|
if (!this.#options.isPlaced)
|
||||||
|
throw new Error(`[StrucTool] Instance '${this.name}' is not placed.`);
|
||||||
|
this.#options.dimensionId = dimensionId;
|
||||||
|
this.#options.worldLocation = { x: Math.floor(location.x), y: Math.floor(location.y), z: Math.floor(location.z) };
|
||||||
|
this.updateOptions();
|
||||||
|
this.refreshOutliner();
|
||||||
|
}
|
||||||
|
|
||||||
setLayer(layer) {
|
setLayer(layer) {
|
||||||
if (layer < 1 || layer > this.#structure.size.y)
|
if (layer < 1 || layer > this.#structure.size.y)
|
||||||
throw new Error(`[StrucTool] Structure '${this.name}' does not have layer ${layer}.`);
|
throw new Error(`[StrucTool] Instance '${this.name}' of '${this.structureId}' does not have layer ${layer}.`);
|
||||||
this.#options.currentLayer = layer;
|
this.#options.currentLayer = layer;
|
||||||
this.updateOptions();
|
this.updateOptions();
|
||||||
|
this.refreshOutliner();
|
||||||
|
}
|
||||||
|
|
||||||
|
refreshOutliner() {
|
||||||
|
if (this.outliner)
|
||||||
this.outliner.stopDraw();
|
this.outliner.stopDraw();
|
||||||
|
if (this.#options.currentLayer > 0) {
|
||||||
const { min, max } = this.getLayeredBounds();
|
const { min, max } = this.getLayeredBounds();
|
||||||
this.outliner = new Outliner(this.#options.dimensionId, this.toGlobalCoords(min), this.toGlobalCoords(max));
|
this.outliner = new Outliner(this.#options.dimensionId, this.toGlobalCoords(min), this.toGlobalCoords(max));
|
||||||
|
} else {
|
||||||
|
this.outliner = new Outliner(dimensionId, this.toGlobalCoords(this.getBounds().min), this.toGlobalCoords(this.getBounds().max));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
isLocationInStructure(structureLocation) {
|
isLocationInStructure(structureLocation) {
|
||||||
@@ -155,4 +170,8 @@ export class Structure {
|
|||||||
z: worldLocation.z - this.#options.worldLocation.z
|
z: worldLocation.z - this.#options.worldLocation.z
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isPlaced() {
|
||||||
|
return this.#options.isPlaced;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import { Command } from '../lib/canopy/CanopyExtension';
|
||||||
|
import { extension } from '../config';
|
||||||
|
import { structureCollection } from '../classes/StructureCollection';
|
||||||
|
import { MaterialCounter } from '../classes/MaterialCounter';
|
||||||
|
import { world, system } from '@minecraft/server';
|
||||||
|
import { MenuForm } from '../classes/MenuForm';
|
||||||
|
|
||||||
|
const ACTION_ITEM = 'minecraft:paper';
|
||||||
|
|
||||||
|
const structCmd = new Command({
|
||||||
|
name: 'menu',
|
||||||
|
description: { text: 'Manages current StrucTool structures.' },
|
||||||
|
usage: 'menu',
|
||||||
|
callback: structCommand
|
||||||
|
});
|
||||||
|
extension.addCommand(structCmd);
|
||||||
|
|
||||||
|
world.beforeEvents.itemUse.subscribe((event) => {
|
||||||
|
if (!event.source || event.itemStack?.typeId !== ACTION_ITEM) return;
|
||||||
|
event.cancel = true;
|
||||||
|
system.run(() => structCommand(event.source));
|
||||||
|
});
|
||||||
|
|
||||||
|
function structCommand(sender) {
|
||||||
|
new MenuForm(sender);
|
||||||
|
}
|
||||||
@@ -17,7 +17,7 @@ const structCmd = new Command({
|
|||||||
extension.addCommand(structCmd);
|
extension.addCommand(structCmd);
|
||||||
|
|
||||||
function structCommand(sender, args) {
|
function structCommand(sender, args) {
|
||||||
const { option, name, arg3 } = args;
|
const { name, option, arg3 } = args;
|
||||||
switch (option) {
|
switch (option) {
|
||||||
case 'add':
|
case 'add':
|
||||||
addStructure(sender, name);
|
addStructure(sender, name);
|
||||||
@@ -41,7 +41,7 @@ function structCommand(sender, args) {
|
|||||||
|
|
||||||
function addStructure(sender, name) {
|
function addStructure(sender, name) {
|
||||||
try {
|
try {
|
||||||
structureCollection.add(name);
|
structureCollection.add(name, name);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e.message.includes('already exists')) {
|
if (e.message.includes('already exists')) {
|
||||||
sender.sendMessage({ text: `§cStructure '${name}' already exists.` });
|
sender.sendMessage({ text: `§cStructure '${name}' already exists.` });
|
||||||
@@ -70,7 +70,7 @@ function placeStructure(sender, name) {
|
|||||||
structure = structureCollection.get(name);
|
structure = structureCollection.get(name);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
try {
|
try {
|
||||||
structure = structureCollection.add(name);
|
structure = structureCollection.add(name, name);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e.message.includes('already exists')) {
|
if (e.message.includes('already exists')) {
|
||||||
sender.sendMessage({ text: `§cStructure '${name}' already exists.` });
|
sender.sendMessage({ text: `§cStructure '${name}' already exists.` });
|
||||||
@@ -108,8 +108,8 @@ function printInfo(sender, name) {
|
|||||||
sender.sendMessage({ text: `§cStructure '${name}' not found.` });
|
sender.sendMessage({ text: `§cStructure '${name}' not found.` });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const location = structure.getLocation();
|
const { dimensionId, location } = structure.getLocation();
|
||||||
sender.sendMessage({ text: `§7Structure '${name}' at [${location.x} ${location.y} ${location.z}]` });
|
sender.sendMessage({ text: `§7Structure '${name}' at [${location.x} ${location.y} ${location.z}] in '${dimensionId}'` });
|
||||||
sender.sendMessage({ text: `§7Current Layer: ${structure.getLayer()}` });
|
sender.sendMessage({ text: `§7Current Layer: ${structure.getLayer()}` });
|
||||||
sender.sendMessage({ text: `§7Materials: ${MaterialCounter.getPrintable(name)}` });
|
sender.sendMessage({ text: `§7Materials: ${MaterialCounter.getPrintable(name)}` });
|
||||||
}
|
}
|
||||||
@@ -4,6 +4,7 @@ import './rules/fastEasyPlace';
|
|||||||
|
|
||||||
// Commands
|
// Commands
|
||||||
import './commands/struct';
|
import './commands/struct';
|
||||||
|
import './commands/menu';
|
||||||
|
|
||||||
// Other
|
// Other
|
||||||
import './classes/BlockInfo';
|
import './classes/BlockInfo';
|
||||||
|
|||||||
+3
-2
@@ -1,3 +1,4 @@
|
|||||||
|
import { system } from '@minecraft/server';
|
||||||
import { FormCancelationReason } from '@minecraft/server-ui';
|
import { FormCancelationReason } from '@minecraft/server-ui';
|
||||||
|
|
||||||
export async function forceShow(player, form, timeout = Infinity) {
|
export async function forceShow(player, form, timeout = Infinity) {
|
||||||
@@ -5,9 +6,9 @@ export async function forceShow(player, form, timeout = Infinity) {
|
|||||||
while ((system.currentTick - startTick) < timeout) {
|
while ((system.currentTick - startTick) < timeout) {
|
||||||
const response = await form.show(player);
|
const response = await form.show(player);
|
||||||
if (startTick + 1 === system.currentTick && response.cancelationReason === FormCancelationReason.UserBusy)
|
if (startTick + 1 === system.currentTick && response.cancelationReason === FormCancelationReason.UserBusy)
|
||||||
player.sendMessage({ translate: 'commands.canopy.menu.busy' });
|
player.sendMessage("§8Close your chat window to access the menu.");
|
||||||
if (response.cancelationReason !== FormCancelationReason.UserBusy)
|
if (response.cancelationReason !== FormCancelationReason.UserBusy)
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
throw new Error({ translate: 'commands.canopy.menu.timeout', with: [String(timeout)] });
|
throw new Error("Menu timed out.");
|
||||||
};
|
};
|
||||||
Reference in New Issue
Block a user