diff --git a/src/app/app.ts b/src/app/app.ts index bc12fb33..9ede4b1d 100644 --- a/src/app/app.ts +++ b/src/app/app.ts @@ -1,10 +1,10 @@ import { DataModel } from '../model/DataModel' import { TreeView } from '../view/TreeView' import { SourceView } from '../view/SourceView' -import { PredicateSchema } from '../schemas/PredicateSchema' +import { ConditionSchema } from '../schemas/ConditionSchema' import { SandboxSchema } from '../schemas/SandboxSchema' -const predicateModel = new DataModel(PredicateSchema) +const predicateModel = new DataModel(ConditionSchema) const sandboxModel = new DataModel(SandboxSchema) let model = predicateModel diff --git a/src/nodes/AbstractNode.ts b/src/nodes/AbstractNode.ts index 9d535144..9f87a772 100644 --- a/src/nodes/AbstractNode.ts +++ b/src/nodes/AbstractNode.ts @@ -69,7 +69,7 @@ export abstract class AbstractNode implements INode { transform(path: Path, value: T) { if (!this.enabled(path)) return undefined - if (this.force()) value = this.default(value)! + if (value === undefined && this.force()) value = this.default(value)! return this.transformMod(value) } diff --git a/src/nodes/ReferenceNode.ts b/src/nodes/ReferenceNode.ts new file mode 100644 index 00000000..3b902922 --- /dev/null +++ b/src/nodes/ReferenceNode.ts @@ -0,0 +1,33 @@ +import { AbstractNode, NodeChildren, NodeMods, RenderOptions, INode } from './AbstractNode' +import { TreeView } from '../view/TreeView' +import { Path } from '../model/Path' +import { SchemaRegistry } from '../schemas/SchemaRegistry' + +export class ReferenceNode extends AbstractNode { + protected reference: string + + constructor(reference: string, mods?: NodeMods) { + super(mods) + this.reference = reference + } + + get(): INode { + return SchemaRegistry.get(this.reference) + } + + default(value?: any) { + return this.get().default(value) + } + + transform(path: Path, value: any) { + return this.get().transform(path, value) + } + + render(path: Path, value: any, view: TreeView, options?: RenderOptions) { + 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) + } +} diff --git a/src/schemas/Collections.ts b/src/schemas/Collections.ts new file mode 100644 index 00000000..c4789340 --- /dev/null +++ b/src/schemas/Collections.ts @@ -0,0 +1,59 @@ +export const conditions = [ + 'alternative', + 'requirements', + 'inverted', + 'reference', + 'entity_properties', + 'block_state_property', + 'match_tool', + 'damage_source_properties', + 'location_check', + 'weather_check', + 'time_check', + 'entity_scores', + 'random_chance', + 'random_chance_with_looting', + 'table_bonus', + 'killed_by_player', + 'survives_explosion' +] + +export const enchantments = [ + 'aqua_affinity', + 'bane_of_arthropods', + 'blast_protection', + 'channeling', + 'binding_curse', + 'vanishing_curse', + 'depth_strider', + 'efficiency', + 'feather_falling', + 'fire_aspect', + 'fire_protection', + 'flame', + 'fortune', + 'frost_walker', + 'impaling', + 'infinity', + 'knockback', + 'looting', + 'loyalty', + 'luck_of_the_sea', + 'lure', + 'mending', + 'multishot', + 'piercing', + 'power', + 'projectile_protection', + 'protection', + 'punch', + 'quick_charge', + 'respiration', + 'riptide', + 'sharpness', + 'silk_touch', + 'smite', + 'sweeping', + 'thorns', + 'unbreaking' +] diff --git a/src/schemas/PredicateSchema.ts b/src/schemas/ConditionSchema.ts similarity index 64% rename from src/schemas/PredicateSchema.ts rename to src/schemas/ConditionSchema.ts index 41c2318e..7593a672 100644 --- a/src/schemas/PredicateSchema.ts +++ b/src/schemas/ConditionSchema.ts @@ -7,76 +7,20 @@ import { ListNode } from '../nodes/ListNode'; import { RangeNode } from '../nodes/custom/RangeNode'; import { MapNode } from '../nodes/MapNode'; import { StringNode } from '../nodes/StringNode'; -import { INode } from '../nodes/AbstractNode'; +import { ReferenceNode } from '../nodes/ReferenceNode'; +import { SchemaRegistry } from './SchemaRegistry'; -const conditions = [ - 'alternative', - 'requirements', - 'inverted', - 'reference', - 'entity_properties', - 'block_state_property', - 'match_tool', - 'damage_source_properties', - 'location_check', - 'weather_check', - 'time_check', - 'entity_scores', - 'random_chance', - 'random_chance_with_looting', - 'table_bonus', - 'killed_by_player', - 'survives_explosion' -] - -const enchantments = [ - 'aqua_affinity', - 'bane_of_arthropods', - 'blast_protection', - 'channeling', - 'binding_curse', - 'vanishing_curse', - 'depth_strider', - 'efficiency', - 'feather_falling', - 'fire_aspect', - 'fire_protection', - 'flame', - 'fortune', - 'frost_walker', - 'impaling', - 'infinity', - 'knockback', - 'looting', - 'loyalty', - 'luck_of_the_sea', - 'lure', - 'mending', - 'multishot', - 'piercing', - 'power', - 'projectile_protection', - 'protection', - 'punch', - 'quick_charge', - 'respiration', - 'riptide', - 'sharpness', - 'silk_touch', - 'smite', - 'sweeping', - 'thorns', - 'unbreaking' -] +import { conditions, enchantments } from './Collections' const entitySources = ['this', 'killer', 'killer_player'] -export let PredicateSchema: FilteredNode -PredicateSchema = new FilteredNode('condition', { +export const ConditionSchema = new FilteredNode('condition', { condition: new EnumNode(conditions, 'random_chance'), [Switch]: { 'alternative': { - // terms: new ListNode(PredicateSchema()), + terms: new ListNode( + new ReferenceNode('condition') + ), }, 'block_state_property': { block: new ResourceNode(), @@ -100,7 +44,7 @@ PredicateSchema = new FilteredNode('condition', { ) }, 'inverted': { - // term: PredicateSchema, + term: new ReferenceNode('condition') }, 'killed_by_player': { inverse: new BooleanNode() @@ -121,6 +65,11 @@ PredicateSchema = new FilteredNode('condition', { chance: new NumberNode({min: 0, max: 1}), looting_multiplier: new NumberNode(), }, + 'requirements': { + terms: new ListNode( + new ReferenceNode('condition') + ), + }, 'reference': { name: new StringNode(), }, @@ -145,3 +94,5 @@ PredicateSchema = new FilteredNode('condition', { chance: 0.5 }) }) + +SchemaRegistry.register('condition', ConditionSchema) diff --git a/src/schemas/SchemaRegistry.ts b/src/schemas/SchemaRegistry.ts new file mode 100644 index 00000000..32f7ae2e --- /dev/null +++ b/src/schemas/SchemaRegistry.ts @@ -0,0 +1,17 @@ +import { INode } from "../nodes/AbstractNode"; + +type Registry = { + [id: string]: INode +} + +export class SchemaRegistry { + private static registery: Registry = {} + + static register(id: string, node: INode) { + SchemaRegistry.registery[id] = node + } + + static get(id: string): INode { + return SchemaRegistry.registery[id] + } +}