// Logique de fusion des fichiers de stats de chance de drop. // Utilisée à la fois par main.js (Electron) et par tools/merge-dropstats.js (CLI autonome). // Format du fichier : voir emptyDropStats() ci-dessous. function emptyDropStats() { return { type: 'farm-tracker-dropstats', version: 1, updatedAt: null, mobs: {} }; } /** * Fusionne `source.mobs` dans `target.mobs` (additionne les compteurs). * Modifie `target` en place et retourne le nombre de kills ajoutés. */ function mergeDropStatsInto(target, source) { let addedKills = 0; const sourceMobs = (source && source.mobs) || {}; for (const [mobName, mobData] of Object.entries(sourceMobs)) { if (!mobName) continue; if (!target.mobs[mobName]) target.mobs[mobName] = { kills: 0, totalExp: 0, totalCols: 0, items: {} }; const t = target.mobs[mobName]; const kills = Number(mobData.kills) || 0; t.kills += kills; addedKills += kills; t.totalExp = (t.totalExp || 0) + (Number(mobData.totalExp) || 0); t.totalCols = (t.totalCols || 0) + (Number(mobData.totalCols) || 0); const items = mobData.items || {}; for (const [key, item] of Object.entries(items)) { if (!key) continue; if (!t.items[key]) t.items[key] = { name: '', rawName: '', occurrences: 0, totalQty: 0 }; const ti = t.items[key]; ti.occurrences += Number(item.occurrences) || 0; ti.totalQty += Number(item.totalQty) || 0; if (item.rawName) ti.rawName = item.rawName; if (item.name) ti.name = item.name; } } return addedKills; } function summarize(dropStats) { const mobs = Object.keys(dropStats.mobs || {}); const totalKills = mobs.reduce((sum, m) => sum + (dropStats.mobs[m].kills || 0), 0); const totalCombos = mobs.reduce((sum, m) => sum + Object.keys(dropStats.mobs[m].items || {}).length, 0); return { totalMobs: mobs.length, totalKills, totalCombos }; } module.exports = { emptyDropStats, mergeDropStatsInto, summarize };