From 71f0f381de64e045f91da19450adacf10fbc7902 Mon Sep 17 00:00:00 2001 From: historia <[not public]> Date: Wed, 8 Jul 2026 01:22:38 -0400 Subject: feat: multi-tool gather objects correctly handled. hide more irrelevant fishing fields. --- internal/admin/static/objecteditor.js | 134 ++++++++++++++++++++++++++++++---- 1 file changed, 121 insertions(+), 13 deletions(-) (limited to 'internal/admin/static/objecteditor.js') diff --git a/internal/admin/static/objecteditor.js b/internal/admin/static/objecteditor.js index fdaefd2..29ad66b 100644 --- a/internal/admin/static/objecteditor.js +++ b/internal/admin/static/objecteditor.js @@ -45,9 +45,10 @@ var SECTIONS = [ ['base', 'Base', 'number', '0.5', 'narrow'], ['per_level', 'Per Lvl', 'number', '0.01', 'narrow'], ['cap', 'Cap', 'number', '0.95', 'narrow'] ]}, {label:'Other', row:0, fields:[ - ['respawn_timer', 'Respawn', 'number', '50', 'narrow'], + ['respawn_timer', 'Respawn', 'number', '50', 'narrow', function(d) { return d.skill !== 'fishing'; }], ['deplete_timer', 'Deplete', 'number', '45', 'narrow', function(d) { return d.skill === 'woodcutting'; }], ['nest_chance', 'Nest 1/n', 'number', '256', 'narrow', function(d) { return d.skill === 'woodcutting'; }], + ['no_tool_speed', 'Bare Speed', 'number', '3', 'narrow', function(d) { return !d.tools || d.tools.length === 0; }], ]}, {label:'Tools', key:'tools', type:'tools_checkbox', hint:'any one is sufficient (OR)'}, ], @@ -55,7 +56,7 @@ var SECTIONS = [ {label:'Drops', key:'drops', fields:[ ['item_id', 'Item ID', 'search', 'copper_ore', '', 'items'], ['table', 'Table', 'search', 'gem_table', '', 'drops'], ['weight', 'Weight', 'number', '90', 'narrow'], ['level', 'Level', 'number', '1', 'narrow'], ['xp', 'XP', 'number', '17', 'narrow'], - ['quantity', 'Quantity', 'number', '1', 'narrow'], ['depletes', 'Depletes node', 'checkbox'], + ['quantity', 'Quantity', 'number', '1', 'narrow'], ['tool', 'Tool', 'select'], ['depletes', 'Depletes node', 'checkbox'], ['message', 'Message', 'text', 'You manage to mine some copper ore.'], ]} ] @@ -74,7 +75,7 @@ var SECTIONS = [ ['respawn_on_hide', 'Respawn on hide', 'checkbox'], ], subtables: [ - {label:'Levels of Decay', key:'levels', fields:[ + {label:'Levels of Decay (lower is more decayed)', key:'levels', vertical: true, fields:[ ['message', 'Look Message', 'text'], ['degrade_message', 'Degrade Message', 'text'] ]} ] @@ -93,7 +94,7 @@ var SECTIONS = [ id: 'on_look', label: 'On Look', labelHint: '(what happens when you "look ")', path: 'on_look', detect: function(d) { return d.on_look; }, fields: [ - ['set_flags', 'Set Flags', 'json', '{"flag":"value"}'], + ['set_flags', 'Set Global Flags', 'json', '{"flag":"value"}'], ['set_player_flags', 'Set Player Flags', 'json', '{"pflag":"value"}'], ['give_item', 'Give Item', 'search', 'e.g. keycard', '', null, 'items'], ['take_item', 'Take Item', 'search', 'e.g. bomb', '', null, 'items'], @@ -233,6 +234,28 @@ function renderCard(sec, data) { } else { h += '
'; sec.fields.forEach(function(f) { + if (sec.id === 'gather' && f[0] === 'bait') { + window._gatherVis = window._gatherVis || {}; + var gd = objectData.gather || {}; + var isFishing = gd.skill === 'fishing'; + var showBait = isFishing && (window._gatherVis.bait || (gd.bait && gd.bait !== '')); + if (isFishing && showBait) { + var bv = gd.bait || ''; + h += ''; + } else if (isFishing) { + h += ''; + } + return; + } h += renderField(sec, f, data, -1); }); h += '
'; @@ -497,6 +520,27 @@ function renderOnLookCard(data) { h += renderField(sec, sec.fields[5], data, -1); h += renderField(sec, sec.fields[6], data, -1); h += ''; + var helpCollapsed = window._onLookHelpCollapsed === undefined ? true : window._onLookHelpCollapsed; + h += '
'; + h += '
'; + h += '' + (helpCollapsed ? '▶' : '▼') + ''; + h += 'How Set Global Flags & Set Player Flags Work'; + h += '
'; + if (!helpCollapsed) { + h += '
'; + h += 'When a player looks at this object, these fields apply effects.

'; + h += 'Set Global Flags — Sets world flags shared by all players. JSON object mapping flag names to values:
'; + h += '  {"gate_open":true,"boss_summoned":false}
'; + h += '  Flags persist until changed by another on_look, room script, or interact action.

'; + h += 'Set Player Flags — Sets per-character flags saved to the player\'s YAML. JSON object mapping flag names to values:
'; + h += '  {"has_seen_cave":true,"dialog_spoke":1}
'; + h += '  These flags can be used in conditions (player_flag) to track player progress.

'; + h += 'Other FieldsGive Item grants an item, Take Item removes one, '; + h += 'Teleport sends player to a room, Heal restores HP, Credits adds/removes credits (use negative for cost).

'; + h += 'All effects fire simultaneously when the player looks at this object.'; + h += '
'; + } + h += '
'; return h; } @@ -602,10 +646,15 @@ function renderSubtable(sec, st, data) { arr = sectionRoot[st.key] || []; } var isDrops = sec.id === 'gather' && st.key === 'drops'; + var isVertical = st.vertical; + var gatherTools = []; + if (isDrops) { + gatherTools = (sectionRoot.tools || []).filter(function(t) { return t && t !== ''; }); + } var h = '
'; h += '
' + esc(st.label) + '
'; arr.forEach(function(item, idx) { - h += '
'; + h += '
'; if (isDrops) { if (!st.single) { h += ''; @@ -628,7 +677,21 @@ function renderSubtable(sec, st, data) { var dp = cardPath(sec) + '.' + st.key + '[' + idx + '].' + f[0]; h += ''; } else if (f[2] === 'checkbox') { - h += ''; + var hideStyle = ''; + if (isDrops && f[0] === 'depletes' && sectionRoot.skill === 'fishing') { + hideStyle = ' style="display:none"'; + } + h += ''; + } else if (f[2] === 'select' && f[0] === 'tool') { + if (gatherTools.length >= 2) { + var dpTool = cardPath(sec) + '.' + st.key + '[' + idx + '].' + f[0]; + h += ''; + } } else { h += ''; } @@ -641,6 +704,9 @@ function renderSubtable(sec, st, data) { h += ''; h += '
'; } else { + if (isVertical && !st.single) { + h += ''; + } st.fields.forEach(function(f) { var fid = fieldIDSub(sec, st.key, idx, f[0]); var val = item[f[0]]; @@ -659,7 +725,7 @@ function renderSubtable(sec, st, data) { h += ''; } }); - if (!st.single) { + if (!st.single && !isVertical) { h += ''; } } @@ -718,7 +784,7 @@ function renderToolsCheckbox(sec, il, data) { h += '
'; arr.forEach(function(t, idx) { h += '
'; - h += ''; choices.forEach(function(c) { var sel = c === t ? ' selected' : ''; h += '' + esc(c) + ''; @@ -738,14 +804,18 @@ function addToolRow(secID, key) { if (!sec) return; var p = cardPath(sec); if (!objectData[p]) objectData[p] = {}; - objectData[p][key] = (objectData[p][key] || []).concat(['']); - renderCurrent(); + ced_syncDOMToData(objectData); + syncGatherToolsFromDOM(); + var val = (toolTypes && toolTypes.length > 0) ? toolTypes[0] : ''; + objectData[p][key] = (objectData[p][key] || []).concat([val]); + renderObjectEditor(objectID, objectData); } function removeToolRow(secID, key, idx) { var sec = SECTIONS.find(function(s) { return s.id === secID; }); if (!sec) return; ced_syncDOMToData(objectData); + syncGatherToolsFromDOM(); var p = cardPath(sec); var arr = objectData[p] && objectData[p][key]; if (!arr) return; @@ -764,6 +834,19 @@ function fetchToolTypes() { }); } +function syncGatherToolsFromDOM() { + if (!objectData || !objectData.gather) return; + var selects = document.querySelectorAll('.obj-tool-select'); + if (selects.length === 0) return; + var tools = []; + selects.forEach(function(s) { if (s.value) tools.push(s.value); }); + if (tools.length > 0) { + objectData.gather.tools = tools; + } else if (objectData.gather.tools && objectData.gather.tools.length > 0) { + delete objectData.gather.tools; + } +} + function toggleCard(id) { expandedCards[id] = expandedCards[id] === false ? true : false; renderCurrent(); @@ -774,6 +857,20 @@ function toggleCardWidth(id) { renderCurrent(); } +function showBaitField() { + window._gatherVis = window._gatherVis || {}; + window._gatherVis.bait = true; + renderCurrent(); +} + +function hideBaitField() { + window._gatherVis = window._gatherVis || {}; + window._gatherVis.bait = false; + ced_syncDOMToData(objectData); + if (objectData.gather) objectData.gather.bait = ''; + renderObjectEditor(objectID, objectData); +} + function toggleSafespotHelp() { if (window._safespotHelpCollapsed === undefined) { window._safespotHelpCollapsed = false; @@ -884,7 +981,7 @@ function addDropRow(cardID, subKey, dropType) { if (!sec) return; var sectionRoot = objectData[sec.path || ''] || objectData; var arr = sectionRoot[subKey] || []; - var empty = { item_id: '', table: '', weight: 0, level: 0, xp: 0, quantity: 0, depletes: false, message: '', _type: (dropType === 'table' ? 't' : 'i') }; + var empty = { item_id: '', table: '', weight: 0, level: 0, xp: 0, quantity: 0, depletes: false, tool: '', message: '', _type: (dropType === 'table' ? 't' : 'i') }; arr.push(empty); sectionRoot[subKey] = arr; renderCurrent(); @@ -896,6 +993,7 @@ function validateDropRow(idx) { function renderCurrent() { ced_syncDOMToData(objectData); + syncGatherToolsFromDOM(); if (!objectData || !objectID) return; renderObjectEditor(objectID, objectData); } @@ -961,13 +1059,22 @@ function toggleUseInterHelp() { renderCurrent(); } +function toggleOnLookHelp() { + if (window._onLookHelpCollapsed === undefined) { + window._onLookHelpCollapsed = false; + } else { + window._onLookHelpCollapsed = !window._onLookHelpCollapsed; + } + renderCurrent(); +} + function toggleGatherConditionals() { var skillEl = document.getElementById('f_gather_skill'); var skill = skillEl ? skillEl.value : ''; var fishing = skill === 'fishing'; var wood = skill === 'woodcutting'; - var els = ['bait', 'exhausted_message', 'depleted_message', 'deplete_timer', 'nest_chance', 'respawn_broadcast']; - var vis = {bait: fishing, exhausted_message: wood, depleted_message: !fishing, deplete_timer: wood, nest_chance: wood, respawn_broadcast: !fishing}; + var els = ['exhausted_message', 'depleted_message', 'deplete_timer', 'nest_chance', 'respawn_broadcast', 'respawn_timer']; + var vis = {exhausted_message: wood, depleted_message: !fishing, deplete_timer: wood, nest_chance: wood, respawn_broadcast: !fishing, respawn_timer: !fishing}; els.forEach(function(key) { var el = document.getElementById('f_gather_' + key); if (el) el.closest('.obj-field').style.display = vis[key] ? '' : 'none'; @@ -975,6 +1082,7 @@ function toggleGatherConditionals() { document.querySelectorAll('[id^="f_gather_drops_"][id$="_depletes"]').forEach(function(el) { el.closest('.obj-field').style.display = fishing ? 'none' : ''; }); + renderCurrent(); } function setupSearchFields() { ced_setupSearchFields(); } -- cgit v1.2.3