Commit Graph
3 Commits
Author SHA1 Message Date
darroyo e8e5ab41c7 feat(personajes): capacity by weight (L2 dwarf model)
CI / Build Native (push) Successful in 6m51s
Reemplaza el modelo slots × stack por el modelo real de L2 para
vendedores enanos: capacidad basada en el límite de peso del personaje
con multiplicador por el pasivo 'Weight Limit Increase' del enano.

Modelo:
- maxWeight = baseWeight × (1 + skillLevel)
  - skillLevel 0 → ×1 (sin pasivo)
  - skillLevel 1 → ×2 (+100%, lv1)
  - skillLevel 2 → ×3 (+200%, lv2)
  - skillLevel 3 → ×4 (+300%, lv3)
- capacity(tipo, grado) = floor(maxWeight / shotWeight[tipo][grado])

Backend (V5 migration):
- DROP COLUMN inventory_slots, stack_limit
- ADD COLUMN base_weight DEFAULT 115230
- ADD COLUMN skill_level DEFAULT 0
- Character/CharacterDto/CharacterIn con los nuevos campos
- PUT /api/characters/{id}/weight endpoint (reemplaza /inventory)
- Validación: baseWeight > 0, skillLevel 0..3

Frontend:
- Form: Base weight (default 115230) + Skill level select (0..3)
- Tabla: Peso base + Skill enano (select editable) + Peso máx calculado
- Sección '💼 Capacidad de inventario de shots (por peso)':
  - Por personaje: header con nombre, lvl, base, multiplicador, badge skill
  - Tabla 3×5 con las 15 capacidades (3 tipos × 5 grados)
  - Sub-info: Peso máx = base × (1+skill)
  - Total 15 tipos por personaje
- Shot weights constants en Alpine (SHOT_WEIGHTS, TIPOS, GRADOS)
- Métodos: maxWeightOf(c), capacityOf(c, tipo, grado), totalCapacityOf(c),
  updateWeight(c), tipoShort(tipo)

Pesos de shots (hardcoded):
- SS: D=3, C=3, B=2, A=2, S=2
- SPS: D=5, C=3, B=3, A=2, S=2
- BSS: D=5, C=3, B=3, A=2, S=2

Verificado en navegador:
- Migration V5 aplicada limpiamente (5 migrations total)
- Personajes existentes preservados con default baseWeight=115230 skillLevel=0
- Math correcta: skillLevel=3, baseWeight=115230 → maxWeight=460.920 →
  SS D=153.640, BSS S=230.460
- Edición inline de skill en la tabla persiste via PUT /weight
- Visualización 3×5 por personaje con badge dinámico
2026-08-23 12:34:47 -04:00
darroyo c11f2e5aac feat(personajes): inventory capacity for shots per character
CI / Build Native (push) Successful in 6m57s
Add 2 new fields per character:
- inventorySlots (default 80) — slots disponibles en el inventario
- stackLimit (default 9999) — límite por stack (config del server)

Capacidad por personaje = slots × stack limit (total shots que puede
cargar). Útil para responder 'tengo N shots, ¿me alcanzan los chars?'.

Backend:
- V4__character_inventory.sql migration adds the 2 columns with defaults
- Character entity + CharacterDto + CharacterIn records include them
- CharacterService.updateInventory() + CharacterResource PUT
  /api/characters/{id}/inventory endpoint for inline edits
- Validation: slots and stackLimit must be > 0

Frontend:
- Agregar personaje form: 2 nuevos inputs (Slots default 80, Stack default 9999)
- Mis personajes table: columnas Slots, Stack y Capacidad (shots),
  editables inline con @blur y @keydown.enter (mismo patrón que level)
- Nueva sección '💼 Capacidad de inventario de shots' con:
  - Total de la cuenta (verde, grande)
  - Sub-info: N personajes · M slots · stack máx X
  - Cards por personaje (slots × stack)
- Alpine helpers nuevos: capacityOf(), totalCapacity(), totalSlots(),
  maxStack(), updateInventory()

Verificado en navegador:
- Math correcta: 100×9999 + 100×99999 = 10.999.800 shots ✓
- Edición inline persiste via PUT /inventory
- Migration V4 aplicada limpiamente en el boot (4 migrations total)
2026-08-23 11:15:49 -04:00
darroyo 661ac4d953 feat: add personajes page with level tracking and fix timer reactivity
CI / Build Native (push) Failing after 58s
- New /personajes page with CRUD for characters (name, class, level)
- Level editable inline, deletable (blocked if has active sales)
- ventas.html now loads characters list as datalist suggestions
- Fix timer: add reactive 'now' property so countdown updates
- Fix script loading: add defaults.js + app.js to ventas/personajes
- Fix table auto-reload: use loadCharacters()/loadSales() after mutations
- Timer now uses setTimeout recursion + visibilitychange handler
2026-08-18 10:09:10 -04:00