diff options
| author | historia <[not public]> | 2026-07-05 16:42:01 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-07-05 16:42:01 -0400 |
| commit | 9b54188970c51070d86f4c87e909ea7836c86f07 (patch) | |
| tree | 9dea17fee340bb92dee8bb4632001dbf219d2462 /internal/admin/static/objecteditor.js | |
| parent | 21c1997a3fd0f5ec5dcff1add45e4dfaf7a338ca (diff) | |
| download | thehouseoficarus-9b54188970c51070d86f4c87e909ea7836c86f07.tar.gz | |
fix: restructure steal yaml, update admin web gui
Diffstat (limited to 'internal/admin/static/objecteditor.js')
| -rw-r--r-- | internal/admin/static/objecteditor.js | 177 |
1 files changed, 137 insertions, 40 deletions
diff --git a/internal/admin/static/objecteditor.js b/internal/admin/static/objecteditor.js index c80cb57..f8ef18a 100644 --- a/internal/admin/static/objecteditor.js +++ b/internal/admin/static/objecteditor.js @@ -18,14 +18,14 @@ var SECTIONS = [ ] }, { - id: 'steal', label: 'Steal', - detect: function(d) { return d.steal_table !== undefined || d.steal_level !== undefined || d.steal_speed !== undefined || d.steal_xp !== undefined || d.guard_mob !== undefined; }, + id: 'steal', label: 'Steal', path: 'steal', + detect: function(d) { return d.steal !== undefined; }, fields: [ - ['steal_table', 'Table ID', 'text'], - ['steal_level', 'Level', 'number', '', 'narrow'], - ['steal_xp', 'XP', 'number', '', 'narrow'], - ['steal_speed', 'Speed', 'number', '', 'narrow'], - ['guard_mob', 'Guard Mob', 'text'], + ['table', 'Table ID', 'search', '', '', null, 'drops'], + ['level', 'Level', 'number', '1', 'narrow'], + ['xp', 'XP', 'number', '5', 'narrow'], + ['speed', 'Speed', 'number', '4', 'narrow'], + ['guard_mob', 'Guard Mob', 'search', '', '', null, 'mobs'], ] }, { @@ -148,6 +148,8 @@ function loadObject(id) { window._editorData = objectData; window._useInterVis = {}; window._useInterHelpCollapsed = undefined; + window._coreVis = {}; + window._stealVis = {}; renderObjectEditor(id, data); }).catch(function(e) { $('#editorMain').innerHTML = '<p style="color:var(--danger)">Failed to load: ' + esc(e.message) + '</p>'; @@ -250,6 +252,8 @@ function renderCard(sec, data) { h += renderArraySection(sec, data); } else if (sec.id === 'core') { h += renderCoreCard(data); + } else if (sec.id === 'steal') { + h += renderStealCard(data); } else { h += '<div class="obj-card-grid">'; sec.fields.forEach(function(f) { @@ -351,6 +355,17 @@ function renderField(sec, f, data, idx, subPath, optStyle) { if (!showIf(sectionData)) hiddenStyle = ' style="display:none"'; } + var pfx = cardPath(sec); + var dp; + if (idx >= 0) { + dp = pfx + '[' + idx + '].' + key; + } else if (subPath) { + dp = (pfx ? pfx + '.' : '') + subPath + '.' + key; + } else { + dp = (pfx ? pfx + '.' : '') + key; + } + var dpAttr = ' data-field-path="' + escAttr(dp) + '"'; + function wrap(cls, inner) { var w = (wide === 'wide') ? ' obj-wide' : ''; if (wide === 'narrow') w = ' obj-narrow'; @@ -359,19 +374,19 @@ function renderField(sec, f, data, idx, subPath, optStyle) { } if (type === 'checkbox') { - return wrap('obj-field obj-check', '<input type="checkbox" id="' + fid + '"' + (val ? ' checked' : '') + '> <span>' + esc(label) + '</span>'); + return wrap('obj-field obj-check', '<input type="checkbox" id="' + fid + '"' + (val ? ' checked' : '') + dpAttr + '> <span>' + esc(label) + '</span>'); } if (type === 'json') { var jstr = typeof val === 'object' ? JSON.stringify(val) : String(val); - return wrap('obj-field', '<span>' + esc(label) + '</span><textarea id="' + fid + '" rows="2" placeholder="{}">' + esc(jstr) + '</textarea>'); + return wrap('obj-field', '<span>' + esc(label) + '</span><textarea id="' + fid + '" rows="2" placeholder="{}"' + dpAttr + '>' + esc(jstr) + '</textarea>'); } if (type === 'textarea') { var dstr = typeof val === 'object' ? (Array.isArray(val) ? val.map(function(v){return v.text||'';}).join('\n') : JSON.stringify(val)) : String(val); - return wrap('obj-field', '<span>' + esc(label) + '</span><textarea id="' + fid + '" rows="3">' + esc(dstr) + '</textarea>'); + return wrap('obj-field', '<span>' + esc(label) + '</span><textarea id="' + fid + '" rows="3"' + dpAttr + '>' + esc(dstr) + '</textarea>'); } if (type === 'select') { var opts = hint ? hint.split('|') : []; - var inner = '<span>' + esc(label) + '</span><select id="' + fid + '" onchange="toggleGatherConditionals()">'; + var inner = '<span>' + esc(label) + '</span><select id="' + fid + '" onchange="toggleGatherConditionals()"' + dpAttr + '>'; opts.forEach(function(o) { inner += '<option value="' + escAttr(o) + '"' + (String(val) === o ? ' selected' : '') + '>' + (o === '' ? 'All' : esc(o)) + '</option>'; }); @@ -380,39 +395,93 @@ function renderField(sec, f, data, idx, subPath, optStyle) { } if (type === 'color') { var swatch = '<span class="color-swatch" style="background:#' + escAttr(String(val) || '808080') + '"></span>'; - return wrap('obj-field color-field', '<span>' + esc(label) + '</span><div class="obj-color-row">' + swatch + '<input id="' + fid + '" value="' + escAttr(String(val)) + '" class="color-input"></div>'); + return wrap('obj-field color-field', '<span>' + esc(label) + '</span><div class="obj-color-row">' + swatch + '<input id="' + fid + '" value="' + escAttr(String(val)) + '" class="color-input"' + dpAttr + '></div>'); } if (type === 'search') { var entity = searchEntity || 'items'; var ph = hint ? ' placeholder="' + esc(hint) + '"' : ' placeholder="Search ' + entity + '..."'; - var pfx = cardPath(sec); - var dp; - if (idx >= 0) { - dp = pfx + '[' + idx + '].' + key; - } else if (subPath) { - dp = (pfx ? pfx + '.' : '') + subPath + '.' + key; - } else { - dp = (pfx ? pfx + '.' : '') + key; - } - return wrap('obj-field obj-search', '<span>' + esc(label) + '</span><div style="position:relative;width:100%"><input id="' + fid + '" value="' + escAttr(String(val)) + '" class="search-input" data-search-type="' + entity + '" data-data-path="' + escAttr(dp) + '"' + ph + '><div class="search-results" style="display:none"></div></div>'); + return wrap('obj-field obj-search', '<span>' + esc(label) + '</span><div style="position:relative;width:100%"><input id="' + fid + '" value="' + escAttr(String(val)) + '" class="search-input" data-search-type="' + entity + '" data-field-path="' + escAttr(dp) + '"' + ph + '><div class="search-results" style="display:none"></div></div>'); } var ph = hint ? ' placeholder="' + esc(hint) + '"' : ''; - return wrap('obj-field', '<span>' + esc(label) + '</span><input id="' + fid + '" value="' + escAttr(String(val)) + '"' + ph + '>'); + return wrap('obj-field', '<span>' + esc(label) + '</span><input id="' + fid + '" value="' + escAttr(String(val)) + '"' + ph + dpAttr + '>'); } function renderCoreCard(data) { var sec = SECTIONS[0]; + window._coreVis = window._coreVis || {}; + var vis = window._coreVis; + var showAliases = vis.aliases || (data.aliases && data.aliases.length > 0); + var showInRoom = vis.inroom_description || (data.inroom_description && data.inroom_description !== ''); + var showRemoval = vis.removal_item || (data.removal_item && data.removal_item !== ''); + var h = '<div class="obj-core-row">'; h += renderField(sec, sec.fields[0], data, -1, null, 'flex:1'); // name - h += renderField(sec, sec.fields[2], data, -1, null, 'flex:2'); // aliases h += renderField(sec, sec.fields[1], data, -1); // color h += renderField(sec, sec.fields[3], data, -1); // hidden h += '</div>'; h += '<div style="display:flex;flex-direction:column;gap:8px">'; h += renderField(sec, sec.fields[5], data, -1); // description - h += renderField(sec, sec.fields[4], data, -1); // in-room description - h += renderField(sec, sec.fields[6], data, -1); // removal item + + if (showAliases) { + h += '<div style="display:flex;gap:6px;align-items:flex-start">'; + h += '<div style="flex:1">' + renderField(sec, sec.fields[2], data, -1, null, 'flex:2') + '</div>'; + h += '<button class="btn btn-sm btn-danger" onclick="hideCoreField(\'aliases\')" style="margin-top:2px">X</button>'; + h += '</div>'; + } + if (showInRoom) { + h += '<div style="display:flex;gap:6px;align-items:flex-start">'; + h += '<div style="flex:1">' + renderField(sec, sec.fields[4], data, -1) + '</div>'; + h += '<button class="btn btn-sm btn-danger" onclick="hideCoreField(\'inroom_description\')" style="margin-top:2px">X</button>'; + h += '</div>'; + } + if (showRemoval) { + h += '<div style="display:flex;gap:6px;align-items:flex-start">'; + h += '<div style="flex:1">' + renderField(sec, sec.fields[6], data, -1) + '</div>'; + h += '<button class="btn btn-sm btn-danger" onclick="hideCoreField(\'removal_item\')" style="margin-top:2px">X</button>'; + h += '</div>'; + } h += '</div>'; + + h += '<div style="display:flex;gap:8px;margin-top:4px">'; + if (!showAliases) { + h += '<button class="btn btn-sm" style="background:var(--accent);color:var(--text);border:1px solid #1a5a8e;white-space:nowrap" onclick="showCoreField(\'aliases\')">+ Add Aliases</button>'; + } + if (!showInRoom) { + h += '<button class="btn btn-sm" style="background:var(--accent);color:var(--text);border:1px solid #1a5a8e;white-space:nowrap" onclick="showCoreField(\'inroom_description\')">+ Add In-Room Desc</button>'; + } + if (!showRemoval) { + h += '<button class="btn btn-sm" style="background:var(--accent);color:var(--text);border:1px solid #1a5a8e;white-space:nowrap" onclick="showCoreField(\'removal_item\')">+ Add Removal Item</button>'; + } + h += '</div>'; + + return h; +} + +function renderStealCard(data) { + var sec = SECTIONS[1]; + window._stealVis = window._stealVis || {}; + var vis = window._stealVis; + var stealData = data.steal || {}; + var showGuard = vis.guard_mob || (stealData.guard_mob && stealData.guard_mob !== ''); + + var h = '<div style="display:flex;gap:10px">'; + h += '<div style="flex:1">' + renderField(sec, sec.fields[0], data, -1) + '</div>'; + h += renderField(sec, sec.fields[1], data, -1); + h += renderField(sec, sec.fields[2], data, -1); + h += renderField(sec, sec.fields[3], data, -1); + h += '</div>'; + + if (showGuard) { + h += '<div style="display:flex;gap:6px;align-items:flex-start;margin-top:8px">'; + h += '<div style="flex:1">' + renderField(sec, sec.fields[4], data, -1) + '</div>'; + h += '<button class="btn btn-sm btn-danger" onclick="hideGuardMob()" style="margin-top:2px">X</button>'; + h += '</div>'; + } else { + h += '<div style="margin-top:8px">'; + h += '<button class="btn btn-sm" style="background:var(--accent);color:var(--text);border:1px solid #1a5a8e;white-space:nowrap;width:100%" onclick="showGuardMob()">+ Guard Mob</button>'; + h += '</div>'; + } + return h; } @@ -433,7 +502,9 @@ function renderArraySection(sec, data) { h += '<div class="obj-sub-row" data-idx="' + idx + '" style="flex-direction:column;align-items:stretch;position:relative;gap:6px">'; - h += '<div style="display:flex;gap:6px;align-items:flex-end;flex-wrap:wrap">'; + h += '<button class="btn btn-sm btn-danger" style="position:absolute;top:0;right:0;white-space:nowrap;z-index:1" onclick="removeArrayItem(\'' + sec.id + '\',' + idx + ')">Remove Interaction</button>'; + + h += '<div style="display:flex;gap:4px;align-items:flex-end;flex-wrap:wrap;padding-right:125px">'; h += renderField(sec, sec.fields[0], data, idx, null, 'max-width:260px'); h += '<div style="width:1px;background:var(--border);align-self:stretch;margin:2px 0;flex-shrink:0"></div>'; if (!showCond) { @@ -445,7 +516,6 @@ function renderArraySection(sec, data) { if (!showMsg) { h += '<button class="btn btn-sm" style="background:var(--accent);color:var(--text);border:1px solid #1a5a8e;align-self:flex-end;margin-bottom:3px;white-space:nowrap" onclick="showUseInterField(' + idx + ',\'message\')">+ Add Message</button>'; } - h += '<button class="btn btn-sm btn-danger" style="margin-left:auto;align-self:flex-end;margin-bottom:3px;white-space:nowrap" onclick="removeArrayItem(\'' + sec.id + '\',' + idx + ')">Remove Interaction</button>'; h += '</div>'; h += '<div style="display:' + (showCond ? 'flex' : 'none') + ';gap:6px;align-items:flex-start">'; @@ -541,7 +611,7 @@ function renderSubtable(sec, st, data) { var entity = f[5] || 'items'; var ph = f[3] ? ' placeholder="' + escAttr(f[3]) + '"' : ' placeholder="Search ' + entity + '..."'; var dp = cardPath(sec) + '.' + st.key + '[' + idx + '].' + f[0]; - h += '<label class="obj-field obj-search' + extraCls + '"><span>' + esc(f[1]) + '</span><div style="position:relative;width:100%"><input id="' + fid + '" value="' + escAttr(String(val)) + '" class="search-input" data-search-type="' + entity + '" data-data-path="' + escAttr(dp) + '"' + ph + '><div class="search-results" style="display:none"></div></div></label>'; + h += '<label class="obj-field obj-search' + extraCls + '"><span>' + esc(f[1]) + '</span><div style="position:relative;width:100%"><input id="' + fid + '" value="' + escAttr(String(val)) + '" class="search-input" data-search-type="' + entity + '" data-field-path="' + escAttr(dp) + '"' + ph + '><div class="search-results" style="display:none"></div></div></label>'; } else if (f[2] === 'checkbox') { h += '<label class="obj-field obj-check' + extraCls + '"><input type="checkbox" id="' + fid + '"' + (val ? ' checked' : '') + '> <span>' + esc(f[1]) + '</span></label>'; } else { @@ -567,7 +637,7 @@ function renderSubtable(sec, st, data) { var entity = f[5] || 'items'; var ph = f[3] ? ' placeholder="' + escAttr(f[3]) + '"' : ' placeholder="Search ' + entity + '..."'; var dp = cardPath(sec) + '.' + st.key + '[' + idx + '].' + f[0]; - h += '<label class="obj-field obj-search' + extraCls + '"><span>' + esc(f[1]) + '</span><div style="position:relative;width:100%"><input id="' + fid + '" value="' + escAttr(String(val)) + '" class="search-input" data-search-type="' + entity + '" data-data-path="' + escAttr(dp) + '"' + ph + '><div class="search-results" style="display:none"></div></div></label>'; + h += '<label class="obj-field obj-search' + extraCls + '"><span>' + esc(f[1]) + '</span><div style="position:relative;width:100%"><input id="' + fid + '" value="' + escAttr(String(val)) + '" class="search-input" data-search-type="' + entity + '" data-field-path="' + escAttr(dp) + '"' + ph + '><div class="search-results" style="display:none"></div></div></label>'; } else if (f[2] === 'checkbox') { h += '<label class="obj-field obj-check' + extraCls + '"><input type="checkbox" id="' + fid + '"' + (val ? ' checked' : '') + '> <span>' + esc(f[1]) + '</span></label>'; } else { @@ -693,11 +763,7 @@ function removeSection(id) { if (sec.path) { delete objectData[sec.path]; } else if (id === 'steal') { - delete objectData.steal_table; - delete objectData.steal_level; - delete objectData.steal_xp; - delete objectData.steal_speed; - delete objectData.guard_mob; + delete objectData.steal; } renderCurrent(); } @@ -724,11 +790,7 @@ function addSection() { objectData[sec.path] = {}; } } else if (id === 'steal') { - objectData.steal_table = ''; - objectData.steal_level = 0; - objectData.steal_xp = 0; - objectData.steal_speed = 0; - objectData.guard_mob = ''; + objectData.steal = {table: ''}; } expandedCards[id] = true; renderCurrent(); @@ -806,6 +868,7 @@ function validateDropRow(idx) { } function renderCurrent() { + ced_syncDOMToData(objectData); if (!objectData || !objectID) return; renderObjectEditor(objectID, objectData); } @@ -827,6 +890,38 @@ function hideUseInterField(idx, key) { renderCurrent(); } +function showCoreField(key) { + window._coreVis = window._coreVis || {}; + window._coreVis[key] = true; + renderCurrent(); +} + +function hideCoreField(key) { + window._coreVis = window._coreVis || {}; + window._coreVis[key] = false; + if (key === 'aliases') { + objectData.aliases = []; + } else if (key === 'inroom_description') { + objectData.inroom_description = ''; + } else if (key === 'removal_item') { + objectData.removal_item = ''; + } + renderCurrent(); +} + +function showGuardMob() { + window._stealVis = window._stealVis || {}; + window._stealVis.guard_mob = true; + renderCurrent(); +} + +function hideGuardMob() { + window._stealVis = window._stealVis || {}; + window._stealVis.guard_mob = false; + if (objectData.steal) objectData.steal.guard_mob = ''; + renderCurrent(); +} + function toggleUseInterHelp() { if (window._useInterHelpCollapsed === undefined) { window._useInterHelpCollapsed = false; @@ -967,6 +1062,8 @@ function saveObject() { } } else if (hasValues && sec.path) { out[sec.path] = sectionObj; + } else if (hasValues) { + Object.keys(sectionObj).forEach(function(k) { out[k] = sectionObj[k]; }); } }); |
