Skip to content

Commit

Permalink
Merge pull request #18 from TheMrZZ/develop
Browse files Browse the repository at this point in the history
Sandstone 0.4.4 - A few improvements
  • Loading branch information
TheMrZZ authored Oct 6, 2020
2 parents 171b2d7 + 2b5535a commit 6ce5464
Show file tree
Hide file tree
Showing 10 changed files with 95 additions and 47 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "sandstone",
"version": "0.4.3",
"version": "0.4.4",
"main": "dist/src/index.js",
"types": "dist/src/index.d.ts",
"license": "MIT",
Expand Down
2 changes: 1 addition & 1 deletion src/_internals/arguments/resources/predicate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,6 @@ export type PredicateCondition = (
/** If true, the condition evaluates to true only if it's thundering. */
thundering?: boolean
}>
)
) |never

export type PredicateType = ObjectOrArray<PredicateCondition>
14 changes: 6 additions & 8 deletions src/_internals/datapack/Datapack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,18 @@ import type {
AdvancementType, JsonTextComponent, LootTableType, OBJECTIVE_CRITERION, PredicateType, RecipeType, TAG_TYPES,
} from '@arguments'
import { CommandsRoot } from '@commands'
import { RecipeCommand } from '@commands/implementations'
import { Flow } from '@flow'
import type { HintedTagValues, McFunctionOptions } from '@resources'
import type { HintedTagStringType, McFunctionOptions } from '@resources'
import {
Recipe,
Advancement, LootTable, McFunction, Predicate, Tag,
Advancement, LootTable, McFunction, Predicate, Recipe,
Tag,
} from '@resources'

import type { ObjectiveClass } from '@variables'
import { Objective, SelectorCreator } from '@variables'
import type { CommandArgs } from './minecraft'
import { toMcFunctionName } from './minecraft'
import type {
FunctionResource, ResourceOnlyTypeMap, ResourcePath, ResourceTypes, TagObjectValue,
FunctionResource, ResourceOnlyTypeMap, ResourcePath, ResourceTypes, TagSingleValue,
} from './resourcesTree'
import { ResourcesTree } from './resourcesTree'
import type { SaveOptions } from './saveDatapack'
Expand All @@ -27,7 +25,7 @@ export interface McFunctionReturn<T extends unknown[]> {

schedule: (delay: number | LiteralUnion<'1t' | '1s' | '1d'>, type?: 'append' | 'replace', ...callbackArgs: T) => void

getNameFromArgs: (...args: T) => string
getName: (...args: T) => string

clearSchedule: (...args: T) => void
}
Expand Down Expand Up @@ -361,7 +359,7 @@ export default class Datapack {

Predicate = (name: string, predicate: PredicateType) => new Predicate(this.commandsRoot, name, predicate)

Tag = <T extends TAG_TYPES>(type: T, name: string, values: HintedTagValues<T>, replace?: boolean) => new Tag(this, type, name, values as TagObjectValue<string>[], replace)
Tag = <T extends TAG_TYPES>(type: T, name: string, values: TagSingleValue<HintedTagStringType<T>>[], replace?: boolean) => new Tag(this, type, name, values, replace)

LootTable = (name: string, lootTable: LootTableType) => new LootTable(this, name, lootTable)

Expand Down
4 changes: 2 additions & 2 deletions src/_internals/datapack/resourcesTree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ export type File<T extends Record<string, unknown>, P extends ResourcePath = Res
type FunctionProperties = { commands: CommandArgs[] }
export type FunctionResource = FolderOrFile<FunctionProperties>

export type TagObjectValue<T extends unknown = string> = { id: T, required: boolean }
type TagProperties = { values: (TagObjectValue | string)[], replace?: boolean }
export type TagSingleValue<T> = T | { id: T, required: boolean }
type TagProperties = { values: TagSingleValue<string>[], replace?: boolean }
type TagPath = readonly [
namespace: string,
type: TAG_TYPES,
Expand Down
7 changes: 5 additions & 2 deletions src/_internals/generalTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@
* Allows to get autocompletion on string unions, while still allowing generic strings.
* @see https://github.com/microsoft/TypeScript/issues/29729#issuecomment-700527227
*/
export type LiteralUnion<T extends string> = T | (Pick<string, never> & {
export type LiteralUnion<T extends string> = T | (Omit<string, keyof string> & {
/**
* Ignore this property.
* @deprecated
* @internal
* @hidden
* @ignore
*/
_?: never
trimStart: string['trimStart']
});

export type AtLeastOne<T> = [T, ...T[]]
6 changes: 3 additions & 3 deletions src/_internals/resources/McFunction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,15 +200,15 @@ export class McFunction<T extends any[]> {
}

getNameFromArgs = (...args: T): string => {
const jsonRepresentation = JSON.stringify(args)
const mcfunction = this.alreadyInitializedParameters.get(jsonRepresentation)
const repr = hash(args)
const mcfunction = this.alreadyInitializedParameters.get(repr)

if (mcfunction) {
return mcfunction.name
}

this.callAndRegister(args)
return this.alreadyInitializedParameters.get(jsonRepresentation)?.name as string
return this.alreadyInitializedParameters.get(repr)?.name as string
}

generateInitialFunction = () => {
Expand Down
4 changes: 4 additions & 0 deletions src/_internals/resources/Predicate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,8 @@ export class Predicate extends ConditionClass {
value: ['predicate', this.name],
}
}

toString() {
return this.name
}
}
53 changes: 34 additions & 19 deletions src/_internals/resources/Tag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,51 @@ import type {
BLOCKS, ENTITY_TYPES, FLUIDS, ITEMS, TAG_TYPES,
} from '@arguments'
import type { Datapack } from '@datapack'
import type { TagObjectValue } from '@datapack/resourcesTree'

type HintedTagStringType<T extends TAG_TYPES> = (
T extends 'blocks' ? BLOCKS :
T extends 'fluids' ? FLUIDS :
T extends 'entity_types' ? ENTITY_TYPES :
T extends 'functions' ? string :
T extends 'items' ? ITEMS :
import type { McFunctionReturn } from '@datapack/Datapack'
import type { TagSingleValue } from '@datapack/resourcesTree'

export type HintedTagStringType<T extends TAG_TYPES> = (
T extends 'blocks' ? LiteralUnion<BLOCKS> :
T extends 'fluids' ? LiteralUnion<FLUIDS> :
T extends 'entity_types' ? LiteralUnion<ENTITY_TYPES> :
T extends 'functions' ? (LiteralUnion<string> | McFunctionReturn<[]>) :
T extends 'items' ? LiteralUnion<ITEMS> :
string
)

export type HintedTagValues<T extends TAG_TYPES> = (
LiteralUnion<HintedTagStringType<T>> |
TagObjectValue<
LiteralUnion<HintedTagStringType<T>>
>
)[]
function isMcFunctionReturn(v: unknown): v is McFunctionReturn<[]> {
return typeof v === 'function'
}

function isTagObject<T>(v: TagSingleValue<T>): v is Exclude<TagSingleValue<T>, T> {
return typeof v === 'object'
}

export class Tag {
export class Tag<TYPE extends TAG_TYPES> {
readonly type

readonly values
readonly values: TagSingleValue<string>[]

readonly name

readonly datapack

constructor(datapack: Datapack, type: TAG_TYPES, name: string, values: TagObjectValue[], replace?: boolean) {
constructor(datapack: Datapack, type: TYPE, name: string, values: readonly TagSingleValue<HintedTagStringType<TYPE>>[], replace?: boolean) {
this.type = type
this.values = values

this.values = values.map((v) => {
if (isMcFunctionReturn(v)) {
return v.getName()
}
if (isTagObject(v) && isMcFunctionReturn(v.id)) {
return {
id: v.id.getName(),
required: v.required,
}
}
return v as string | TagSingleValue<string>
})

this.name = name
this.datapack = datapack

Expand All @@ -42,7 +57,7 @@ export class Tag {
children: new Map(),
isResource: true,
path: [namespace, type, ...fullPath],
values,
values: this.values,
replace,
})
}
Expand Down
21 changes: 19 additions & 2 deletions src/_internals/variables/Selector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type {
ENTITY_TYPES, TextComponentObject,
} from '@arguments'
import type { CommandsRoot } from '@commands'
import type { Predicate } from '@resources'
import type { LiteralUnion } from '../generalTypes'
import type { ConditionClass } from './abstractClasses'
import { ComponentClass } from './abstractClasses'
Expand Down Expand Up @@ -116,7 +117,7 @@ export type SelectorProperties<MustBeSingle extends boolean, MustBePlayer extend
advancements?: AdvancementsArgument

/** Select all targets that match the specified predicate. */
predicate?: string | string[]
predicate?: string | string[] | Predicate | Predicate[]
} & ({} | {
/** Define a position on the X-axis in the world the selector starts at,
* for use with the `distance` argument or the volume arguments, `dx`, `dy` and `dz`. */
Expand Down Expand Up @@ -145,15 +146,31 @@ export type SelectorProperties<MustBeSingle extends boolean, MustBePlayer extend
MustBeSingle extends true ? { limit: 0 | 1 } : { limit?: number }
)

// Sanitize score values. null => '', Infinity => '', any number => itself
function sanitizeValue(value: number | null): string {
if (value === undefined || value === null) {
return ''
}

if (Number.isFinite(value)) {
return value.toString()
}

// Value is Infinity or -Infinity
return ''
}

// Returns the string representation of a score range. [0, null] => '0..', [-Infinity, 5] => '..5', 8 => '8'
function parseScore(scores: ScoreArgument): string {
return `{${Object.entries(scores).map(([scoreName, value]) => {
if (Array.isArray(value)) {
return [scoreName, `${value[0] ?? ''}..${value[1] ?? ''}`].join('=')
return [scoreName, `${sanitizeValue(value[0])}..${sanitizeValue(value[1])}`].join('=')
}
return [scoreName, value].join('=')
}).join(', ')}}`
}

// Returns the string representation of advancements
function parseAdvancements(advancements: AdvancementsArgument): string {
return `{${Object.entries(advancements).map(([advancementName, value]) => {
if (typeof value === 'boolean') {
Expand Down
29 changes: 20 additions & 9 deletions tests/test.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,31 @@
import type { LiteralUnion } from '../src/arguments'
import {
execute, gamerule, give, raw, say, tellraw,
} from '../src/commands'
import {
mcfunction, Recipe, saveDatapack, _,
mcfunction, Predicate, Recipe, saveDatapack, Tag, _,
} from '../src/core'
import { createObjective, Selector } from '../src/variables'

Recipe('test', {
type: 'blasting',
ingredient: { item: 'minecraft:acacia_boat' },
result: 'minecraft:coal',
experience: 0,
const myPredicate = Predicate('mypred', {
condition: 'minecraft:entity_scores',
entity: 'killer',
scores: {
cc: {
max: 0,
min: 2,
},
},
})

mcfunction('cc', () => {
give(Selector('@s', { scores: { xx: [0, 1] } }), 'minecraft:blue_ice')
})
const myScore = createObjective('aa', 'dummy')

const cc = mcfunction('cc', () => {})

Tag('functions', 'hi2', [
'test:mc',
'minecraft:acacia_button',
cc,
])

saveDatapack('My datapack', { verbose: true, world: 'Crea1_15' })

0 comments on commit 6ce5464

Please sign in to comment.