Skip to content

Commit

Permalink
Finish beta 0
Browse files Browse the repository at this point in the history
  • Loading branch information
MulverineX committed Dec 1, 2023
1 parent 870d4fc commit fa41907
Show file tree
Hide file tree
Showing 21 changed files with 143 additions and 141 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
### Dist folder ###
dist

.tsbuildinfo
tsconfig.tsbuildinfo

### VisualStudioCode Patch ###
.history
Expand Down
1 change: 0 additions & 1 deletion .npmignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
node_modules
.prettierrc.js
.tsbuildinfo
.eslintignore
.eslintrc.cjs
.editorconfig
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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...

Expand Down Expand Up @@ -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!
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down Expand Up @@ -65,7 +65,7 @@
"engines": {
"node": ">=12.22.3"
},
"homepage": "https://sandstone-documentation.vercel.app/",
"homepage": "https://sandstone.dev",
"keywords": [
"autocompletion",
"creator",
Expand Down
17 changes: 9 additions & 8 deletions src/commands/implementations/entity/execute.ts
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -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,
Expand Down Expand Up @@ -106,7 +107,7 @@ export class ExecuteCommandNode extends ContainerCommandNode<SubCommand[]> {
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())
Expand All @@ -131,12 +132,12 @@ export class ExecuteCommandNode extends ContainerCommandNode<SubCommand[]> {

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) => {
Expand Down Expand Up @@ -342,14 +343,14 @@ export class ExecuteIfUnlessCommand<MACRO extends boolean> 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)
Expand Down
6 changes: 3 additions & 3 deletions src/commands/implementations/server/random.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -25,7 +25,7 @@ export class RandomCommand<MACRO extends boolean> 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])
}

/**
Expand All @@ -39,7 +39,7 @@ export class RandomCommand<MACRO extends boolean> 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])
}

/**
Expand Down
4 changes: 2 additions & 2 deletions src/commands/implementations/server/return.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand Down
28 changes: 18 additions & 10 deletions src/core/Macro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)})`
}
}
}

Expand All @@ -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<string, string>, public strings: TemplateStringsArray, public macros: (MacroArgument | string | number)[]) {
constructor(public sandstoneCore: SandstoneCore, public strings: TemplateStringsArray, public macros: (MacroArgument | string | number)[]) {
super(sandstoneCore)

this.toMacro = () => {
Expand All @@ -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()
}
}
Expand Down
7 changes: 4 additions & 3 deletions src/core/nodes.ts
Original file line number Diff line number Diff line change
@@ -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'

Expand Down Expand Up @@ -76,7 +77,7 @@ export abstract class CommandNode<ARGS extends unknown[] = unknown[]> 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())
Expand All @@ -91,7 +92,7 @@ export abstract class CommandNode<ARGS extends unknown[] = unknown[]> extends No
}
}

return `${this.isMacro ? '/' : ''}${this.command} ${filteredArgs.join(' ')}`
return `${this.isMacro ? '$' : ''}${this.command} ${filteredArgs.join(' ')}`
}

/**
Expand Down
59 changes: 19 additions & 40 deletions src/core/resources/datapack/mcfunction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -336,56 +336,35 @@ export class _RawMCFunctionClass<PARAMS extends readonly MacroArgument[] | undef
function: (delay: TimeArgument, type: ScheduleType): FinalCommandOutput => 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<PARAMS, ENV>[] | [() => any]) => {
if (contents[0] instanceof _RawMCFunctionClass) {
for (const mcfunction of contents as _RawMCFunctionClass<PARAMS, ENV>[]) {
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<PARAMS, ENV>[] | [() => any]) {
if (contents[0] instanceof _RawMCFunctionClass) {
for (const mcfunction of contents as _RawMCFunctionClass<PARAMS, ENV>[]) {
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<PARAMS, ENV>[] | [() => 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<PARAMS, ENV>[] | [() => any]) => {
if (contents[0] instanceof _RawMCFunctionClass) {
for (const mcfunction of contents as _RawMCFunctionClass<PARAMS, ENV>[]) {
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<PARAMS, ENV>[]) {
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<PARAMS, ENV>[] | [() => void]) {
Expand Down
4 changes: 2 additions & 2 deletions src/core/resources/resource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ export abstract class ResourceClass<N extends ResourceNode = ResourceNode<any>>

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
Expand Down
4 changes: 2 additions & 2 deletions src/flow/Flow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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]())
Expand Down
2 changes: 1 addition & 1 deletion src/flow/conditions/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
}
}
4 changes: 2 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
Loading

0 comments on commit fa41907

Please sign in to comment.