diff --git a/custom.css b/custom.css index 08af558a..70fe2bd4 100644 --- a/custom.css +++ b/custom.css @@ -1,6 +1,3 @@ -.card.child { - background-color: #eee; -} .card.bg-info { background-color: #91cdd6 !important; @@ -22,6 +19,18 @@ color: white !important; } +.card.child { + background-color: #eee !important; +} + +.card.term, .card.terms { + background-color: #7cb6bf !important; +} + +.card.bg-dark .card.bg-dark { + background-color: #4b4f54 !important; +} + .dropdown-item { cursor: pointer; } diff --git a/index.html b/index.html index 7a621773..b449be86 100644 --- a/index.html +++ b/index.html @@ -396,19 +396,19 @@
Multiplier
- +
Extra
- +
Propability
- +
@@ -534,14 +534,14 @@ Condition -
-
- -
-
@@ -617,13 +612,13 @@
- +
- +
@@ -655,6 +650,138 @@
+
+
+ +
+
+ X +
+ Min + + Max + +
+
+
+ Y +
+ Min + + Max + +
+
+
+ Z +
+ Min + + Max + +
+
+
+ Biome +
+ +
+
+
+ Feature +
+ +
+
+
+ Dimension +
+ +
+
+
+
+
+
+
+ Type +
+ +
+
+
+ NBT +
+ +
+ +
+
+
+
+
+
+ Item + + +
+ Name + + Tag + +
+
+
+ Count + + +
+ + Min + + Max + +
+
+
+ Durability + + +
+ + Min + + Max + +
+
+
+ Potion +
+ +
+
+
+ NBT +
+ +
+
+
diff --git a/model.js b/model.js index 3513df8b..7d2f547c 100644 --- a/model.js +++ b/model.js @@ -6,13 +6,13 @@ $('#indentationSelect').val("2"); let indentation = 2; let luck_based = false; -const nodes = '.loot-table, .pool, .entry, .child, .term, .terms, .function, .condition, .modifier, .operation'; +const nodes = '.loot-table, .pool, .entry, .child, .term, .terms, .function, .condition, .modifier, .operation, .predicate, .location'; let table = { type: "minecraft:generic", pools: [] }; addPool(); -addEntry($('#structure .pool').get()); +addCondition($('#structure .pool').get()); const params = new URLSearchParams(window.location.search); if (params.has('q')) { @@ -32,7 +32,6 @@ function updateLuckBased() { function linkSource() { let link = window.location.origin + window.location.pathname + '?q=' + JSON.stringify(table); - console.log(link); $('#copyTextarea').removeClass('d-none').val(link); $('#copyTextarea').get()[0].select(); document.execCommand('copy'); @@ -92,6 +91,10 @@ function getParent(el) { return getParent($parent.parent()).modifiers[index]; } else if ($parent.hasClass('operation')) { return getParent($parent.parent()).ops[index]; + } else if ($parent.hasClass('predicate')) { + return getParent($parent.parent()).predicate; + } else if ($parent.hasClass('location')) { + return getParent($parent.parent()).location; } } @@ -203,24 +206,57 @@ function addCondition(el) { function removeCondition(el) { let parent = getSuperParent(el); - parent.conditions.splice(getIndex(el), 1); - if (parent.conditions.length === 0) { - delete parent.conditions; + if (parent.conditions) { + parent.conditions.splice(getIndex(el), 1); + if (parent.conditions.length === 0) { + delete parent.conditions; + } + } else { + parent.terms.splice(getIndex(el), 1); + if (parent.terms.length === 0) { + delete parent.terms; + } } invalidated(); } +function updateValue(root, field, value) { + let f = field.split('.'); + if (f.length === 1) return root[f[0]] = value; + if (!root[f[0]]) root[f[0]] = {}; + if (f.length === 2) return root[f[0]][f[1]] = value; + if (!root[f[0]][f[1]]) root[f[0]][f[1]] = {}; + if (f.length === 3) return root[f[0]][f[1]][f[2]] = value; + if (!root[f[0]][f[1]][f[2]]) root[f[0]][f[1]][f[2]] = {}; + if (f.length === 4) return root[f[0]][f[1]][f[2]][f[3]] = value; + if (!root[f[0]][f[1]][f[2]][f[3]]) root[f[0]][f[1]][f[2]][f[3]] = {}; + if (f.length === 5) return root[f[0]][f[1]][f[2]][f[3]][f[4]] = value; + if (!root[f[0]][f[1]][f[2]][f[3]][f[4]]) root[f[0]][f[1]][f[2]][f[3]][f[4]] = {}; + if (f.length === 6) return root[f[0]][f[1]][f[2]][f[3]][f[4]][f[5]] = value; +} + +function deleteValue(root, field) { + let f = field.split('.'); + if (f.length === 1) delete root[f[0]]; + if (f.length === 2) delete root[f[0]][f[1]]; + if (f.length === 3) delete root[f[0]][f[1]][f[2]]; + if (f.length === 4) delete root[f[0]][f[1]][f[2]][f[3]]; + if (f.length === 5) delete root[f[0]][f[1]][f[2]][f[3]][f[4]]; + if (f.length === 6) delete root[f[0]][f[1]][f[2]][f[3]][f[4]][f[6]]; +} + function updateField(el, field) { - getParent(el)[field] = $(el).val(); + updateValue(getParent(el), field, $(el).val()); + console.log(getParent(el)); invalidated(); } function updateIntField(el, field) { let value = parseInt($(el).val()); if (isNaN(value)) { - delete getParent(el)[field]; + deleteValue(getParent(el), field); } else { - getParent(el)[field] = value; + updateValue(getParent(el), field, value); } invalidated(); } @@ -228,9 +264,9 @@ function updateIntField(el, field) { function updateFloatField(el, field) { let value = parseFloat($(el).val()); if (isNaN(value)) { - delete getParent(el)[field]; + deleteValue(getParent(el), field); } else { - getParent(el)[field] = value; + updateValue(getParent(el), field, value); } invalidated(); } @@ -240,6 +276,11 @@ function updateCheckedField(el, field) { invalidated(); } +function updateRangeType(el, field, type) { + $(el).closest('[data-type]').attr('data-type', type); + updateRangeField(el, field); +} + function updateRangeField(el, field) { let type = $(el).closest('[data-type]').attr('data-type'); let data = getRangeField($(el).closest('[data-type]'), type); @@ -247,11 +288,6 @@ function updateRangeField(el, field) { invalidated(); } -function updateRangeType(el, field, type) { - $(el).closest('[data-type]').attr('data-type', type); - updateRangeField(el, field); -} - function getRangeField($el, type) { if (type === 'exact') { return parseInt($el.find('.exact').val()); @@ -341,6 +377,9 @@ function removeModifierSlot(el) { function addScore(el) { let condition = getParent(el); let objective = $(el).closest('.condition-entity-scores').find('input').val(); + if (!objective.length) { + return; + } if (!condition.scores) { condition.scores = {}; } @@ -356,7 +395,7 @@ function removeScore(el) { function updateScoreType(el, type) { $(el).closest('.score').attr('data-type', type); - updateConditionScoreField(el); + updateScoreField(el); } function updateScoreField(el) { @@ -390,26 +429,6 @@ function removeOperation(el) { invalidated(); } -function updateParameterIntField(el, field) { - let value = parseInt($(el).val()); - if (isNaN(value)) { - delete getParent(el).parameters[field]; - } else { - getParent(el).parameters[field] = value; - } - invalidated(); -} - -function updateParameterFloatField(el, field) { - let value = parseFloat($(el).val()); - if (isNaN(value)) { - delete getParent(el).parameters[field]; - } else { - getParent(el).parameters[field] = value; - } - invalidated(); -} - function addBlockProperty(el) { let func = getParent(el); let blockstate = $(el).closest('.condition-block-properties').find('input').val(); @@ -431,3 +450,58 @@ function updateBlockPropertyField(el) { getParent(el).properties[blockstate] = $(el).val(); invalidated(); } + +function addTerm(el) { + let condition = getParent(el); + if (!condition.terms) { + condition.terms = []; + } + condition.terms.push({ + condition: "minecraft:random_chance", + chance: 0.5 + }); + invalidated(); +} + +function togglePosition(el) { + let parent = getParent(el); + if (parent.position) { + delete parent.position; + } else { + parent.position = {}; + } + invalidated(); +} + +function toggleEntityLocation(el) { + let parent = getParent(el); + if (parent.location) { + delete parent.location; + } else { + parent.location = {}; + } + invalidated(); +} + +function updateItemType(el, type) { + let $predicate = $(el).closest('.predicate'); + if (type === 'name') { + $predicate.find('.name').removeClass('d-none'); + $predicate.find('.tag').addClass('d-none'); + } else { + $predicate.find('.tag').removeClass('d-none'); + $predicate.find('.name').addClass('d-none'); + } +} + +function updateItemField(el, type) { + let parent = getParent(el); + if (type === 'name') { + parent.name = $(el).closest('.predicate').find('input.name').val(); + delete parent.tag; + } else { + parent.tag = $(el).closest('.predicate').find('input.tag').val(); + delete parent.name; + } + invalidated(); +} diff --git a/view.js b/view.js index 8aae4091..c1ff67b0 100644 --- a/view.js +++ b/view.js @@ -328,7 +328,6 @@ function generateFunction(func, i) { func.parameters.probability = 0.5; } delete func.parameters.multiplier; - console.log(func); $function.find('.function-bonus-extra').removeClass('d-none'); $function.find('.function-bonus-extra input').val(func.parameters.extra); $function.find('.function-bonus-probability').removeClass('d-none'); @@ -404,6 +403,32 @@ function generateCondition(condition, i) { $condition.find('.condition-type').val(condition.condition); + if (table.type === 'minecraft:generic') { + $condition.find('option[value="minecraft:blockstate_propery"]').addClass('d-none'); + $condition.find('option[value="minecraft:match_tool"]').addClass('d-none'); + $condition.find('option[value="minecraft:damage_source_properties"]').addClass('d-none'); + $condition.find('option[value="minecraft:survives_explosion"]').addClass('d-none'); + $condition.find('option[value="minecraft:table_bonus"]').addClass('d-none'); + } else if (table.type === 'minecraft:block') { + $condition.find('option[value="minecraft:damage_source_properties"]').addClass('d-none'); + } else if (table.type === 'minecraft:fishing') { + $condition.find('option[value="minecraft:blockstate_propery"]').addClass('d-none'); + $condition.find('option[value="minecraft:damage_source_properties"]').addClass('d-none'); + $condition.find('option[value="minecraft:survives_explosion"]').addClass('d-none'); + $condition.find('option[value="minecraft:table_bonus"]').addClass('d-none'); + } else if (table.type === 'minecraft:entity') { + $condition.find('option[value="minecraft:blockstate_propery"]').addClass('d-none'); + $condition.find('option[value="minecraft:survives_explosion"]').addClass('d-none'); + $condition.find('option[value="minecraft:table_bonus"]').addClass('d-none'); + $condition.find('option[value="minecraft:match_tool"]').addClass('d-none'); + } else if (table.type === 'minecraft:chest') { + $condition.find('option[value="minecraft:blockstate_propery"]').addClass('d-none'); + $condition.find('option[value="minecraft:damage_source_properties"]').addClass('d-none'); + $condition.find('option[value="minecraft:survives_explosion"]').addClass('d-none'); + $condition.find('option[value="minecraft:table_bonus"]').addClass('d-none'); + $condition.find('option[value="minecraft:match_tool"]').addClass('d-none'); + } + if (condition.condition === 'minecraft:random_chance' || condition.condition === 'minecraft:random_chance_with_looting') { $condition.find('.condition-chance').removeClass('d-none'); $condition.find('.condition-chance input').val(condition.chance); @@ -423,6 +448,8 @@ function generateCondition(condition, i) { let inverted = false; if (condition.inverted) { inverted = true; + } else { + delete condition.inverted; } let id = 'invertedCheckbox' + Math.floor(1000000*Math.random()); $condition.find('.condition-killed-inverted').attr('for', id); @@ -433,6 +460,9 @@ function generateCondition(condition, i) { } if (condition.condition === 'minecraft:entity_properties' || condition.condition === 'minecraft:entity_scores') { + if (!condition.entity) { + condition.entity = 'this'; + } $condition.find('.condition-entity').removeClass('d-none'); $condition.find('.condition-entity select').val(condition.entity); } else { @@ -448,8 +478,43 @@ function generateCondition(condition, i) { delete condition.properties; } - if (condition.condition === 'minecraft:entity_properties' || condition.condition === 'minecraft:location_predicate' || condition.condition === 'minecraft:match_tool') { - $condition.find('.condition-predicate').removeClass('d-none'); + if (condition.condition === 'minecraft:entity_properties' || condition.condition === 'minecraft:location_check' || condition.condition === 'minecraft:match_tool') { + + if(!condition.predicate) { + condition.predicate = {}; + } + + if (condition.condition === 'minecraft:entity_properties') { + let $entity = generateEntity(condition.predicate); + $condition.children('.card-body').append($entity); + } else { + delete condition.predicate.entity; + delete condition.predicate.location; + } + + if (condition.condition === 'minecraft:location_check') { + let $location = generateLocation(condition.predicate); + $condition.children('.card-body').append($location); + if (condition.predicate) { + delete condition.nbt; + } + } else { + if (condition.predicate) { + delete condition.predicate.biome; + delete condition.predicate.feature; + delete condition.predicate.position; + delete condition.predicate.dimension; + } + } + + if (condition.condition === 'minecraft:match_tool') { + console.log('!!'); + console.log(condition.predicate); + let $item = generateItem(condition.predicate); + $condition.children('.card-body').append($item); + } else { + } + } else { delete condition.predicate; } @@ -460,12 +525,50 @@ function generateCondition(condition, i) { delete condition.scores; } - if (condition.condition === 'minecraft:alternatives') { - $condition.find('.condition-terms').removeCLass('d-none'); + if (condition.condition === 'minecraft:alternative') { + $condition.find('.condition-terms').removeClass('d-none'); } else { delete condition.terms; } + if (condition.condition === 'minecraft:inverted') { + if (!condition.term) { + condition.term = { + condition: "minecraft:random_chance", + chance: 0.5 + }; + } + } else { + delete condition.term; + } + + if (condition.condition === 'minecraft:weather_check') { + $condition.find('.condition-raining').removeClass('d-none'); + let raining = false; + if (condition.raining) { + raining = true; + } else { + delete condition.raining; + } + let id = 'rainingCheckbox' + Math.floor(1000000*Math.random()); + $condition.find('.condition-raining label').attr('for', id); + $condition.find('.condition-raining input').prop('checked', raining).attr('id', id); + + $condition.find('.condition-thundering').removeClass('d-none'); + let thundering = false; + if (condition.thundering) { + thundering = true; + } else { + delete condition.thundering; + } + let id2 = 'thunderingCheckbox' + Math.floor(1000000*Math.random()); + $condition.find('.condition-thundering label').attr('for', id2); + $condition.find('.condition-thundering input').prop('checked', thundering).attr('id', id2); + } else { + delete condition.raining; + delete condition.thundering; + } + if (condition.scores) { $condition.find('.scores-list').removeClass('d-none'); for (let objective in condition.scores) { @@ -495,6 +598,7 @@ function generateCondition(condition, i) { if (condition.term) { let $term = generateCondition(condition.term, 0); $term.removeClass('condition').addClass('term'); + $term.find('.card-header').remove(); $condition.children('.card-body').append($term); } @@ -508,3 +612,120 @@ function generateCondition(condition, i) { return $condition; } + +function generateLocation(location) { + let $location = $('#locationTemplate').clone().removeAttr('id').addClass('predicate'); + if (!location) { + location = {}; + } + + if (location.position) { + $location.find('.position-collapse').removeClass('d-none'); + if (location.position.x) { + $location.find('.position-x .min').val(location.position.x.min); + $location.find('.position-x .max').val(location.position.x.max); + if ($.isEmptyObject(location.position.x)) { + delete location.position.x; + } + } + if (location.position.y) { + $location.find('.position-y .min').val(location.position.y.min); + $location.find('.position-y .max').val(location.position.y.max); + if ($.isEmptyObject(location.position.y)) { + delete location.position.y; + } + } + if (location.position.z) { + $location.find('.position-z .min').val(location.position.z.min); + $location.find('.position-z .max').val(location.position.z.max); + if ($.isEmptyObject(location.position.z)) { + delete location.position.z; + } + } + } + + $location.find('.biome').val(location.biome); + $location.find('.feature').val(location.feature); + $location.find('.dimension').val(location.dimension); + if (location.biome === '') { + delete location.biome; + } + if (location.feature === '') { + delete location.feature; + } + if (location.dimension === '') { + delete location.dimension; + } + + return $location; +} + +function generateEntity(entity) { + let $entity = $('#entityTemplate').clone().removeAttr('id').addClass('predicate'); + if (!entity) { + entity = {}; + } + if (entity.location) { + let $location = generateLocation(entity.location); + $location.removeClass('predicate').addClass('location'); + $entity.children('.card-body').append($location); + } + if (entity.nbt) { + if (!entity.nbt.startsWith('{')) { + entity.nbt = '{' + entity.nbt; + } + if (!entity.nbt.endsWith('}')) { + entity.nbt = entity.nbt + '}'; + } + } + $entity.find('.type').val(entity.type); + $entity.find('.nbt').val(entity.nbt); + if (entity.type === '') { + delete entity.type; + } + if (entity.nbt === '') { + delete entity.nbt; + } + + return $entity; +} + +function generateItem(item) { + let $item = $('#itemTemplate').clone().removeAttr('id').addClass('predicate'); + console.log(item.nbt); + if (!item) { + item = {}; + } + if (item.nbt) { + if (!item.nbt.startsWith('{')) { + item.nbt = '{' + item.nbt; + } + if (!item.nbt.endsWith('}')) { + item.nbt = item.nbt + '}'; + } + } + + if (item.tag) { + $item.find('.tag').removeClass('d-none').val(item.tag); + } else { + $item.find('.name').removeClass('d-none').val(item.name); + } + generateRange($item.find('.item-count'), item.count); + generateRange($item.find('.item-durability'), item.durability); + $item.find('.nbt').val(item.nbt); + $item.find('.potion').val(item.potion); + if (item.name === '') { + delete item.name; + } + if (item.tag === '') { + delete item.tag; + } + if (item.nbt === '') { + delete item.nbt; + } + if (item.nbt === '') { + delete item.nbt; + } + + return $item; +}