Skip to content

Commit fa41907

Browse files
committed
Finish beta 0
1 parent 870d4fc commit fa41907

21 files changed

+143
-141
lines changed

.gitignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
### Dist folder ###
22
dist
33

4-
.tsbuildinfo
4+
tsconfig.tsbuildinfo
55

66
### VisualStudioCode Patch ###
77
.history

.npmignore

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
node_modules
22
.prettierrc.js
3-
.tsbuildinfo
43
.eslintignore
54
.eslintrc.cjs
65
.editorconfig

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ You don't need to remember commands syntax anymore.
2626
This autocompletion works for all resources: commands, predicates, loot tables, advancements...
2727

2828
## 📂 Better organisation of resources
29-
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.
29+
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.
3030

3131
You also benefit from all the capabilities of a real programming language: multiline comments, indentation, documentation...
3232

@@ -55,4 +55,4 @@ If you want to support Sandstone, the simplest way is to star the repository! It
5555

5656
# Getting started
5757

58-
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!
58+
See the [Getting Started](https://sandstone.dev/docs) section on [sandstone.dev](https://sandstone.dev/) to start using Sandstone!

package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "sandstone",
3-
"description": "Sandstone, a Typescript library for Minecraft datapacks.",
4-
"version": "1.0.0-alpha.6",
3+
"description": "Sandstone, a Typescript library for Minecraft datapacks & resource packs.",
4+
"version": "1.0.0-beta.0",
55
"contributors": [
66
{
77
"name": "TheMrZZ - Florian ERNST",
@@ -65,7 +65,7 @@
6565
"engines": {
6666
"node": ">=12.22.3"
6767
},
68-
"homepage": "https://sandstone-documentation.vercel.app/",
68+
"homepage": "https://sandstone.dev",
6969
"keywords": [
7070
"autocompletion",
7171
"creator",

src/commands/implementations/entity/execute.ts

+9-8
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
import {
2+
type Macroable, type MacroArgument, type MCFunctionNode, type PredicateClass,
3+
isMacroArgument,
4+
} from 'sandstone/core'
15
import { ContainerCommandNode } from 'sandstone/core/nodes'
26
import { makeCallable, toMinecraftResourceName } from 'sandstone/utils'
37
import {
@@ -16,9 +20,6 @@ import type {
1620
Coordinates, DIMENSIONS, ENTITY_TYPES, MultipleEntitiesArgument, ObjectiveArgument, Range, Rotation, SingleEntityArgument,
1721
} from 'sandstone/arguments'
1822
import type { SandstoneCommands } from 'sandstone/commands'
19-
import type {
20-
Macroable, MacroArgument, MCFunctionNode, PredicateClass,
21-
} from 'sandstone/core'
2223
import type { Node } from 'sandstone/core/nodes'
2324
import type {
2425
_RawMCFunctionClass,
@@ -106,7 +107,7 @@ export class ExecuteCommandNode extends ContainerCommandNode<SubCommand[]> {
106107
if (arg !== undefined && arg !== null) {
107108
// Yes these are cursed, unfortunately, there's not really a better way to do this as visitors only visit the root nodes.
108109
if (typeof arg === 'object') {
109-
if (Object.hasOwn(arg, 'toMacro') && (arg as MacroArgument)['local'].has(this.sandstoneCore.currentNode)) {
110+
if (isMacroArgument(this.sandstoneCore, arg)) {
110111
this.isMacro = true
111112

112113
args.push((arg as MacroArgument).toMacro())
@@ -131,12 +132,12 @@ export class ExecuteCommandNode extends ContainerCommandNode<SubCommand[]> {
131132

132133
let command = this.body[0].getValue()
133134

134-
if (command.startsWith('/')) {
135+
if (command.startsWith('$')) {
135136
this.isMacro = true
136137
command = command.slice(1)
137138
}
138139

139-
return `${this.isMacro ? '/' : ''}${executeString} run ${command}`
140+
return `${this.isMacro ? '$' : ''}${executeString} run ${command}`
140141
}
141142

142143
createMCFunction = (currentMCFunction: MCFunctionNode | null) => {
@@ -342,14 +343,14 @@ export class ExecuteIfUnlessCommand<MACRO extends boolean> extends ExecuteComman
342343
if (isScore(args[2])) {
343344
finalArgs.push(args[2].target.toString(), args[2].objective.name)
344345
} else {
345-
finalArgs.push(rangeParser(args[2]))
346+
finalArgs.push(rangeParser(this.sandstoneCore, args[2]))
346347
}
347348
} else {
348349
finalArgs.push(targetParser(args[0]), isObjective(args[1]) ? args[1].name : args[1], args[2])
349350
if (args[4]) {
350351
finalArgs.push(targetParser(args[3]), isObjective(args[4]) ? args[4].name : args[4])
351352
} else {
352-
finalArgs.push(rangeParser(args[3]))
353+
finalArgs.push(rangeParser(this.sandstoneCore, args[3]))
353354
}
354355
}
355356
return this.nestedExecute(['score', ...finalArgs], true)

src/commands/implementations/server/random.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import { rangeParser } from 'sandstone/variables/parsers'
44
import { CommandArguments } from '../../helpers.js'
55

66
import type { Range } from 'sandstone/arguments'
7-
import type { LiteralUnion } from 'sandstone/utils.js'
87
import type { Macroable } from 'sandstone/core'
8+
import type { LiteralUnion } from 'sandstone/utils.js'
99

1010
export class RandomCommandNode extends CommandNode {
1111
command = 'random' as const
@@ -25,7 +25,7 @@ export class RandomCommand<MACRO extends boolean> extends CommandArguments {
2525
if (typeof sequence === 'string' && !sequence.includes(':')) {
2626
seq = `${this.sandstonePack.defaultNamespace}:${seq}`
2727
}
28-
return this.finalCommand(['value', rangeParser(range), seq])
28+
return this.finalCommand(['value', rangeParser(this.sandstoneCore, range), seq])
2929
}
3030

3131
/**
@@ -39,7 +39,7 @@ export class RandomCommand<MACRO extends boolean> extends CommandArguments {
3939
if (sequence && typeof sequence === 'string' && !sequence.includes(':')) {
4040
seq = `${this.sandstonePack.defaultNamespace}:${seq}`
4141
}
42-
return this.finalCommand(['roll', rangeParser(range), seq])
42+
return this.finalCommand(['roll', rangeParser(this.sandstoneCore, range), seq])
4343
}
4444

4545
/**

src/commands/implementations/server/return.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,12 @@ export class ReturnRunCommandNode extends ContainerCommandNode {
3434

3535
let command = this.body[0].getValue()
3636

37-
if (command.startsWith('/')) {
37+
if (command.startsWith('$')) {
3838
this.isMacro = true
3939
command = command.slice(1)
4040
}
4141

42-
return `${this.isMacro ? '/' : ''}${this.command} run ${command}`
42+
return `${this.isMacro ? '$' : ''}${this.command} run ${command}`
4343
}
4444

4545
createMCFunction = (currentMCFunction: MCFunctionNode | null) => {

src/core/Macro.ts

+18-10
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,18 @@ export class MacroArgument {
88

99
public toMacro: () => string
1010

11-
readonly Macro = (strings: TemplateStringsArray, ...macros: (string | number | MacroArgument)[]) => new MacroLiteral(this.sandstoneCore, this.local, strings, macros)
12-
1311
constructor(protected sandstoneCore: SandstoneCore) {
1412
this.local = new Map()
1513

16-
this.toMacro = () => `$(${this.local.get(this.sandstoneCore.currentNode) || this.local.get(this.sandstoneCore.getCurrentMCFunctionOrThrow().resource.name)})`
14+
this.toMacro = () => {
15+
let currentMCFunctionName: string = ''
16+
try {
17+
currentMCFunctionName = sandstoneCore.getCurrentMCFunctionOrThrow().resource.name
18+
// eslint-disable-next-line no-empty
19+
} catch (e) {}
20+
21+
return `$(${this.local.get(this.sandstoneCore.currentNode) || this.local.get(currentMCFunctionName)})`
22+
}
1723
}
1824
}
1925

@@ -25,15 +31,21 @@ export function isMacroArgument(core: SandstoneCore, arg: any) {
2531
if (typeof arg === 'object' && Object.hasOwn(arg, 'toMacro')) {
2632
// eslint-disable-next-line prefer-destructuring
2733
const local = (arg as MacroArgument)['local']
28-
if (local.has(core.getCurrentMCFunctionOrThrow().resource.name) || local.has(core.currentNode)) return arg as MacroArgument
34+
35+
let currentMCFunctionName: string = ''
36+
try {
37+
currentMCFunctionName = core.getCurrentMCFunctionOrThrow().resource.name
38+
// eslint-disable-next-line no-empty
39+
} catch (e) {}
40+
if (arg instanceof MacroLiteral || local.has(currentMCFunctionName) || local.has(core.currentNode)) return arg as MacroArgument
2941
}
3042
return undefined
3143
}
3244

33-
class MacroLiteral extends MacroArgument {
45+
export class MacroLiteral extends MacroArgument {
3446
public toMacro: () => string
3547

36-
constructor(public sandstoneCore: SandstoneCore, public local: Map<string, string>, public strings: TemplateStringsArray, public macros: (MacroArgument | string | number)[]) {
48+
constructor(public sandstoneCore: SandstoneCore, public strings: TemplateStringsArray, public macros: (MacroArgument | string | number)[]) {
3749
super(sandstoneCore)
3850

3951
this.toMacro = () => {
@@ -48,10 +60,6 @@ class MacroLiteral extends MacroArgument {
4860
if (typeof macro === 'string' || typeof macro === 'number') {
4961
result += `${macro}`
5062
} else {
51-
const current = this.sandstoneCore.currentNode || this.sandstoneCore.getCurrentMCFunctionOrThrow().resource.name
52-
53-
macro['local'].set(current, this.local.get(current)!)
54-
5563
result += macro.toMacro()
5664
}
5765
}

src/core/nodes.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
import { type MacroArgument, isMacroArgument } from './Macro.js'
2+
13
import type { SandstonePack } from 'sandstone/pack'
24
import type { LoopArgument } from 'sandstone/variables'
3-
import type { MacroArgument } from './Macro.js'
45
import type { MCFunctionClass, MCFunctionNode } from './resources/datapack/index.js'
56
import type { SandstoneCore } from './sandstoneCore.js'
67

@@ -76,7 +77,7 @@ export abstract class CommandNode<ARGS extends unknown[] = unknown[]> extends No
7677
if (arg !== undefined && arg !== null) {
7778
// Yes these are cursed, unfortunately, there's not really a better way to do this as visitors only visit the root nodes.
7879
if (typeof arg === 'object') {
79-
if (Object.hasOwn(arg, 'toMacro') && (arg as MacroArgument)['local'].has(this.sandstoneCore.currentNode)) {
80+
if (isMacroArgument(this.sandstoneCore, arg)) {
8081
this.isMacro = true
8182

8283
filteredArgs.push((arg as MacroArgument).toMacro())
@@ -91,7 +92,7 @@ export abstract class CommandNode<ARGS extends unknown[] = unknown[]> extends No
9192
}
9293
}
9394

94-
return `${this.isMacro ? '/' : ''}${this.command} ${filteredArgs.join(' ')}`
95+
return `${this.isMacro ? '$' : ''}${this.command} ${filteredArgs.join(' ')}`
9596
}
9697

9798
/**

src/core/resources/datapack/mcfunction.ts

+19-40
Original file line numberDiff line numberDiff line change
@@ -336,56 +336,35 @@ export class _RawMCFunctionClass<PARAMS extends readonly MacroArgument[] | undef
336336
function: (delay: TimeArgument, type: ScheduleType): FinalCommandOutput => this.commands.schedule.function(this.name, delay, type),
337337
}
338338

339-
get push() {
340-
const commands = new Proxy(this.pack.commands, {
341-
get: (target, p, receiver) => {
342-
this.core.enterMCFunction(this)
343-
this.core.insideContext(this.node, () => (this.pack.commands as any)[p], false)
344-
this.core.exitMCFunction()
345-
},
346-
})
347-
348-
return makeCallable(commands, (...contents: _RawMCFunctionClass<PARAMS, ENV>[] | [() => any]) => {
349-
if (contents[0] instanceof _RawMCFunctionClass) {
350-
for (const mcfunction of contents as _RawMCFunctionClass<PARAMS, ENV>[]) {
351-
this.node.body.push(...mcfunction.node.body)
352-
}
353-
} else {
354-
this.core.enterMCFunction(this)
355-
this.core.insideContext(this.node, contents[0], false)
356-
this.core.exitMCFunction()
339+
push(...contents: _RawMCFunctionClass<PARAMS, ENV>[] | [() => any]) {
340+
if (contents[0] instanceof _RawMCFunctionClass) {
341+
for (const mcfunction of contents as _RawMCFunctionClass<PARAMS, ENV>[]) {
342+
this.node.body.push(...mcfunction.node.body)
357343
}
358-
}, true)
344+
} else {
345+
this.core.enterMCFunction(this)
346+
this.core.insideContext(this.node, contents[0], false)
347+
this.core.exitMCFunction()
348+
}
359349
}
360350

361-
get unshift() {
351+
unshift(...contents: _RawMCFunctionClass<PARAMS, ENV>[] | [() => any]) {
362352
const fake = new MCFunctionClass(this.core, 'fake', {
363353
addToSandstoneCore: false,
364354
creator: 'sandstone',
365355
onConflict: 'ignore',
366356
})
367357

368-
const commands = new Proxy(this.pack.commands, {
369-
get: (target, p, receiver) => {
370-
this.core.enterMCFunction(fake)
371-
this.core.insideContext(fake.node, () => (this.pack.commands as any)[p], false)
372-
this.core.exitMCFunction()
373-
this.node.body.unshift(...fake.node.body)
374-
},
375-
})
376-
377-
return makeCallable(commands, (...contents: _RawMCFunctionClass<PARAMS, ENV>[] | [() => any]) => {
378-
if (contents[0] instanceof _RawMCFunctionClass) {
379-
for (const mcfunction of contents as _RawMCFunctionClass<PARAMS, ENV>[]) {
380-
this.node.body.unshift(...mcfunction.node.body)
381-
}
382-
} else {
383-
this.core.enterMCFunction(fake)
384-
this.core.insideContext(fake.node, contents[0], false)
385-
this.core.exitMCFunction()
386-
this.node.body.unshift(...fake.node.body)
358+
if (contents[0] instanceof _RawMCFunctionClass) {
359+
for (const mcfunction of contents as _RawMCFunctionClass<PARAMS, ENV>[]) {
360+
this.node.body.unshift(...mcfunction.node.body)
387361
}
388-
}, true)
362+
} else {
363+
this.core.enterMCFunction(fake)
364+
this.core.insideContext(fake.node, contents[0], false)
365+
this.core.exitMCFunction()
366+
this.node.body.unshift(...fake.node.body)
367+
}
389368
}
390369

391370
splice(start: number, removeItems: number | 'auto', ...contents: _RawMCFunctionClass<PARAMS, ENV>[] | [() => void]) {

src/core/resources/resource.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ export abstract class ResourceClass<N extends ResourceNode = ResourceNode<any>>
7272

7373
this.packType = args.packType || file.packType
7474

75-
this.fileExtension = file.extension
76-
this.fileEncoding = file.encoding === undefined ? 'utf8' : file.encoding
75+
this.fileExtension = file.extension || 'json'
76+
this.fileEncoding = file.encoding ?? 'utf8'
7777

7878
this.pack = core.pack
7979
this.commands = core.pack.commands

src/flow/Flow.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -206,11 +206,11 @@ export class Flow {
206206
MCFunction(`__sandstone:switch_${id}`, [value], () => {
207207
const index = Data('storage', `__sandstone:switch_${id}`, 'Index')
208208

209-
Macro.data.modify.storage(index.currentTarget, 'Index').set.from.storage(values.currentTarget, value.Macro`Values[{Value:${value}}}].Index`)
209+
Macro.data.modify.storage(index.currentTarget, 'Index').set.from.storage(values.currentTarget, Macro`Values[{Value:${value}}}].Index`)
210210

211211
const _if = flow.if(index, () => {
212212
MCFunction(`__sandstone:switch_${id}_inner`, [index], () => {
213-
Macro.functionCmd(index.Macro`__sandstone:switch_${id}_case_${index}`)
213+
Macro.functionCmd(Macro`__sandstone:switch_${id}_case_${index}`)
214214
})()
215215
})
216216
if (_default) _if.else(() => _default?.[1]())

src/flow/conditions/command.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,6 @@ export class CommandConditionNode extends SingleConditionNode {
2828
/** @ts-ignore */
2929
return this.result(this.variable)._toMinecraftCondition().getCondition()
3030
}
31-
return ['score', this.variable, 'matches', rangeParser(this.result)]
31+
return ['score', this.variable, 'matches', rangeParser(this.sandstoneCore, this.result)]
3232
}
3333
}

src/index.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -249,14 +249,14 @@ export interface SandstoneConfig {
249249
/**
250250
* The world to save the packs in.
251251
*
252-
* Incompatible with `root` and `path`.
252+
* Incompatible with `root`.
253253
*/
254254
world?: string
255255

256256
/**
257257
* Whether to save the resource pack & datapack in the `.minecraft/datapacks` & `.minecraft/resource_pack` folders.
258258
*
259-
* Incompatible with `world` and `path`.
259+
* Incompatible with `world`.
260260
*/
261261
root?: true
262262

0 commit comments

Comments
 (0)