first commit

This commit is contained in:
DuOtto
2026-10-19 22:27:05 +02:00
commit afbdc4b139
28 changed files with 4242 additions and 0 deletions
+47
View File
@@ -0,0 +1,47 @@
import { compute, effectiveRules, kitItems } from './calc.js'
// Flat, comparable view of a character, used by the side panel to show what changed.
export function sheetModel(ch, baseRules) {
const rules = effectiveRules(baseRules, ch)
const c = compute(ch, rules)
const prof = rules.professions.find((p) => p.id === ch.profession)
const cls = rules.classes.find((k) => k.id === ch.class_id)
const sub = cls?.subclasses.find((x) => x.id === ch.subclass_id)
const preset = ch.preset === 'custom' ? 'Custom' : baseRules.presets?.find((p) => p.id === ch.preset)?.name || 'Custom'
const training = (s) => (s.pips === 2 ? 'Expertise' : s.pips === 1 ? 'Proficient' : s.type === 'advanced' && s.unlocked ? 'Unlocked' : '')
return {
c,
head: [
{ k: 'name', label: 'Name', val: ch.name || 'Nameless' },
{ k: 'profession', label: 'Profession', val: prof?.name || '–' },
{ k: 'class', label: 'Class', val: cls ? [cls.name, sub?.name].filter(Boolean).join(' / ') : '–' },
{ k: 'preset', label: 'Rules', val: preset },
],
attrs: rules.attributes.map((a) => ({ k: a.id, label: a.name, val: c.attrs[a.id], extra: `Mod ${c.mods[a.id]}` })),
derived: rules.derived.map((d) => ({ k: d.id, label: d.name, val: c.derived[d.id] })),
skills: c.skills.filter((s) => s.points || s.prof || (s.unlocked && s.type === 'advanced'))
.map((s) => ({ k: s.id, label: s.name, val: s.total, extra: training(s) })),
talents: rules.talents.filter((t) => ch.talents.includes(t.id)).map((t) => ({ k: t.id, label: t.name, desc: t.desc })),
augments: rules.augments.filter((a) => ch.augments.includes(a.id)).map((a) => ({ k: a.id, label: a.name, desc: `${a.kind === 'implant' ? 'Implant' : 'Mutation'} · cost ${a.cost}${a.desc ? ` · ${a.desc}` : ''}` })),
gear: kitItems(ch, rules).map((g) => ({ k: g.item.id, label: g.item.name, val: g.qty, desc: [g.item.stat, `${g.item.kg} kg`, g.item.note].filter(Boolean).join(' · ') })),
}
}
// Merges two row lists into one with a status per row: same | changed | added | removed.
export function diffRows(now, before) {
const old = new Map(before.map((r) => [r.k, r]))
const seen = new Set()
const out = now.map((r) => {
seen.add(r.k)
const o = old.get(r.k)
if (!o) return { ...r, status: 'added' }
return { ...r, old: o, status: o.val === r.val && (o.extra || '') === (r.extra || '') ? 'same' : 'changed' }
})
before.forEach((o) => { if (!seen.has(o.k)) out.push({ ...o, status: 'removed' }) })
return out
}
export const countChanges = (a, b) => {
const n = (rows, bef) => diffRows(rows, bef).filter((r) => r.status !== 'same').length
return n(a.head, b.head) + n(a.attrs, b.attrs) + n(a.skills, b.skills) + n(a.talents, b.talents) + n(a.augments, b.augments) + n(a.gear, b.gear)
}