From e89e4efc4da6c2a399ca28513e704af41f1eba79 Mon Sep 17 00:00:00 2001 From: Misode Date: Wed, 27 May 2020 03:05:02 +0200 Subject: [PATCH] Add schemas for predicates --- src/app/app.ts | 4 +- src/nodes/ObjectNode.ts | 2 +- src/nodes/ReferenceNode.ts | 12 +- src/schemas/Collections.ts | 167 ++++++++++++++++++ .../{ConditionSchema.ts => Condition.ts} | 33 ++-- src/schemas/Predicates.ts | 140 +++++++++++++++ src/schemas/{SandboxSchema.ts => Sandbox.ts} | 0 src/schemas/SchemaRegistry.ts | 3 +- 8 files changed, 336 insertions(+), 25 deletions(-) rename src/schemas/{ConditionSchema.ts => Condition.ts} (79%) create mode 100644 src/schemas/Predicates.ts rename src/schemas/{SandboxSchema.ts => Sandbox.ts} (100%) diff --git a/src/app/app.ts b/src/app/app.ts index 9ede4b1d..9d68065e 100644 --- a/src/app/app.ts +++ b/src/app/app.ts @@ -1,8 +1,8 @@ import { DataModel } from '../model/DataModel' import { TreeView } from '../view/TreeView' import { SourceView } from '../view/SourceView' -import { ConditionSchema } from '../schemas/ConditionSchema' -import { SandboxSchema } from '../schemas/SandboxSchema' +import { ConditionSchema } from '../schemas/Condition' +import { SandboxSchema } from '../schemas/Sandbox' const predicateModel = new DataModel(ConditionSchema) const sandboxModel = new DataModel(SandboxSchema) diff --git a/src/nodes/ObjectNode.ts b/src/nodes/ObjectNode.ts index dd031b08..6c7f047a 100644 --- a/src/nodes/ObjectNode.ts +++ b/src/nodes/ObjectNode.ts @@ -30,7 +30,7 @@ export class ObjectNode extends AbstractNode { } renderRaw(path: Path, value: IObject, view: TreeView, options?: RenderOptions) { - if (value === undefined) return `` + value = value ?? {} return `${options?.hideLabel ? `` : `
`} ${Object.keys(this.fields).map(f => { diff --git a/src/nodes/ReferenceNode.ts b/src/nodes/ReferenceNode.ts index 3b902922..d07f735d 100644 --- a/src/nodes/ReferenceNode.ts +++ b/src/nodes/ReferenceNode.ts @@ -12,7 +12,11 @@ export class ReferenceNode extends AbstractNode { } get(): INode { - return SchemaRegistry.get(this.reference) + const node = SchemaRegistry.get(this.reference) + if (node === undefined) { + console.error(`Invalid schema reference "${this.reference}"`) + } + return node } default(value?: any) { @@ -20,14 +24,14 @@ export class ReferenceNode extends AbstractNode { } transform(path: Path, value: any) { - return this.get().transform(path, value) + return this.get()?.transform(path, value) } render(path: Path, value: any, view: TreeView, options?: RenderOptions) { - return this.get().render(path, value, view, options) + return this.get()?.render(path, value, view, options) } renderRaw(path: Path, value: any, view: TreeView, options?: RenderOptions) { - return this.get().renderRaw(path, value, view, options) + return this.get()?.renderRaw(path, value, view, options) } } diff --git a/src/schemas/Collections.ts b/src/schemas/Collections.ts index c4789340..44f1ad42 100644 --- a/src/schemas/Collections.ts +++ b/src/schemas/Collections.ts @@ -57,3 +57,170 @@ export const enchantments = [ 'thorns', 'unbreaking' ] + +export const biomes = [ + 'badlands', + 'badlands_plateau', + 'bamboo_jungle', + 'bamboo_jungle_hills', + 'beach', + 'birch_forest', + 'birch_forest_hills', + 'cold_ocean', + 'dark_forest', + 'dark_forest_hills', + 'deep_cold_ocean', + 'deep_frozen_ocean', + 'deep_lukewarm_ocean', + 'deep_ocean', + 'deep_warm_ocean', + 'desert', + 'desert_hills', + 'desert_lakes', + 'end_barrens', + 'end_highlands', + 'end_midlands', + 'eroded_badlands', + 'flower_forest', + 'forest', + 'frozen_ocean', + 'frozen_river', + 'giant_spruce_taiga', + 'giant_spruce_taiga_hills', + 'giant_tree_taiga', + 'giant_tree_taiga_hills', + 'gravelly_mountains', + 'ice_spikes', + 'jungle', + 'jungle_edge', + 'jungle_hills', + 'lukewarm_ocean', + 'modified_badlands_plateau', + 'modified_gravelly_mountains', + 'modified_jungle', + 'modified_jungle_edge', + 'modified_wooded_badlands_plateau', + 'mountain_edge', + 'mountains', + 'mushroom_field_shore', + 'mushroom_fields', + 'nether', + 'ocean', + 'plains', + 'river', + 'savanna', + 'savanna_plateau', + 'shattered_savanna', + 'shattered_savanna_plateau', + 'small_end_islands', + 'snowy_beach', + 'snowy_mountains', + 'snowy_taiga', + 'snowy_taiga_hills', + 'snowy_taiga_mountains', + 'snowy_tundra', + 'stone_shore', + 'sunflower_plains', + 'swamp', + 'swamp_hills', + 'taiga', + 'taiga_hills', + 'taiga_mountains', + 'tall_birch_forest', + 'tall_birch_hills', + 'the_end', + 'the_void', + 'warm_ocean', + 'wooded_badlands_plateau', + 'wooded_hills', + 'wooded_mountains' +] + +export const structures = [ + 'pillager_outpost', + 'mineshaft', + 'mansion', + 'jungle_pyramid', + 'desert_pyramid', + 'igloo', + 'shipwreck', + 'swamp_hut', + 'stronghold', + 'monument', + 'ocean_ruin', + 'fortress', + 'endcity', + 'buried_treasure', + 'village' +] + +export const dimensions = [ + 'overworld', + 'the_nether', + 'the_end' +] + +export const slots = [ + 'mainhand', + 'offhand', + 'head', + 'chest', + 'legs', + 'feet' +] + +export const statusEffects = [ + 'speed', + 'slowness', + 'haste', + 'mining_fatigue', + 'strength', + 'instant_health', + 'instant_damage', + 'jump_boost', + 'nausea', + 'regeneration', + 'resistance', + 'fire_resistance', + 'water_breathing', + 'invisibility', + 'blindness', + 'night_vision', + 'hunger', + 'weakness', + 'poison', + 'wither', + 'health_boost', + 'absorption', + 'saturation', + 'glowing', + 'levitation', + 'luck', + 'unluck', + 'slow_falling', + 'conduit_power', + 'dolphins_grace', + 'bad_omen', + 'hero_of_the_village' +] + +export const gameModes = [ + 'survival', + 'creative', + 'adventure', + 'spectator' +] + +export const statisticTypes = [ + 'minecraft:broken', + 'minecraft:crafted', + 'minecraft:custom', + 'minecraft:dropped', + 'minecraft:killed', + 'minecraft:killed_by', + 'minecraft:mined', + 'minecraft:picked_up', + 'minecraft:used', + 'killedByTeam', + 'teamkill' +] diff --git a/src/schemas/ConditionSchema.ts b/src/schemas/Condition.ts similarity index 79% rename from src/schemas/ConditionSchema.ts rename to src/schemas/Condition.ts index 7593a672..5f374a0f 100644 --- a/src/schemas/ConditionSchema.ts +++ b/src/schemas/Condition.ts @@ -9,32 +9,33 @@ import { MapNode } from '../nodes/MapNode'; import { StringNode } from '../nodes/StringNode'; import { ReferenceNode } from '../nodes/ReferenceNode'; import { SchemaRegistry } from './SchemaRegistry'; - import { conditions, enchantments } from './Collections' +import './Predicates' + const entitySources = ['this', 'killer', 'killer_player'] -export const ConditionSchema = new FilteredNode('condition', { +export const ConditionSchema = SchemaRegistry.register('condition', new FilteredNode('condition', { condition: new EnumNode(conditions, 'random_chance'), [Switch]: { 'alternative': { terms: new ListNode( new ReferenceNode('condition') - ), + ) }, 'block_state_property': { block: new ResourceNode(), properties: new MapNode( new StringNode(), new StringNode() - ), + ) }, 'damage_source_properties': { - // predicate: DamageSchema, + predicate: new ReferenceNode('damage-source-predicate') }, 'entity_properties': { entity: new EnumNode(entitySources, 'this'), - // predicate: EntitySchema, + predicate: new ReferenceNode('entity-predicate') }, 'entity_scores': { entity: new EnumNode(entitySources, 'this'), @@ -53,17 +54,17 @@ export const ConditionSchema = new FilteredNode('condition', { offsetX: new NumberNode({integer: true}), offsetY: new NumberNode({integer: true}), offsetZ: new NumberNode({integer: true}), - // predicate: LocationSchema, + predicate: new ReferenceNode('location-predicate') }, 'match_tool': { - // predicate: ItemSchema, + predicate: new ReferenceNode('item-predicate') }, 'random_chance': { - chance: new NumberNode({min: 0, max: 1}), + chance: new NumberNode({min: 0, max: 1}) }, 'random_chance_with_looting': { chance: new NumberNode({min: 0, max: 1}), - looting_multiplier: new NumberNode(), + looting_multiplier: new NumberNode() }, 'requirements': { terms: new ListNode( @@ -71,21 +72,21 @@ export const ConditionSchema = new FilteredNode('condition', { ), }, 'reference': { - name: new StringNode(), + name: new StringNode() }, 'table_bonus': { enchantment: new EnumNode(enchantments), chances: new ListNode( new NumberNode({min: 0, max: 1}) - ), + ) }, 'time_check': { value: new RangeNode(), - period: new NumberNode(), + period: new NumberNode() }, 'weather_check': { raining: new BooleanNode(), - thrundering: new BooleanNode(), + thrundering: new BooleanNode() } } }, { @@ -93,6 +94,4 @@ export const ConditionSchema = new FilteredNode('condition', { condition: 'random_chance', chance: 0.5 }) -}) - -SchemaRegistry.register('condition', ConditionSchema) +})) diff --git a/src/schemas/Predicates.ts b/src/schemas/Predicates.ts new file mode 100644 index 00000000..08533899 --- /dev/null +++ b/src/schemas/Predicates.ts @@ -0,0 +1,140 @@ +import { ObjectNode } from '../nodes/ObjectNode'; +import { ResourceNode } from '../nodes/custom/ResourceNode'; +import { EnumNode } from '../nodes/EnumNode'; +import { ListNode } from '../nodes/ListNode'; +import { RangeNode } from '../nodes/custom/RangeNode'; +import { StringNode } from '../nodes/StringNode'; +import { ReferenceNode } from '../nodes/ReferenceNode'; +import { SchemaRegistry } from './SchemaRegistry'; +import { BooleanNode } from '../nodes/BooleanNode'; +import { MapNode } from '../nodes/MapNode'; +import { + enchantments, + biomes, + structures, + dimensions, + slots, + statusEffects, + gameModes, + statisticTypes +} from './Collections' + +SchemaRegistry.register('item-predicate', new ObjectNode({ + item: new ResourceNode(), + tag: new StringNode(), + count: new RangeNode(), + durability: new RangeNode(), + potion: new StringNode(), + nbt: new StringNode(), + enchantments: new ListNode( + new ReferenceNode('enchantment-predicate') + ) +})) + +SchemaRegistry.register('enchantment-predicate', new ObjectNode({ + enchantment: new EnumNode(enchantments), + levels: new RangeNode() +})) + +SchemaRegistry.register('block-predicate', new ObjectNode({ + block: new ResourceNode(), + tag: new StringNode(), + nbt: new StringNode(), + state: new MapNode( + new StringNode(), + new StringNode() + ) +})) + +SchemaRegistry.register('fluid-predicate', new ObjectNode({ + fluid: new ResourceNode(), + tag: new StringNode(), + nbt: new StringNode(), + state: new MapNode( + new StringNode(), + new StringNode() + ) +})) + +SchemaRegistry.register('location-predicate', new ObjectNode({ + position: new ObjectNode({ + x: new RangeNode(), + y: new RangeNode(), + z: new RangeNode() + }), + biome: new EnumNode(biomes), + feature: new EnumNode(structures), + dimension: new EnumNode(dimensions), + light: new ObjectNode({ + light: new RangeNode() + }), + smokey: new BooleanNode(), + block: new ReferenceNode('block-predicate'), + fluid: new ReferenceNode('fluid-predicate') +})) + +SchemaRegistry.register('statistic-predicat', new ObjectNode({ + type: new EnumNode(statisticTypes), + stat: new StringNode(), + value: new RangeNode() +})) + +SchemaRegistry.register('player-predicate', new ObjectNode({ + gamemode: new EnumNode(gameModes), + level: new RangeNode(), + advancements: new MapNode( + new StringNode(), + new BooleanNode() + ), + recipes: new MapNode( + new StringNode(), + new BooleanNode() + ), + stats: new ListNode( + new ReferenceNode('statistic-predicate') + ) +})) + +SchemaRegistry.register('status-effect', new ObjectNode({ + amplifier: new RangeNode(), + duration: new RangeNode(), + ambient: new BooleanNode(), + visible: new BooleanNode() +})) + +SchemaRegistry.register('distance-predicate', new ObjectNode({ + x: new RangeNode(), + y: new RangeNode(), + z: new RangeNode(), + absolute: new RangeNode(), + horizontal: new RangeNode() +})) + +SchemaRegistry.register('entity-predicate', new ObjectNode({ + type: new StringNode(), + nbt: new StringNode(), + team: new StringNode(), + location: new ReferenceNode('location-predicate'), + distance: new ReferenceNode('distance-predicate'), + flags: new ObjectNode({ + is_on_fire: new BooleanNode(), + is_sneaking: new BooleanNode(), + is_sprinting: new BooleanNode(), + is_swimming: new BooleanNode(), + is_baby: new BooleanNode() + }), + equipment: new MapNode( + new EnumNode(slots), + new ReferenceNode('item-predicate') + ), + // vehicle: new ReferenceNode('entity-predicate'), + // targeted_entity: new ReferenceNode('entity-predicate'), + player: new ReferenceNode('player-predicate'), + fishing_hook: new ObjectNode({ + in_open_water: new BooleanNode() + }), + effects: new MapNode( + new EnumNode(statusEffects), + new ReferenceNode('status-effect-predicate') + ) +})) diff --git a/src/schemas/SandboxSchema.ts b/src/schemas/Sandbox.ts similarity index 100% rename from src/schemas/SandboxSchema.ts rename to src/schemas/Sandbox.ts diff --git a/src/schemas/SchemaRegistry.ts b/src/schemas/SchemaRegistry.ts index 32f7ae2e..fa988f10 100644 --- a/src/schemas/SchemaRegistry.ts +++ b/src/schemas/SchemaRegistry.ts @@ -1,4 +1,4 @@ -import { INode } from "../nodes/AbstractNode"; +import { INode } from '../nodes/AbstractNode'; type Registry = { [id: string]: INode @@ -9,6 +9,7 @@ export class SchemaRegistry { static register(id: string, node: INode) { SchemaRegistry.registery[id] = node + return node } static get(id: string): INode {