diff --git a/.gitignore b/.gitignore index 4b6078b..a24f8c6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ ### Dist folder ### dist -.tsbuildinfo +tsconfig.tsbuildinfo ### VisualStudioCode Patch ### .history diff --git a/.npmignore b/.npmignore index 40aeba5..f3a4dd3 100644 --- a/.npmignore +++ b/.npmignore @@ -1,6 +1,5 @@ node_modules .prettierrc.js -.tsbuildinfo .eslintignore .eslintrc.cjs .editorconfig diff --git a/README.md b/README.md index 0bc0a3c..bf0344b 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ You don't need to remember commands syntax anymore. This autocompletion works for all resources: commands, predicates, loot tables, advancements... ## 📂 Better organisation of resources -You can have multiple functions, advancements, loot tables per files - or you can keep the vanilla organisation, and have only 1 per file. Sandstone allows you to organise your datapack as you prefer, without sticking to Mojang's conventions. +You can have multiple functions, advancements, loot tables per files - or you can keep the vanilla organization, and have only 1 per file. Sandstone allows you to organize your packs as you prefer, without sticking to Mojang's conventions. You also benefit from all the capabilities of a real programming language: multiline comments, indentation, documentation... @@ -55,4 +55,4 @@ If you want to support Sandstone, the simplest way is to star the repository! It # Getting started -See the [Getting Started](https://sandstone-documentation.vercel.app/docs) section on [sandstone-documentation.vercel.app](https://sandstone-documentation.vercel.app/) to start using Sandstone! +See the [Getting Started](https://sandstone.dev/docs) section on [sandstone.dev](https://sandstone.dev/) to start using Sandstone! diff --git a/package.json b/package.json index 3705a61..2d03e24 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "sandstone", - "description": "Sandstone, a Typescript library for Minecraft datapacks.", - "version": "1.0.0-alpha.6", + "description": "Sandstone, a Typescript library for Minecraft datapacks & resource packs.", + "version": "1.0.0-beta.0", "contributors": [ { "name": "TheMrZZ - Florian ERNST", @@ -65,7 +65,7 @@ "engines": { "node": ">=12.22.3" }, - "homepage": "https://sandstone-documentation.vercel.app/", + "homepage": "https://sandstone.dev", "keywords": [ "autocompletion", "creator", diff --git a/src/commands/implementations/entity/execute.ts b/src/commands/implementations/entity/execute.ts index eaeeeab..9240223 100644 --- a/src/commands/implementations/entity/execute.ts +++ b/src/commands/implementations/entity/execute.ts @@ -1,3 +1,7 @@ +import { + type Macroable, type MacroArgument, type MCFunctionNode, type PredicateClass, + isMacroArgument, +} from 'sandstone/core' import { ContainerCommandNode } from 'sandstone/core/nodes' import { makeCallable, toMinecraftResourceName } from 'sandstone/utils' import { @@ -16,9 +20,6 @@ import type { Coordinates, DIMENSIONS, ENTITY_TYPES, MultipleEntitiesArgument, ObjectiveArgument, Range, Rotation, SingleEntityArgument, } from 'sandstone/arguments' import type { SandstoneCommands } from 'sandstone/commands' -import type { - Macroable, MacroArgument, MCFunctionNode, PredicateClass, -} from 'sandstone/core' import type { Node } from 'sandstone/core/nodes' import type { _RawMCFunctionClass, @@ -106,7 +107,7 @@ export class ExecuteCommandNode extends ContainerCommandNode { if (arg !== undefined && arg !== null) { // Yes these are cursed, unfortunately, there's not really a better way to do this as visitors only visit the root nodes. if (typeof arg === 'object') { - if (Object.hasOwn(arg, 'toMacro') && (arg as MacroArgument)['local'].has(this.sandstoneCore.currentNode)) { + if (isMacroArgument(this.sandstoneCore, arg)) { this.isMacro = true args.push((arg as MacroArgument).toMacro()) @@ -131,12 +132,12 @@ export class ExecuteCommandNode extends ContainerCommandNode { let command = this.body[0].getValue() - if (command.startsWith('/')) { + if (command.startsWith('$')) { this.isMacro = true command = command.slice(1) } - return `${this.isMacro ? '/' : ''}${executeString} run ${command}` + return `${this.isMacro ? '$' : ''}${executeString} run ${command}` } createMCFunction = (currentMCFunction: MCFunctionNode | null) => { @@ -342,14 +343,14 @@ export class ExecuteIfUnlessCommand extends ExecuteComman if (isScore(args[2])) { finalArgs.push(args[2].target.toString(), args[2].objective.name) } else { - finalArgs.push(rangeParser(args[2])) + finalArgs.push(rangeParser(this.sandstoneCore, args[2])) } } else { finalArgs.push(targetParser(args[0]), isObjective(args[1]) ? args[1].name : args[1], args[2]) if (args[4]) { finalArgs.push(targetParser(args[3]), isObjective(args[4]) ? args[4].name : args[4]) } else { - finalArgs.push(rangeParser(args[3])) + finalArgs.push(rangeParser(this.sandstoneCore, args[3])) } } return this.nestedExecute(['score', ...finalArgs], true) diff --git a/src/commands/implementations/server/random.ts b/src/commands/implementations/server/random.ts index a92dd4d..860163a 100644 --- a/src/commands/implementations/server/random.ts +++ b/src/commands/implementations/server/random.ts @@ -4,8 +4,8 @@ import { rangeParser } from 'sandstone/variables/parsers' import { CommandArguments } from '../../helpers.js' import type { Range } from 'sandstone/arguments' -import type { LiteralUnion } from 'sandstone/utils.js' import type { Macroable } from 'sandstone/core' +import type { LiteralUnion } from 'sandstone/utils.js' export class RandomCommandNode extends CommandNode { command = 'random' as const @@ -25,7 +25,7 @@ export class RandomCommand extends CommandArguments { if (typeof sequence === 'string' && !sequence.includes(':')) { seq = `${this.sandstonePack.defaultNamespace}:${seq}` } - return this.finalCommand(['value', rangeParser(range), seq]) + return this.finalCommand(['value', rangeParser(this.sandstoneCore, range), seq]) } /** @@ -39,7 +39,7 @@ export class RandomCommand extends CommandArguments { if (sequence && typeof sequence === 'string' && !sequence.includes(':')) { seq = `${this.sandstonePack.defaultNamespace}:${seq}` } - return this.finalCommand(['roll', rangeParser(range), seq]) + return this.finalCommand(['roll', rangeParser(this.sandstoneCore, range), seq]) } /** diff --git a/src/commands/implementations/server/return.ts b/src/commands/implementations/server/return.ts index 1aca73b..8162424 100644 --- a/src/commands/implementations/server/return.ts +++ b/src/commands/implementations/server/return.ts @@ -34,12 +34,12 @@ export class ReturnRunCommandNode extends ContainerCommandNode { let command = this.body[0].getValue() - if (command.startsWith('/')) { + if (command.startsWith('$')) { this.isMacro = true command = command.slice(1) } - return `${this.isMacro ? '/' : ''}${this.command} run ${command}` + return `${this.isMacro ? '$' : ''}${this.command} run ${command}` } createMCFunction = (currentMCFunction: MCFunctionNode | null) => { diff --git a/src/core/Macro.ts b/src/core/Macro.ts index 5e032d9..e11157e 100644 --- a/src/core/Macro.ts +++ b/src/core/Macro.ts @@ -8,12 +8,18 @@ export class MacroArgument { public toMacro: () => string - readonly Macro = (strings: TemplateStringsArray, ...macros: (string | number | MacroArgument)[]) => new MacroLiteral(this.sandstoneCore, this.local, strings, macros) - constructor(protected sandstoneCore: SandstoneCore) { this.local = new Map() - this.toMacro = () => `$(${this.local.get(this.sandstoneCore.currentNode) || this.local.get(this.sandstoneCore.getCurrentMCFunctionOrThrow().resource.name)})` + this.toMacro = () => { + let currentMCFunctionName: string = '' + try { + currentMCFunctionName = sandstoneCore.getCurrentMCFunctionOrThrow().resource.name + // eslint-disable-next-line no-empty + } catch (e) {} + + return `$(${this.local.get(this.sandstoneCore.currentNode) || this.local.get(currentMCFunctionName)})` + } } } @@ -25,15 +31,21 @@ export function isMacroArgument(core: SandstoneCore, arg: any) { if (typeof arg === 'object' && Object.hasOwn(arg, 'toMacro')) { // eslint-disable-next-line prefer-destructuring const local = (arg as MacroArgument)['local'] - if (local.has(core.getCurrentMCFunctionOrThrow().resource.name) || local.has(core.currentNode)) return arg as MacroArgument + + let currentMCFunctionName: string = '' + try { + currentMCFunctionName = core.getCurrentMCFunctionOrThrow().resource.name + // eslint-disable-next-line no-empty + } catch (e) {} + if (arg instanceof MacroLiteral || local.has(currentMCFunctionName) || local.has(core.currentNode)) return arg as MacroArgument } return undefined } -class MacroLiteral extends MacroArgument { +export class MacroLiteral extends MacroArgument { public toMacro: () => string - constructor(public sandstoneCore: SandstoneCore, public local: Map, public strings: TemplateStringsArray, public macros: (MacroArgument | string | number)[]) { + constructor(public sandstoneCore: SandstoneCore, public strings: TemplateStringsArray, public macros: (MacroArgument | string | number)[]) { super(sandstoneCore) this.toMacro = () => { @@ -48,10 +60,6 @@ class MacroLiteral extends MacroArgument { if (typeof macro === 'string' || typeof macro === 'number') { result += `${macro}` } else { - const current = this.sandstoneCore.currentNode || this.sandstoneCore.getCurrentMCFunctionOrThrow().resource.name - - macro['local'].set(current, this.local.get(current)!) - result += macro.toMacro() } } diff --git a/src/core/nodes.ts b/src/core/nodes.ts index 18ad937..592e7e9 100644 --- a/src/core/nodes.ts +++ b/src/core/nodes.ts @@ -1,6 +1,7 @@ +import { type MacroArgument, isMacroArgument } from './Macro.js' + import type { SandstonePack } from 'sandstone/pack' import type { LoopArgument } from 'sandstone/variables' -import type { MacroArgument } from './Macro.js' import type { MCFunctionClass, MCFunctionNode } from './resources/datapack/index.js' import type { SandstoneCore } from './sandstoneCore.js' @@ -76,7 +77,7 @@ export abstract class CommandNode extends No if (arg !== undefined && arg !== null) { // Yes these are cursed, unfortunately, there's not really a better way to do this as visitors only visit the root nodes. if (typeof arg === 'object') { - if (Object.hasOwn(arg, 'toMacro') && (arg as MacroArgument)['local'].has(this.sandstoneCore.currentNode)) { + if (isMacroArgument(this.sandstoneCore, arg)) { this.isMacro = true filteredArgs.push((arg as MacroArgument).toMacro()) @@ -91,7 +92,7 @@ export abstract class CommandNode extends No } } - return `${this.isMacro ? '/' : ''}${this.command} ${filteredArgs.join(' ')}` + return `${this.isMacro ? '$' : ''}${this.command} ${filteredArgs.join(' ')}` } /** diff --git a/src/core/resources/datapack/mcfunction.ts b/src/core/resources/datapack/mcfunction.ts index 3ff2924..3932c81 100644 --- a/src/core/resources/datapack/mcfunction.ts +++ b/src/core/resources/datapack/mcfunction.ts @@ -336,56 +336,35 @@ export class _RawMCFunctionClass this.commands.schedule.function(this.name, delay, type), } - get push() { - const commands = new Proxy(this.pack.commands, { - get: (target, p, receiver) => { - this.core.enterMCFunction(this) - this.core.insideContext(this.node, () => (this.pack.commands as any)[p], false) - this.core.exitMCFunction() - }, - }) - - return makeCallable(commands, (...contents: _RawMCFunctionClass[] | [() => any]) => { - if (contents[0] instanceof _RawMCFunctionClass) { - for (const mcfunction of contents as _RawMCFunctionClass[]) { - this.node.body.push(...mcfunction.node.body) - } - } else { - this.core.enterMCFunction(this) - this.core.insideContext(this.node, contents[0], false) - this.core.exitMCFunction() + push(...contents: _RawMCFunctionClass[] | [() => any]) { + if (contents[0] instanceof _RawMCFunctionClass) { + for (const mcfunction of contents as _RawMCFunctionClass[]) { + this.node.body.push(...mcfunction.node.body) } - }, true) + } else { + this.core.enterMCFunction(this) + this.core.insideContext(this.node, contents[0], false) + this.core.exitMCFunction() + } } - get unshift() { + unshift(...contents: _RawMCFunctionClass[] | [() => any]) { const fake = new MCFunctionClass(this.core, 'fake', { addToSandstoneCore: false, creator: 'sandstone', onConflict: 'ignore', }) - const commands = new Proxy(this.pack.commands, { - get: (target, p, receiver) => { - this.core.enterMCFunction(fake) - this.core.insideContext(fake.node, () => (this.pack.commands as any)[p], false) - this.core.exitMCFunction() - this.node.body.unshift(...fake.node.body) - }, - }) - - return makeCallable(commands, (...contents: _RawMCFunctionClass[] | [() => any]) => { - if (contents[0] instanceof _RawMCFunctionClass) { - for (const mcfunction of contents as _RawMCFunctionClass[]) { - this.node.body.unshift(...mcfunction.node.body) - } - } else { - this.core.enterMCFunction(fake) - this.core.insideContext(fake.node, contents[0], false) - this.core.exitMCFunction() - this.node.body.unshift(...fake.node.body) + if (contents[0] instanceof _RawMCFunctionClass) { + for (const mcfunction of contents as _RawMCFunctionClass[]) { + this.node.body.unshift(...mcfunction.node.body) } - }, true) + } else { + this.core.enterMCFunction(fake) + this.core.insideContext(fake.node, contents[0], false) + this.core.exitMCFunction() + this.node.body.unshift(...fake.node.body) + } } splice(start: number, removeItems: number | 'auto', ...contents: _RawMCFunctionClass[] | [() => void]) { diff --git a/src/core/resources/resource.ts b/src/core/resources/resource.ts index 2c344af..057b889 100644 --- a/src/core/resources/resource.ts +++ b/src/core/resources/resource.ts @@ -72,8 +72,8 @@ export abstract class ResourceClass> this.packType = args.packType || file.packType - this.fileExtension = file.extension - this.fileEncoding = file.encoding === undefined ? 'utf8' : file.encoding + this.fileExtension = file.extension || 'json' + this.fileEncoding = file.encoding ?? 'utf8' this.pack = core.pack this.commands = core.pack.commands diff --git a/src/flow/Flow.ts b/src/flow/Flow.ts index 304bb04..e7fb760 100644 --- a/src/flow/Flow.ts +++ b/src/flow/Flow.ts @@ -206,11 +206,11 @@ export class Flow { MCFunction(`__sandstone:switch_${id}`, [value], () => { const index = Data('storage', `__sandstone:switch_${id}`, 'Index') - Macro.data.modify.storage(index.currentTarget, 'Index').set.from.storage(values.currentTarget, value.Macro`Values[{Value:${value}}}].Index`) + Macro.data.modify.storage(index.currentTarget, 'Index').set.from.storage(values.currentTarget, Macro`Values[{Value:${value}}}].Index`) const _if = flow.if(index, () => { MCFunction(`__sandstone:switch_${id}_inner`, [index], () => { - Macro.functionCmd(index.Macro`__sandstone:switch_${id}_case_${index}`) + Macro.functionCmd(Macro`__sandstone:switch_${id}_case_${index}`) })() }) if (_default) _if.else(() => _default?.[1]()) diff --git a/src/flow/conditions/command.ts b/src/flow/conditions/command.ts index a52cdd9..861b30c 100644 --- a/src/flow/conditions/command.ts +++ b/src/flow/conditions/command.ts @@ -28,6 +28,6 @@ export class CommandConditionNode extends SingleConditionNode { /** @ts-ignore */ return this.result(this.variable)._toMinecraftCondition().getCondition() } - return ['score', this.variable, 'matches', rangeParser(this.result)] + return ['score', this.variable, 'matches', rangeParser(this.sandstoneCore, this.result)] } } diff --git a/src/index.ts b/src/index.ts index 3182e35..6db3fe7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -249,14 +249,14 @@ export interface SandstoneConfig { /** * The world to save the packs in. * - * Incompatible with `root` and `path`. + * Incompatible with `root`. */ world?: string /** * Whether to save the resource pack & datapack in the `.minecraft/datapacks` & `.minecraft/resource_pack` folders. * - * Incompatible with `world` and `path`. + * Incompatible with `world`. */ root?: true diff --git a/src/pack/pack.ts b/src/pack/pack.ts index ef321f7..103cf21 100644 --- a/src/pack/pack.ts +++ b/src/pack/pack.ts @@ -3,11 +3,12 @@ import { SandstoneCommands } from 'sandstone/commands' import { AdvancementClass, AtlasClass, BlockStateClass, DamageTypeClass, FontClass, ItemModifierClass, LanguageClass, LootTableClass, + MacroLiteral, MCFunctionClass, ModelClass, PlainTextClass, PredicateClass, RecipeClass, SandstoneCore, SoundEventClass, TagClass, TextureClass, TrimMaterialClass, TrimPatternClass, } from 'sandstone/core' import { CustomResourceClass } from 'sandstone/core/resources/custom' import { Flow, SandstoneConditions } from 'sandstone/flow' -import { randomUUID } from 'sandstone/utils' +import { makeCallable, randomUUID } from 'sandstone/utils' import { coordinatesParser, DataArray, @@ -159,7 +160,7 @@ export class SandstonePack { readonly commands: SandstoneCommands - readonly Macro: SandstoneCommands + readonly Macro: SandstoneCommands & ((strings: TemplateStringsArray, ...macros: (string | number | MacroArgument)[]) => MacroLiteral) readonly conditions = SandstoneConditions @@ -181,7 +182,7 @@ export class SandstonePack { this.commands = new SandstoneCommands(this) // SandstonePack.Macro is only a type hack - this.Macro = this.commands as unknown as SandstoneCommands + this.Macro = makeCallable(this.commands, (strings: TemplateStringsArray, ...macros: (string | number | MacroArgument)[]) => new MacroLiteral(this.core, strings, macros), true) as unknown as this['Macro'] this.flow = new Flow(this.core) this.objectives = new Set() @@ -407,8 +408,6 @@ export class SandstonePack { if (!this.__rootStorage) { this.__rootStorage = new DataPointClass(this, 'storage', '__sandstone:variable', []) - this.initMCFunction.push.data.merge.storage('__sandstone:variable', {}) - return this.__rootStorage } @@ -532,14 +531,14 @@ export class SandstonePack { MCFunction( name: string, - environment_variables: ENV, + environmentVariables: ENV, callback: (loop: MCFunctionClass) => void, options?: MCFunctionArgs ): MCFunctionClass MCFunction( name: string, - environment_variables: ENV, + environmentVariables: ENV, callback: (loop: MCFunctionClass, ...params: PARAMS) => void, options?: MCFunctionArgs ): MCFunctionClass @@ -556,7 +555,7 @@ export class SandstonePack { options?: MCFunctionArgs ] | [ name: string, - environment_variables: ENV, + environmentVariables: ENV, callback: (this: MCFunctionClass, ...params: PARAMS extends readonly MacroArgument[] ? PARAMS : []) => void, options?: MCFunctionArgs, ] diff --git a/src/utils.ts b/src/utils.ts index b5dc3f7..31bc770 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,3 +1,4 @@ +/* eslint-disable operator-linebreak */ /* eslint-disable @typescript-eslint/no-non-null-assertion */ import fs from 'fs-extra' import { coerce } from 'semver' @@ -6,11 +7,14 @@ import * as util from 'util' import { FormatRegistry, Type } from '@sinclair/typebox' import type FetchType from 'node-fetch' +import type { Response } from 'node-fetch' import type { Static } from '@sinclair/typebox' import type { MultipleEntitiesArgument } from './arguments/selector.js' import type { UUIDinNumber } from './variables/UUID.js' -export const fetch = async (...args: Parameters) => (await import('node-fetch')).default(...args) +/* @ts-ignore */ +export const fetch: (input: URL | RequestInfo, init?: RequestInit | undefined) => Promise = Object.hasOwn(globalThis, 'fetch') ? + globalThis.fetch : async (...args: Parameters) => ((await import('node-fetch')).default(...args) as unknown as Promise) /** * Allows to get autocompletion on string unions, while still allowing generic strings. diff --git a/src/variables/DataSets.ts b/src/variables/DataSets.ts index 85e0428..a248558 100644 --- a/src/variables/DataSets.ts +++ b/src/variables/DataSets.ts @@ -136,6 +136,10 @@ export class DataIndexMapClass extends Iter return index } + const { + Macro, MCFunction, Variable, DataVariable, + } = this.pack + let _key: DataPointClass if (key instanceof DataPointClass) { @@ -143,19 +147,19 @@ export class DataIndexMapClass extends Iter } else if (Object.hasOwn(key, '_toDataPoint')) { _key = (key as DataPointPickClass)._toDataPoint() } else if (key instanceof Score) { - _key = this.pack.DataVariable().set(key) + _key = DataVariable().set(key) } - const index = this.pack.Variable(this.size()) + const index = Variable(this.size()) this.dataPoint.select('Keys').append(_key!) this.dataPoint.select('Values').append(value as NBTObject) - this.pack.MCFunction('__sandstone:variable/index_map/set', [_key!], () => { - const indexData = this.pack.DataVariable().set(index) + MCFunction('__sandstone:variable/index_map/set', [_key!], () => { + const indexData = DataVariable().set(index) - this.pack.Macro.data.modify.storage(this.dataPoint.currentTarget, _key.Macro`${this.dataPoint.path}.Index[${_key}]`).set.from.storage(indexData.currentTarget, indexData.path) + Macro.data.modify.storage(this.dataPoint.currentTarget, Macro`${this.dataPoint.path}.Index[${_key}]`).set.from.storage(indexData.currentTarget, indexData.path) })() this.dataPoint.select('Entries').append([]) @@ -176,6 +180,10 @@ export class DataIndexMapClass extends Iter get(key: Macroable): DataPointClass<'storage'> get(key: Macroable>, true>) { + const { + MCFunction, Macro, DataVariable, + } = this.pack + if (typeof key === 'string') { if (this.entries[key]) { return this.dataPoint.select(`Entries[${this.entries[key]}]`) @@ -183,14 +191,10 @@ export class DataIndexMapClass extends Iter const index = this.dataPoint.select('Index').select(key) - const { - MCFunction, Macro, DataVariable, - } = this.pack - const value = DataVariable() MCFunction('__sandstone:variable/index_map/get', [index], () => { - Macro.data.modify.storage(value.currentTarget, value.path).set.from.storage(this.dataPoint.currentTarget, index.Macro`Entries[${index}]`) + Macro.data.modify.storage(value.currentTarget, value.path).set.from.storage(this.dataPoint.currentTarget, Macro`Entries[${index}]`) })() return value @@ -202,18 +206,18 @@ export class DataIndexMapClass extends Iter } else if (Object.hasOwn(key, '_toDataPoint')) { _key = (key as DataPointPickClass)._toDataPoint() } else if (key instanceof Score) { - _key = this.pack.DataVariable().set(key) + _key = DataVariable().set(key) } - const output = this.pack.DataVariable() + const output = DataVariable() - this.pack.MCFunction('__sandstone:variable/index_map/get', [_key!], () => { - const index = this.pack.DataVariable() + MCFunction('__sandstone:variable/index_map/get', [_key!], () => { + const index = DataVariable() - this.pack.Macro.data.modify.storage(index.currentTarget, index.path).set.from.storage(this.dataPoint.currentTarget, _key.Macro`${this.dataPoint.path}.Index[${_key}]`) + Macro.data.modify.storage(index.currentTarget, index.path).set.from.storage(this.dataPoint.currentTarget, Macro`${this.dataPoint.path}.Index[${_key}]`) - this.pack.MCFunction('__sandstone:variable/index_map/_get', [index], () => { - this.pack.Macro.data.modify.storage(output.currentTarget, output.path).set.from.storage(this.dataPoint.currentTarget, _key.Macro`${this.dataPoint.path}.Entries[${index}]`) + MCFunction('__sandstone:variable/index_map/_get', [index], () => { + Macro.data.modify.storage(output.currentTarget, output.path).set.from.storage(this.dataPoint.currentTarget, Macro`${this.dataPoint.path}.Entries[${index}]`) })() })() @@ -221,13 +225,13 @@ export class DataIndexMapClass extends Iter } remove(key: Macroable>, true>) { + const { MCFunction, Macro, DataVariable } = this.pack + if (typeof key === 'string') { const index = this.dataPoint.select('Index').select(key) - const { MCFunction, Macro } = this.pack - MCFunction('__sandstone:variable/index_map/remove', [index], () => { - Macro.data.modify.storage(this.dataPoint.currentTarget, index.Macro`Entries[${index}]`).set.value(0) + Macro.data.modify.storage(this.dataPoint.currentTarget, Macro`Entries[${index}]`).set.value(0) index.remove() })() @@ -242,15 +246,15 @@ export class DataIndexMapClass extends Iter _key = (key as DataPointPickClass)._toDataPoint() } - const index = this.pack.DataVariable() + const index = DataVariable() - this.pack.MCFunction('__sandstone:variable/index_map/remove', [_key], () => { - this.pack.Macro.data.modify.storage(index.currentTarget, index.path).set.from.storage(this.dataPoint.currentTarget, _key.Macro`${this.dataPoint.path}.Index[${_key}]`) + MCFunction('__sandstone:variable/index_map/remove', [_key], () => { + Macro.data.modify.storage(index.currentTarget, index.path).set.from.storage(this.dataPoint.currentTarget, Macro`${this.dataPoint.path}.Index[${_key}]`) - this.pack.Macro.data.remove.storage(this.dataPoint.currentTarget, _key.Macro`${this.dataPoint.path}.Index[${_key}]`) + Macro.data.remove.storage(this.dataPoint.currentTarget, Macro`${this.dataPoint.path}.Index[${_key}]`) - this.pack.MCFunction('__sandstone:variable/index_map/_remove', [index], () => { - this.pack.Macro.data.modify.storage(this.dataPoint.currentTarget, index.Macro`${this.dataPoint.path}.Entries[${index}]`).set.value(0) + MCFunction('__sandstone:variable/index_map/_remove', [index], () => { + Macro.data.modify.storage(this.dataPoint.currentTarget, Macro`${this.dataPoint.path}.Entries[${index}]`).set.value(0) })() })() @@ -325,14 +329,16 @@ export class DataArrayClass extends IterableDa return this } - this.pack.MCFunction('__sandstone:variable/array/set', [index], () => { + const { Macro, MCFunction } = this.pack + + MCFunction('__sandstone:variable/array/set', [index], () => { if (value instanceof DataPointClass) { - this.pack.Macro.data.modify.storage(this.dataPoint.currentTarget, index.Macro`${this.dataPoint.path}[${index}]`).set.from.storage(value.currentTarget, value.path) + Macro.data.modify.storage(this.dataPoint.currentTarget, Macro`${this.dataPoint.path}[${index}]`).set.from.storage(value.currentTarget, value.path) } else if (typeof value === 'object' && Object.hasOwn(value, '_toDataPoint')) { const point = (value as DataPointPickClass)._toDataPoint() - this.pack.Macro.data.modify.storage(this.dataPoint.currentTarget, index.Macro`${this.dataPoint.path}[${index}]`).set.from.storage(point.currentTarget, point.path) + Macro.data.modify.storage(this.dataPoint.currentTarget, Macro`${this.dataPoint.path}[${index}]`).set.from.storage(point.currentTarget, point.path) } else { - this.pack.Macro.data.modify.storage(this.dataPoint.currentTarget, index.Macro`${this.dataPoint.path}[${index}]`).set.value(value) + Macro.data.modify.storage(this.dataPoint.currentTarget, Macro`${this.dataPoint.path}[${index}]`).set.value(value) } })() return this @@ -354,10 +360,13 @@ export class DataArrayClass extends IterableDa if (typeof index === 'number') { return this.dataPoint.select(`[${index}]`) } - const output = this.pack.DataVariable() - this.pack.MCFunction('__sandstone:variable/array/get', [index], () => { - this.pack.Macro.data.modify.storage(output.currentTarget, output.path).set.from.storage(this.dataPoint.currentTarget, index.Macro`${this.dataPoint.path}[${index}]`) + const { Macro, MCFunction, DataVariable } = this.pack + + const output = DataVariable() + + MCFunction('__sandstone:variable/array/get', [index], () => { + Macro.data.modify.storage(output.currentTarget, output.path).set.from.storage(this.dataPoint.currentTarget, Macro`${this.dataPoint.path}[${index}]`) })() return output @@ -369,8 +378,10 @@ export class DataArrayClass extends IterableDa return this } - this.pack.MCFunction('__sandstone:variable/array/remove', [index], () => { - this.pack.Macro.data.remove.storage(this.dataPoint.currentTarget, index.Macro`${this.dataPoint.path}[${index}]`) + const { MCFunction, Macro } = this.pack + + MCFunction('__sandstone:variable/array/remove', [index], () => { + Macro.data.remove.storage(this.dataPoint.currentTarget, Macro`${this.dataPoint.path}[${index}]`) })() return this } diff --git a/src/variables/Score.ts b/src/variables/Score.ts index 3f1fa9c..35a2d6d 100644 --- a/src/variables/Score.ts +++ b/src/variables/Score.ts @@ -613,7 +613,7 @@ export class Score extends MacroArgument implements ConditionClass, ComponentCla * @param range The range to compare the current score against. */ matches = (range: Range) => ({ - _toMinecraftCondition: () => new this.sandstonePack.conditions.Score(this.sandstonePack.core, [`${this.target}`, `${this.objective}`, 'matches', rangeParser(range)]), + _toMinecraftCondition: () => new this.sandstonePack.conditions.Score(this.sandstonePack.core, [`${this.target}`, `${this.objective}`, 'matches', rangeParser(this.sandstoneCore, range)]), }) match = (minimum: number, maximum: number, callback: (num: number) => void) => { @@ -634,6 +634,6 @@ export class Score extends MacroArgument implements ConditionClass, ComponentCla MCFunction(`__sandstone:score_match/${matcher}/${i}`, () => callback(i)) } - return MCFunction(`__sandstone:score_match/${matcher}`, [score], () => Macro.returnCmd.run.functionCmd(score.Macro`__sandstone:score_match/${matcher}/${score}`)) + return MCFunction(`__sandstone:score_match/${matcher}`, [score], () => Macro.returnCmd.run.functionCmd(Macro`__sandstone:score_match/${matcher}/${score}`)) } } diff --git a/src/variables/Selector.ts b/src/variables/Selector.ts index b30ad26..8941225 100644 --- a/src/variables/Selector.ts +++ b/src/variables/Selector.ts @@ -6,12 +6,12 @@ import { rangeParser } from 'sandstone/variables/parsers' import type { ENTITY_TYPES, GAMEMODES, JSONTextComponent, Range, RootNBT, } from 'sandstone/arguments' -import type { PredicateClass } from 'sandstone/core' +import type { PredicateClass, SandstoneCore } from 'sandstone/core' import type { SandstonePack } from 'sandstone/pack' +import type { Macroable } from '../core/Macro.js' import type { LiteralUnion } from '../utils.js' import type { ConditionTextComponentClass, SelectorPickClass } from './abstractClasses.js' import type { LabelClass } from './Label.js' -import type { Macroable } from '../core/Macro.js' import type { NotNBT } from './nbt/NBTs.js' type ScoreArgument = Record> @@ -184,8 +184,8 @@ export type SelectorProperties {myScore=0..}`, `{ myScore: [-Infinity, 5] } => {myScore='..5'}`, 8 => '8' -function parseScore(scores: ScoreArgument): string { - return `{${Object.entries(scores).map(([scoreName, value]) => [scoreName, rangeParser(value)].join('=')).join(', ')}}` +function parseScore(core: SandstoneCore, scores: ScoreArgument): string { + return `{${Object.entries(scores).map(([scoreName, value]) => [scoreName, rangeParser(core, value)].join('=')).join(', ')}}` } // Returns the string representation of advancements @@ -236,7 +236,7 @@ export class SelectorClass) => result.push(['scores', parseScore(scores)]), + scores: (scores: ScoreArgument) => result.push(['scores', parseScore(this.sandstonePack.core, scores)]), // Parse potentially multiple nbt nbt: (nbt: RootNBT | RootNBT[]) => { @@ -281,7 +281,7 @@ export class SelectorClass) => result.push(['distance', rangeParser(range_)]), + distance: (range_: Range) => result.push(['distance', rangeParser(this.sandstonePack.core, range_)]), } as const for (const [baseName, modifier] of Object.entries(modifiers)) { diff --git a/src/variables/parsers.ts b/src/variables/parsers.ts index 8e54c97..cb24ffd 100644 --- a/src/variables/parsers.ts +++ b/src/variables/parsers.ts @@ -1,9 +1,10 @@ +import { type MacroArgument, isMacroArgument } from '../core/Macro.js' import { VectorClass } from './Coordinates.js' import type { Coordinates, Range, Rotation, STRUCTURE_MIRROR, STRUCTURE_ROTATION, } from 'sandstone/arguments' -import type { MacroArgument } from '../core/Macro.js' +import type { SandstoneCore } from 'sandstone/core/sandstoneCore.js' // PARSERS export function arrayToArgsParser(args: unknown): ( typeof args extends string[] ? VectorClass : typeof args @@ -36,7 +37,7 @@ export function rotationParser(rotation: T): ( } // Sanitize score values. null => '', Infinity => '', any number => itself -export const sanitizeValue = (value: MacroArgument | number | string | null | undefined): string => { +export const sanitizeValue = (core: SandstoneCore, value: MacroArgument | number | string | null | undefined): string => { if (value === undefined || value === null) { return '' } @@ -45,8 +46,8 @@ export const sanitizeValue = (value: MacroArgument | number | string | null | un return value } - if (typeof value === 'object' && value.toMacro) { - return value.toMacro() + if (isMacroArgument(core, value)) { + return (value as MacroArgument).toMacro() } if (Number.isFinite(value)) { @@ -58,9 +59,9 @@ export const sanitizeValue = (value: MacroArgument | number | string | null | un } // Returns the string representation of a range. [0, null] => '0..', [-Infinity, 5] => '..5', 8 => '8' -export const rangeParser = (range: Range | MacroArgument): string => { +export const rangeParser = (core: SandstoneCore, range: Range | MacroArgument): string => { if (Array.isArray(range)) { - return `${sanitizeValue(range[0])}..${sanitizeValue(range[1])}` + return `${sanitizeValue(core, range[0])}..${sanitizeValue(core, range[1])}` } return range.toString() } diff --git a/tsconfig.json b/tsconfig.json index 2adc61b..9c56e87 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -67,9 +67,8 @@ "outDir": "./dist", /* Redirect output structure to the directory. */ "rootDir": "src", // "composite": true, /* Enable project compilation */ - "tsBuildInfoFile": ".tsbuildinfo", /* Specify file to store incremental compilation information */ + "tsBuildInfoFile": "tsconfig.tsbuildinfo", /* Specify file to store incremental compilation information */ // "removeComments": true, /* Do not emit comments to output. */ - // "noEmit": true, /* Do not emit outputs. */ // "importHelpers": true, /* Import emit helpers from 'tslib'. */ // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ @@ -107,7 +106,7 @@ // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ /* Advanced Options */ "skipLibCheck": true, - "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ + "forceConsistentCasingInFileNames": true, /* Disallow inconsistently-cased references to the same file. */ }, "include": [ "src"