Read structure when invalidated

This commit is contained in:
Misode
2019-09-12 02:29:16 +02:00
parent 16e7d37ffc
commit 9fb7f21311
4 changed files with 248 additions and 112 deletions
+24 -9
View File
@@ -44,7 +44,7 @@
<button type="button" class="btn btn-secondary" onclick="showSource()" data-i18n="show_source"></button>
</div>
</div>
<div id="structure" class="loot-table" data-field="table">
<div id="structure" class="loot-table mt-3" data-field="table">
</div>
</div>
<div class="col-12 col-lg-5 source-container">
@@ -75,22 +75,22 @@
<div class="d-none">
<div id="components">
<div data-type="string">
<div class="input-group mt-3" data-type="string">
<div class="input-group-prepend">
<span class="input-group-text"></span>
<span class="input-group-text" data-name></span>
</div>
<input type="text" class="form-control" onchange="updateField(this)" onfocus="this.select()">
</div>
<div data-type="enum">
<div class="input-group mt-3" data-type="enum">
<div class="input-group-prepend">
<span class="input-group-text"></span>
<span class="input-group-text" data-name></span>
</div>
<select class="form-control entry-type" onchange="updateField(this)">
</select>
</div>
<div data-type="range">
<div class="input-group mt-3" data-type="random">
<div class="input-group-prepend">
<span class="input-group-text"></span>
<span class="input-group-text" data-name></span>
<button type="button" class="btn btn-outline-secondary bg-light dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button>
<div class="dropdown-menu">
<a class="dropdown-item" value="exact" onclick="updateRangeType(this)" data-i18n="range.exact"></a>
@@ -108,9 +108,24 @@
<span class="input-group-text rounded-0 binomial d-none" data-i18n="range.p"></span>
<input type="text" class="form-control binomial p d-none rounded-right" value="0.5" onchange="updateField(this)" onfocus="this.select()">
</div>
<div data-type="radio">
<div class="input-group mt-3" data-type="range">
<div class="input-group-prepend">
<span class="input-group-text"></span>
<span class="input-group-text" data-name></span>
<button type="button" class="btn btn-outline-secondary bg-light dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button>
<div class="dropdown-menu">
<a class="dropdown-item" value="exact" onclick="updateRangeType(this)" data-i18n="range.exact"></a>
<a class="dropdown-item" value="range" onclick="updateRangeType(this)" data-i18n="range.range"></a>
</div>
</div>
<input type="text" class="form-control exact d-none rounded-right" value="1" onchange="updateField(this)" onfocus="this.select()">
<span class="input-group-text rounded-0 range d-none" data-i18n="range.min"></span>
<input type="text" class="form-control range min d-none" value="1" onchange="updateField(this)" onfocus="this.select()">
<span class="input-group-text rounded-0 range d-none" data-i18n="range.max"></span>
<input type="text" class="form-control range max d-none rounded-right" value="2" onchange="updateField(this)" onfocus="this.select()">
</div>
<div data-type="boolean">
<div class="input-group-prepend">
<span class="input-group-text" data-name></span>
</div>
<div class="btn-group">
<button type="button" value="false" class="btn btn-secondary rounded-0" onclick="updateField(this)" data-i18n="false"></button>
+30 -68
View File
@@ -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') {
+27 -13
View File
@@ -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
+167 -22
View File
@@ -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) {
$('<option/>').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 = $('<div/>').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 = $('<div/>').addClass('card bg-' + struct.color + ' mt-3');
let $header = $('<div class="card-header pb-1"></div>').appendTo($el);
let $body = $('<div class="card-body"></div>').appendTo($el);
let filter = struct.fields.find(e => e.type === 'enum');
$header.append('<button type="button" class="btn btn-danger mb-2 float-right" onclick="removeComponent(this)" data-i18n="remove_' + struct.id + '"></button>');
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('<button type="button" class="btn btn-' + color + ' mr-3 mb-2 float-left" onclick="addComponent(this, \'' + field.id + '\')" data-i18n="add_' + field.values + '"></button>');
}
if (field.button === 'field') {
let color = 'outline-success';
$body.append('<button type="button" class="btn btn-' + color + ' mr-3 mt-3" onclick="addComponent(this, \'' + field.id + '\')" data-i18n="add_' + field.values + '"></button>');
}
} 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');
}
}
*/