var dropData = null;
var dropID = null;
var expandedCards = {};
var cardWidths = {};
var DROP_SECTIONS = [
{
id: 'drops', label: 'Drops', always: true, path: 'drops', isArray: true,
fields: [
['item_id', 'Item ID', 'search', 'e.g. copper_ore', '', null, 'items'],
['table', 'Table', 'search', 'e.g. gem_table', '', null, 'drops'],
['weight', 'Weight', 'number', '10', 'narrow'],
['quantity', 'Quantity', 'number', '1', 'narrow'],
['level', 'Level', 'number', '1', 'narrow'],
['xp', 'XP', 'number', '5', 'narrow'],
['depletes', 'Depletes', 'checkbox'],
['success_message', 'Success Message', 'text', 'You get some %n.', 'wide'],
]
}
];
function initDropEditor() {
editorType = 'drops';
editorFields = [];
loadList();
if (window.location.hash) loadDropEditor(window.location.hash.substring(1));
}
function cardPath(sec) { return sec.path || ''; }
function getVal(data, sec, key) {
return ced_getVal(data, sec, key);
}
function fieldID(sec, key, idx) {
return ced_fieldID(sec, key, idx);
}
function setupSearchFields() { ced_setupSearchFields(); }
function collectFieldValue(el, type) { return ced_collectFieldValue(el, type); }
function loadDropEditor(id) {
dropID = id;
currentID = id;
renderList('');
window.location.hash = id;
API.get('/api/drops/' + encodeURIComponent(id)).then(function(data) {
dropData = data;
renderDropEditor(id, data);
}).catch(function(e) {
$('#editorMain').innerHTML = '
Failed to load: ' + esc(e.message) + '
';
});
}
function loadItem(id) { loadDropEditor(id); }
function renderDropEditor(id, data) {
var html = renderRenameableHeader('Drop Table', id);
html += 'Fields ';
html += 'Raw YAML
';
html += '';
html += '
';
DROP_SECTIONS.forEach(function(sec) {
html += renderCard(sec, data);
});
html += '
';
html += '
' + renderMoveBar() + '
';
html += '
';
html += '';
html += '
' + esc(data._raw || JSON.stringify(data, null, 2)) + ' ';
html += '
';
html += '';
html += 'Save ';
html += 'Duplicate ';
html += 'Remove ';
html += 'New Directory ';
html += '
';
$('#editorMain').innerHTML = html;
setupSearchFields();
}
function renderCurrent() {
ced_syncDOMToData(dropData);
if (!dropData || !dropID) return;
renderDropEditor(dropID, dropData);
}
function renderCard(sec, data) {
var collapsed = expandedCards[sec.id] === false;
var isFull = cardWidths[sec.id] !== undefined ? cardWidths[sec.id] : (sec.fullWidth || false);
var fullClass = isFull ? ' obj-card-full' : '';
var h = '';
h += '';
if (!collapsed) {
h += '
';
h += renderArraySection(sec, data);
h += '
';
}
h += '
';
return h;
}
function renderArraySection(sec, data) {
var arr = dropData[cardPath(sec)] || [];
var h = '';
arr.forEach(function(item, idx) {
h += '';
h += '
';
sec.fields.forEach(function(f) {
h += renderField(sec, f, data, idx);
});
h += '
';
h += '
X ';
h += '
';
});
h += '+ Add Entry ';
return h;
}
function renderField(sec, f, data, idx) {
return ced_renderField(sec, f, data, idx, null, null, cardPath, fieldID, getVal);
}
function toggleCard(id) {
expandedCards[id] = expandedCards[id] === false ? true : false;
renderCurrent();
}
function toggleCardWidth(id) {
cardWidths[id] = !cardWidths[id];
renderCurrent();
}
function addArrayItem(cardID) {
var sec = DROP_SECTIONS.find(function(s) { return s.id === cardID; });
if (!sec || !sec.isArray) return;
var arr = dropData[sec.path] || [];
var empty = {};
sec.fields.forEach(function(f) {
empty[f[0]] = f[2] === 'checkbox' ? false : (f[2] === 'number' ? 0 : '');
});
arr.push(empty);
dropData[sec.path] = arr;
renderCurrent();
}
function removeArrayItem(cardID, idx) {
var sec = DROP_SECTIONS.find(function(s) { return s.id === cardID; });
if (!sec || !sec.isArray) return;
ced_syncDOMToData(dropData);
var arr = dropData[sec.path] || [];
arr.splice(idx, 1);
renderDropEditor(dropID, dropData);
}
function saveDrop() {
if (!ced_validateFields(DROP_SECTIONS, fieldID, null)) return;
var out = {};
DROP_SECTIONS.forEach(function(sec) {
if (sec.isArray) {
var arr = [];
var card = document.querySelector('.obj-card[data-card="' + sec.id + '"]');
if (!card) return;
var rows = card.querySelectorAll('.obj-sub-row');
rows.forEach(function(row, idx) {
var item = {};
sec.fields.forEach(function(f) {
var fid = fieldID(sec, f[0], idx);
var el = document.getElementById(fid);
if (el) item[f[0]] = collectFieldValue(el, f[2]);
});
if (Object.keys(item).length > 0) arr.push(item);
});
if (arr.length > 0) out[sec.path] = arr;
return;
}
var sectionObj = {};
sec.fields.forEach(function(f) {
var fid = fieldID(sec, f[0]);
var el = document.getElementById(fid);
if (!el) return;
sectionObj[f[0]] = collectFieldValue(el, f[2]);
});
if (sec.always && sec.path) {
out[sec.path] = sectionObj;
} else if (sec.always) {
Object.keys(sectionObj).forEach(function(k) { out[k] = sectionObj[k]; });
} else if (sec.path) {
out[sec.path] = sectionObj;
} else {
Object.keys(sectionObj).forEach(function(k) { out[k] = sectionObj[k]; });
}
});
ced_cleanOutput(out);
out.id = dropID;
API.put('/api/drops/' + encodeURIComponent(dropID), out).then(function(resp) {
notify('Drop table ' + dropID + ' saved', 'success');
updateUndoBar();
if (resp && resp._raw) dropData._raw = resp._raw;
}).catch(function(e) { notify('Save failed: ' + e.message, 'error'); });
}
function deleteDrop() {
if (!confirm('Delete drop table "' + dropID + '"?')) return;
API.del('/api/drops/' + encodeURIComponent(dropID)).then(function() {
notify('Drop table ' + dropID + ' deleted', 'success');
updateUndoBar();
dropID = null;
currentID = null;
dropData = null;
$('#editorMain').innerHTML = 'Deleted
';
loadList();
}).catch(function(e) { notify('Delete failed: ' + e.message, 'error'); });
}
function duplicateDrop() {
var baseID = dropID + '_copy';
var newID = baseID;
var counter = 2;
while (true) {
var exists = false;
for (var i = 0; i < allIDs.length; i++) {
if (allIDs[i] === newID) { exists = true; break; }
}
if (!exists) break;
newID = baseID + '_' + counter;
counter++;
}
var copy = JSON.parse(JSON.stringify(dropData));
delete copy._raw;
delete copy._path;
copy.id = newID;
var dir = '';
if (dropData._path) {
var parts = dropData._path.split('/');
var parentDir = parts[parts.length - 2];
if (parentDir !== 'drops') dir = parentDir;
}
API.post('/api/drops', {id: newID}).then(function() {
var putOp = API.put('/api/drops/' + encodeURIComponent(newID), copy);
if (dir) {
return putOp.then(function() {
return API.post('/api/drops/move', {id: newID, dir: dir});
});
}
return putOp;
}).then(function() {
notify('Duplicated as ' + newID, 'success');
updateUndoBar();
loadList();
loadDropEditor(newID);
}).catch(function(e) { notify('Duplicate failed: ' + e.message, 'error'); });
}