feat: compute base item values by reversing active spell buffs

Extract spell effect mappings from Dictionaries.cs into spell_effects.json.
During item ingestion, compute_base_values() reverses active enchantment
effects to get true base stats:
- base_armor_level: armor without Impenetrability buffs
- base_max_damage: damage without Blood Drinker buffs
- base_attack_bonus: attack without Heart Seeker buffs
- base_melee_defense_bonus: defense without Defender buffs
- base_elemental_damage_vs_monsters: elemental without Spirit Drinker
- base_mana_conversion_bonus: mana conv without Hermetic Link

New columns in ItemCombatStats, exposed in search CTEs.
Frontend: Base Armor and Base Dmg columns (hidden by default, toggle on).
Requires ALTER TABLE migration before deploy.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-04-09 12:31:39 +02:00
parent 77e5a544d1
commit c4856dc701
4 changed files with 141 additions and 0 deletions

View file

@ -457,8 +457,12 @@ const RESULT_COLUMNS = [
render: item => `<td class="text-right narrow-col">${item.coverage ? item.coverage.replace(/,\s*/g, '<br>') : '-'}</td>` },
{ key: 'armor_level', label: 'Armor', sort: 'armor', defaultVisible: true, cls: 'text-right',
render: item => `<td class="text-right">${item.armor_level > 0 ? item.armor_level : '-'}</td>` },
{ key: 'base_armor_level', label: 'Base Armor', sort: 'base_armor_level', defaultVisible: false, cls: 'text-right',
render: item => `<td class="text-right">${item.base_armor_level > 0 ? item.base_armor_level : '-'}</td>` },
{ key: 'max_damage', label: 'Max Dmg', sort: 'max_damage', defaultVisible: true, cls: 'text-right',
render: item => `<td class="text-right">${item.max_damage > 0 ? item.max_damage : '-'}</td>` },
{ key: 'base_max_damage', label: 'Base Dmg', sort: 'base_max_damage', defaultVisible: false, cls: 'text-right',
render: item => `<td class="text-right">${item.base_max_damage > 0 ? item.base_max_damage : '-'}</td>` },
{ key: 'weapon_time', label: 'Speed', sort: 'weapon_time', defaultVisible: true, cls: 'text-right',
render: item => `<td class="text-right">${item.weapon_time > 0 && item.weapon_time < 100 ? item.weapon_time : '-'}</td>` },
{ key: 'attack_bonus', label: 'Attack Bonus', sort: 'attack_bonus', defaultVisible: true, cls: 'text-right',