/** * Equipment Rendering Module * Handles UI rendering for the equipment grid and item creation */ import { extensionSettings, $equipmentContainer } from '../../core/state.js'; import { i18n } from '../../core/i18n.js'; import { EQUIPMENT_CATEGORIES, SLOTS_LIST, escapeHtml } from '../equipment/constants.js'; /** * Renders a single equipment slot * @param {Object} slotDef - Slot definition from SLOTS_LIST * @param {Object|null} item - The equipped item or null * @returns {string} HTML for the slot */ function renderSlot(slotDef, item) { const slotId = slotDef.id; const slotName = i18n.getTranslation(`equipment.slots.${slotId}`) || slotId.replace(/(\d+)/, ' $1'); const equippedClass = item ? 'equipped' : ''; if (item) { const statsText = Object.entries(item.stats || {}) .filter(([_, val]) => val > 0) .map(([key, val]) => `${escapeHtml(key.toUpperCase())}+${val}`) .join(''); return `
${escapeHtml(slotName)}
${escapeHtml(item.name)}
${statsText ? `
${statsText}
` : ''} ${item.description ? `
${escapeHtml(item.description)}
` : ''}
`; } return `
${escapeHtml(slotName)}
${i18n.getTranslation('equipment.emptySlot') || 'Empty'}
`; } /** * Generates the full equipment section HTML * @returns {string} Complete HTML for the equipment section */ function generateEquipmentHTML() { const equipment = extensionSettings.userStats?.equipment || { items: [], slots: {} }; const slots = equipment.slots || {}; const items = equipment.items || []; let html = '
'; // Header with add button html += `

${i18n.getTranslation('equipment.title') || 'Equipment'}

`; // Equipment grid html += '
'; // Render each slot for (const slotDef of SLOTS_LIST) { const item = items.find(i => i.slot === slotDef.id); html += renderSlot(slotDef, item); } html += '
'; // Inventory list (items not currently equipped) const unequipped = items.filter(item => !item.slot); if (unequipped.length > 0) { html += '
'; html += `

${i18n.getTranslation('equipment.inventoryTitle') || 'Inventory'}

`; html += '
'; for (const item of unequipped) { const category = EQUIPMENT_CATEGORIES[item.type]; const statsText = Object.entries(item.stats || {}) .filter(([_, val]) => val > 0) .map(([key, val]) => `${escapeHtml(key.toUpperCase())}+${val}`) .join(''); html += `
${escapeHtml(item.name)} ${category ? (i18n.getTranslation(`equipment.types.${item.type}`) || item.type) : escapeHtml(item.type)}
${statsText ? `
${statsText}
` : ''}
`; } html += '
'; html += '
'; } html += '
'; return html; } /** * Main equipment rendering function * Gets data from state/settings and updates DOM directly. */ export function renderEquipment() { if (!$equipmentContainer || !extensionSettings.showEquipment) { return; } const html = generateEquipmentHTML(); $equipmentContainer.html(html); // Re-apply translations i18n.applyTranslations($equipmentContainer[0]); }