diff --git a/model.js b/model.js
index 10148024..493d075f 100644
--- a/model.js
+++ b/model.js
@@ -8,10 +8,19 @@ let indentation = 2;
let luck_based = false;
let table = {
type: "minecraft:generic",
- pools: []
+ pools: [
+ {
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "minecraft:stone"
+ }
+ ]
+ }
+ ]
};
-addPool();
-addEntry($('#structure .pool').get());
+invalidated();
const params = new URLSearchParams(window.location.search);
if (params.has('q')) {
@@ -156,60 +165,24 @@ function getIndex(el) {
return parseInt($parent.attr('data-index'));
}
-function addPool(el) {
- if (!table.pools) {
- table.pools = [];
- }
- table.pools.push({
- rolls: 1
- });
- invalidated();
-}
-
-function addEntry(el) {
- let pool = getParent(el);
- if (!pool.entries) {
- pool.entries = [];
- }
- pool.entries.push({
- type: "minecraft:item",
- name: "minecraft:stone"
- });
- invalidated();
-}
-
-function addChild(el) {
- let entry = getParent(el);
- if (!entry.children) {
- entry.children = [];
- }
- entry.children.push({
- type: "minecraft:item",
- name: "minecraft:stone"
- });
- invalidated();
-}
-
-function addFunction(el) {
- let entry = getParent(el);
- if (!entry.functions) {
- entry.functions = [];
- }
- entry.functions.push({
- function: "minecraft:set_count"
- });
- invalidated();
-}
-
-function addCondition(el) {
+function addComponent(el, array) {
let parent = getParent(el);
- if (!parent.conditions) {
- parent.conditions = [];
+ if (!parent[array]) {
+ parent[array] = [];
+ }
+ parent[array].push({});
+ invalidated();
+}
+
+function removeComponent(el) {
+ let node = getSuperParent(el);
+ let $field = $(el).closest('[data-field]');
+ let index = $field.attr('data-index');
+ let last = $field.attr('data-field').slice(0, -2);
+ node[last].splice(index, 1);
+ if (node[last].length === 0) {
+ delete node[last];
}
- parent.conditions.push({
- condition: "minecraft:random_chance",
- chance: 0.5
- });
invalidated();
}
@@ -244,7 +217,7 @@ function updateField(el) {
}
} else if (type === 'json') {
value = parseJSONValue(value)
- } else if (type === 'range') {
+ } else if (type === 'range' || type === 'random') {
value = getRangeValue($field, node[field]);
} else if (type === 'checkbox') {
value = $(el).prop('checked');
@@ -259,22 +232,11 @@ function updateField(el) {
invalidated();
}
-function removeField(el) {
- let node = getSuperParent(el);
- let $field = $(el).closest('[data-field]');
- let index = $field.attr('data-index');
- let last = $field.attr('data-field').slice(0, -2);
- node[last].splice(index, 1);
- if (node[last].length === 0) {
- delete node[last];
- }
- invalidated();
-}
-
function updateRangeType(el) {
let $field = $(el).closest('[data-field]');
let field = $field.attr('data-field');
let type = $(el).attr('value');
+ console.log('update range type!!', type, field);
if (type === 'range') {
setField(getParent(el), field, {});
} else if (type === 'binomial') {
diff --git a/structure.json b/structure.json
index dc43d9a5..86a9f039 100644
--- a/structure.json
+++ b/structure.json
@@ -25,7 +25,7 @@
{
"id": "pool",
"type": "object",
- "class": "card bg-success",
+ "color": "success",
"default": {
"rolls": 1,
"entries": [
@@ -38,30 +38,33 @@
"fields": [
{
"id": "rolls",
- "type": "range",
+ "type": "random",
"default": 1
},
{
"id": "bonus_rolls",
- "type": "number",
- "default": 1
+ "type": "random",
+ "default": 1,
+ "luck_based": true
},
{
"id": "entries",
"type": "array",
- "values": "entry"
+ "values": "entry",
+ "button": "header"
},
{
"id": "conditions",
"type": "array",
- "values": "condition"
+ "values": "condition",
+ "button": "header"
}
]
},
{
"id": "entry",
"type": "object",
- "class": "card",
+ "color": "light",
"default": {
"type": "minecraft:item",
"name": "minecraft:stone"
@@ -70,6 +73,7 @@
{
"id": "type",
"type": "enum",
+ "source": "entry",
"values": [
"minecraft:empty",
"minecraft:item",
@@ -97,6 +101,7 @@
"id": "children",
"type": "array",
"values": "entry",
+ "button": "field",
"require": [
"minecraft:alternatives",
"minecraft:sequence",
@@ -106,19 +111,21 @@
{
"id": "functions",
"type": "array",
- "values": "function"
+ "values": "function",
+ "button": "header"
},
{
"id": "conditions",
"type": "array",
- "values": "condition"
+ "values": "condition",
+ "button": "header"
}
]
},
{
"id": "function",
"type": "object",
- "class": "card bg-info",
+ "color": "secondary",
"default": {
"function": "minecraft:set_count",
"count": 2
@@ -127,6 +134,7 @@
{
"id": "function",
"type": "enum",
+ "source": "function",
"values": [
"minecraft:set_count",
"minecraft:set_damage",
@@ -150,7 +158,7 @@
},
{
"id": "count",
- "type": "range",
+ "type": "random",
"default": 2,
"require": [
"minecraft:set_count"
@@ -158,18 +166,24 @@
},
{
"id": "damage",
- "type": "range",
+ "type": "random",
"default": 1,
"require": [
"minecraft:set_damage"
]
+ },
+ {
+ "id": "conditions",
+ "type": "array",
+ "values": "condition",
+ "button": "header"
}
]
},
{
"id": "condition",
"type": "object",
- "card": true,
+ "color": "info",
"default": {
"condition": "minecraft:random_chance",
"chance": 0.5
diff --git a/view.js b/view.js
index 86f4a684..1a3c5491 100644
--- a/view.js
+++ b/view.js
@@ -1,17 +1,75 @@
+let structure;
+let components;
+
+$.getJSON('structure.json', json => {
+ structure = json.root;
+ components = json.components;
+ invalidated();
+});
function invalidated() {
- generateStructure();
+ if (structure) {
+ generateTable();
+ if (i18next.isInitialized) {
+ $('html').localize();
+ }
+ }
$('#source').val(JSON.stringify(table, null, indentation));
}
-function preventNewline(e) {
- if (e.which === 13) {
- $(e.target).trigger('change');
- e.preventDefault();
+function generateTable() {
+ $('#structure').removeClass('d-none').html('');
+
+ if (!table.type) {
+ table.type = 'minecraft:empty';
+ }
+ $('#tableType').val(table.type);
+
+ if (table.pools) {
+ $table = generateComponent(table.pools, structure.fields.find(e => e.id === 'pools'));
+ $('#structure').append($table);
+ }
+
+ $('#luck-based').attr('checked', luck_based);
+
+}
+
+function generateComponent(data, struct) {
+ switch (struct.type) {
+ case 'string': return generateString(data, struct);
+ case 'boolean': return generateBoolean(data, struct);
+ case 'random': return generateRandom(data, struct);
+ case 'range': return generateRange(data, struct);
+ case 'enum': return generateEnum(data, struct);
+ case 'array': return generateArray(data, struct);
+ case 'object': return generateObject(data, struct);
}
}
-function generateRange($el, data) {
+function generateString(data, struct) {
+ let $el = $('#components').find('[data-type="string"]').clone();
+ $el.attr('data-field', struct.id);
+ $el.find('[data-name]').attr('data-i18n', struct.id);
+ $el.find('input').val(data);
+ return $el;
+}
+
+function generateBoolean(data, struct) {
+ let $el = $('#components').find('[data-type="boolean"]').clone();
+ $el.attr('data-field', struct.id);
+ $el.find('[data-name]').attr('data-i18n', struct.id);
+ if (data === true) {
+ $el.find('[value="true"]').addClass('active');
+ } else if (data === false) {
+ $el.find('[value="false"]').addClass('active');
+ }
+ return $el;
+}
+
+function generateRandom(data, struct) {
+ let $el = $('#components').find('[data-type="random"]').clone();
+ $el.attr('data-field', struct.id);
+ $el.find('[data-name]').attr('data-i18n', struct.id);
if (typeof data === 'object') {
if (data.type && data.type.match(/(minecraft:)?binomial/)) {
$el.find('.binomial').removeClass('d-none');
@@ -26,34 +84,88 @@ function generateRange($el, data) {
$el.find('.exact').removeClass('d-none');
$el.find('.exact').val(data);
}
+ return $el;
}
-function generateRadio($el, data) {
- if (data === true) {
- $el.find('[value="true"]').addClass('active');
- } else if (data === false) {
- $el.find('[value="false"]').addClass('active');
+function generateRange(data, struct) {
+ let $el = $('#components').find('[data-type="range"]').clone();
+ $el.attr('data-field', struct.id);
+ $el.find('[data-name]').attr('data-i18n', struct.id);
+ if (typeof data === 'object') {
+ $el.find('.range').removeClass('d-none');
+ $el.find('.range.min').val(data.min);
+ $el.find('.range.max').val(data.max);
+ } else {
+ $el.find('.exact').removeClass('d-none');
+ $el.find('.exact').val(data);
}
+ return $el;
}
-function generateStructure() {
- $('#structure').html('');
-
- if (!table.type) {
- table.type = 'minecraft:empty';
+function generateEnum(data, struct) {
+ let $el = $('#components').find('[data-type="enum"]').clone();
+ $el.attr('data-field', struct.id);
+ $el.find('[data-name]').attr('data-i18n', struct.id);
+ for (let option of struct.values) {
+ $('
').appendTo($el.find('select')).attr('value', option).attr('data-i18n', struct.source + '.' + option);
}
- $('#tableType').val(table.type);
+ if (data) {
+ $el.find('select').val(data);
+ } else {
+ $el.find('select').val(struct.default);
+ }
+ return $el;
+}
- if (table.pools) {
- for (let i = 0; i < table.pools.length; i += 1) {
- let $pool = generatePool(table.pools[i], i);
- $('#structure').append($pool);
+function generateArray(data, struct) {
+ if (!data || data.length === 0) {
+ return undefined;
+ }
+ let $el = $('
').addClass('mt-3');
+ let child = components.find(e => e.id === struct.values);
+ for (let i = 0; i < data.length; i += 1) {
+ let $child = generateObject(data[i], child);
+ $child.attr('data-field', struct.id + '[]');
+ $child.attr('data-index', i);
+ $child.removeAttr('data-type');
+ $el.append($child);
+ }
+ $el.children().first().removeClass('mt-3');
+ return $el;
+}
- $('#luck-based').attr('checked', luck_based);
+function generateObject(data, struct) {
+ let $el = $('
').addClass('card bg-' + struct.color + ' mt-3');
+ let $header = $('').appendTo($el);
+ let $body = $('
').appendTo($el);
+ let filter = struct.fields.find(e => e.type === 'enum');
+ $header.append('
');
+ if (data._collapsed) {
+ return $el;
+ }
+ for (let field of struct.fields) {
+ if ((luck_based || !field.luck_based) && (!field.require || (filter && field.require.includes(data[filter.id])))) {
+ let $field = generateComponent(data[field.id], field);
+ if (field.type === 'array') {
+ if (field.button === 'header') {
+ let color = components.find(e => e.id === field.values).color;
+ $header.append('
');
+ }
+ if (field.button === 'field') {
+ let color = 'outline-success';
+ $body.append('
');
+ }
+ } else {
+ $field.attr('data-field', field.id);
+ }
+ $body.append($field);
}
}
+ $body.children().first().removeClass('mt-3');
+ return $el;
}
+/*
function generatePool(pool, i) {
let $pool = $('#poolTemplate').clone();
$pool.removeAttr('id').attr('data-index', i);
@@ -813,3 +925,36 @@ function generateEnchantment(enchantment, i) {
return $enchantment;
}
+
+function preventNewline(e) {
+ if (e.which === 13) {
+ $(e.target).trigger('change');
+ e.preventDefault();
+ }
+}
+
+function generateRange($el, data) {
+ if (typeof data === 'object') {
+ if (data.type && data.type.match(/(minecraft:)?binomial/)) {
+ $el.find('.binomial').removeClass('d-none');
+ $el.find('.binomial.n').val(data.n);
+ $el.find('.binomial.p').val(data.p);
+ } else {
+ $el.find('.range').removeClass('d-none');
+ $el.find('.range.min').val(data.min);
+ $el.find('.range.max').val(data.max);
+ }
+ } else {
+ $el.find('.exact').removeClass('d-none');
+ $el.find('.exact').val(data);
+ }
+}
+
+function generateRadio($el, data) {
+ if (data === true) {
+ $el.find('[value="true"]').addClass('active');
+ } else if (data === false) {
+ $el.find('[value="false"]').addClass('active');
+ }
+}
+*/