diff --git a/Canopy [BP]/scripts/include/utils.js b/Canopy [BP]/scripts/include/utils.js index 3188067..a99f4f1 100644 --- a/Canopy [BP]/scripts/include/utils.js +++ b/Canopy [BP]/scripts/include/utils.js @@ -1,3 +1,4 @@ +/* eslint-disable max-lines */ import { world, ItemStack, DimensionTypes } from '@minecraft/server'; class Utils { @@ -18,21 +19,19 @@ class Utils { } static parseLookingAtBlock(lookingAtBlock) { - let block; let blockName = ''; let raycastHitFace; - - block = lookingAtBlock?.block ?? undefined; + const block = lookingAtBlock?.block ?? undefined; if (block) { raycastHitFace = lookingAtBlock.face; try { blockName = `§a${Utils.parseName(block)}`; } catch (error) { - if (error.message.includes('loaded')) { + if (error.message.includes('loaded')) blockName = `§c${Utils.stringifyLocation(block.location, 0)} Unloaded`; - } else if (error.message.includes('undefined')) { + else if (error.message.includes('undefined')) blockName = '§7Undefined'; - } + } } @@ -47,15 +46,15 @@ class Utils { try { entityName = `§a${Utils.parseName(entity)}`; - if (entity.typeId === 'minecraft:player') { + if (entity.typeId === 'minecraft:player') entityName = `§a§o${entity.name}§r`; - } + } catch (error) { - if (error.message.includes('loaded')) { + if (error.message.includes('loaded')) entityName = `§c${Utils.stringifyLocation(entity.location, 0)} Unloaded`; - } else if (error.message.includes('undefined')) { + else if (error.message.includes('undefined')) entityName = '§7Undefined'; - } + } } @@ -80,7 +79,9 @@ class Utils { } static parseName(target, includePrefix = true) { - return target.typeId.replace('minecraft:', '') === 'player' ? `§o${target.name}§r` : (includePrefix ? target.typeId : target.typeId.replace('minecraft:', '')); + if (target.typeId.replace('minecraft:', '') === 'player') + return `§o${target.name}§r`; + return includePrefix ? target.typeId : target.typeId.replace('minecraft:', ''); } static stringifyLocation(location, precision = 0) { @@ -90,14 +91,14 @@ class Utils { } static populateItems(inventory) { - let items = {}; + const items = {}; inventory = inventory.container; for (let i=0; i { - let argData = this.#argParser(arg, index, raw); + const argData = this.#argParser(arg, index, raw); args[index] = argData; }); - return args.filter(_ => _ != '$nll_'); + return args.filter(_ => _ !== '$nll_'); } static #argParser(char, idx, raw) { - let data; - const isBoolean = this.booleans.includes(char); const isNumber = !isNaN(Number(char)); - const isString = this.stringRE.test(char); - const isArray = idx < raw.length - 1 && this.arrayRE.test(raw[idx + 1]); - const isEntity = this.entityRE.test(char); - - if (isBoolean) data = char == 'true'; - else if (isNumber) data = Number(char); - else if (isString) data = char.replace(this.stringRE, ''); - else if (isEntity && isArray) { + const isString = this.stringRegEx.test(char); + const isArray = idx < raw.length - 1 && this.arrayRegEx.test(raw[idx + 1]); + const isEntity = this.entityRegEx.test(char); + + let data; + if (isBoolean) { + data = char === 'true'; + } else if (isNumber) { + data = Number(char); + } else if (isString) { + data = char.replace(this.stringRegEx, ''); + } else if (isEntity && isArray) { data = raw[idx] += raw[idx + 1]; raw[idx + 1] = '$nll_'; + } else if (char.match(this.arrayRegEx)) { + data = JSON.parse(char); + } else { + data = char.trim(); } - else if (char.match(this.arrayRE)) data = JSON.parse(char); - else data = char.trim(); - return data; } } diff --git a/Canopy [BP]/scripts/lib/canopy/Command.js b/Canopy [BP]/scripts/lib/canopy/Command.js index 929be0b..cc4f872 100644 --- a/Canopy [BP]/scripts/lib/canopy/Command.js +++ b/Canopy [BP]/scripts/lib/canopy/Command.js @@ -26,9 +26,7 @@ class Command { this.#extensionName = extensionName; this.checkMembers(); - if (Commands.exists(this.#name)) - throw new Error(`[Command] Command '${this.#name}' already exists.`); - Commands.add(this); + Commands.register(this); } checkMembers() { diff --git a/Canopy [BP]/scripts/lib/canopy/Commands.js b/Canopy [BP]/scripts/lib/canopy/Commands.js index bf35280..8029a82 100644 --- a/Canopy [BP]/scripts/lib/canopy/Commands.js +++ b/Canopy [BP]/scripts/lib/canopy/Commands.js @@ -10,7 +10,9 @@ export class Commands { static #commands = {}; static #prefix = COMMAND_PREFIX; - static add(command) { + static register(command) { + if (this.exists(command.getName())) + throw new Error(`[Canopy] Command with name '${command.getName()}' already exists.`); this.#commands[command.getName()] = command; } @@ -39,42 +41,47 @@ export class Commands { } static getNativeCommands() { - let result = Object.values(this.#commands).filter(cmd => !cmd.getExtensionName()); + const result = Object.values(this.#commands).filter(cmd => !cmd.getExtensionName()); result.sort((a, b) => a.getName().localeCompare(b.getName())); return result; } static checkArg(value, type) { let data; - if (type == 'array' && Array.isArray(value)) data = value; - else if (type == 'identifier' && /@[aepsr]\[/g.test(value)) data = value; - else if (type == 'identifier' && /@[aepsr]/g.test(value) && value.length == 2) data = value; - else if (type == 'player' && value.startsWith('@"') && value.endsWith('"')) data = value; - else if (type == 'player' && value.startsWith('@') && !value.includes(' ')) data = value; - else if (type.includes('|')) { - let ts = type.split('|'); - let tv = typeof value; + if (type === 'array' && Array.isArray(value)) { + data = value; + } else if (type === 'identifier' && /@[aepsr]\[/g.test(value)) { + data = value; + } else if (type === 'identifier' && /@[aepsr]/g.test(value) && value.length === 2) { + data = value; + } else if (type === 'player' && value.startsWith('@"') && value.endsWith('"')) { + data = value; + } else if (type === 'player' && value.startsWith('@') && !value.includes(' ')) { + data = value; + } else if (type.includes('|')) { + const ts = type.split('|'); + const tv = typeof value; if (ts.includes(tv)) data = value; else data = null; + } else if (typeof value == type) { + data = value; + } else { + data = null; } - else if (typeof value == type) data = value; - else data = null; return data; } static handleGetPrefixRequest() { - IPC.on('canopy:getCommandPrefix', () => { - return this.#prefix; - }); + IPC.on('canopy:getCommandPrefix', () => this.#prefix); } static handleChatCommands() { world.beforeEvents.chatSend.subscribe((event) => { const { sender, message } = event; - - let [name, ...args] = ArgumentParser.parseArgs(message); + const [...args] = ArgumentParser.parseArgs(message); + let name = args.shift(); if (!String(name).startsWith(this.getPrefix())) return; name = name.replace(this.getPrefix(), ''); @@ -86,14 +93,14 @@ export class Commands { return sender.sendMessage({ translate: 'commands.generic.nopermission' }); system.run(async () => { - for (let ruleID of command.getContingentRules()) { + for (const ruleID of command.getContingentRules()) { const ruleValue = await Rules.getValue(ruleID); - if (!ruleValue) { + if (!ruleValue) return sender.sendMessage({ translate: 'rules.generic.blocked', with: [ruleID] }); - } + } - let parsedArgs = {}; + const parsedArgs = {}; command.getArgs().forEach((argData, index) => { parsedArgs[argData.name] = this.checkArg(args[index], argData.type); }); diff --git a/Canopy [BP]/scripts/lib/canopy/Rule.js b/Canopy [BP]/scripts/lib/canopy/Rule.js index cff058d..0ed460b 100644 --- a/Canopy [BP]/scripts/lib/canopy/Rule.js +++ b/Canopy [BP]/scripts/lib/canopy/Rule.js @@ -1,5 +1,6 @@ import { world } from '@minecraft/server'; import IPC from "../ipc/ipc"; +import Rules from "./Rules"; export class Rule { #category; @@ -18,6 +19,7 @@ export class Rule { this.#contingentRules = contingentRules; this.#independentRules = independentRules; this.#extensionName = extensionName; + Rules.register(this); } getCategory() { @@ -47,10 +49,10 @@ export class Rule { async getValue() { if (this.#extensionName) { // console.warn(`[Canopy] [Rule] Attempting to get value for ${this.#identifier} from extension ${this.#extensionName}.`); - return await IPC.invoke(`canopyExtension:${this.#extensionName}:ruleValueRequest`, { ruleID: this.#identifier }).then(result => { + return await IPC.invoke(`canopyExtension:${this.#extensionName}:ruleValueRequest`, { ruleID: this.#identifier }).then(result => // console.warn(`[Canopy] [Rule] Received value for ${this.#identifier} from extension ${this.#extensionName}: ${result}`); - return result; - }); + result + ); } return this.parseValue(world.getDynamicProperty(this.#identifier)); } @@ -73,11 +75,11 @@ export class Rule { } setValue(value) { - if (this.#extensionName) { + if (this.#extensionName) IPC.send(`canopyExtension:${this.#extensionName}:ruleValueSet`, { extensionName: this.#extensionName, ruleID: this.#identifier, value: value }); - } else { + else world.setDynamicProperty(this.#identifier, value); - } + } } diff --git a/Canopy [BP]/scripts/lib/canopy/Rules.js b/Canopy [BP]/scripts/lib/canopy/Rules.js index 796af48..8504ec1 100644 --- a/Canopy [BP]/scripts/lib/canopy/Rules.js +++ b/Canopy [BP]/scripts/lib/canopy/Rules.js @@ -1,10 +1,9 @@ export class Rules { static rules = {}; - static add(rule) { - if (this.exists(rule.getID())) { + static register(rule) { + if (this.exists(rule.getID())) throw new Error(`[Canopy] Rule with identifier '${rule.getID()}' already exists.`); - } this.rules[rule.getID()] = rule; } @@ -57,7 +56,7 @@ export class Rules { const rule = this.get(identifier); if (!rule) throw new Error(`[Canopy] Rule with identifier '${identifier}' does not exist.`); - return Rules.getAll().filter(rule => rule.getContigentRuleIDs().includes(identifier)).map(rule => rule.getID()); + return Rules.getAll().filter(r => r.getContigentRuleIDs().includes(identifier)).map(r => r.getID()); } } diff --git a/Canopy [BP]/scripts/lib/canopy/help/CommandHelpEntry.js b/Canopy [BP]/scripts/lib/canopy/help/CommandHelpEntry.js new file mode 100644 index 0000000..c6da960 --- /dev/null +++ b/Canopy [BP]/scripts/lib/canopy/help/CommandHelpEntry.js @@ -0,0 +1,19 @@ +import HelpEntry from './HelpEntry'; +import Commands from '../Commands'; + +class CommandHelpEntry extends HelpEntry { + constructor(command) { + super(command.getName(), command.getDescription()); + this.command = command; + } + + toRawMessage() { + const message = { rawtext: [{ text: `§2${this.command.getUsage()}§8 - ` }, this.description] }; + for (const helpEntry of this.command.getHelpEntries()) + message.rawtext.push({ rawtext: [{ text: `\n §7> §2${Commands.getPrefix()}${helpEntry.usage}§8 - ` }, helpEntry.description] }); + + return message; + } +} + +export default CommandHelpEntry; \ No newline at end of file diff --git a/Canopy [BP]/scripts/lib/canopy/help/CommandHelpPage.js b/Canopy [BP]/scripts/lib/canopy/help/CommandHelpPage.js new file mode 100644 index 0000000..463f97a --- /dev/null +++ b/Canopy [BP]/scripts/lib/canopy/help/CommandHelpPage.js @@ -0,0 +1,34 @@ +import HelpPage from "./HelpPage"; +import CommandHelpEntry from "./CommandHelpEntry"; +import Command from "../Command"; + +class CommandHelpPage extends HelpPage { + constructor(title, description = null, extensionName = false) { + super(title, description, extensionName); + } + + addEntry(command) { + if (!(command instanceof Command)) + throw new Error('[HelpPage] Entry must be an instance of Command'); + + if (this.hasEntry(command)) + return; + this.entries.push(new CommandHelpEntry(command)); + } + + hasEntry(command) { + return this.entries.some(entry => entry.command.getName() === command.getName()); + } + + toRawMessage() { + const message = this.getPrintStarter(); + if (this.description !== null) + message.rawtext.push({ rawtext: [ { text: `\n§2` }, this.description ] }); + for (const entry of this.entries) + message.rawtext.push({ rawtext: [ { text: '\n ' }, entry.toRawMessage() ] }); + + return message; + } +} + +export default CommandHelpPage; \ No newline at end of file diff --git a/Canopy [BP]/scripts/lib/canopy/help/HelpBook.js b/Canopy [BP]/scripts/lib/canopy/help/HelpBook.js index 8344137..7d239a1 100644 --- a/Canopy [BP]/scripts/lib/canopy/help/HelpBook.js +++ b/Canopy [BP]/scripts/lib/canopy/help/HelpBook.js @@ -8,23 +8,23 @@ class HelpBook { } newPage(page) { - if (!(page instanceof HelpPage)) { + if (!(page instanceof HelpPage)) throw new Error('[HelpBook] Page must be an instance of HelpPage'); - } + this.helpPages[page.title] = page; } getPage(pageName) { - if (!this.helpPages[pageName]) { + if (!this.helpPages[pageName]) throw new Error('[HelpBook] Page does not exist'); - } + return this.helpPages[pageName]; } addEntry(pageName, entry, player = false) { - if (!this.helpPages[pageName]) { + if (!this.helpPages[pageName]) throw new Error('[HelpBook] Page does not exist'); - } + if (pageName === 'InfoDisplay') this.helpPages[pageName].addEntry(entry, player); else @@ -44,13 +44,13 @@ class HelpBook { } async print(player) { - for (let page of Object.values(this.helpPages)) { + for (const page of Object.values(this.helpPages)) player.sendMessage(await page.toRawMessage()); - } + } async printPage(pageName, player) { - for (let page of Object.values(this.helpPages)) { + for (const page of Object.values(this.helpPages)) { if (String(page.title).toLowerCase() === String(pageName).toLowerCase()) { player.sendMessage(await page.toRawMessage()); return; @@ -61,11 +61,11 @@ class HelpBook { async printSearchResults(searchTerm, player) { const results = []; - for (let page of Object.values(this.helpPages)) { - for (let entry of page.entries) { - if (entry.title.toLowerCase().includes(searchTerm.toLowerCase())) { + for (const page of Object.values(this.helpPages)) { + for (const entry of page.entries) { + if (entry.title.toLowerCase().includes(searchTerm.toLowerCase())) results.push(entry); - } + } } diff --git a/Canopy [BP]/scripts/lib/canopy/help/HelpEntry.js b/Canopy [BP]/scripts/lib/canopy/help/HelpEntry.js index 5b7a3c5..3dac1f0 100644 --- a/Canopy [BP]/scripts/lib/canopy/help/HelpEntry.js +++ b/Canopy [BP]/scripts/lib/canopy/help/HelpEntry.js @@ -1,55 +1,14 @@ -import Command from "../Command"; - class HelpEntry { constructor(title, description) { + if (this.constructor === HelpEntry) + throw new TypeError('HelpEntry is an abstract class and cannot be instantiated.'); this.title = title; this.description = description; } -} - -class RuleHelpEntry extends HelpEntry { - constructor(rule) { - super(rule.getID(), rule.getDescription()); - this.rule = rule; - } - - async fetchColoredValue() { - const value = await this.rule.getValue(); - return value ? '§atrue§r' : '§cfalse§r'; - } - - async toRawMessage() { - const coloredValue = await this.fetchColoredValue().then(value => value); - return { rawtext: [ { text: `§7${this.title}: ${coloredValue}§8 - ` }, this.description ] }; - } -} - -class CommandHelpEntry extends HelpEntry { - constructor(command) { - super(command.getName(), command.getDescription()); - this.command = command; - } toRawMessage() { - const message = { rawtext: [{ text: `§2${this.command.getUsage()}§8 - ` }, this.description] }; - for (let helpEntry of this.command.getHelpEntries()) { - message.rawtext.push({ rawtext: [{ text: `\n §7> §2${Command.prefix}${helpEntry.usage}§8 - ` }, helpEntry.description] }); - } - return message; + throw new TypeError('Method "toRawMessage" must be implemented.'); } } -class InfoDisplayRuleHelpEntry extends RuleHelpEntry { - constructor(infoDisplayRule, player) { - super(infoDisplayRule); - this.player = player; - } - - async fetchColoredValue() { - const value = await this.rule.getValue(this.player); - return value ? '§atrue§r' : '§cfalse§r'; - } -} - - -export { HelpEntry, RuleHelpEntry, CommandHelpEntry, InfoDisplayRuleHelpEntry }; \ No newline at end of file +export default HelpEntry; \ No newline at end of file diff --git a/Canopy [BP]/scripts/lib/canopy/help/HelpPage.js b/Canopy [BP]/scripts/lib/canopy/help/HelpPage.js index 938a37c..caceaba 100644 --- a/Canopy [BP]/scripts/lib/canopy/help/HelpPage.js +++ b/Canopy [BP]/scripts/lib/canopy/help/HelpPage.js @@ -1,8 +1,3 @@ -import { RuleHelpEntry, CommandHelpEntry, InfoDisplayRuleHelpEntry } from './HelpEntry.js'; -import Rule from '../Rule.js'; -import InfoDisplayRule from '../InfoDisplayRule.js'; -import Command from '../Command.js'; - class HelpPage { entries = []; @@ -30,77 +25,4 @@ class HelpPage { } } -class RuleHelpPage extends HelpPage { - constructor(title, description, usage, extensionName = false) { - super(title, description, extensionName); - this.usage = usage; - } - - addEntry(rule) { - if (!(rule instanceof Rule)) { - throw new Error('[HelpPage] Entry must be an instance of Rule'); - } - if (this.hasEntry(rule)) - return; - this.entries.push(new RuleHelpEntry(rule)); - } - - hasEntry(rule) { - return this.entries.some(entry => entry.rule.getID() === rule.getID()); - } - - async toRawMessage() { - let message = this.getPrintStarter(); - message.rawtext.push({ rawtext: [ { text: `\n§2${this.usage}§8 - ` }, this.description ] }); - for (let entry of this.entries) { - message.rawtext.push({ rawtext: [ { text: '\n ' }, await entry.toRawMessage() ] }); - } - return message; - } -} - -class CommandHelpPage extends HelpPage { - constructor(title, description = null, extensionName = false) { - super(title, description, extensionName); - } - - addEntry(command) { - if (!(command instanceof Command)) { - throw new Error('[HelpPage] Entry must be an instance of Command'); - } - if (this.hasEntry(command)) - return; - this.entries.push(new CommandHelpEntry(command)); - } - - hasEntry(command) { - return this.entries.some(entry => entry.command.getName() === command.getName()); - } - - toRawMessage() { - let message = this.getPrintStarter(); - if (this.description !== null) - message.rawtext.push({ rawtext: [ { text: `\n§2` }, this.description ] }); - for (let entry of this.entries) { - message.rawtext.push({ rawtext: [ { text: '\n ' }, entry.toRawMessage() ] }); - } - return message; - } -} - -class InfoDisplayRuleHelpPage extends RuleHelpPage { - constructor(title, description, usage, extensionName = false) { - super(title, description, usage, extensionName); - } - - addEntry(rule, player) { - if (!(rule instanceof InfoDisplayRule)) { - throw new Error('[HelpPage] Entry must be an instance of InfoDisplayRule'); - } - if (this.hasEntry(rule)) - return; - this.entries.push(new InfoDisplayRuleHelpEntry(rule, player)); - } -} - -export { HelpPage, RuleHelpPage, CommandHelpPage, InfoDisplayRuleHelpPage }; \ No newline at end of file +export default HelpPage; \ No newline at end of file diff --git a/Canopy [BP]/scripts/lib/canopy/help/InfoDisplayRuleHelpEntry.js b/Canopy [BP]/scripts/lib/canopy/help/InfoDisplayRuleHelpEntry.js new file mode 100644 index 0000000..36ab521 --- /dev/null +++ b/Canopy [BP]/scripts/lib/canopy/help/InfoDisplayRuleHelpEntry.js @@ -0,0 +1,15 @@ +import RuleHelpEntry from "./RuleHelpEntry"; + +class InfoDisplayRuleHelpEntry extends RuleHelpEntry { + constructor(infoDisplayRule, player) { + super(infoDisplayRule); + this.player = player; + } + + async fetchColoredValue() { + const value = await this.rule.getValue(this.player); + return value ? '§atrue§r' : '§cfalse§r'; + } +} + +export default InfoDisplayRuleHelpEntry; \ No newline at end of file diff --git a/Canopy [BP]/scripts/lib/canopy/help/InfoDisplayRuleHelpPage.js b/Canopy [BP]/scripts/lib/canopy/help/InfoDisplayRuleHelpPage.js new file mode 100644 index 0000000..46b1121 --- /dev/null +++ b/Canopy [BP]/scripts/lib/canopy/help/InfoDisplayRuleHelpPage.js @@ -0,0 +1,20 @@ +import RuleHelpPage from './RuleHelpPage'; +import InfoDisplayRuleHelpEntry from './InfoDisplayRuleHelpEntry'; +import InfoDisplayRule from '../InfoDisplayRule'; + +class InfoDisplayRuleHelpPage extends RuleHelpPage { + constructor(title, description, usage, extensionName = false) { + super(title, description, usage, extensionName); + } + + addEntry(rule, player) { + if (!(rule instanceof InfoDisplayRule)) + throw new Error('[HelpPage] Entry must be an instance of InfoDisplayRule'); + + if (this.hasEntry(rule)) + return; + this.entries.push(new InfoDisplayRuleHelpEntry(rule, player)); + } +} + +export default InfoDisplayRuleHelpPage; \ No newline at end of file diff --git a/Canopy [BP]/scripts/lib/canopy/help/RuleHelpEntry.js b/Canopy [BP]/scripts/lib/canopy/help/RuleHelpEntry.js new file mode 100644 index 0000000..06f3b2e --- /dev/null +++ b/Canopy [BP]/scripts/lib/canopy/help/RuleHelpEntry.js @@ -0,0 +1,20 @@ +import HelpEntry from "./HelpEntry"; + +class RuleHelpEntry extends HelpEntry { + constructor(rule) { + super(rule.getID(), rule.getDescription()); + this.rule = rule; + } + + async fetchColoredValue() { + const value = await this.rule.getValue(); + return value ? '§atrue§r' : '§cfalse§r'; + } + + async toRawMessage() { + const coloredValue = await this.fetchColoredValue().then(value => value); + return { rawtext: [ { text: `§7${this.title}: ${coloredValue}§8 - ` }, this.description ] }; + } +} + +export default RuleHelpEntry; \ No newline at end of file diff --git a/Canopy [BP]/scripts/lib/canopy/help/RuleHelpPage.js b/Canopy [BP]/scripts/lib/canopy/help/RuleHelpPage.js new file mode 100644 index 0000000..995a2e1 --- /dev/null +++ b/Canopy [BP]/scripts/lib/canopy/help/RuleHelpPage.js @@ -0,0 +1,34 @@ +import HelpPage from './HelpPage'; +import RuleHelpEntry from './RuleHelpEntry'; +import Rule from '../Rule'; + +class RuleHelpPage extends HelpPage { + constructor(title, description, usage, extensionName = false) { + super(title, description, extensionName); + this.usage = usage; + } + + addEntry(rule) { + if (!(rule instanceof Rule)) + throw new Error('[HelpPage] Entry must be an instance of Rule'); + + if (this.hasEntry(rule)) + return; + this.entries.push(new RuleHelpEntry(rule)); + } + + hasEntry(rule) { + return this.entries.some(entry => entry.rule.getID() === rule.getID()); + } + + async toRawMessage() { + const message = this.getPrintStarter(); + message.rawtext.push({ rawtext: [ { text: `\n§2${this.usage}§8 - ` }, this.description ] }); + for (const entry of this.entries) + message.rawtext.push({ rawtext: [ { text: '\n ' }, await entry.toRawMessage() ] }); + + return message; + } +} + +export default RuleHelpPage; \ No newline at end of file diff --git a/Canopy [BP]/scripts/src/classes/BlockRotator.js b/Canopy [BP]/scripts/src/classes/BlockRotator.js index 80345dd..ceecd63 100644 --- a/Canopy [BP]/scripts/src/classes/BlockRotator.js +++ b/Canopy [BP]/scripts/src/classes/BlockRotator.js @@ -48,7 +48,7 @@ class BlockRotator { if (!this.isValidId(structureId)) return console.warn('[BlockRotator] Invalid structure ID.'); const mirroredDirection = DirectionStateFinder.getMirroredDirection(block); let axis; - let items = Utils.getInventory(block); + const items = Utils.getInventory(block); if ([StructureMirrorAxis.X, StructureMirrorAxis.Z].includes(mirroredDirection)) { axis = mirroredDirection; } else { // block data has to be rebuilt manually 🎉 @@ -86,9 +86,9 @@ class BlockRotator { world.afterEvents.worldInitialize.subscribe(() => { world.structureManager.getWorldStructureIds().forEach(id => { - if (id.startsWith(BlockRotator.idPrefix)) { + if (id.startsWith(BlockRotator.idPrefix)) world.structureManager.delete(id); - } + }); }); diff --git a/Canopy [BP]/scripts/src/classes/DirectionState.js b/Canopy [BP]/scripts/src/classes/DirectionState.js index 62b2f8a..0c66ff2 100644 --- a/Canopy [BP]/scripts/src/classes/DirectionState.js +++ b/Canopy [BP]/scripts/src/classes/DirectionState.js @@ -1,12 +1,5 @@ import { StructureMirrorAxis } from "@minecraft/server"; -class DirectionState { - constructor(name, value) { - this.name = name; - this.value = value; - } -} - class DirectionStateFinder { static getDirectionState(permutation) { const potentialStates = { @@ -18,7 +11,7 @@ class DirectionStateFinder { }; for (const state in potentialStates) { if (potentialStates[state] === undefined) continue; - return new DirectionState(state, potentialStates[state]); + return { name: state, value: potentialStates[state] }; } return undefined; } @@ -62,6 +55,8 @@ class DirectionStateFinder { 0: StructureMirrorAxis.Z, 1: StructureMirrorAxis.X }[directionState.value]; + default: + throw new Error('Could not mirror direction. Invalid direction state.'); } } @@ -109,6 +104,8 @@ class DirectionStateFinder { 'x': 'z', 'z': 'y' }[directionState.value]; + default: + throw new Error('Could not rotate direction. Invalid direction state.'); } } @@ -152,6 +149,8 @@ class DirectionStateFinder { 0: 1, 1: 0 }[directionState.value]; + default: + throw new Error('Could not mirror direction. Invalid direction state.'); } } diff --git a/Canopy [BP]/scripts/src/classes/EventTracker.js b/Canopy [BP]/scripts/src/classes/EventTracker.js index 209a35b..923ab93 100644 --- a/Canopy [BP]/scripts/src/classes/EventTracker.js +++ b/Canopy [BP]/scripts/src/classes/EventTracker.js @@ -13,13 +13,13 @@ class EventTracker { } setCallback(eventName, isAfterEvent = true) { - if (isAfterEvent && this.afterEvents[eventName]) { + if (isAfterEvent && this.afterEvents[eventName]) this.callback = this.afterEvents[eventName]; - } else if (this.beforeEvents[eventName]) { + else if (this.beforeEvents[eventName]) this.callback = this.beforeEvents[eventName]; - } else { + else throw new Error(`[EventTracker] Event ${eventName} not found. Could not create new tracker.`); - } + } updateDynamicProperty() { @@ -29,18 +29,18 @@ class EventTracker { let found = false; for (let i = 0; i < trackedEvents.length; i++) { if (trackedEvents[i].eventName === this.eventName && trackedEvents[i].isAfterEvent === this.isAfterEvent) { - if (this.isTracking) { + if (this.isTracking) trackedEvents[i].count = this.count; - } else { + else trackedEvents.splice(i, 1); - } + found = true; break; } } - if (!found && this.isTracking) { + if (!found && this.isTracking) trackedEvents.push(this.getInfo()); - } + world.setDynamicProperty('trackedEvents', JSON.stringify(trackedEvents)); } diff --git a/Canopy [BP]/scripts/src/classes/HopperGenerators.js b/Canopy [BP]/scripts/src/classes/HopperGenerators.js index 531b5f3..3ac335c 100644 --- a/Canopy [BP]/scripts/src/classes/HopperGenerators.js +++ b/Canopy [BP]/scripts/src/classes/HopperGenerators.js @@ -119,14 +119,14 @@ class GeneratorChannelMap { } resetAll() { - for (const color of this.colors) { + for (const color of this.colors) this.reset(color); - } + } getQueryOutput(channel) { - let realtimeText = this.realtime ? 'realtime: ' : ''; - let message = { rawtext: [ + const realtimeText = this.realtime ? 'realtime: ' : ''; + const message = { rawtext: [ { translate: 'commands.generator.query.channel', with: [ formatColor(channel.color), realtimeText, @@ -134,9 +134,9 @@ class GeneratorChannelMap { String(channel.totalCount), Utils.calculatePerTime(channel.totalCount, this.getDeltaTime(channel)) ] }] }; - for (const item of Object.keys(channel.itemMap)) { + for (const item of Object.keys(channel.itemMap)) message.rawtext.push({ text: `\n §7- ${item}: ${getAllModeOutput(channel, item)}` }); - } + return message; } @@ -144,11 +144,11 @@ class GeneratorChannelMap { const millisecondsPerTick = 50.0; let deltaTicks; - if (this.realtime) { + if (this.realtime) deltaTicks = (Date.now() - channel.startRealTime) / millisecondsPerTick; - } else { + else deltaTicks = system.currentTick - channel.startTickTime; - } + deltaTicks = Math.floor(deltaTicks / 8) * 8; // normalize to hopper speed return deltaTicks; } diff --git a/Canopy [BP]/scripts/src/classes/HotbarManager.js b/Canopy [BP]/scripts/src/classes/HotbarManager.js index 2d98712..52b7249 100644 --- a/Canopy [BP]/scripts/src/classes/HotbarManager.js +++ b/Canopy [BP]/scripts/src/classes/HotbarManager.js @@ -3,18 +3,18 @@ import SRCItemDatabase from 'lib/SRCItemDatabase'; class HotbarManager { constructor(player) { this.player = player; - let tableName = 'bar' + player.id.toString().substr(0, 9); + const tableName = 'bar' + player.id.toString().substr(0, 9); this.itemDatabase = new SRCItemDatabase(tableName); } getActiveHotbarItems() { const container = this.player.getComponent('minecraft:inventory')?.container; - let hotbarItems = []; + const hotbarItems = []; for (let slotIndex = 0; slotIndex < 9; slotIndex++) { const itemStack = container.getItem(slotIndex); - if (itemStack) { + if (itemStack) hotbarItems.push({ key: slotIndex, item: itemStack }); - } + } return hotbarItems; } @@ -24,14 +24,14 @@ class HotbarManager { const items = this.getActiveHotbarItems().map(item => ({ ...item, key: `${index}-${item.key}` })); this.itemDatabase.setMany(items); for (let slotIndex = 0; slotIndex < 9; slotIndex++) { - if (!items.some(item => item.key === `${index}-${slotIndex}`)) { + if (!items.some(item => item.key === `${index}-${slotIndex}`)) this.itemDatabase.delete(`${index}-${slotIndex}`); - } + } } loadHotbar(index) { - let playerInventory = this.player.getComponent('inventory').container; + const playerInventory = this.player.getComponent('inventory').container; for (let slotIndex = 0; slotIndex < 9; slotIndex++) { const item = this.itemDatabase.get(`${index}-${slotIndex}`); if (item) @@ -43,7 +43,7 @@ class HotbarManager { getItemsString(items) { let output = 'Items:'; - for (let slotIndex in items) { + for (const slotIndex in items) { const itemStruct = items[slotIndex]; output += `\n${itemStruct.key}: ${itemStruct.item.typeId} x${itemStruct.item.count}`; } diff --git a/Canopy [BP]/scripts/src/classes/Instaminable.js b/Canopy [BP]/scripts/src/classes/Instaminable.js index 1f71168..bb10ffe 100644 --- a/Canopy [BP]/scripts/src/classes/Instaminable.js +++ b/Canopy [BP]/scripts/src/classes/Instaminable.js @@ -1,7 +1,7 @@ import { system, world } from "@minecraft/server"; import { Rule } from "lib/canopy/Canopy"; -const beaconRefreshOffset = new Map(); +const beaconRefreshOffset = {}; const BEACON_REFRESH_RATE = 80; world.afterEvents.effectAdd.subscribe(event => { @@ -21,9 +21,9 @@ class Instaminable { for (const player of world.getPlayers()) { if (!player) continue; - if (player.getEffect('haste')?.amplifier == 2 && this.isTickBeforeRefresh(player)) { + if (player.getEffect('haste')?.amplifier === 2 && this.isTickBeforeRefresh(player)) player.removeEffect('haste'); - } + } }); @@ -33,7 +33,7 @@ class Instaminable { if (!this.litmusCallback(blockId)) return; const player = event.player; if (this.isEfficiencyFiveNetheritePick(event.itemStack) && this.hasHasteTwo(player)) { - let duration = player.getEffect('haste')?.duration; + const duration = player.getEffect('haste')?.duration; if (duration > 0) player.addEffect('haste', duration, { amplifier: 2 }); } @@ -54,7 +54,7 @@ class Instaminable { hasHasteTwo(player) { const haste = player.getEffect('haste'); - return haste?.amplifier == 1; + return haste?.amplifier === 1; } } diff --git a/Canopy [BP]/scripts/src/classes/ProbeManager.js b/Canopy [BP]/scripts/src/classes/ProbeManager.js index 71c2a97..f05093c 100644 --- a/Canopy [BP]/scripts/src/classes/ProbeManager.js +++ b/Canopy [BP]/scripts/src/classes/ProbeManager.js @@ -60,20 +60,20 @@ class ProbeManager { } getProperty(player, property) { - let result = '?'; + const result = '?'; if (this.isDoingBannedAction(player)) { this.removeProbe(player); return result; } - let probe = this.getProbe(player); + const probe = this.getProbe(player); if (!probe) { - probe = this.addProbe(player); + this.addProbe(player); return result; } else if (probe.entityInvalid) { this.removeProbe(player); - probe = this.addProbe(player); + this.addProbe(player); return result; } diff --git a/Canopy [BP]/scripts/src/classes/SpawnTracker.js b/Canopy [BP]/scripts/src/classes/SpawnTracker.js index b1eca7f..ee339c4 100644 --- a/Canopy [BP]/scripts/src/classes/SpawnTracker.js +++ b/Canopy [BP]/scripts/src/classes/SpawnTracker.js @@ -1,28 +1,34 @@ -import { system, world } from '@minecraft/server' -import Utils from 'include/utils' -import { categoryToMobMap } from 'include/data' +import { system, world } from "@minecraft/server"; +import Utils from "../../include/utils"; +import { categoryToMobMap } from "../../include/data"; const CLEAR_RECENTS_THRESHOLD = 600; // 600 ticks = 30 seconds let wasTrackingLastTick = false; class SpawnTracker { - constructor(dimensionId, category = null, mobIds = [], activeArea = null) { - if (category !== null && mobIds.length > 0) { - throw new Error("SpawnTracker constructor should be called with either 'category' or 'mobIds', but not both."); - } - - this.category = category; + constructor(dimensionId, mobIds = [], activeArea = null ) { this.dimensionId = dimensionId; - this.startTick = system.currentTick; - this.activeArea = activeArea; + this.mobs = mobIds || []; + this.category = this.getCategory(); + this.activeArea = activeArea || null; this.spawns = {}; this.recents = {}; this.mobsPerTick = {}; this.recentsClearRunner = null; - this.mobs = category ? categoryToMobMap[category] : mobIds; + this.startTick = system.currentTick; this.startTracking(); } + getCategory() { + for (const [category, mobs] of Object.entries(categoryToMobMap)) { + for (const mob of this.mobs) { + if (mobs.includes(mob)) + return category; + } + } + return null; + } + getMobsPerTickMap() { return this.mobsPerTick; } @@ -71,11 +77,9 @@ class SpawnTracker { } clearOldMobs(tickThreshold) { - for (const mobType in this.recents) { - this.recents[mobType] = this.recents[mobType].filter((timedLocation) => { - return system.currentTick - timedLocation.time < tickThreshold; - }); - } + for (const mobType in this.recents) + this.recents[mobType] = this.recents[mobType].filter((timedLocation) => system.currentTick - timedLocation.time < tickThreshold); + } reset() { @@ -115,9 +119,9 @@ class SpawnTracker { getRecents() { const recents = {}; - for (const mobType in this.recents) { + for (const mobType in this.recents) recents[mobType] = this.recents[mobType].map((timedLocation) => timedLocation.location); - } + return recents; } diff --git a/Canopy [BP]/scripts/src/classes/Vector.js b/Canopy [BP]/scripts/src/classes/Vector.js index 94f7158..5677eed 100644 --- a/Canopy [BP]/scripts/src/classes/Vector.js +++ b/Canopy [BP]/scripts/src/classes/Vector.js @@ -1,5 +1,6 @@ /** * Part of ItemStack Database by @gameza_src + * Unknown author */ const isVec3Symbol = Symbol("isVec3"); export function Vector(x = 0, y = 0, z = 0) { @@ -7,7 +8,7 @@ export function Vector(x = 0, y = 0, z = 0) { this.x = Number(x); this.y = Number(y); this.z = Number(z); - } else return { x: Number(x), y: Number(y), z: Number(z), __proto__: Vector.prototype }; + } else {return { x: Number(x), y: Number(y), z: Number(z), __proto__: Vector.prototype };} } Vector.magnitude = function magnitude(vec) { return Math.sqrt(vec.x * vec.x + vec.y * vec.y + vec.z * vec.z); } Vector.normalize = function normalize(vec) { const l = Vector.magnitude(vec); return { x: vec.x / l, y: vec.y / l, z: vec.z / l, __proto__: Vector.prototype }; } @@ -18,7 +19,7 @@ Vector.subtract = function subtract(a, b) { return { x: a.x - b.x, y: a.y - b.y, Vector.add = function add(a, b) { return { x: a.x + b.x, y: a.y + b.y, z: a.z + b.z, __proto__: Vector.prototype } }; Vector.multiply = function multiply(vec, num) { if (typeof num == "number") return { x: vec.x * num, y: vec.y * num, z: vec.z * num, __proto__: Vector.prototype }; - else return { x: vec.x * num.x, y: vec.y * num.y, z: vec.z * num.z, __proto__: Vector.prototype }; + return { x: vec.x * num.x, y: vec.y * num.y, z: vec.z * num.z, __proto__: Vector.prototype }; } Vector.isVec3 = function isVec3(vec) { return vec[isVec3Symbol] === true; } Vector.floor = function floor(vec) { return { x: Math.floor(vec.x), y: Math.floor(vec.y), z: Math.floor(vec.z), __proto__: Vector.prototype }; } @@ -29,7 +30,7 @@ Vector.lerp = function lerp(a, b, t) { return Vector.multiply(a, 1 - t).add(Vect Vector.distance = function distance(a, b) { return Vector.magnitude(Vector.subtract(a, b)); } Vector.from = function from(object) { if (Vector.isVec3(object)) return object; - if (Array.isArray(object)) return Vector(object[0], object[1], object[2]); + if (Array.isArray(object)) return new Vector(object[0], object[1], object[2]); const { x = 0, y = 0, z = 0 } = object ?? {}; return { x: Number(x), y: Number(y), z: Number(z), __proto__: Vector.prototype }; } diff --git a/Canopy [BP]/scripts/src/classes/WorldSpawns.js b/Canopy [BP]/scripts/src/classes/WorldSpawns.js index a3cc287..c010a72 100644 --- a/Canopy [BP]/scripts/src/classes/WorldSpawns.js +++ b/Canopy [BP]/scripts/src/classes/WorldSpawns.js @@ -27,9 +27,9 @@ class WorldSpawns { sendMobToTrackers(entity) { for (const dimensionId in this.trackers) { - for (const category in this.trackers[dimensionId]) { + for (const category in this.trackers[dimensionId]) this.trackers[dimensionId][category].recieveMob(entity); - } + } } @@ -71,7 +71,7 @@ class WorldSpawns { dimensionIds.forEach(dimensionId => { this.trackers[dimensionId] = {}; categories.forEach(category => { - this.trackers[dimensionId][category] = new SpawnTracker(dimensionId, category, [], this.activeArea); + this.trackers[dimensionId][category] = new SpawnTracker(dimensionId, categoryToMobMap[category], this.activeArea); }); }); } @@ -79,10 +79,25 @@ class WorldSpawns { trackMobs(mobIds) { dimensionIds.forEach(dimensionId => { this.trackers[dimensionId] = this.trackers[dimensionId] || {}; - this.trackers[dimensionId]['custom'] = new SpawnTracker(dimensionId, null, mobIds, this.activeArea); + const categorizedMobs = this.categorizeMobs(mobIds); + for (const category in categorizedMobs) + this.trackers[dimensionId][category] = new SpawnTracker(dimensionId, categorizedMobs[category], this.activeArea); }); } + categorizeMobs(mobIds) { + const categorizedMobs = {}; + for (const [category, mobs] of Object.entries(categoryToMobMap)) { + mobIds.forEach(mobId => { + if (mobs.includes(mobId)) { + categorizedMobs[category] = categorizedMobs[category] || []; + categorizedMobs[category].push(mobId); + } + }); + } + return categorizedMobs; + } + reset() { this.startTick = system.currentTick; Object.values(this.trackers).forEach(dimensionTracker => { @@ -94,7 +109,7 @@ class WorldSpawns { getRecentsOutput(mobname = null) { let output = `Recent spawns (last 30s):`; - let recents = this.getRecents(mobname); + const recents = this.getRecents(mobname); for (const dimensionId in recents) { output += `\n${Utils.getColoredDimensionName(dimensionId)}§7:`; for (const category in recents[dimensionId]) { @@ -110,7 +125,7 @@ class WorldSpawns { } getRecents(mobname = null) { - let recents = {}; + const recents = {}; for (const dimensionId in this.trackers) { recents[dimensionId] = {}; for (const category in this.trackers[dimensionId]) { diff --git a/Canopy [BP]/scripts/src/commands/camera.js b/Canopy [BP]/scripts/src/commands/camera.js index e9ba601..a924f25 100644 --- a/Canopy [BP]/scripts/src/commands/camera.js +++ b/Canopy [BP]/scripts/src/commands/camera.js @@ -53,14 +53,6 @@ new Command({ helpHidden: true }); -class CameraPlacement { - constructor(location, rotation, dimension) { - this.location = location; - this.rotation = rotation; - this.dimension = dimension; - } -} - class BeforeSpectatorPlayer { constructor(player) { this.location = player.location; @@ -68,7 +60,7 @@ class BeforeSpectatorPlayer { this.dimensionId = player.dimension.id; this.gamemode = player.getGameMode(); this.effects = []; - for (let effect of player.getEffects()) + for (const effect of player.getEffects()) this.effects.push({ typeId: effect.typeId, duration: effect.duration, amplifier: effect.amplifier }); } } @@ -114,23 +106,22 @@ function cameraCommand(sender, args) { } function placeCameraAction(sender) { - let camera; const eyeHeight = 1.62001002; if (sender.getDynamicProperty('isViewingCamera')) return sender.sendMessage({ translate: 'commands.camera.place.viewing' }); - camera = new CameraPlacement( - { x: sender.location.x, y: sender.location.y + eyeHeight, z: sender.location.z }, - sender.getRotation(), - sender.dimension.id - ); - placeCamera(sender, camera); + const cameraSettings = { + location: { x: sender.location.x, y: sender.location.y + eyeHeight, z: sender.location.z }, + rotation: sender.getRotation(), + dimensionId: sender.dimension.id + }; + placeCamera(sender, cameraSettings); } -function placeCamera(sender, camera) { - sender.setDynamicProperty('placedCamera', JSON.stringify(camera)); - sender.sendMessage({ translate: 'commands.camera.place.success', with: [Utils.stringifyLocation(camera.location, 0)] }); +function placeCamera(sender, cameraSettings) { + sender.setDynamicProperty('placedCamera', JSON.stringify(cameraSettings)); + sender.sendMessage({ translate: 'commands.camera.place.success', with: [Utils.stringifyLocation(cameraSettings.location, 0)] }); } function viewCameraAction(sender, option) { @@ -139,36 +130,36 @@ function viewCameraAction(sender, option) { if (!sender.getDynamicProperty('placedCamera')) return sender.sendMessage({ translate: 'commands.camera.view.fail' }); - const placedCamera = JSON.parse(sender.getDynamicProperty('placedCamera')); - toggleCameraView(sender, placedCamera, option); + const placedCameraSettings = JSON.parse(sender.getDynamicProperty('placedCamera')); + toggleCameraView(sender, placedCameraSettings, option); } -function toggleCameraView(sender, placedCamera, option) { - if (!sender.getDynamicProperty('isViewingCamera')) { - if (placedCamera.dimension !== sender.dimension.id) - return sender.sendMessage({ translate: 'commands.camera.view.dimension', with: [placedCamera.dimension] }); - startCameraView(sender, placedCamera, option); - } else { +function toggleCameraView(sender, placedCameraSettings, option) { + if (sender.getDynamicProperty('isViewingCamera')) { endCameraView(sender); + } else { + if (placedCameraSettings.dimensionId !== sender.dimension.id) + return sender.sendMessage({ translate: 'commands.camera.view.dimension', with: [placedCameraSettings.dimensionId] }); + startCameraView(sender, placedCameraSettings, option); } } -function startCameraView(sender, placedCamera, option) { +function startCameraView(sender, placedCameraSettings, option) { if (option === 'load') - loadChunkForTicks(placedCamera, 20); + loadChunkForTicks(placedCameraSettings, 20); sender.camera.setCamera('minecraft:free', { easeOptions: { easeTime: 1.0, easeType: 'InOutSine' }, - location: placedCamera.location, - rotation: placedCamera.rotation + location: placedCameraSettings.location, + rotation: placedCameraSettings.rotation }); sender.setDynamicProperty('isViewingCamera', true); sender.onScreenDisplay.setActionBar({ translate: 'commands.camera.view.started' }); } -function loadChunkForTicks(placedCamera, ticks) { - const dimension = world.getDimension(placedCamera.dimension); +function loadChunkForTicks(placedCameraSettings, ticks) { + const dimension = world.getDimension(placedCameraSettings.dimensionId); dimension.runCommand('tickingarea remove Canopy-cameraLoad'); - dimension.runCommand(`tickingarea add ${placedCamera.location.x} ${placedCamera.location.y} ${placedCamera.location.z} ${placedCamera.location.x} ${placedCamera.location.y} ${placedCamera.location.z} Canopy-cameraLoad`); + dimension.runCommand(`tickingarea add ${placedCameraSettings.location.x} ${placedCameraSettings.location.y} ${placedCameraSettings.location.z} ${placedCameraSettings.location.x} ${placedCameraSettings.location.y} ${placedCameraSettings.location.z} Canopy-cameraLoad`); system.runTimeout(() => { dimension.runCommand('tickingarea remove Canopy-cameraLoad'); }, ticks); @@ -186,10 +177,10 @@ function endCameraView(sender) { function spectateAction(sender) { if (sender.getDynamicProperty('isViewingCamera')) return sender.sendMessage({ translate: 'commands.camera.spectate.viewing' }); - if (!sender.getDynamicProperty('isSpectating')) - startSpectate(sender); - else + if (sender.getDynamicProperty('isSpectating')) endSpectate(sender); + else + startSpectate(sender); } function startSpectate(sender) { @@ -200,7 +191,7 @@ function startSpectate(sender) { system.runTimeout(() => { sender.setGameMode('spectator'); - for (let effect of sender.getEffects()) + for (const effect of sender.getEffects()) sender.removeEffect(effect?.typeId); sender.addEffect('night_vision', 20000000, { amplifier: 0, showParticles: false }); sender.addEffect('conduit_power', 20000000, { amplifier: 0, showParticles: false }); @@ -213,7 +204,7 @@ function endSpectate(sender) { const beforeSpectatorPlayer = JSON.parse(sender.getDynamicProperty('beforeSpectatorPlayer')); sender.setDynamicProperty('isSpectating', false); system.runTimeout(() => { - for (let effect of sender.getEffects()) { + for (const effect of sender.getEffects()) { if (!effect) continue; sender.removeEffect(effect.typeId); } diff --git a/Canopy [BP]/scripts/src/commands/canopy.js b/Canopy [BP]/scripts/src/commands/canopy.js index b90db0d..438f379 100644 --- a/Canopy [BP]/scripts/src/commands/canopy.js +++ b/Canopy [BP]/scripts/src/commands/canopy.js @@ -1,6 +1,5 @@ -import { Rule, Command } from 'lib/canopy/Canopy'; +import { Rule, Command, InfoDisplayRule } from 'lib/canopy/Canopy'; import { resetCounterMap } from 'src/commands/counter'; -import { InfoDisplayRule } from 'lib/canopy/Canopy'; const cmd = new Command({ name: 'canopy', @@ -34,16 +33,17 @@ async function canopyCommand(sender, args) { if (ruleID === 'hopperCounters' && !enable) resetCounterMap(); - if (!enable) - await updateRules(sender, rule.getDependentRuleIDs(), enable); - else + if (enable) await updateRules(sender, rule.getContigentRuleIDs(), enable); + else + await updateRules(sender, rule.getDependentRuleIDs(), enable); await updateRules(sender, rule.getIndependentRuleIDs(), false); - updateRule(sender, ruleID, ruleValue, enable); + await updateRule(sender, ruleID, enable); } -function updateRule(sender, ruleID, ruleValue, enable) { +async function updateRule(sender, ruleID, enable) { + const ruleValue = await Rule.getValue(ruleID); if (ruleValue === enable) return; Rule.getRule(ruleID).setValue(enable); const enabledRawText = enable ? { translate: 'rules.generic.enabled' } : { translate: 'rules.generic.disabled' }; @@ -51,7 +51,6 @@ function updateRule(sender, ruleID, ruleValue, enable) { } async function updateRules(sender, ruleIDs, enable) { - for (const ruleID of ruleIDs) { - updateRule(sender, ruleID, await Rule.getValue(ruleID), enable); - } + for (const ruleID of ruleIDs) + await updateRule(sender, ruleID, enable); } diff --git a/Canopy [BP]/scripts/src/commands/changedimension.js b/Canopy [BP]/scripts/src/commands/changedimension.js index e9818af..12afee6 100644 --- a/Canopy [BP]/scripts/src/commands/changedimension.js +++ b/Canopy [BP]/scripts/src/commands/changedimension.js @@ -62,6 +62,5 @@ function convertCoords(fromDimension, toDimension, location) { return { x: location.x / 8, y: location.y, z: location.z / 8 }; else if (fromDimension === 'nether' && toDimension === 'overworld') return { x: location.x * 8, y: location.y, z: location.z * 8 }; - else - return location; + return location; } diff --git a/Canopy [BP]/scripts/src/commands/claimprojectiles.js b/Canopy [BP]/scripts/src/commands/claimprojectiles.js index c2a289d..ed881c2 100644 --- a/Canopy [BP]/scripts/src/commands/claimprojectiles.js +++ b/Canopy [BP]/scripts/src/commands/claimprojectiles.js @@ -23,7 +23,8 @@ new Command({ }); function claimProjectilesCommand(sender, args) { - let { playerName, radius } = args; + const playerName = args.playerName; + let radius = args.radius; let targetPlayer; if (playerName === null) targetPlayer = sender; @@ -56,8 +57,7 @@ function getTargetPlayer(sender, playerName) { return players[0]; else if (Utils.isNumeric(playerName)) return playerName; - else - return undefined; + return undefined; } function getProjectilesInRange(sender, radius) { diff --git a/Canopy [BP]/scripts/src/commands/cleanup.js b/Canopy [BP]/scripts/src/commands/cleanup.js index f95f753..409622b 100644 --- a/Canopy [BP]/scripts/src/commands/cleanup.js +++ b/Canopy [BP]/scripts/src/commands/cleanup.js @@ -33,14 +33,14 @@ function cleanupCommand(sender, args) { const { distance } = args; let entities; if (distance === null) - entities = sender.dimension.getEntities({ type: 'minecraft:item' }) - .concat(sender.dimension.getEntities({ type: 'minecraft:xp_orb' })); + {entities = sender.dimension.getEntities({ type: 'minecraft:item' }) + .concat(sender.dimension.getEntities({ type: 'minecraft:xp_orb' }));} else - entities = sender.dimension.getEntities({ type: 'minecraft:item', location: sender.location, maxDistance: distance }) - .concat(sender.dimension.getEntities({ type: 'minecraft:xp_orb', location: sender.location, maxDistance: distance })); + {entities = sender.dimension.getEntities({ type: 'minecraft:item', location: sender.location, maxDistance: distance }) + .concat(sender.dimension.getEntities({ type: 'minecraft:xp_orb', location: sender.location, maxDistance: distance }));} - for (const entity of entities) { + for (const entity of entities) entity.remove(); - } + sender.sendMessage({ translate: 'commands.cleanup.success', with: [entities.length.toString()] }); } \ No newline at end of file diff --git a/Canopy [BP]/scripts/src/commands/counter.js b/Canopy [BP]/scripts/src/commands/counter.js index 5c89fa7..e773d45 100644 --- a/Canopy [BP]/scripts/src/commands/counter.js +++ b/Canopy [BP]/scripts/src/commands/counter.js @@ -156,9 +156,9 @@ class CounterChannelMap { } resetAll() { - for (const color of this.colors) { + for (const color of this.colors) this.reset(color); - } + } setMode(color, mode) { @@ -168,8 +168,8 @@ class CounterChannelMap { } getQueryOutput(channel) { - let realtimeText = this.realtime ? 'realtime: ' : ''; - let message = { rawtext: [ + const realtimeText = this.realtime ? 'realtime: ' : ''; + const message = { rawtext: [ { translate: 'commands.counter.query.channel', with: [ formatColor(channel.color), realtimeText, @@ -177,9 +177,9 @@ class CounterChannelMap { String(channel.totalCount), Utils.calculatePerTime(channel.totalCount ,this.getDeltaTime(channel), channel.mode) ] }] }; - for (const item of Object.keys(channel.itemMap)) { + for (const item of Object.keys(channel.itemMap)) message.rawtext.push({ text: `\n §7- ${item}: ${getAllModeOutput(channel, item)}` }); - } + return message; } @@ -187,11 +187,11 @@ class CounterChannelMap { const msPerTick = 50.0; let deltaTime; - if (this.realtime) { + if (this.realtime) deltaTime = (Date.now() - channel.startRealTime) / msPerTick; - } else { + else deltaTime = system.currentTick - channel.startTickTime; - } + deltaTime = Math.floor(deltaTime / 8) * 8; return deltaTime; } @@ -262,9 +262,9 @@ function updateCount(channel) { function counterCommand(sender, args) { const { argOne, argTwo } = args; - if (argOne !== null && !channelMap.colors.includes(argOne) && argOne !== 'reset' && argOne !== 'realtime' && argOne !== 'all' && validModes.includes(argTwo)) { + if (argOne !== null && !channelMap.colors.includes(argOne) && argOne !== 'reset' && argOne !== 'realtime' && argOne !== 'all' && validModes.includes(argTwo)) return sender.sendMessage({ translate: 'commands.counter.channel.notfound', with: [argOne] }); - } + if (argOne === 'reset') resetAll(sender); @@ -322,7 +322,7 @@ function queryAll(sender) { message.rawtext.push({ rawtext: [channelMap.getQueryOutput(channel), { text: '\n' }] }); }); - if (message == { rawtext: [] }) + if (message.rawtext.length === 0) message = { translate: 'commands.counter.query.empty' }; sender?.sendMessage(message); } @@ -381,7 +381,7 @@ function getModeOutput(channel) { function getAllModeOutput(channel, item) { let output = ''; - let rateModes = validModes.filter(mode => mode !== 'countMode'); + const rateModes = validModes.filter(mode => mode !== 'countMode'); if (channel.mode === 'countMode') output += `${Utils.getColorCode(channel.color)}${channel.itemMap[item]}`; @@ -405,12 +405,12 @@ export function getInfoDisplayOutput() { let hopperCounterOutput; if (activeChannels?.length === 0) return ''; - if (activeChannels.length <= 4) { + if (activeChannels.length <= 4) output += 'Counters: '; - } + for (let i = 0; i < activeChannels.length; i++) { const color = activeChannels[i]; - if (i != 0 && (i % 4) == 0) + if (i !== 0 && (i % 4) === 0) output += '\n'; const channel = channelMap.getChannel(color); if (channel.hopperList.length === 0) { @@ -425,9 +425,9 @@ export function getInfoDisplayOutput() { } export function resetCounterMap() { - for (const color in channelMap.colors) { + for (const color in channelMap.colors) channelMap.removeChannel(color); - } + } export { channelMap, formatColor, query, queryAll }; \ No newline at end of file diff --git a/Canopy [BP]/scripts/src/commands/data.js b/Canopy [BP]/scripts/src/commands/data.js index fa215ed..accfaec 100644 --- a/Canopy [BP]/scripts/src/commands/data.js +++ b/Canopy [BP]/scripts/src/commands/data.js @@ -17,27 +17,33 @@ new Command({ function dataCommand(sender, args) { const targetId = args.id; - if (targetId !== null) { - const entity = world.getEntity(String(targetId)); - if (entity) - sender.sendMessage(formatEntityOutput(entity)); - else - sender.sendMessage({ translate: 'commands.data.notarget.id', with: [targetId] }); - } else { - const blockRayResult = sender.getBlockFromViewDirection({ includeLiquidBlocks: true, includePassableBlocks: true, maxDistance: 7 }); - const entityRayResult = sender.getEntitiesFromViewDirection({ ignoreBlockCollision: false, includeLiquidBlocks: false, includePassableBlocks: true, maxDistance: 7 }); - const block = blockRayResult?.block; - const entity = entityRayResult[0]?.entity; - if (!block && !entity) - return sender.sendMessage({ translate: 'generic.target.notfound' }); - - let output; - if (entity) - output = formatEntityOutput(entity); - else if (block) - output = formatBlockOutput(block); - sender.sendMessage(output); - } + let message; + if (targetId === null) + message = getTargetedMessage(sender); + else + message = getIdentifierMessage(targetId); + sender.sendMessage(message); +} + +function getTargetedMessage(sender) { + const blockRayResult = sender.getBlockFromViewDirection({ includeLiquidBlocks: true, includePassableBlocks: true, maxDistance: 7 }); + const entityRayResult = sender.getEntitiesFromViewDirection({ ignoreBlockCollision: false, includeLiquidBlocks: false, includePassableBlocks: true, maxDistance: 7 }); + const block = blockRayResult?.block; + const entity = entityRayResult[0]?.entity; + if (!block && !entity) + return sender.sendMessage({ translate: 'generic.target.notfound' }); + + if (entity) + return formatEntityOutput(entity); + else if (block) + return formatBlockOutput(block); +} + +function getIdentifierMessage(targetId) { + const entity = world.getEntity(String(targetId)); + if (entity) + return formatEntityOutput(entity); + return { translate: 'commands.data.notarget.id', with: [targetId] }; } function formatBlockOutput(block) { @@ -94,7 +100,7 @@ function formatEntityOutput(entity) { function formatProperties(target) { let output = ''; - for (let key in target) { + for (const key in target) { try { let value = target[key]; if (typeof value === 'function') @@ -115,7 +121,7 @@ function formatProperties(target) { } function tryGetBlockComponents(target) { - let components = []; + const components = []; for (const componentType of BLOCK_COMPONENTS) { try { @@ -133,15 +139,15 @@ function formatComponents(target, components) { if (components.length === 0) return 'none'; let output = ''; - for (const component of components) { + for (const component of components) output += formatComponent(target, component); - } + return output; } function formatComponent(target, component) { let output = ''; - for (let key in component) { + for (const key in component) { try { let value = component[key]; if (typeof value === 'function') @@ -163,13 +169,13 @@ function formatComponent(target, component) { function formatObject(target, object) { let output = ''; - for (let key in object) { + for (const key in object) { try { if (typeof object[key] === 'function') continue; - let value = object[key]; - if (typeof value === 'object') { + const value = object[key]; + if (typeof value === 'object') formatObject(target, value); - } + output += `${key}=${JSON.stringify(value)}, `; } catch(error) { console.warn(error); diff --git a/Canopy [BP]/scripts/src/commands/distance.js b/Canopy [BP]/scripts/src/commands/distance.js index 6e3dedd..ba002b0 100644 --- a/Canopy [BP]/scripts/src/commands/distance.js +++ b/Canopy [BP]/scripts/src/commands/distance.js @@ -47,20 +47,19 @@ new Command({ function distanceCommand(sender, args) { const { actionArgOne, actionArgTwo } = args; - let output = ''; - + + let message; if (actionArgOne === 'from' && actionArgTwo !== 'to') - output = trySaveLocation(sender, args); + message = trySaveLocation(sender, args); else if (actionArgOne === 'to') - output = tryCalculateDistanceFromSave(sender, args); + message = tryCalculateDistanceFromSave(sender, args); else if (actionArgOne === 'from' && actionArgTwo === 'to') - output = tryCalculateDistance(sender, args); + message = tryCalculateDistance(sender, args); else if (actionArgOne === 'target') - output = targetDistance(sender, args); + message = targetDistance(sender, args); else - output = { translate: 'commands.generic.usage', with: [cmd.getUsage()] }; - - sender.sendMessage(output); + message = { translate: 'commands.generic.usage', with: [cmd.getUsage()] }; + sender.sendMessage(message); } function trySaveLocation(sender, args) { @@ -77,13 +76,12 @@ function trySaveLocation(sender, args) { function tryCalculateDistanceFromSave(sender, args) { const { fromArgX, fromArgY, fromArgZ } = args; - let fromLocation; - let toLocation; - + if (!hasSavedLocation() || (savedLocation.x === null && savedLocation.y === null && savedLocation.z === null)) return { translate: 'commands.distance.to.fail.nosave', with: [Command.prefix] }; - fromLocation = savedLocation; - + const fromLocation = savedLocation; + + let toLocation; if (areDefined(fromArgX, fromArgY, fromArgZ)) toLocation = { x: fromArgX, y: fromArgY, z: fromArgZ }; else if (areUndefined(fromArgX, fromArgY, fromArgZ)) @@ -114,7 +112,7 @@ function tryCalculateDistance(sender, args) { } function targetDistance(sender) { - let playerLocation = sender.getHeadLocation(); + const playerLocation = sender.getHeadLocation(); let targetLocation; const { blockRayResult, entityRayResult } = Utils.getRaycastResults(sender, MAX_DISTANCE); diff --git a/Canopy [BP]/scripts/src/commands/entitydensity.js b/Canopy [BP]/scripts/src/commands/entitydensity.js index 2a71f85..6fc4e9f 100644 --- a/Canopy [BP]/scripts/src/commands/entitydensity.js +++ b/Canopy [BP]/scripts/src/commands/entitydensity.js @@ -16,7 +16,8 @@ const cmd = new Command({ }); function entityDensityCommand(sender, args) { - let { firstArg, gridSize } = args; + const firstArg = args.firstArg; + let gridSize = args.gridSize; if (firstArg === null) return cmd.sendUsage(sender); const { validDimensionId, parsedGridSize, hasNoErrors } = parseArgs(sender, firstArg, gridSize); diff --git a/Canopy [BP]/scripts/src/commands/generator.js b/Canopy [BP]/scripts/src/commands/generator.js index 3b8f885..1d9978a 100644 --- a/Canopy [BP]/scripts/src/commands/generator.js +++ b/Canopy [BP]/scripts/src/commands/generator.js @@ -91,13 +91,13 @@ function generateItems(channel) { if (!hopper) continue; const hopperContainer = hopper.getComponent('minecraft:inventory').container; const itemStack = hopperContainer?.getItem(0); - if (!itemStack) { + if (itemStack) { + hopperGenerator.outputItemType = itemStack.typeId; + } else { if (hopperGenerator.outputItemType === null) continue; hopperContainer.setItem(0, new ItemStack(hopperGenerator.outputItemType)); generatedItems.push(hopperGenerator.outputItemType); - } else { - hopperGenerator.outputItemType = itemStack.typeId; } } return generatedItems; @@ -114,9 +114,9 @@ function updateCount(channel, generatedItems) { function generatorCommand(sender, args) { const { argOne, argTwo } = args; - if (argOne !== null && !channelMap.colors.includes(argOne) && argOne !== 'reset' && argOne !== 'realtime' && argOne !== 'all') { + if (argOne !== null && !channelMap.colors.includes(argOne) && argOne !== 'reset' && argOne !== 'realtime' && argOne !== 'all') return sender.sendMessage({ translate: 'commands.generator.channel.notfound', with: [argOne] }); - } + if (argOne === 'reset') resetAll(sender); @@ -170,7 +170,7 @@ function queryAll(sender) { message.rawtext.push({ rawtext: [channelMap.getQueryOutput(channel), { text: '\n' }] }); }); - if (message == { rawtext: [] }) + if (message.rawtext.length === 0) message = { translate: 'commands.generator.query.empty' }; sender?.sendMessage(message); } @@ -181,7 +181,7 @@ function formatColor(color) { function getAllModeOutput(channel, item) { let output = ''; - let rateModes = ['perhourMode', 'perminuteMode', 'persecondMode']; + const rateModes = ['perhourMode', 'perminuteMode', 'persecondMode']; output += `${Utils.getColorCode(channel.color)}${channel.itemMap[item]}`; for (let i = 0; i < rateModes.length; i++) { @@ -194,9 +194,9 @@ function getAllModeOutput(channel, item) { } export function resetGeneratorMap() { - for (const color in channelMap.colors) { + for (const color in channelMap.colors) channelMap.removeChannel(color); - } + } export { channelMap, formatColor, query, queryAll, getAllModeOutput }; \ No newline at end of file diff --git a/Canopy [BP]/scripts/src/commands/health.js b/Canopy [BP]/scripts/src/commands/health.js index 1ee48e4..04d6574 100644 --- a/Canopy [BP]/scripts/src/commands/health.js +++ b/Canopy [BP]/scripts/src/commands/health.js @@ -21,18 +21,13 @@ function healthCommand(sender) { } function printRealMspt(sender) { - let lastTick; - let startTime; - let endTime; - let realMspt; - - lastTick = system.currentTick; - ({ startTime, endTime } = Utils.wait(50)); + const lastTick = system.currentTick; + const { startTime, endTime } = Utils.wait(50); system.runTimeout(() => { - if (system.currentTick - lastTick != 1) + if (system.currentTick - lastTick !== 1) return sender.sendMessage({ translate: 'commands.health.fail.mspt' }); - realMspt = Date.now() - startTime - (endTime - startTime); + const realMspt = Date.now() - startTime - (endTime - startTime); const realMsptFormatted = realMspt > 50.0 ? `§c${realMspt}` : `§a${realMspt}`; sender.sendMessage(`§7MSPT:§r ${realMsptFormatted}`) }, 1); diff --git a/Canopy [BP]/scripts/src/commands/help.js b/Canopy [BP]/scripts/src/commands/help.js index ff07a8e..5d7c0a1 100644 --- a/Canopy [BP]/scripts/src/commands/help.js +++ b/Canopy [BP]/scripts/src/commands/help.js @@ -1,8 +1,6 @@ -import { Commands, Command, Rule, InfoDisplayRule, Extensions } from 'lib/canopy/Canopy'; -import { HelpBook, CommandHelpPage, RuleHelpPage, InfoDisplayRuleHelpPage } from 'lib/canopy/Canopy'; +import { Commands, Command, Rule, InfoDisplayRule, Extensions, HelpBook, CommandHelpPage, RuleHelpPage, InfoDisplayRuleHelpPage } from '../../lib/canopy/Canopy'; const COMMANDS_PER_PAGE = 8; -const helpBook = new HelpBook(); new Command({ name: 'help', @@ -15,6 +13,7 @@ new Command({ }); function helpCommand(sender, args) { + const helpBook = new HelpBook(); populateNativeCommandPages(helpBook); populateNativeRulePages(helpBook, sender); populateExtensionPages(helpBook); @@ -48,16 +47,16 @@ function populateNativeRulePages(helpBook, player) { const infoDisplayPage = new InfoDisplayRuleHelpPage('InfoDisplay', { translate: 'commands.help.infodisplay' }, Commands.getPrefix() + 'info '); const infoDisplayRules = InfoDisplayRule.getRules(); helpBook.newPage(infoDisplayPage); - for (let infoDisplayRule of infoDisplayRules) { + for (const infoDisplayRule of infoDisplayRules) helpBook.addEntry(infoDisplayRule.getCategory(), infoDisplayRule, player); - } + const rulesPage = new RuleHelpPage('Rules', { translate: 'commands.help.rules' }, Commands.getPrefix() + 'canopy '); const globalRules = Rule.getRulesByCategory('Rules'); helpBook.newPage(rulesPage); - for (let rule of globalRules) { + for (const rule of globalRules) helpBook.addEntry(rule.getCategory(), rule); - } + } function populateExtensionPages(helpBook) { @@ -72,9 +71,9 @@ function populateExtensionRulePages(helpBook) { if (rules.length > 0) { const rulePage = new RuleHelpPage(`Rules`, { translate: 'commands.help.extension.rules', with: [extension.getName()] }, Commands.getPrefix() + `canopy `, extension.getName()); helpBook.newPage(rulePage); - for (let rule of rules) { + for (const rule of rules) helpBook.addEntry(rulePage.title, rule); - } + } } } @@ -86,9 +85,9 @@ function populateExtensionCommandPages(helpBook) { if (commands.length > 0) { const commandPage = new CommandHelpPage(`Commands`, { translate: 'commands.help.extension.commands', with: [extension.getName()] }, extension.getName()); helpBook.newPage(commandPage); - for (let command of commands) { + for (const command of commands) helpBook.addEntry(commandPage.title, command); - } + } } } diff --git a/Canopy [BP]/scripts/src/commands/info.js b/Canopy [BP]/scripts/src/commands/info.js index 14981b6..1b5f9d8 100644 --- a/Canopy [BP]/scripts/src/commands/info.js +++ b/Canopy [BP]/scripts/src/commands/info.js @@ -33,9 +33,9 @@ function infoCommand(sender, args) { return; } - if (!InfoDisplayRule.exists(ruleID)) { + if (!InfoDisplayRule.exists(ruleID)) return sender.sendMessage({ rawtext: [ { translate: 'rules.generic.unknown', with: [ruleID, Commands.getPrefix()] }, { text: '§r§7.' } ] }); - } + if (!(InfoDisplayRule.getRule(ruleID) instanceof InfoDisplayRule)) return sender.sendMessage({ translate: 'commands.info.canopyRule', with: [ruleID, Command.getPrefix()] }); @@ -56,19 +56,19 @@ function infoCommand(sender, args) { clearInfoDisplay(sender); const rule = InfoDisplayRule.getRule(ruleID); - if (!enable) - updateRules(sender, rule.getDependentRuleIDs(), enable); - else + if (enable) updateRules(sender, rule.getContigentRuleIDs(), enable); + else + updateRules(sender, rule.getDependentRuleIDs(), enable); updateRules(sender, rule.getIndependentRuleIDs(), !enable); - updateRule(sender, ruleID, ruleValue, enable); + updateRule(sender, ruleID, enable); } function changeAll(sender, enable) { - for (let entry of InfoDisplayRule.getRules()) { + for (const entry of InfoDisplayRule.getRules()) entry.setValue(sender, enable); - } + if (!enable) clearInfoDisplay(sender); const enabledRawText = enable ? { translate: 'rules.generic.enabled' } : { translate: 'rules.generic.disabled' }; sender.sendMessage({ rawtext: [ { translate: 'commands.info.allupdated' }, enabledRawText, { text: '§r§7.' } ] }); @@ -78,7 +78,8 @@ function clearInfoDisplay(sender) { sender.onScreenDisplay.setTitle(''); } -function updateRule(sender, ruleID, ruleValue, enable) { +function updateRule(sender, ruleID, enable) { + const ruleValue = InfoDisplayRule.getValue(sender, ruleID); if (ruleValue === enable) return; InfoDisplayRule.setValue(sender, ruleID, enable); const enabledRawText = enable ? { translate: 'rules.generic.enabled' } : { translate: 'rules.generic.disabled' }; @@ -86,7 +87,6 @@ function updateRule(sender, ruleID, ruleValue, enable) { } function updateRules(sender, ruleIDs, enable) { - for (const ruleID of ruleIDs) { - updateRule(sender, ruleID, InfoDisplayRule.getValue(sender, ruleID), enable); - } + for (const ruleID of ruleIDs) + updateRule(sender, ruleID, enable); } diff --git a/Canopy [BP]/scripts/src/commands/jump.js b/Canopy [BP]/scripts/src/commands/jump.js index 557b92c..b6c924b 100644 --- a/Canopy [BP]/scripts/src/commands/jump.js +++ b/Canopy [BP]/scripts/src/commands/jump.js @@ -22,26 +22,31 @@ new Command({ }) async function jumpCommand(sender) { - let blockRayResult; - let maxDistance = 64*16; - let jumpLocation; if (!await Rule.getValue('commandJumpSurvival') && sender.getGameMode() === 'survival') return sender.sendMessage({ translate: 'rules.generic.blocked', with: ['commandJumpSurvival'] }); - - blockRayResult = sender.getBlockFromViewDirection({ includeLiquidBlocks: false, includePassableBlocks: true, maxDistance: maxDistance }); + + const blockRayResult = sender.getBlockFromViewDirection({ includeLiquidBlocks: false, includePassableBlocks: true, maxDistance: 64*16 }); if (!blockRayResult?.block) return sender.sendMessage({ translate: 'commands.jump.fail.noblock' }); - jumpLocation = getBlockLocationFromFace(blockRayResult.block, blockRayResult.face); + const jumpLocation = getBlockLocationFromFace(blockRayResult.block, blockRayResult.face); sender.teleport(jumpLocation); } function getBlockLocationFromFace(block, face) { switch(face) { - case 'Up': return { x: block.x, y: block.y + 1, z: block.z}; - case 'Down': return { x: block.x, y: block.y - 2, z: block.z}; - case 'North': return { x: block.x, y: block.y, z: block.z - 1}; - case 'South': return { x: block.x, y: block.y, z: block.z + 1}; - case 'East': return { x: block.x + 1, y: block.y, z: block.z}; - case 'West': return { x: block.x - 1, y: block.y, z: block.z}; + case 'Up': + return { x: block.x, y: block.y + 1, z: block.z}; + case 'Down': + return { x: block.x, y: block.y - 2, z: block.z}; + case 'North': + return { x: block.x, y: block.y, z: block.z - 1}; + case 'South': + return { x: block.x, y: block.y, z: block.z + 1}; + case 'East': + return { x: block.x + 1, y: block.y, z: block.z}; + case 'West': + return { x: block.x - 1, y: block.y, z: block.z}; + default: + throw new Error('Invalid face'); } } \ No newline at end of file diff --git a/Canopy [BP]/scripts/src/commands/log.js b/Canopy [BP]/scripts/src/commands/log.js index 035b98a..d8ed263 100644 --- a/Canopy [BP]/scripts/src/commands/log.js +++ b/Canopy [BP]/scripts/src/commands/log.js @@ -28,7 +28,7 @@ class LoggingPlayer { } removeType(type) { - this.types = this.types.filter(t => t != type); + this.types = this.types.filter(t => t !== type); } } @@ -47,7 +47,7 @@ class LoggingPlayers { } get(player) { - return this.playerList.find(loggingPlayer => loggingPlayer.player.id == player.id); + return this.playerList.find(loggingPlayer => loggingPlayer.player.id === player.id); } includes(player) { @@ -73,14 +73,14 @@ class TypeLog { for (const dimensionId of ['overworld', 'nether', 'the_end']) { const dimEntities = world.getDimension(dimensionId).getEntities(); for (const entity of dimEntities) { - if (hasTrait(entity, this.logType)) { + if (hasTrait(entity, this.logType)) this.thisTickEntities.push(entity); - } + } } - for (const entity of this.thisTickEntities) { + for (const entity of this.thisTickEntities) if (this.hasMovedSinceLastTick(entity)) this.movingEntities.push(entity); - } + } updateLastTickEntities() { @@ -96,12 +96,12 @@ class TypeLog { } hasMovedSinceLastTick(entity) { - const lastTickEntity = this.lastTickEntities.find(lastTickEntity => - lastTickEntity.id === entity.id && - lastTickEntity.location.x === entity.location.x && - lastTickEntity.location.y === entity.location.y && - lastTickEntity.location.z === entity.location.z && - lastTickEntity.dimension.id === entity.dimension.id + const lastTickEntity = this.lastTickEntities.find(e => + e.id === entity.id && + e.location.x === entity.location.x && + e.location.y === entity.location.y && + e.location.z === entity.location.z && + e.dimension.id === entity.dimension.id ); return lastTickEntity === undefined; } @@ -109,9 +109,9 @@ class TypeLog { printLogBody(player, precision) { const formattedTypeMap = this.createFormattedTypeMap(precision); let output = ''; - for (const typeId of Object.keys(formattedTypeMap)) { + for (const typeId of Object.keys(formattedTypeMap)) output += `${TERTIARY_COLOR}${typeId}\n${MAIN_COLOR} - ${formattedTypeMap[typeId].join(', ')}\n`; - } + player.sendMessage(output); } @@ -128,40 +128,43 @@ class TypeLog { const x = entity.location.x.toFixed(precision); const y = entity.location.y.toFixed(precision); const z = entity.location.z.toFixed(precision); - const lastTickEntity = this.lastTickEntities.find(lastTickEntity => lastTickEntity.id === entity.id); - if (lastTickEntity === undefined) return `${MAIN_COLOR}[${x}, ${y}, ${z}]`; - const xColor = lastTickEntity.location.x !== entity.location.x ? SECONDARY_COLOR : MAIN_COLOR; - const yColor = lastTickEntity.location.y !== entity.location.y ? SECONDARY_COLOR : MAIN_COLOR; - const zColor = lastTickEntity.location.z !== entity.location.z ? SECONDARY_COLOR : MAIN_COLOR; + const lastTickEntity = this.lastTickEntities.find(e => e.id === entity.id); + if (lastTickEntity === undefined) + return `${MAIN_COLOR}[${x}, ${y}, ${z}]`; + const xColor = lastTickEntity.location.x === entity.location.x ? MAIN_COLOR : SECONDARY_COLOR; + const yColor = lastTickEntity.location.y === entity.location.y ? MAIN_COLOR : SECONDARY_COLOR; + const zColor = lastTickEntity.location.z === entity.location.z ? MAIN_COLOR : SECONDARY_COLOR; return `${MAIN_COLOR}[${xColor}${x}${MAIN_COLOR}, ${yColor}${y}${MAIN_COLOR}, ${zColor}${z}${MAIN_COLOR}]`; } } function hasTrait(entity, logType) { - if (logType === 'projectiles') return entity.getComponent('minecraft:projectile') !== undefined; - if (logType === 'falling_blocks') return entity.typeId === 'minecraft:falling_block'; + if (logType === 'projectiles') + return entity.getComponent('minecraft:projectile') !== undefined; + if (logType === 'falling_blocks') + return entity.typeId === 'minecraft:falling_block'; } const loggingPlayers = new LoggingPlayers(); const projectileLog = new TypeLog('projectiles'); const fallingBlockLog = new TypeLog('falling_blocks'); let logStartTick = system.currentTick; -let activeTntLocations = {}; +const activeTntLocations = {}; world.afterEvents.entitySpawn.subscribe((event) => { const entity = event.entity; - if (entity.typeId === 'minecraft:tnt') { + if (entity.typeId === 'minecraft:tnt') activeTntLocations[entity.id] = entity.location; - } + }); world.beforeEvents.entityRemove.subscribe((event) => { const removedEntity = event.removedEntity; if (removedEntity?.typeId === 'minecraft:tnt') { loggingPlayers.forEach(loggingPlayer => { - if (loggingPlayer.types.includes('tnt')) { + if (loggingPlayer.types.includes('tnt')) printTntLog(loggingPlayer.player, removedEntity); - } + }); } }); @@ -189,12 +192,12 @@ function logUpdate(loggingPlayer) { const player = loggingPlayer.player; const precision = player.getDynamicProperty('logPrecision'); - if (loggingPlayer.types.includes('projectiles')) { + if (loggingPlayer.types.includes('projectiles')) projectileLog.update(); - } - if (loggingPlayer.types.includes('falling_blocks')) { + + if (loggingPlayer.types.includes('falling_blocks')) fallingBlockLog.update(); - } + if (projectileLog.movingEntities.length === 0 && fallingBlockLog.movingEntities.length === 0) logStartTick = system.currentTick; if (projectileLog.movingEntities.length > 0 || fallingBlockLog.movingEntities.length > 0) @@ -217,7 +220,7 @@ function getLogHeader(movingEntities) { } function logCommand(sender, args) { - let { type, precision } = args; + const { type, precision } = args; if (sender.getDynamicProperty('logPrecision') === undefined) sender.setDynamicProperty('logPrecision', 3); if (precision !== null) setLogPrecsion(sender, precision); @@ -238,7 +241,7 @@ function toggleLogging(sender, type) { if (!loggingPlayers.includes(sender)) loggingPlayers.add(sender); const loggingPlayer = loggingPlayers.get(sender); - let output = ''; + let output; if (loggingPlayer.types.includes(type)) { loggingPlayer.removeType(type); output = { translate: 'commands.log.stopped', with: [type] }; diff --git a/Canopy [BP]/scripts/src/commands/peek.js b/Canopy [BP]/scripts/src/commands/peek.js index 66645f5..620c2f4 100644 --- a/Canopy [BP]/scripts/src/commands/peek.js +++ b/Canopy [BP]/scripts/src/commands/peek.js @@ -15,39 +15,59 @@ new Command({ }) function peekCommand(sender, args) { - let { itemQuery } = args; - let blockRayResult; - let entityRayResult; - let target; - let inventory; - let items = {}; - let targetName; - + const { itemQuery } = args; + updateQueryMap(sender, itemQuery); - ({blockRayResult, entityRayResult} = Utils.getRaycastResults(sender, MAX_DISTANCE)); + const target = getTarget(sender); + if (!target) return; + const inventory = getInventory(sender, target); + if (!inventory) return; + const items = Utils.populateItems(inventory); + sender.sendMessage(formatOutput(target, items, itemQuery)); +} + +function updateQueryMap(sender, itemQuery) { + const oldQuery = currentQuery[sender.name]; + if ([null, undefined].includes(oldQuery) && itemQuery === null) {return;} + else if (itemQuery === null && ![null, undefined].includes(oldQuery)) { + currentQuery[sender.name] = null; + return sender.sendMessage({ translate: 'commands.peek.query.cleared' }); + } + currentQuery[sender.name] = itemQuery; + sender.sendMessage({ translate: 'commands.peek.query.set', with: [itemQuery] }); +} + +function getTarget(sender) { + const {blockRayResult, entityRayResult} = Utils.getRaycastResults(sender, MAX_DISTANCE); if (!blockRayResult && !entityRayResult[0]) return sender.sendMessage({ translate: 'generic.target.notfound' }); - target = Utils.getClosestTarget(sender, blockRayResult, entityRayResult); - targetName = Utils.parseName(target); + const targetEntity = Utils.getClosestTarget(sender, blockRayResult, entityRayResult); + const targetData = { + name: Utils.parseName(targetEntity), + entity: targetEntity, + }; + return targetData; +} + +function getInventory(sender, target) { + let inventory; try { - inventory = target.getComponent('inventory'); + inventory = target.entity.getComponent('inventory'); } catch { - return sender.sendMessage({ translate: 'commands.peek.fail.unloaded', with: [Utils.stringifyLocation(target.location, 0)] }); + return sender.sendMessage({ translate: 'commands.peek.fail.unloaded', with: [Utils.stringifyLocation(target.entity.location, 0)] }); } if (!inventory) - return sender.sendMessage({ translate: 'commands.peek.fail.noinventory', with: [targetName, Utils.stringifyLocation(target.location, 0)] }); - - items = Utils.populateItems(inventory); - sender.sendMessage(formatOutput(targetName, target.location, items, itemQuery)); + return sender.sendMessage({ translate: 'commands.peek.fail.noinventory', with: [target.name, Utils.stringifyLocation(target.entity.location, 0)] }); + return inventory; } -function formatOutput(targetName, targetLocation, items, itemQuery) { +function formatOutput(target, items, itemQuery) { if (Object.keys(items).length === 0) - return { translate: 'commands.peek.fail.noitems', with: [targetName, Utils.stringifyLocation(targetLocation, 0)] }; + return { translate: 'commands.peek.fail.noitems', with: [target.name, Utils.stringifyLocation(target.entity.location, 0)] }; let output = '§g-------------\n'; - output += `§l§e${targetName}§r: ${Utils.stringifyLocation(targetLocation, 0)}`; - for (let itemName in items) { + output += `§l§e${target.name}§r: ${Utils.stringifyLocation(target.entity.location, 0)}`; + for (const itemName in items) { if (itemQuery && itemName.includes(itemQuery)) output += `\n§c${itemName}§r: ${items[itemName]}`; else @@ -57,16 +77,4 @@ function formatOutput(targetName, targetLocation, items, itemQuery) { return output; } -function updateQueryMap(sender, itemQuery) { - const oldQuery = currentQuery[sender.name]; - if ([null, undefined].includes(oldQuery) && itemQuery === null) return; - else if (itemQuery === null && ![null, undefined].includes(oldQuery)) { - currentQuery[sender.name] = null; - return sender.sendMessage({ translate: 'commands.peek.query.cleared' }); - } else { - currentQuery[sender.name] = itemQuery; - sender.sendMessage({ translate: 'commands.peek.query.set', with: [itemQuery] }); - } -} - export { currentQuery }; diff --git a/Canopy [BP]/scripts/src/commands/pos.js b/Canopy [BP]/scripts/src/commands/pos.js index 78c18f2..605ddef 100644 --- a/Canopy [BP]/scripts/src/commands/pos.js +++ b/Canopy [BP]/scripts/src/commands/pos.js @@ -27,24 +27,31 @@ function posCommand(sender, args) { if (!target) return sender.sendMessage({ translate: 'generic.player.notfound', with: [player] }); - let output = `§a${player !== null ? `${target.name}'s` : 'Your'} position: §f${Utils.stringifyLocation(target.location, 2)}`; - output += `\n§7Dimension: §f${Utils.getColoredDimensionName(target.dimension.id)}`; - if (target.dimension.id === 'minecraft:nether') - output += `\n§7Relative Overworld position: §a${Utils.stringifyLocation(netherPosToOverworld(target.location), 2)}`; - else if (target.dimension.id === 'minecraft:overworld') - output += `\n§7Relative Nether position: §c${Utils.stringifyLocation(overworldPosToNether(target.location), 2)}`; - sender.sendMessage(output); - - const message = { rawtext: [] } - if (player !== null) - message.rawtext.push({ translate: 'commands.pos.other', with: [target.name, Utils.stringifyLocation(target.location, 2)] }); - else - message.rawtext.push({ translate: 'commands.pos.self', with: [Utils.stringifyLocation(target.location, 2)] }); - message.rawtext.push({ translate: 'commands.pos.dimension', with: [Utils.getColoredDimensionName(netherPosToOverworld(target.location), 2)] }); + const message = { + rawtext: [ + getPositionText(player, target), + getDimensionText(target), + getRelativeDimensionPositionText(target) + ] + }; + sender.sendMessage(message); +} + +function getPositionText(player, target) { + if (player === null) + return { translate: 'commands.pos.self', with: [Utils.stringifyLocation(target.location, 2)] }; + return { translate: 'commands.pos.other', with: [target.name, Utils.stringifyLocation(target.location, 2)] }; +} + +function getDimensionText(target) { + return { translate: 'commands.pos.dimension', with: [Utils.getColoredDimensionName(target.dimension.id)] }; +} + +function getRelativeDimensionPositionText(target) { if (target.dimension.id === 'minecraft:nether') - message.rawtext.push({ translate: 'commands.pos.relative.overworld', with: [Utils.stringifyLocation(netherPosToOverworld(target.location), 2)] }); + return { translate: 'commands.pos.relative.overworld', with: [Utils.stringifyLocation(netherPosToOverworld(target.location), 2)] }; else if (target.dimension.id === 'minecraft:overworld') - message.rawtext.push({ translate: 'commands.pos.relative.nether', with: [Utils.stringifyLocation(overworldPosToNether(target.location), 2)]}); + return { translate: 'commands.pos.relative.nether', with: [Utils.stringifyLocation(overworldPosToNether(target.location), 2)] }; } function netherPosToOverworld(pos) { diff --git a/Canopy [BP]/scripts/src/commands/removeentity.js b/Canopy [BP]/scripts/src/commands/removeentity.js index db57f7a..30063d3 100644 --- a/Canopy [BP]/scripts/src/commands/removeentity.js +++ b/Canopy [BP]/scripts/src/commands/removeentity.js @@ -26,10 +26,10 @@ function removeEntityCommand(sender, args) { } else if (target) { target.remove(); sender.sendMessage({ translate: 'commands.removeentity.success', with: [target.typeId.replace('minecraft:', ''), target.id] }); - } else if (id !== null) { - sender.sendMessage({ translate: 'commands.removeentity.fail.noid', with: [String(id)] }); - } else { + } else if (id === null) { sender.sendMessage({ translate: 'generic.entity.notfound' }); + } else { + sender.sendMessage({ translate: 'commands.removeentity.fail.noid', with: [String(id)] }); } } diff --git a/Canopy [BP]/scripts/src/commands/scriptevents/loop.js b/Canopy [BP]/scripts/src/commands/scriptevents/loop.js index 387f836..50cad17 100644 --- a/Canopy [BP]/scripts/src/commands/scriptevents/loop.js +++ b/Canopy [BP]/scripts/src/commands/scriptevents/loop.js @@ -22,7 +22,7 @@ function loopCommand(times, command, runLocation) { if (!Utils.isNumeric(times)) return 'Invalid arguments. Usage: loop '; - for (let i = 0; i < times; i++) { + for (let i = 0; i < times; i++) runLocation.runCommand(command); - } + } diff --git a/Canopy [BP]/scripts/src/commands/scriptevents/tick.js b/Canopy [BP]/scripts/src/commands/scriptevents/tick.js index b16ea41..65cfca0 100644 --- a/Canopy [BP]/scripts/src/commands/scriptevents/tick.js +++ b/Canopy [BP]/scripts/src/commands/scriptevents/tick.js @@ -16,9 +16,9 @@ system.afterEvents.scriptEventReceive.subscribe((event) => { function tickSleep(sourceName, milliseconds) { if (milliseconds === null || milliseconds < 1) return; world.sendMessage({ translate: 'command.tick.sleep.success', with: [sourceName, String(milliseconds)] }); - let startTime = Date.now(); + const startTime = Date.now(); let waitTime = 0; - while (waitTime < milliseconds) { + while (waitTime < milliseconds) waitTime = Date.now() - startTime; - } + } \ No newline at end of file diff --git a/Canopy [BP]/scripts/src/commands/simmap.js b/Canopy [BP]/scripts/src/commands/simmap.js index 75d5283..b8860fc 100644 --- a/Canopy [BP]/scripts/src/commands/simmap.js +++ b/Canopy [BP]/scripts/src/commands/simmap.js @@ -38,28 +38,31 @@ const cmd = new Command({ }); function simmapCommand(sender, args) { - let { argOne, argTwo, argThree, argFour } = args; - if (argOne === 'display') { - handleInfoDisplayConfig(sender, argTwo, argThree, argFour); - } else { - handleChatCommand(sender, argOne, argTwo, argThree, argFour); - } + const { argOne } = args; + if (argOne === 'display') + handleInfoDisplayConfig(sender, args); + else + handleChatCommand(sender, args); + } -function handleInfoDisplayConfig(sender, argTwo, x, z) { +function handleInfoDisplayConfig(sender, args) { + const { argTwo, argThree: x, argFour: z } = args; if (Utils.isNumeric(argTwo) && (argTwo < 1 || argTwo > MAX_CHUNK_DISTANCE)) { sender.sendMessage({ translate: 'commands.simmap.invalidDistance', with: [String(argTwo), String(MAX_CHUNK_DISTANCE)] }); return; } - if (Utils.isNumeric(argTwo)) + if (Utils.isNumeric(argTwo)) { updateDistance(sender, argTwo); - else if (validDimensions[argTwo] && x !== null && z !== null) - updateLocation(sender, world.getDimension(validDimensions[argTwo]), x, z); - else if (argTwo === 'here') + } else if (validDimensions[argTwo] && x !== null && z !== null) { + const dimensionLocation = { dimension: validDimensions[argTwo], x, z }; + updateLocation(sender, dimensionLocation); + } else if (argTwo === 'here') { resetLocation(sender); - else + } else { return cmd.sendUsage(sender); + } } function updateDistance(sender, distance) { @@ -69,7 +72,8 @@ function updateDistance(sender, distance) { sender.sendMessage({ translate: 'commands.simmap.config.distance', with: [String(distance)] }); } -function updateLocation(sender, dimension, x, z) { +function updateLocation(sender, dimensionLocation) { + const { dimension, x, z } = dimensionLocation; const config = getConfig(sender); config.isLocked = true; config.dimension = dimension.id; @@ -88,9 +92,9 @@ function resetLocation(sender) { function getConfig(player) { const dynamicConfig = player.getDynamicProperty('simulationMapConfig'); - if (dynamicConfig) { + if (dynamicConfig) return JSON.parse(dynamicConfig); - } + const config = { isLocked: false, dimension: MinecraftDimensionTypes.overworld, @@ -101,28 +105,35 @@ function getConfig(player) { return config; } -function handleChatCommand(sender, argOne, argTwo, argThree, argFour) { +function handleChatCommand(sender, args) { + const { argOne, argTwo, argThree, argFour } = args; if (Utils.isNumeric(argOne) && (argOne < 1 || argOne > MAX_CHUNK_DISTANCE)) { sender.sendMessage({ translate: 'commands.simmap.invalidDistance', with: [String(argOne), String(MAX_CHUNK_DISTANCE)] }); return; } + const dimensionLocation = { dimension: sender.dimension, location: sender.location }; if (argOne === null) { - printLoadedChunks(sender, sender.dimension, sender.location, DEFAULT_CHUNK_DISTANCE); + printLoadedChunks(sender, dimensionLocation, DEFAULT_CHUNK_DISTANCE); } else if (Utils.isNumeric(argOne) && argTwo === null) { - printLoadedChunks(sender, sender.dimension, sender.location, argOne); + printLoadedChunks(sender, dimensionLocation, argOne); } else if (argOne !== null && argTwo !== null && argThree === null) { return cmd.sendUsage(sender); } else if (Utils.isNumeric(argOne) && argTwo !== null && argThree !== null && argFour !== null) { - printLoadedChunks(sender, world.getDimension(validDimensions[argTwo]), { x: argThree, z: argFour }, argOne); + dimensionLocation.dimension = world.getDimension(validDimensions[argTwo]); + dimensionLocation.location = { x: argThree, z: argFour }; + printLoadedChunks(sender, dimensionLocation, argOne); } else if (!Utils.isNumeric(argOne) && Utils.isNumeric(argTwo) && argThree !== null) { - printLoadedChunks(sender, world.getDimension(validDimensions[argOne]), { argTwo, x: argThree }, DEFAULT_CHUNK_DISTANCE); + dimensionLocation.dimension = world.getDimension(validDimensions[argOne]); + dimensionLocation.location = { x: argTwo, z: argThree }; + printLoadedChunks(sender, dimensionLocation, DEFAULT_CHUNK_DISTANCE); } else { return cmd.sendUsage(sender); } } -function printLoadedChunks(player, dimension, location, distance) { +function printLoadedChunks(player, dimensionLocation, distance) { + const { dimension, location } = dimensionLocation; const chunkLocation = coordsToChunkLocation(location); const dimensionChunkLocation = { dimension, ...chunkLocation }; const loadedChunks = getNearbyLoadedChunks(dimensionChunkLocation, distance); @@ -169,8 +180,7 @@ function isChunkLoaded(dimension, x, z) { } catch (error) { if (error.message === 'cannot read property \'typeId\' of undefined') return false; - else - throw error; + throw error; } } diff --git a/Canopy [BP]/scripts/src/commands/spawn.js b/Canopy [BP]/scripts/src/commands/spawn.js index 702dc84..53d9e3c 100644 --- a/Canopy [BP]/scripts/src/commands/spawn.js +++ b/Canopy [BP]/scripts/src/commands/spawn.js @@ -49,16 +49,18 @@ world.afterEvents.entitySpawn.subscribe(async (event) => { if (!isMocking || event.cause === 'Loaded' || !await Rule.getValue('commandSpawnMocking')) return; let shouldCancelSpawn = false; - for (const category in categoryToMobMap) { + for (const category in categoryToMobMap) if (categoryToMobMap[category].includes(event.entity.typeId.replace('minecraft:', ''))) shouldCancelSpawn = true; - } + if (shouldCancelSpawn && event.entity) event.entity.remove(); }); function spawnCommand(sender, args) { const { action, actionTwo, x1, y1, z1, x2, y2, z2 } = args; - const posOne = { x: x1, y: y1, z: z1 }; - const posTwo = { x: x2, y: y2, z: z2 }; + const area = { + posOne: { x: x1, y: y1, z: z1 }, + posTwo: { x: x2, y: y2, z: z2 } + }; if (action === 'entities') printAllEntities(sender); else if (action === 'mocking') handleMockingCmd(sender, actionTwo); @@ -66,9 +68,9 @@ function spawnCommand(sender, args) { else if (action === 'recent') recentSpawns(sender, actionTwo); else if (action === 'tracking' && actionTwo === null) printTrackingStatus(sender); else if (action === 'tracking' && actionTwo !== null && x1 !== null && z2 === null) sender.sendMessage({ translate: 'commands.generic.usage', with: [`${Command.prefix}spawn tracking [x1 y1 z1] [x2 y2 z2]`] }); - else if (action === 'tracking' && actionTwo === 'start') startTracking(sender, posOne, posTwo); + else if (action === 'tracking' && actionTwo === 'start') startTracking(sender, area); else if (action === 'tracking' && actionTwo === 'stop') stopTracking(sender); - else if (action === 'tracking' && actionTwo !== null) trackMob(sender, actionTwo, posOne, posTwo); + else if (action === 'tracking' && actionTwo !== null) trackMob(sender, actionTwo, area); else return cmd.sendUsage(sender); } @@ -125,7 +127,8 @@ function printTrackingStatus(sender) { sender.sendMessage(worldSpawns.getOutput()); } -function startTracking(sender, posOne, posTwo) { +function startTracking(sender, area) { + const { posOne, posTwo } = area; if (worldSpawns !== null) return sender.sendMessage({ translate: 'commands.spawn.tracking.already' }); if (!isLocationNull(posOne) && !isLocationNull(posTwo)) @@ -152,11 +155,12 @@ function stopTracking(sender) { Utils.broadcastActionBar({ translate: 'commands.spawn.tracking.stop.actionbar', with: [sender.name] }, sender); } -function trackMob(sender, mobName, posOne, posTwo) { +function trackMob(sender, mobName, area) { + const { posOne, posTwo } = area; let isTrackable = false; - for (const category in categoryToMobMap) { + for (const category in categoryToMobMap) if (categoryToMobMap[category].includes(mobName)) isTrackable = true; - } + if (!isTrackable) return sender.sendMessage({ translate: 'commands.spawn.tracking.mob.invalid', with: [String(mobName)] }); if (!currMobIds.includes(mobName)) diff --git a/Canopy [BP]/scripts/src/commands/tick.js b/Canopy [BP]/scripts/src/commands/tick.js index bf62e7c..9e943ff 100644 --- a/Canopy [BP]/scripts/src/commands/tick.js +++ b/Canopy [BP]/scripts/src/commands/tick.js @@ -33,7 +33,7 @@ let shouldStep = 0; system.runInterval(() => { if (shouldStep > 0) { shouldStep--; - if (shouldStep == 0) + if (shouldStep === 0) world.sendMessage({ translate: 'commands.tick.step.done' }); return; } @@ -53,8 +53,7 @@ function tickCommand(sender, args) { return tickSleep(sender, steps); else if (Utils.isNumeric(arg)) return tickSlow(sender, arg); - else - return cmd.sendUsage(sender); + return cmd.sendUsage(sender); } function tickSlow(sender, mspt) { @@ -84,18 +83,18 @@ function tickSleep(sender, milliseconds) { if (milliseconds === null || milliseconds < 1) return sender.sendMessage({ translate: 'commands.tick.sleep.fail' }); world.sendMessage({ translate: 'commands.tick.sleep.success', with: [sender.name, String(milliseconds)] }); - let startTime = Date.now(); + const startTime = Date.now(); let waitTime = 0; - while (waitTime < milliseconds) { + while (waitTime < milliseconds) waitTime = Date.now() - startTime; - } + } function tickSpeed(desiredMspt) { if (targetMSPT === 50.0) return; let currentMspt = Date.now() - DataTPS.lastTick; - while (currentMspt <= desiredMspt) { + while (currentMspt <= desiredMspt) currentMspt = Date.now() - DataTPS.lastTick; - } + } diff --git a/Canopy [BP]/scripts/src/commands/tntfuse.js b/Canopy [BP]/scripts/src/commands/tntfuse.js index 303896e..1b458b6 100644 --- a/Canopy [BP]/scripts/src/commands/tntfuse.js +++ b/Canopy [BP]/scripts/src/commands/tntfuse.js @@ -21,7 +21,7 @@ const cmd = new Command({ contingentRules: ['commandTntFuse'] }); -world.afterEvents.entitySpawn.subscribe(async (event) => { +world.afterEvents.entitySpawn.subscribe((event) => { if (event.entity?.typeId !== 'minecraft:tnt') return; const fuseTimeProperty = world.getDynamicProperty('tntFuseTime'); let fuseTime = 80; @@ -36,7 +36,6 @@ world.afterEvents.entitySpawn.subscribe(async (event) => { event.entity.triggerEvent('canopy:explode'); }, fuseTime - 1); } - }); function tntfuseCommand(sender, args) { @@ -47,7 +46,7 @@ function tntfuseCommand(sender, args) { ticks = 80; sender.sendMessage({ translate: 'commands.tntfuse.reset.success' }); } else if (ticks < MIN_FUSE_TICKS || ticks > MAX_FUSE_TICKS) - return sender.sendMessage({ translate: 'commands.tntfuse.set.fail', with: [String(ticks), String(MIN_FUSE_TICKS), String(MAX_FUSE_TICKS)] }); + {return sender.sendMessage({ translate: 'commands.tntfuse.set.fail', with: [String(ticks), String(MIN_FUSE_TICKS), String(MAX_FUSE_TICKS)] });} else { sender.sendMessage({ translate: 'commands.tntfuse.set.success', with: [String(ticks)] }); } diff --git a/Canopy [BP]/scripts/src/commands/trackevent.js b/Canopy [BP]/scripts/src/commands/trackevent.js index 915146f..a6a610d 100644 --- a/Canopy [BP]/scripts/src/commands/trackevent.js +++ b/Canopy [BP]/scripts/src/commands/trackevent.js @@ -9,7 +9,7 @@ const cmd = new Command({ usage: 'trackevent [beforeEvent/afterEvent]', args: [ { type: 'string', name: 'eventName' }, - { type: 'string', name: 'isAfterEvent' } + { type: 'string', name: 'eventType' } ], callback: trackCommand }); @@ -31,12 +31,13 @@ world.afterEvents.worldInitialize.subscribe(() => { }); function trackCommand(sender, args) { - let { eventName, isAfterEvent } = args; + const { eventName, eventType } = args; + let isAfterEvent; if (eventName === null) return cmd.sendUsage(sender); - if (isAfterEvent == 'beforeEvent') + if (eventType === 'beforeEvent') isAfterEvent = false; - else if (isAfterEvent == 'afterEvent' || isAfterEvent === null) + else if (eventType === 'afterEvent' || eventType === null) isAfterEvent = true; else return cmd.sendUsage(sender); diff --git a/Canopy [BP]/scripts/src/commands/warp.js b/Canopy [BP]/scripts/src/commands/warp.js index d812ba0..3ab81f6 100644 --- a/Canopy [BP]/scripts/src/commands/warp.js +++ b/Canopy [BP]/scripts/src/commands/warp.js @@ -92,7 +92,7 @@ function addWarp(sender, name, warpMap) { if (warpMap.has(name)) return sender.sendMessage({ translate: 'commands.warp.exists', with: [name] }); const { location, dimension } = sender; - let warps = JSON.parse(world.getDynamicProperty('warps')); + const warps = JSON.parse(world.getDynamicProperty('warps')); warps.warpList[name] = new Warp(name, location, dimension); world.setDynamicProperty(`warps`, JSON.stringify(warps)); sender.sendMessage({ translate: 'commands.warp.add.success', with: [name] }); @@ -120,7 +120,7 @@ function warpTP(sender, name, warpMap) { function getWarpMapCopy() { let warps = world.getDynamicProperty('warps'); if (warps === undefined || warps === false) { - let initWarps = new Warps(); + const initWarps = new Warps(); world.setDynamicProperty(`warps`, JSON.stringify(initWarps)); warps = world.getDynamicProperty('warps'); } @@ -128,10 +128,10 @@ function getWarpMapCopy() { } function setWarpMap(newWarpMap) { - let warps = JSON.parse(world.getDynamicProperty('warps')); - let newWarpList = {}; + const warps = JSON.parse(world.getDynamicProperty('warps')); + const newWarpList = {}; - for (let key of Object.keys(warps.warpList)) { + for (const key of Object.keys(warps.warpList)) { if (!newWarpMap.has(key)) continue; newWarpList[key] = newWarpMap.get(key); } @@ -143,7 +143,7 @@ async function warpListCommand(sender) { if (!await Rule.getValue('commandWarpSurvival') && sender.getGameMode() === 'survival') return sender.sendMessage({ translate: 'commands.generic.blocked.survival' }); - let warpMap = getWarpMapCopy(); + const warpMap = getWarpMapCopy(); if (warpMap.size === 0) return sender.sendMessage({ translate: 'commands.warp.list.empty' }); diff --git a/Canopy [BP]/scripts/src/rules/autoItemPickup.js b/Canopy [BP]/scripts/src/rules/autoItemPickup.js index 47093b6..5063380 100644 --- a/Canopy [BP]/scripts/src/rules/autoItemPickup.js +++ b/Canopy [BP]/scripts/src/rules/autoItemPickup.js @@ -59,9 +59,9 @@ function itemFitsInPartiallyFilledSlot(slot, itemStack) { function addItem(inventory, itemStack) { const isItemDeposited = partiallyFilledSlotPass(inventory, itemStack); - if (!isItemDeposited) { + if (!isItemDeposited) emptySlotPass(inventory, itemStack); - } + } function partiallyFilledSlotPass(inventory, itemStack) { diff --git a/Canopy [BP]/scripts/src/rules/cauldronConcreteConversion.js b/Canopy [BP]/scripts/src/rules/cauldronConcreteConversion.js index 756b238..709f5d9 100644 --- a/Canopy [BP]/scripts/src/rules/cauldronConcreteConversion.js +++ b/Canopy [BP]/scripts/src/rules/cauldronConcreteConversion.js @@ -13,15 +13,15 @@ new Rule({ world.afterEvents.entitySpawn.subscribe((event) => { if (!Rule.getNativeValue('cauldronConcreteConversion') || event.entity?.typeId !== "minecraft:item" || !event.entity.hasComponent('item')) return; const itemStack = event.entity.getComponent('item').itemStack; - if (itemStack && itemStack.typeId.includes('concrete_powder')) { + if (itemStack && itemStack.typeId.includes('concrete_powder')) event.entity.addTag('concrete_powder'); - } + }); world.afterEvents.entityRemove.subscribe((event) => { - if (CURRENT_CONVERSIONS[event.removedEntityId] !== undefined) { + if (CURRENT_CONVERSIONS[event.removedEntityId] !== undefined) delete CURRENT_CONVERSIONS[event.removedEntityId]; - } + }); system.runInterval(() => { @@ -30,9 +30,9 @@ system.runInterval(() => { const dimension = world.getDimension(dimensionType.typeId); const concretePowderItems = dimension.getEntities({ type: 'minecraft:item', tags: ['concrete_powder'] }); for (const itemEntity of concretePowderItems) { - if (isInWaterCauldron(dimension, itemEntity) && isDoneConverting(itemEntity)) { + if (isInWaterCauldron(dimension, itemEntity) && isDoneConverting(itemEntity)) convertToConcrete(dimension, itemEntity); - } + } }); }); @@ -52,11 +52,11 @@ function isDoneConverting(itemEntity) { CURRENT_CONVERSIONS[entityId] = 0; else if (CURRENT_CONVERSIONS[entityId] < CONVERSION_TIME) CURRENT_CONVERSIONS[entityId]++; - else if (CURRENT_CONVERSIONS[entityId] >= CONVERSION_TIME) { + else if (CURRENT_CONVERSIONS[entityId] >= CONVERSION_TIME) return true; - } else { + else return false; - } + } function convertToConcrete(dimension, itemEntity) { diff --git a/Canopy [BP]/scripts/src/rules/dupeTnt.js b/Canopy [BP]/scripts/src/rules/dupeTnt.js index 6a65919..702009e 100644 --- a/Canopy [BP]/scripts/src/rules/dupeTnt.js +++ b/Canopy [BP]/scripts/src/rules/dupeTnt.js @@ -54,25 +54,17 @@ function correctAttachedLocations(attachedLocations, pistonState, direction) { }; let offset = directionToOffsetExpandMap[direction]; if (pistonState === 'Retracting') offset = { x: -offset.x, y: -offset.y, z: -offset.z }; - return attachedLocations.map((location) => { - return { x: location.x + offset.x, y: location.y + offset.y, z: location.z + offset.z }; - }); + return attachedLocations.map((location) => ({ x: location.x + offset.x, y: location.y + offset.y, z: location.z + offset.z })); } function isOverlapping(entityList, locationList) { - return entityList.some((entity) => { - return locationList.some((location) => { - return Math.floor(entity.location.x) === location.x + return entityList.some((entity) => locationList.some((location) => Math.floor(entity.location.x) === location.x && Math.floor(entity.location.y) === location.y - && Math.floor(entity.location.z) === location.z; - }); - }); + && Math.floor(entity.location.z) === location.z)); } function getEntityAtLocation(entityList, location) { - return entityList.find((entity) => { - return Math.floor(entity.location.x) === location.x && Math.floor(entity.location.y) === location.y && Math.floor(entity.location.z) === location.z; - }); + return entityList.find((entity) => Math.floor(entity.location.x) === location.x && Math.floor(entity.location.y) === location.y && Math.floor(entity.location.z) === location.z); } function dupeTnt(block, tntEntity) { diff --git a/Canopy [BP]/scripts/src/rules/durabilityNotifier.js b/Canopy [BP]/scripts/src/rules/durabilityNotifier.js index 4c334a3..fc51401 100644 --- a/Canopy [BP]/scripts/src/rules/durabilityNotifier.js +++ b/Canopy [BP]/scripts/src/rules/durabilityNotifier.js @@ -20,9 +20,9 @@ function durabilityClink(player, beforeItemStack, itemStack) { || !usedDurability(beforeItemStack, itemStack) ) return; const durability = getRemainingDurability(itemStack); - if (ADDITIONAL_DURABILITIES.includes(durability)) { + if (ADDITIONAL_DURABILITIES.includes(durability)) showNotification(player, durability); - } + if (durability <= ACTIVE_DURABILITY) { const pitch = 1 - (durability/5); showNotification(player, durability, pitch); diff --git a/Canopy [BP]/scripts/src/rules/durabilitySwap.js b/Canopy [BP]/scripts/src/rules/durabilitySwap.js index 434dbd1..a059a06 100644 --- a/Canopy [BP]/scripts/src/rules/durabilitySwap.js +++ b/Canopy [BP]/scripts/src/rules/durabilitySwap.js @@ -37,9 +37,9 @@ function swapOutItem(player) { function findEmptySlot(playerInventory) { for (let slotIndex = 9; slotIndex < playerInventory.size; slotIndex++) { const slot = playerInventory.getSlot(slotIndex); - if (!slot.hasItem()) { + if (!slot.hasItem()) return slotIndex; - } + } return -1; } @@ -47,9 +47,9 @@ function findEmptySlot(playerInventory) { function findSlotWithoutDurabilityComponent(playerInventory) { for (let slotIndex = 0; slotIndex < playerInventory.size; slotIndex++) { const slot = playerInventory.getSlot(slotIndex); - if (slot.hasItem() && !slot.getItem()?.hasComponent('durability')) { + if (slot.hasItem() && !slot.getItem()?.hasComponent('durability')) return slotIndex; - } + } return -1; } @@ -57,9 +57,9 @@ function findSlotWithoutDurabilityComponent(playerInventory) { function findSlotWithSomeDurability(playerInventory) { for (let slotIndex = 0; slotIndex < playerInventory.size; slotIndex++) { const slot = playerInventory.getSlot(slotIndex); - if (slot.hasItem() && getRemainingDurability(slot.getItem()) > 0) { + if (slot.hasItem() && getRemainingDurability(slot.getItem()) > 0) return slotIndex; - } + } return -1; } \ No newline at end of file diff --git a/Canopy [BP]/scripts/src/rules/flippinArrows.js b/Canopy [BP]/scripts/src/rules/flippinArrows.js index cb7f4b8..337e22d 100644 --- a/Canopy [BP]/scripts/src/rules/flippinArrows.js +++ b/Canopy [BP]/scripts/src/rules/flippinArrows.js @@ -11,7 +11,7 @@ new Rule({ const WAIT_TIME_BETWEEN_USE = 5; // in ticks -let previousBlocks = new Array(WAIT_TIME_BETWEEN_USE).fill(null); +const previousBlocks = new Array(WAIT_TIME_BETWEEN_USE).fill(null); const flipOnPlaceIds = ['piston', 'sticky_piston', 'dropper', 'dispenser', 'observer', 'crafter', 'unpowered_repeater', 'unpowered_comparator', 'powered_repeater', 'powered_comparator','hopper', 'end_rod', 'lightning_rod']; const flipIds = ['piston', 'sticky_piston', 'observer', 'end_rod', 'lightning_rod']; @@ -21,9 +21,9 @@ const noInteractBlockIds = ['piston_arm_collision', 'sticky_piston_arm_collision system.runInterval(() => { previousBlocks.shift(); - if (previousBlocks.length < WAIT_TIME_BETWEEN_USE) { + if (previousBlocks.length < WAIT_TIME_BETWEEN_USE) previousBlocks.push(null); - } + }); world.beforeEvents.playerPlaceBlock.subscribe(async (event) => { @@ -76,7 +76,7 @@ function rotate(block) { } function open(player, block) { - let directionState = { + const directionState = { name: 'open_bit', value: block.permutation.getState('open_bit') } @@ -104,7 +104,13 @@ function open(player, block) { 'door_hinge_bit': hingeBit }; } - safeSetblock(player, block, directionState, openPermutation, otherPermutations); + const blockData = { + block, + directionState, + openPermutation, + otherPermutations + } + safeSetblock(player, blockData); } function flipWhenVertical(block) { @@ -122,13 +128,16 @@ function checkForAbort(block, blockId) { return false; } -function safeSetblock(player, block, directionState, permutationValue, otherPermutations = {}) { - if (Object.keys(otherPermutations).length === 0) otherPermutations = ''; +function safeSetblock(player, blockData) { + const { block, directionState, permutationValue } = blockData; + let otherPermutations = blockData.otherPermutations; + if (Object.keys(otherPermutations).length === 0) + otherPermutations = ''; else otherPermutations = ',' + Object.entries(otherPermutations).map(([key, value]) => `"${key}"=${value}`).join(','); const setblockCmd = `setblock ${block.location.x} ${block.location.y} ${block.location.z} ${block.typeId} ["${directionState.name}"=${permutationValue}${otherPermutations}] replace`; (async () => { - player.runCommandAsync(`setblock ${block.location.x} ${block.location.y} ${block.location.z} air replace`); - player.runCommandAsync(setblockCmd); + await player.runCommandAsync(`setblock ${block.location.x} ${block.location.y} ${block.location.z} air replace`); + await player.runCommandAsync(setblockCmd); })(); return block.dimension.getBlock(block.location); } diff --git a/Canopy [BP]/scripts/src/rules/hotbarSwitching.js b/Canopy [BP]/scripts/src/rules/hotbarSwitching.js index 02ba483..7ef5e27 100644 --- a/Canopy [BP]/scripts/src/rules/hotbarSwitching.js +++ b/Canopy [BP]/scripts/src/rules/hotbarSwitching.js @@ -43,9 +43,9 @@ function processHotbarSwitching(player) { } else if (lastSelectedSlots[player.id] === undefined && (!hasArrowInCorrectSlot(player) || !hasAppropriateGameMode(player))) { return; } - if (hasScrolled(player) && player.inputInfo.getButtonState(InputButton.Sneak) === ButtonState.Pressed) { + if (hasScrolled(player) && player.inputInfo.getButtonState(InputButton.Sneak) === ButtonState.Pressed) switchToHotbar(player, player.selectedSlotIndex); - } + lastSelectedSlots[player.id] = player.selectedSlotIndex; } diff --git a/Canopy [BP]/scripts/src/rules/infodisplay/Biome.js b/Canopy [BP]/scripts/src/rules/infodisplay/Biome.js index fa7061a..3c0e31b 100644 --- a/Canopy [BP]/scripts/src/rules/infodisplay/Biome.js +++ b/Canopy [BP]/scripts/src/rules/infodisplay/Biome.js @@ -4,8 +4,9 @@ import ProbeManager from 'src/classes/ProbeManager'; class Biome extends InfoDisplayElement { player; - constructor(player) { - super('biome', { translate: 'rules.infoDisplay.biome' }, 5); + constructor(player, displayLine) { + const ruleData = { identifier: 'biome', description: { translate: 'rules.infoDisplay.biome' } }; + super(ruleData, displayLine); this.player = player; } diff --git a/Canopy [BP]/scripts/src/rules/infodisplay/ChunkCoords.js b/Canopy [BP]/scripts/src/rules/infodisplay/ChunkCoords.js index fd66efe..8418be1 100644 --- a/Canopy [BP]/scripts/src/rules/infodisplay/ChunkCoords.js +++ b/Canopy [BP]/scripts/src/rules/infodisplay/ChunkCoords.js @@ -1,8 +1,9 @@ import InfoDisplayElement from './InfoDisplayElement.js'; class ChunkCoords extends InfoDisplayElement { - constructor(player) { - super('chunkCoords', { translate: 'rules.infoDisplay.chunkCoords' }, 3); + constructor(player, displayLine) { + const ruleData = { identifier: 'chunkCoords', description: { translate: 'rules.infoDisplay.chunkCoords' } }; + super(ruleData, displayLine); this.player = player; } diff --git a/Canopy [BP]/scripts/src/rules/infodisplay/Entities.js b/Canopy [BP]/scripts/src/rules/infodisplay/Entities.js index 93cab51..a97d17d 100644 --- a/Canopy [BP]/scripts/src/rules/infodisplay/Entities.js +++ b/Canopy [BP]/scripts/src/rules/infodisplay/Entities.js @@ -4,8 +4,9 @@ import { Vector } from 'src/classes/Vector'; class Entities extends InfoDisplayElement { player; - constructor(player) { - super('entities', { translate: 'rules.infoDisplay.entities' }, 4); + constructor(player, displayLine) { + const ruleData = { identifier: 'entities', description: { translate: 'rules.infoDisplay.entities' } }; + super(ruleData, displayLine); this.player = player; } diff --git a/Canopy [BP]/scripts/src/rules/infodisplay/EventTrackers.js b/Canopy [BP]/scripts/src/rules/infodisplay/EventTrackers.js index 444e488..6dcac7a 100644 --- a/Canopy [BP]/scripts/src/rules/infodisplay/EventTrackers.js +++ b/Canopy [BP]/scripts/src/rules/infodisplay/EventTrackers.js @@ -2,8 +2,9 @@ import InfoDisplayElement from './InfoDisplayElement.js'; import { getAllTrackerInfoString } from 'src/commands/trackevent'; class EventTrackers extends InfoDisplayElement { - constructor() { - super('eventTrackers', { translate: 'rules.infoDisplay.eventTrackers' }, 9, true); + constructor(displayLine) { + const ruleData = { identifier: 'eventTrackers', description: { translate: 'rules.infoDisplay.eventTrackers' } }; + super(ruleData, displayLine, true); } getFormattedDataOwnLine() { diff --git a/Canopy [BP]/scripts/src/rules/infodisplay/HopperCounterCounts.js b/Canopy [BP]/scripts/src/rules/infodisplay/HopperCounterCounts.js index 674c013..6825dd7 100644 --- a/Canopy [BP]/scripts/src/rules/infodisplay/HopperCounterCounts.js +++ b/Canopy [BP]/scripts/src/rules/infodisplay/HopperCounterCounts.js @@ -2,8 +2,9 @@ import InfoDisplayElement from './InfoDisplayElement.js'; import { getInfoDisplayOutput } from 'src/commands/counter'; class HopperCounterCounts extends InfoDisplayElement { - constructor() { - super('hopperCounterCounts', { translate: 'rules.infoDisplay.hopperCounterCounts' }, 10, true); + constructor(displayLine) { + const ruleData = { identifier: 'hopperCounterCounts', description: { translate: 'rules.infoDisplay.hopperCounterCounts' } }; + super(ruleData, displayLine, true); } getFormattedDataOwnLine() { diff --git a/Canopy [BP]/scripts/src/rules/infodisplay/Light.js b/Canopy [BP]/scripts/src/rules/infodisplay/Light.js index cf983d2..0fa7686 100644 --- a/Canopy [BP]/scripts/src/rules/infodisplay/Light.js +++ b/Canopy [BP]/scripts/src/rules/infodisplay/Light.js @@ -4,8 +4,9 @@ import ProbeManager from 'src/classes/ProbeManager'; class Light extends InfoDisplayElement { player; - constructor(player) { - super('light', { translate: 'rules.infoDisplay.light' }, 5); + constructor(player, displayLine) { + const ruleData = { identifier: 'light', description: { translate: 'rules.infoDisplay.light' } }; + super(ruleData, displayLine); this.player = player; } diff --git a/Canopy [BP]/scripts/src/rules/infodisplay/LookingAt.js b/Canopy [BP]/scripts/src/rules/infodisplay/LookingAt.js index c7df253..2403974 100644 --- a/Canopy [BP]/scripts/src/rules/infodisplay/LookingAt.js +++ b/Canopy [BP]/scripts/src/rules/infodisplay/LookingAt.js @@ -2,8 +2,9 @@ import InfoDisplayElement from './InfoDisplayElement.js'; import Utils from 'include/utils'; class LookingAt extends InfoDisplayElement { - constructor(player) { - super('lookingAt', { translate: 'rules.infoDisplay.lookingAt' }, 12); + constructor(player, displayLine) { + const ruleData = { identifier: 'lookingAt', description: { translate: 'rules.infoDisplay.lookingAt' } }; + super(ruleData, displayLine); this.player = player; } @@ -16,8 +17,7 @@ class LookingAt extends InfoDisplayElement { } getLookingAtName() { - let blockRayResult, entityRayResult; - ({ blockRayResult, entityRayResult } = Utils.getRaycastResults(this.player, 7)); + const { blockRayResult, entityRayResult } = Utils.getRaycastResults(this.player, 7); return Utils.parseLookingAtEntity(entityRayResult).LookingAtName || Utils.parseLookingAtBlock(blockRayResult).LookingAtName; } } diff --git a/Canopy [BP]/scripts/src/rules/infodisplay/MoonPhase.js b/Canopy [BP]/scripts/src/rules/infodisplay/MoonPhase.js index 080fe2d..59a7090 100644 --- a/Canopy [BP]/scripts/src/rules/infodisplay/MoonPhase.js +++ b/Canopy [BP]/scripts/src/rules/infodisplay/MoonPhase.js @@ -2,8 +2,9 @@ import InfoDisplayElement from './InfoDisplayElement.js'; import { world } from '@minecraft/server'; class MoonPhase extends InfoDisplayElement { - constructor() { - super('moonPhase', { translate: 'rules.infoDisplay.moonPhase' }, 8, true); + constructor(displayLine) { + const ruleData = { identifier: 'moonPhase', description: { translate: 'rules.infoDisplay.moonPhase' } }; + super(ruleData, displayLine, true); } getFormattedDataOwnLine() { diff --git a/Canopy [BP]/scripts/src/rules/infodisplay/PeekInventory.js b/Canopy [BP]/scripts/src/rules/infodisplay/PeekInventory.js index 346524e..ab7d610 100644 --- a/Canopy [BP]/scripts/src/rules/infodisplay/PeekInventory.js +++ b/Canopy [BP]/scripts/src/rules/infodisplay/PeekInventory.js @@ -5,8 +5,9 @@ import { currentQuery } from 'src/commands/peek.js'; class PeekInventory extends InfoDisplayElement { player; - constructor(player) { - super('peekInventory', { translate: 'rules.infoDisplay.peekInventory' }, 13, false, ['lookingAt']); + constructor(player, displayLine) { + const ruleData = { identifier: 'peekInventory', description: { translate: 'rules.infoDisplay.peekInventory', contingentRules: ['lookingAt'] } }; + super(ruleData, displayLine, false); this.player = player; } @@ -19,8 +20,7 @@ class PeekInventory extends InfoDisplayElement { } parsePeekInventory() { - let blockRayResult, entityRayResult; - ({ blockRayResult, entityRayResult } = Utils.getRaycastResults(this.player, 9)); + const { blockRayResult, entityRayResult } = Utils.getRaycastResults(this.player, 9); if (!blockRayResult && !entityRayResult) return ''; const target = Utils.getClosestTarget(this.player, blockRayResult, entityRayResult); if (!target) return ''; @@ -36,13 +36,13 @@ class PeekInventory extends InfoDisplayElement { let output = ''; const items = Utils.populateItems(inventory); if (Object.keys(items).length > 0) { - for (let itemName in items) { + for (const itemName in items) { if (itemName.includes(currentQuery[this.player.name])) output += `§c${itemName}: ${items[itemName]}\n`; else output += `§r${itemName}: ${items[itemName]}\n`; } - } else output = '§rEmpty'; + } else {output = '§rEmpty';} return output; } diff --git a/Canopy [BP]/scripts/src/rules/infodisplay/SessionTime.js b/Canopy [BP]/scripts/src/rules/infodisplay/SessionTime.js index 2d935cd..4c274bb 100644 --- a/Canopy [BP]/scripts/src/rules/infodisplay/SessionTime.js +++ b/Canopy [BP]/scripts/src/rules/infodisplay/SessionTime.js @@ -3,8 +3,9 @@ import InfoDisplayElement from './InfoDisplayElement.js'; class SessionTime extends InfoDisplayElement { player; - constructor(player) { - super('sessionTime', { translate: 'rules.infoDisplay.sessionTime' }, 7); + constructor(player, displayLine) { + const ruleData = { identifier: 'sessionTime', description: { translate: 'rules.infoDisplay.sessionTime' } }; + super(ruleData, displayLine); this.player = player; player.setDynamicProperty('joinDate', Date.now()); } diff --git a/Canopy [BP]/scripts/src/rules/infodisplay/SignalStrength.js b/Canopy [BP]/scripts/src/rules/infodisplay/SignalStrength.js index d998c9f..72e324b 100644 --- a/Canopy [BP]/scripts/src/rules/infodisplay/SignalStrength.js +++ b/Canopy [BP]/scripts/src/rules/infodisplay/SignalStrength.js @@ -1,11 +1,12 @@ -import InfoDisplayElement from './InfoDisplayElement.js'; -import Utils from 'include/utils'; +import InfoDisplayElement from "./InfoDisplayElement.js"; +import Utils from "../../../include/utils.js"; class SignalStrength extends InfoDisplayElement { player; - constructor(player) { - super('signalStrength', { translate: 'rules.infoDisplay.signalStrength' }, 12, false, ['lookingAt']); + constructor(player, displayLine) { + const ruleData = { identifier: 'signalStrength', description: { translate: 'rules.infoDisplay.signalStrength' }, contingentRules: ['lookingAt'] }; + super(ruleData, displayLine, false); this.player = player; } @@ -19,8 +20,7 @@ class SignalStrength extends InfoDisplayElement { } getSignalStrength() { - let blockRayResult, entityRayResult; - ({ blockRayResult, entityRayResult } = Utils.getRaycastResults(this.player, 7)); + const { blockRayResult, entityRayResult } = Utils.getRaycastResults(this.player, 7); if (entityRayResult[0]?.entity) return 0; if (blockRayResult?.block) diff --git a/Canopy [BP]/scripts/src/rules/infodisplay/SlimeChunk.js b/Canopy [BP]/scripts/src/rules/infodisplay/SlimeChunk.js index 7322ba1..ae3226d 100644 --- a/Canopy [BP]/scripts/src/rules/infodisplay/SlimeChunk.js +++ b/Canopy [BP]/scripts/src/rules/infodisplay/SlimeChunk.js @@ -4,8 +4,9 @@ import MT from 'lib/mt.js'; class SlimeChunk extends InfoDisplayElement { player; - constructor(player) { - super('slimeChunk', { translate: 'rules.infoDisplay.slimeChunk' }, 3); + constructor(player, displayLine) { + const ruleData = { identifier: 'slimeChunk', description: { translate: 'rules.infoDisplay.slimeChunk' } }; + super(ruleData, displayLine); this.player = player; } @@ -17,6 +18,7 @@ class SlimeChunk extends InfoDisplayElement { return this.getFormattedDataOwnLine(); } + isSlime() { if (this.player.dimension.id !== "minecraft:overworld") return false; @@ -24,26 +26,26 @@ class SlimeChunk extends InfoDisplayElement { const chunkX = Math.floor(this.player.location.x / 16) >>> 0; const chunkZ = Math.floor(this.player.location.z / 16) >>> 0; const seed = ((a, b) => { - let a00 = a & 0xffff; - let a16 = a >>> 16; - let b00 = b & 0xffff; - let b16 = b >>> 16; - let c00 = a00 * b00; + const a00 = a & 0xffff; + const a16 = a >>> 16; + const b00 = b & 0xffff; + const b16 = b >>> 16; + const c00 = a00 * b00; let c16 = c00 >>> 16; c16 += a16 * b00; c16 &= 0xffff; c16 += a00 * b16; - let lo = c00 & 0xffff; - let hi = c16 & 0xffff; + const lo = c00 & 0xffff; + const hi = c16 & 0xffff; return((hi << 16) | lo) >>> 0; })(chunkX, 0x1f1f1f1f) ^ chunkZ; const mt = new MT(seed); const n = mt.nextInt(); - const isSlime = (n % 10 == 0); + const isSlime = (n % 10 === 0); return(isSlime); } diff --git a/Canopy [BP]/scripts/src/rules/infodisplay/TimeOfDay.js b/Canopy [BP]/scripts/src/rules/infodisplay/TimeOfDay.js index 5f06a00..92e1683 100644 --- a/Canopy [BP]/scripts/src/rules/infodisplay/TimeOfDay.js +++ b/Canopy [BP]/scripts/src/rules/infodisplay/TimeOfDay.js @@ -2,8 +2,9 @@ import InfoDisplayElement from './InfoDisplayElement.js'; import { world } from '@minecraft/server'; class TimeOfDay extends InfoDisplayElement { - constructor() { - super('timeOfDay', { translate: 'rules.infoDisplay.timeOfDay' }, 6, true); + constructor(displayLine) { + const ruleData = { identifier: 'timeOfDay', description: { translate: 'rules.infoDisplay.timeOfDay' } }; + super(ruleData, displayLine, true); } getFormattedDataOwnLine() { @@ -16,19 +17,28 @@ class TimeOfDay extends InfoDisplayElement { ticksToTime(ticks) { const ticksPerDay = 24000; - const ticksPerHour = ticksPerDay / 24; - ticks = (ticks + 6 * ticksPerHour) % ticksPerDay; // 0 ticks is 6:00 AM in game + const hoursPerDay = 24; + const ticksPerHour = ticksPerDay / hoursPerDay; + const hoursOffset = 6; // 0 ticks is 6:00 AM ingame + ticks = (ticks + hoursOffset * ticksPerHour) % ticksPerDay; + const ticksPerMinute = 60; let hours = Math.floor(ticks / ticksPerHour); - const minutes = Math.floor((ticks % ticksPerHour) * 60 / ticksPerHour); + const minutes = Math.floor((ticks % ticksPerHour) * ticksPerMinute / ticksPerHour); + const noon = 12; + const halfADay = 12; let period = 'AM'; - if (hours >= 12) period = 'PM'; - if (hours >= 13) hours -= 12; - else if (hours === 0) hours = 12; + if (hours >= noon) + period = 'PM'; + if (hours > noon) + hours -= halfADay; + else if (hours === 0) + hours = noon; - const formattedHours = hours.toString().padStart(2, '0'); - const formattedMinutes = minutes.toString().padStart(2, '0'); + const padding = 2; + const formattedHours = hours.toString().padStart(padding, '0'); + const formattedMinutes = minutes.toString().padStart(padding, '0'); return `${formattedHours}:${formattedMinutes} ${period}`; } diff --git a/Canopy [BP]/scripts/src/rules/infodisplay/WorldDay.js b/Canopy [BP]/scripts/src/rules/infodisplay/WorldDay.js index a9bc8a8..64950ff 100644 --- a/Canopy [BP]/scripts/src/rules/infodisplay/WorldDay.js +++ b/Canopy [BP]/scripts/src/rules/infodisplay/WorldDay.js @@ -2,8 +2,9 @@ import InfoDisplayElement from './InfoDisplayElement.js'; import { world } from '@minecraft/server'; class WorldDay extends InfoDisplayElement { - constructor() { - super('worldDay', { translate: 'rules.infoDisplay.worldDay' }, 6, true); + constructor(displayLine) { + const ruleData = { identifier: 'worldDay', description: { translate: 'rules.infoDisplay.worldDay' } }; + super(ruleData, displayLine, true); } getFormattedDataOwnLine() { diff --git a/Canopy [BP]/scripts/src/rules/infodisplay/cardinalFacing.js b/Canopy [BP]/scripts/src/rules/infodisplay/cardinalFacing.js index 5412025..68f64d2 100644 --- a/Canopy [BP]/scripts/src/rules/infodisplay/cardinalFacing.js +++ b/Canopy [BP]/scripts/src/rules/infodisplay/cardinalFacing.js @@ -3,8 +3,9 @@ import InfoDisplayElement from './InfoDisplayElement.js'; class CardinalFacing extends InfoDisplayElement { player; - constructor(player) { - super('cardinalFacing', { translate: 'rules.infoDisplay.cardinalFacing' }, 1); + constructor(player, displayLine) { + const ruleData = { identifier: 'cardinalFacing', description: { translate: 'rules.infoDisplay.cardinalFacing' } }; + super(ruleData, displayLine); this.player = player; } @@ -23,7 +24,7 @@ class CardinalFacing extends InfoDisplayElement { if (angle >= -45 && angle < 45) return 'E (+x)' else if (angle >= 45 && angle < 135) return 'S (+z)'; else if (angle >= 135 || angle < -135) return 'W (-x)'; - else return 'N (-z)'; + return 'N (-z)'; } } diff --git a/Canopy [BP]/scripts/src/rules/infodisplay/coords.js b/Canopy [BP]/scripts/src/rules/infodisplay/coords.js index 4132ff2..2725f19 100644 --- a/Canopy [BP]/scripts/src/rules/infodisplay/coords.js +++ b/Canopy [BP]/scripts/src/rules/infodisplay/coords.js @@ -3,13 +3,14 @@ import InfoDisplayElement from './InfoDisplayElement.js'; class Coords extends InfoDisplayElement { player; - constructor(player) { - super('coords', { translate: 'rules.infoDisplay.coords' }, 1); + constructor(player, displayLine) { + const ruleData = { identifier: 'coords', description: { translate: 'rules.infoDisplay.coords' } }; + super(ruleData, displayLine); this.player = player; } getFormattedDataOwnLine() { - let coords = this.player.location; + const coords = this.player.location; [coords.x, coords.y, coords.z] = [coords.x.toFixed(2), coords.y.toFixed(2), coords.z.toFixed(2)]; return { text: `§r${coords.x} ${coords.y} ${coords.z}§r` }; } diff --git a/Canopy [BP]/scripts/src/rules/infodisplay/facing.js b/Canopy [BP]/scripts/src/rules/infodisplay/facing.js index 5c1c6d1..a75b9fa 100644 --- a/Canopy [BP]/scripts/src/rules/infodisplay/facing.js +++ b/Canopy [BP]/scripts/src/rules/infodisplay/facing.js @@ -3,13 +3,14 @@ import InfoDisplayElement from './InfoDisplayElement.js'; class Facing extends InfoDisplayElement { player; - constructor(player) { - super('facing', { translate: 'rules.infoDisplay.facing' }, 2); + constructor(player, displayLine) { + const ruleData = { identifier: 'facing', description: { translate: 'rules.infoDisplay.facing' } }; + super(ruleData, displayLine); this.player = player; } getFormattedDataOwnLine() { - let rotation = this.player.getRotation(); + const rotation = this.player.getRotation(); [ rotation.x, rotation.y ] = [ rotation.x.toFixed(2), rotation.y.toFixed(2) ]; return { translate: 'rules.infoDisplay.facing.display', with: [rotation.x, rotation.y] }; } diff --git a/Canopy [BP]/scripts/src/rules/infodisplay/infoDisplay.js b/Canopy [BP]/scripts/src/rules/infodisplay/infoDisplay.js index 8a7a7ac..45ae8f4 100644 --- a/Canopy [BP]/scripts/src/rules/infodisplay/infoDisplay.js +++ b/Canopy [BP]/scripts/src/rules/infodisplay/infoDisplay.js @@ -28,28 +28,29 @@ class InfoDisplay { elements = []; infoMessage = { rawtext: [] }; + constructor(player) { this.player = player; this.elements = [ - new Coords(player), - new CardinalFacing(player), - new Facing(player), - new ChunkCoords(player), - new SlimeChunk(player), - new TPS(), - new Entities(player), - new Light(player), - new Biome(player), - new WorldDay(), - new TimeOfDay(), - new SessionTime(player), - new MoonPhase(), - new EventTrackers(), - new HopperCounterCounts(), - new SimulationMap(player), - new LookingAt(player), - new SignalStrength(player), - new PeekInventory(player) + new Coords(player, 1), + new CardinalFacing(player, 1), + new Facing(player, 2), + new ChunkCoords(player, 3), + new SlimeChunk(player, 3), + new TPS(4), + new Entities(player, 5), + new Light(player, 6), + new Biome(player, 6), + new WorldDay(7), + new TimeOfDay(7), + new SessionTime(player, 8), + new MoonPhase(9), + new EventTrackers(10), + new HopperCounterCounts(11), + new SimulationMap(player, 12), + new LookingAt(player, 13), + new SignalStrength(player, 14), + new PeekInventory(player, 15), ]; playerToInfoDisplayMap[player.id] = this; } @@ -58,9 +59,9 @@ class InfoDisplay { this.infoMessage = { rawtext: [] }; const enabledElements = this.getEnabledElements(); - for (let i = 0; i < enabledElements.length; i++) { + for (let i = 0; i < enabledElements.length; i++) this.updateElementData(enabledElements, i); - } + this.trimTrailingWhitespace(); this.sendInfoMessage(); @@ -70,24 +71,24 @@ class InfoDisplay { const element = elements[currIndex]; if (element.isWorldwide) { - if (!currentTickWorldwideElementData[element.identifier]) { + if (!currentTickWorldwideElementData[element.identifier]) currentTickWorldwideElementData[element.identifier] = { own: element.getFormattedDataOwnLine(), shared: element.getFormattedDataSharedLine() }; - } + } - let data = {}; - if (this.getElementsOnLine(elements, element.lineNumber).length === 1) { + let data; + if (this.getElementsOnLine(elements, element.lineNumber).length === 1) data = currentTickWorldwideElementData[element.identifier]?.own || element.getFormattedDataOwnLine(); - } else { + else data = currentTickWorldwideElementData[element.identifier]?.shared || element.getFormattedDataSharedLine(); - } + - if (currIndex !== 0 && this.isOnNewLine(elements, currIndex) && !this.dataIsWhitespace(data)) { + if (currIndex !== 0 && this.isOnNewLine(elements, currIndex) && !this.dataIsWhitespace(data)) this.infoMessage.rawtext.push({ text: '\n' }); - } - if (!this.isOnNewLine(elements, currIndex) && !this.dataIsWhitespace(data)) { + + if (!this.isOnNewLine(elements, currIndex) && !this.dataIsWhitespace(data)) this.infoMessage.rawtext.push({ text: ' ' }); - } + this.infoMessage.rawtext.push(data); } @@ -116,7 +117,7 @@ class InfoDisplay { } sendInfoMessage() { - if (this.infoMessage.rawtext.length == 0) + if (this.infoMessage.rawtext.length === 0) return; this.player.onScreenDisplay.setTitle(this.infoMessage); } diff --git a/Canopy [BP]/scripts/src/rules/infodisplay/infoDisplayElement.js b/Canopy [BP]/scripts/src/rules/infodisplay/infoDisplayElement.js index 433b41e..e6ac94c 100644 --- a/Canopy [BP]/scripts/src/rules/infodisplay/infoDisplayElement.js +++ b/Canopy [BP]/scripts/src/rules/infodisplay/infoDisplayElement.js @@ -6,12 +6,13 @@ class InfoDisplayElement { lineNumber; isWorldwide; - constructor(identifier, description, lineNumber, isWorldwide = false, contingentRules = []) { - if (this.constructor === InfoDisplayElement) { + constructor(ruleData, lineNumber, isWorldwide = false) { + if (this.constructor === InfoDisplayElement) throw new TypeError("Abstract class 'InfoDisplayElement' cannot be instantiated directly."); - } - this.identifier = identifier; - this.rule = InfoDisplayRule.getRule(identifier) || new InfoDisplayRule({ identifier, description, contingentRules }); + if (!ruleData.identifier || !ruleData.description) + throw new Error("ruleData must have 'identifier' and 'description' properties."); + this.identifier = ruleData.identifier; + this.rule = InfoDisplayRule.getRule(this.identifier) || new InfoDisplayRule({ identifier: this.identifier, description: ruleData.description, contingentRules: ruleData.contingentRules }); this.isWorldwide = isWorldwide; this.lineNumber = lineNumber; } diff --git a/Canopy [BP]/scripts/src/rules/infodisplay/simulationMap.js b/Canopy [BP]/scripts/src/rules/infodisplay/simulationMap.js index 01bde0f..338998f 100644 --- a/Canopy [BP]/scripts/src/rules/infodisplay/simulationMap.js +++ b/Canopy [BP]/scripts/src/rules/infodisplay/simulationMap.js @@ -5,8 +5,9 @@ import { getConfig, getLoadedChunksMessage } from '../../commands/simmap.js'; class SimulationMap extends InfoDisplayElement { player; - constructor(player) { - super('simulationMap', { translate: 'rules.infoDisplay.simulationMap' }, 11); + constructor(player, displayLine) { + const ruleData = { identifier: 'simulationMap', description: { translate: 'rules.infoDisplay.simulationMap' } }; + super(ruleData, displayLine); this.player = player; } @@ -15,9 +16,9 @@ class SimulationMap extends InfoDisplayElement { if (config.isLocked) { const dimension = world.getDimension(config.dimension); return getLoadedChunksMessage(dimension, config.location, config.distance); - } else { + } return getLoadedChunksMessage(this.player.dimension, this.player.location, config.distance); - } + } getFormattedDataSharedLine() { diff --git a/Canopy [BP]/scripts/src/rules/infodisplay/tps.js b/Canopy [BP]/scripts/src/rules/infodisplay/tps.js index a4d6798..14c4d7f 100644 --- a/Canopy [BP]/scripts/src/rules/infodisplay/tps.js +++ b/Canopy [BP]/scripts/src/rules/infodisplay/tps.js @@ -2,11 +2,10 @@ import InfoDisplayElement from './InfoDisplayElement.js'; import { DataTPS } from 'src/tps'; import { TicksPerSecond } from '@minecraft/server'; -const DISPLAY_LINE = 4; - class TPS extends InfoDisplayElement { - constructor() { - super('tps', { translate: 'rules.infoDisplay.tps' }, DISPLAY_LINE, true); + constructor(displayLine) { + const ruleData = { identifier: 'tps', description: { translate: 'rules.infoDisplay.tps' } }; + super(ruleData, displayLine, true); } getFormattedDataOwnLine() { diff --git a/Canopy [BP]/scripts/src/rules/noTileDrops.js b/Canopy [BP]/scripts/src/rules/noTileDrops.js index b41df84..19c7446 100644 --- a/Canopy [BP]/scripts/src/rules/noTileDrops.js +++ b/Canopy [BP]/scripts/src/rules/noTileDrops.js @@ -2,6 +2,8 @@ import { Rule } from 'lib/canopy/Canopy'; import { system, world } from '@minecraft/server'; import Utils from 'include/utils'; +const REMOVAL_DISTANCE = 2.5; + new Rule({ category: 'Rules', identifier: 'noTileDrops', @@ -29,10 +31,12 @@ world.afterEvents.entitySpawn.subscribe(async (entityEvent) => { const item = entityEvent.entity; const brokenBlockEvents = brokenBlockEventsThisTick.concat(brokenBlockEventsLastTick); - const brokenBlockEvent = brokenBlockEvents.find(blockEvent => - Utils.calcDistance(blockEvent.block.location, item.location) < 2.5 - ); + const brokenBlockEvent = brokenBlockEvents.find(blockEvent => isItemWithinRemovalDistance(blockEvent.block.location, item)); if (!brokenBlockEvent) return; item.remove(); -}); \ No newline at end of file +}); + +function isItemWithinRemovalDistance(location, item) { + return Utils.calcDistance(location, item.location) < REMOVAL_DISTANCE; +} \ No newline at end of file diff --git a/Canopy [BP]/scripts/src/rules/pistonBedrockBreaking.js b/Canopy [BP]/scripts/src/rules/pistonBedrockBreaking.js index e58ccda..c5f27e3 100644 --- a/Canopy [BP]/scripts/src/rules/pistonBedrockBreaking.js +++ b/Canopy [BP]/scripts/src/rules/pistonBedrockBreaking.js @@ -14,7 +14,7 @@ world.afterEvents.pistonActivate.subscribe(async (event) => { if (!await Rule.getNativeValue('pistonBedrockBreaking') || !['Expanding', 'Retracting'].includes(event.piston.state)) return; const piston = event.piston; const block = event.block; - let directionState = DirectionStateFinder.getDirectionState(block.permutation); + const directionState = DirectionStateFinder.getDirectionState(block.permutation); if (directionState === undefined) return; directionState.value = DirectionStateFinder.getRawMirroredDirection(block); if (piston.state === 'Expanding') { @@ -27,7 +27,7 @@ world.afterEvents.pistonActivate.subscribe(async (event) => { const oldPiston = getBlockFromPistonList(block); if (oldPiston !== undefined) { const blockType = block.typeId; - const dropLocation = { x: block.location.x + .5, y: block.location.y + .5, z: block.location.z + .5 }; + const dropLocation = block.center(); block.setType('minecraft:air'); event.dimension.spawnItem(new ItemStack(blockType, 1), dropLocation); insideBedrockPistonList.splice(insideBedrockPistonList.indexOf(oldPiston), 1); @@ -40,9 +40,9 @@ function getBlockFromPistonList(block) { if (pistonBlock.dimensionId === block.dimension.id && pistonBlock.location.x === block.location.x && pistonBlock.location.y === block.location.y - && pistonBlock.location.z === block.location.z) { + && pistonBlock.location.z === block.location.z) return pistonBlock; - } + } return undefined; } \ No newline at end of file diff --git a/Canopy [BP]/scripts/src/rules/playerSit.js b/Canopy [BP]/scripts/src/rules/playerSit.js index 4cc2b1d..2e9cb6b 100644 --- a/Canopy [BP]/scripts/src/rules/playerSit.js +++ b/Canopy [BP]/scripts/src/rules/playerSit.js @@ -39,7 +39,9 @@ system.runInterval(() => { }); function sit(player) { - const rideableEntity = player.dimension.spawnEntity('canopy:rideable', { x: player.location.x, y: player.location.y - 0.12, z: player.location.z }); + const heightAdjustment = -0.12; + const entityLocation = { x: player.location.x, y: player.location.y + heightAdjustment, z: player.location.z }; + const rideableEntity = player.dimension.spawnEntity('canopy:rideable', entityLocation); rideableEntity.setRotation(player.getRotation()); rideableEntity.getComponent('rideable').addRider(player); } @@ -47,9 +49,8 @@ function sit(player) { function cleanupRideableEntities() { DimensionTypes.getAll().forEach((dimensionType) => { world.getDimension(dimensionType.typeId).getEntities({ type: 'canopy:rideable' }).forEach(entity => { - if (!entity.getComponent('rideable').getRiders().length > 0) { + if (!entity.getComponent('rideable').getRiders().length > 0) entity.remove(); - } }); }); } diff --git a/Canopy [BP]/scripts/src/rules/refillHand.js b/Canopy [BP]/scripts/src/rules/refillHand.js index 0946c14..0e349b1 100644 --- a/Canopy [BP]/scripts/src/rules/refillHand.js +++ b/Canopy [BP]/scripts/src/rules/refillHand.js @@ -21,12 +21,10 @@ function captureEvent(event) { function processRefillHand(player, beforeItemStack, afterItemStack) { const playerInventory = player.getComponent('inventory')?.container; - if (beforeItemStack === undefined || !hasArrowInCorrectSlot(playerInventory)) { - return; - } - if (hasRunOutOfItems(beforeItemStack, afterItemStack)) { + if (beforeItemStack === undefined || !hasArrowInCorrectSlot(playerInventory)) return; + if (hasRunOutOfItems(beforeItemStack, afterItemStack)) refillHand(player, playerInventory, beforeItemStack); - } + } function hasArrowInCorrectSlot(playerInventory) { diff --git a/Canopy [BP]/scripts/src/rules/renewableElytra.js b/Canopy [BP]/scripts/src/rules/renewableElytra.js index aab9af8..660029e 100644 --- a/Canopy [BP]/scripts/src/rules/renewableElytra.js +++ b/Canopy [BP]/scripts/src/rules/renewableElytra.js @@ -1,6 +1,8 @@ import { Rule } from "lib/canopy/Canopy"; import { ItemStack, world } from "@minecraft/server"; +const DROP_CHANCE = 0.01; + new Rule({ category: 'Rules', identifier: 'renewableElytra', @@ -11,7 +13,7 @@ world.afterEvents.entityDie.subscribe((event) => { if (!Rule.getValue('renewableElytra')) return; const entity = event.deadEntity; if (entity?.typeId === 'minecraft:phantom' && event.damageSource.damagingProjectile?.typeId === 'minecraft:shulker_bullet') { - if (Math.random() > 0.01) return; + if (Math.random() > DROP_CHANCE) return; entity.dimension.spawnItem(new ItemStack('minecraft:elytra', 1), entity.location); } }); \ No newline at end of file diff --git a/Canopy [BP]/scripts/src/rules/tntPrimeMaxMomentum.js b/Canopy [BP]/scripts/src/rules/tntPrimeMaxMomentum.js index 8e158c8..180bf98 100644 --- a/Canopy [BP]/scripts/src/rules/tntPrimeMaxMomentum.js +++ b/Canopy [BP]/scripts/src/rules/tntPrimeMaxMomentum.js @@ -1,4 +1,4 @@ -import { Rule } from "lib/canopy/Canopy"; +import { Rule, Rules } from "lib/canopy/Canopy"; import { world, system } from '@minecraft/server'; new Rule({ @@ -13,10 +13,10 @@ const MAX_VELOCITY = 0.019600000232548116; // From vanilla TNT: 49/2500 with som world.afterEvents.entitySpawn.subscribe(async (event) => { if (event.entity.typeId !== 'minecraft:tnt' || !await Rule.getValue('tntPrimeMaxMomentum')) return; const entity = event.entity; - if (await Rule.getValue('dupeTnt')) { + if (Rules.getNativeValue('dupeTnt')) { system.runTimeout(() => { if (!entity.isValid()) return; - correctErrorAndNegateXZVelocity(entity); + haltHorizontalVelocity(entity); applyHardcodedImpulse(entity); }, 1); } else { @@ -25,23 +25,38 @@ world.afterEvents.entitySpawn.subscribe(async (event) => { } }); -function correctErrorAndNegateXZVelocity(entity) { +function haltHorizontalVelocity(entity) { const velocity = entity.getVelocity(); - const blockCenter = { x: Math.floor(entity.location.x) + 0.5, y: entity.location.y, z: Math.floor(entity.location.z) + 0.5 }; - entity.teleport(blockCenter); + centerEntityPosition(entity); // Entity could be off-center, resulting in a non-straight drop entity.applyImpulse({ x: 0, y: velocity.y, z: 0 }); } +function centerEntityPosition(entity) { + const blockCenter = getHorizontalCenter(entity.location); + entity.teleport(blockCenter); +} + +function getHorizontalCenter(location) { + const halfABlock = 0.5; + return { x: Math.floor(location.x) + halfABlock, y: location.y, z: Math.floor(location.z) + halfABlock }; +} + function negateXZVelocity(entity) { const velocity = entity.getVelocity(); entity.applyImpulse({ x: -velocity.x, y: 0, z: -velocity.z }); } function applyHardcodedImpulse(entity) { - const randValues = [-MAX_VELOCITY, 0, MAX_VELOCITY]; - const randX = randValues[Math.floor(Math.random() * 3)]; - const randZ = randValues[Math.floor(Math.random() * 3)]; + const randX = getRandomMaxMomentumValue(); + const randZ = getRandomMaxMomentumValue(); entity.applyImpulse({ x: randX, y: 0, z: randZ }); } -export { negateXZVelocity, correctErrorAndNegateXZVelocity } \ No newline at end of file +function getRandomMaxMomentumValue() { + const randValues = [-MAX_VELOCITY, 0, MAX_VELOCITY]; + const randIndex = Math.floor(Math.random() * randValues.length); + const randValue = randValues[randIndex]; + return randValue; +} + +export { negateXZVelocity, haltHorizontalVelocity } \ No newline at end of file diff --git a/Canopy [BP]/scripts/src/rules/tntPrimeNoMomentum.js b/Canopy [BP]/scripts/src/rules/tntPrimeNoMomentum.js index ab7e556..fffe814 100644 --- a/Canopy [BP]/scripts/src/rules/tntPrimeNoMomentum.js +++ b/Canopy [BP]/scripts/src/rules/tntPrimeNoMomentum.js @@ -1,6 +1,6 @@ -import { Rule } from 'lib/canopy/Canopy'; +import { Rule, Rules } from 'lib/canopy/Canopy'; import { world, system } from '@minecraft/server'; -import { negateXZVelocity, correctErrorAndNegateXZVelocity } from './tntPrimeMaxMomentum.js'; +import { negateXZVelocity, haltHorizontalVelocity } from './tntPrimeMaxMomentum.js'; new Rule({ category: 'Rules', @@ -12,10 +12,10 @@ new Rule({ world.afterEvents.entitySpawn.subscribe(async (event) => { if (event.entity.typeId !== 'minecraft:tnt' || !await Rule.getValue('tntPrimeNoMomentum')) return; const entity = event.entity; - if (await Rule.getValue('dupeTnt')) { + if (Rules.getNativeValue('dupeTnt')) { system.runTimeout(() => { if (!entity.isValid()) return; - correctErrorAndNegateXZVelocity(entity); + haltHorizontalVelocity(entity); }, 1); } else { negateXZVelocity(entity); diff --git a/Canopy [BP]/scripts/src/validWorld.js b/Canopy [BP]/scripts/src/validWorld.js index a6d96e2..d350d22 100644 --- a/Canopy [BP]/scripts/src/validWorld.js +++ b/Canopy [BP]/scripts/src/validWorld.js @@ -2,10 +2,10 @@ import { world, system } from '@minecraft/server'; import ProbeManager from 'src/classes/ProbeManager'; import { Extensions } from '../lib/canopy/Canopy'; -let hasShownWelcome = {}; +const hasShownWelcome = {}; world.afterEvents.playerJoin.subscribe((event) => { - let runner = system.runInterval(() => { + const runner = system.runInterval(() => { const players = world.getPlayers({ name: event.playerName }); players.forEach(player => { if (!player) return; @@ -37,7 +37,6 @@ function displayWelcome(player) { graphic += `§a+ ----- +\n`; player.sendMessage({ rawtext: [{ text: graphic }, { translate: 'generic.welcome.start' }] }); const extensions = Extensions.getVersionedNames(); - if (extensions.length > 0) { + if (extensions.length > 0) player.sendMessage({ translate: 'generic.welcome.extensions', with: [extensions.join('§r§7, §a§o')] }); - } } diff --git a/__tests__/BP/scripts/include/data.test.js b/__tests__/BP/scripts/include/data.test.js index cc73764..39aab18 100644 --- a/__tests__/BP/scripts/include/data.test.js +++ b/__tests__/BP/scripts/include/data.test.js @@ -20,9 +20,8 @@ async function fetchBedrockSamplesData(entityType) { if (typeof response.data == 'string') { const stringData = stripJsonComments(response.data); return JSON.parse(stringData); - } else { - return response.data; - } + } + return response.data; } describe.concurrent('categoryToMobMap', () => { diff --git a/__tests__/BP/scripts/lib/canopy/Extension.test.js b/__tests__/BP/scripts/lib/canopy/Extension.test.js index 20c94dd..9085dee 100644 --- a/__tests__/BP/scripts/lib/canopy/Extension.test.js +++ b/__tests__/BP/scripts/lib/canopy/Extension.test.js @@ -42,14 +42,14 @@ describe('Extension', () => { }); it('should handle description as an object', () => { - const extensionData = { + const extensionDataWithRawTextDescription = { name: 'Test Extension', version: '1.0.0', author: 'Author Name', description: { text: 'This is a test extension' } }; - const extension = new Extension(extensionData); - expect(extension.getDescription()).toEqual({ text: 'This is a test extension' }); + const extensionWithRawTextDescription = new Extension(extensionDataWithRawTextDescription); + expect(extensionWithRawTextDescription.getDescription()).toEqual({ text: 'This is a test extension' }); }); }); @@ -165,6 +165,6 @@ describe('Extension', () => { expect(extension.makeID({})).toBeNull(); expect(extension.makeID(null)).toBeNull(); expect(extension.makeID(undefined)).toBeNull(); - }); + }); }); }); \ No newline at end of file diff --git a/__tests__/BP/scripts/lib/canopy/Rule.test.js b/__tests__/BP/scripts/lib/canopy/Rule.test.js index 2a6faa1..e349fc0 100644 --- a/__tests__/BP/scripts/lib/canopy/Rule.test.js +++ b/__tests__/BP/scripts/lib/canopy/Rule.test.js @@ -127,22 +127,22 @@ describe('Rule', () => { expect(Rules.get('test_rule').parseValue('{"test": "value"}')).toEqual({ test: 'value' }); expect(Rules.get('test_rule').parseValue('["test", "value"]')).toEqual(['test', 'value']); expect(Rules.get('test_rule').parseValue('true')).toBe(true); - expect(Rules.get('test_rule').parseValue('null')).toBe(null); + expect(Rules.get('test_rule').parseValue('null')).toBeNull(); expect(Rules.get('test_rule').parseValue('1')).toBe(1); expect(Rules.get('test_rule').parseValue('"test"')).toBe('test'); expect(Rules.get('test_rule').parseValue(1)).toBe(1); }); it('should return undefined if the value is \'undefined\'', () => { - expect(Rules.get('test_rule').parseValue('undefined')).toBe(undefined); + expect(Rules.get('test_rule').parseValue('undefined')).toBeUndefined(); }); it('should return NaN if the value is \'NaN\'', () => { - expect(Rules.get('test_rule').parseValue('NaN')).toBe(NaN); + expect(Rules.get('test_rule').parseValue('NaN')).toBeNaN(); }); it('should return null for invalid JSON strings', () => { - expect(Rules.get('test_rule').parseValue('invalid')).toBe(null); + expect(Rules.get('test_rule').parseValue('invalid')).toBeNull(); }); }); diff --git a/eslint.config.js b/eslint.config.js index 5b4cf2a..189014f 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -16,7 +16,6 @@ export default [ '**/scripts/lib/mt.js', '**/scripts/lib/ipc/', '**/scripts/lib/SRCItemDatabase.js', - '**/__tests__/', ] }, js.configs.recommended, @@ -35,16 +34,16 @@ export default [ "no-duplicate-imports": "error", "no-template-curly-in-string": "error", "no-unreachable-loop": "error", - "no-use-before-define": "error", + "no-use-before-define": ["error", { "functions": false }], "no-useless-assignment": "error", // Suggestions: "arrow-body-style": "error", "block-scoped-var": "error", "camelcase": [ "warn", { "ignoreImports": true } ], - "curly": ["error", "multi", "consistent"], + "curly": ["error", "multi-or-nest", "consistent"], "default-case": "error", "default-case-last": "error", - "eqeqeq": "error", + "eqeqeq": ["error", "smart"], "func-style": ["error", "declaration", { "allowArrowFunctions": true }], "max-classes-per-file": ["error", 1], // { ignoreExpressions: true } "max-depth": ["warn"], @@ -54,13 +53,11 @@ export default [ "new-cap": "error", "no-else-return": "error", "no-lonely-if": "error", - "no-magic-numbers": ["error", { "ignore": [0, 1], "ignoreArrayIndexes": true } ], "no-negated-condition": "error", "no-nested-ternary": "error", "no-return-assign": "error", "no-shadow": "error", "no-throw-literal": "error", - "no-undefined": "error", "no-underscore-dangle": "error", "no-unneeded-ternary": "error", "no-useless-computed-key": "error", @@ -75,5 +72,12 @@ export default [ "require-await": "error", "yoda": "error", } + }, + { + files: ["**/__tests__/**"], + rules: { + "max-lines-per-function": "off", + "max-lines": "off", + } } ]; \ No newline at end of file diff --git a/package.json b/package.json index aeca3a8..e506b15 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ }, "scripts": { "test": "vitest run --coverage", - "lint": "eslint ." + "lint": "eslint . --fix" }, "devDependencies": { "@eslint/compat": "^1.2.5",