Commit graph

81 commits

Author SHA1 Message Date
Erik
ee30ad2636 fix(combat): show offense + defense damage by element in grid
The element breakdown grid previously only showed damage RECEIVED
(defense) in the Mel/Msl and Magic columns, which was mostly empty
for characters who evade/resist everything. Now shows both:

- Given M/M + Given Mag: damage dealt by element (offense)
- Recv M/M + Recv Mag: damage taken by element (defense)

This makes the element breakdown immediately useful — you can see
that you're dealing Slash damage via melee, for example.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 10:13:47 +02:00
Erik
c03b1c19f2 feat: combat stats backend + frontend (Mag-Tools style)
Backend:
- db_async.py: new combat_stats + combat_stats_sessions tables
- main.py: combat_stats message handler with DB upsert (lifetime +
  session snapshots), in-memory live_combat_stats dict, broadcast
  to browser clients.
- REST: GET /combat-stats and GET /combat-stats/{character_name}

Frontend:
- index.html: new "Combat Stats" sidebar link
- script.js: full Combat Stats window with two panels:
  - Top: monster list (name, kills, dmg recv, dmg given) with
    clickable rows and "All" aggregate, matching CombatTrackerGUI.cs
  - Bottom: damage breakdown grid matching CombatTrackerGUIInfo.cs
    layout — element × attack type matrix (Mel/Msl + Magic columns),
    Attacks (hit%), Evades (%), Resists (%), A.Surges (%), C.Surges (%),
    normal Avg/Max, Crits (%), Crit Avg/Max, Total Damage.
  - Session / Lifetime toggle button
- style.css: combat-stats-toggle styles

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 09:42:11 +02:00
Erik
da4e840581 fix(vitalsharing): clear stopped peers from the NetworkUI window
Peers who unsubscribed or disconnected from vital sharing were lingering
forever in the Vital Sharing browser window because nothing ever deleted
them from the server-side state or told the browser to drop them.

Backend:
- share_unsubscribe now pops the character from _vital_sharing_peer_state
  (not just flips connected=false) and broadcasts a share_peer_removed
  envelope to browser clients.
- On real plugin disconnect, do the same: pop the state entry and
  broadcast share_peer_removed so the NetworkUI updates immediately.

Frontend:
- New removeVitalSharingPeer(name) deletes from the local
  vitalSharingPeers dict and re-renders.
- socket.onmessage now routes share_peer_removed to it.
- refreshVitalSharingPeers() reconciles against the server's list and
  prunes any local entries the server no longer knows about, catching
  any race where the broadcast was missed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 15:25:08 +02:00
Erik
2b521d1df5 fix(vitalsharing): match sidebar colors for HP/STA/MANA bars
Previously the NetworkUI window used #c44/#4c4/#46c which rendered
stamina as green. Updated to the gradients used in .vital-fill.* in
style.css (#ff4444, #ffaa00, #4488ff) so the network UI matches the
player sidebar.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 14:33:23 +02:00
Erik
1973aa1547 feat: relay cross-machine vital/debuff sharing for MosswartMassacre
Accepts new share_subscribe / share_unsubscribe / share_* WebSocket
messages from MM plugin clients and fans them out to other opted-in
plugin clients (excluding origin) and to browser clients for the
NetworkUI window.

- main.py: _vital_sharing_subscribers set, _vital_sharing_peer_state
  snapshot, _broadcast_share_to_plugin_clients relay, disconnect
  cleanup, GET /vital-sharing/peers endpoint.
- static/index.html: new sidebar link for Vital Sharing window.
- static/script.js: showVitalSharingWindow with live HP/STA/MANA bars,
  per-peer status dot/tags/position, 5s /vital-sharing/peers poll, and
  share_* routing through the existing browser WebSocket handler.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 14:19:41 +02:00
Erik
b09169ade2 feat: add app-level authentication with login, session cookies, and admin panel
Replace Nginx basic auth with proper user accounts:
- Session cookies via itsdangerous (30-day expiry, httponly, secure)
- Password hashing with bcrypt via passlib
- Login page with AC-themed UI
- Admin page for user management (CRUD)
- AuthMiddleware exempts plugin WS and browser WS endpoints
- Issues/comments author auto-populated from session
- Sidebar shows logged-in username, admin link, and logout
- Seed users: erik (admin), alex, lundberg
- SECRET_KEY env var for cookie signing
2026-04-10 19:45:08 +02:00
Erik
fac5063878 feat: show issue comments inline without toggle 2026-04-10 17:44:52 +02:00
Erik
f96171a345 feat: issues board - add submitter name, comments, and edit support 2026-04-10 17:36:08 +02:00
Erik
604d4376b4 feat: two-step issue resolution (resolve then delete)
- New PATCH /issues/{id} endpoint to toggle resolved flag
- Add resolved:false to new issues
- Frontend: click "✓ Resolve" marks issue green with strikethrough
- Resolved issues show "↺ Reopen" and "🗑 Delete" buttons
- Delete requires confirmation
- Sort: unresolved first, then resolved
- Issues persist until explicitly deleted

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 09:48:20 +02:00
Erik
38ca6ead12 feat: version display + issues board
Version: CalVer + git hash shown in top-right corner of main page.
Built via Docker ARG BUILD_VERSION at build time. Served via /api-version.

Issues Board: shared notepad window for tracking issues with plugin,
overlord, nav files, macros. Stored in openissues.json on server.
- GET/POST/DELETE /issues endpoints
- Draggable window matching Chat/Radar pattern
- Category tags (plugin, overlord, nav, macro, other) with colors
- Add/resolve issues through the UI

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 12:53:06 +02:00
Erik
8432c5f7c3 fix: match object rotation to cell canvas rotation in dungeons
Two issues caused objects to float relative to dungeon map:
1. rotAngle used (heading + PI) but canvas uses (PI - heading)
   - these differ: sin(x+PI) = -sin(x) vs sin(PI-x) = sin(x)
2. Object dy was negated, but 180° heading offset already handles N/S
   - double N/S flip caused objects to drift with heading changes

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 16:24:06 +02:00
Erik
6c500f7cdb fix: add 180° heading offset for dungeons (from UB line 1013)
UB applies HeadingToQuaternion(heading - 180) for dungeon rendering.
The layer has Y increasing downward, and the 180° offset flips N/S.
Reverted coordinates to Version 1 (X mirror, Y direct) which had
correct tile connections, and added the 180° heading offset that UB
uses to fix N/S orientation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 16:17:16 +02:00
Erik
203ae0a4fb fix: revert to Version 1 approach (tiles connected) + just add Y negate
Version 1 (X mirror, Y direct) had correct tile connections but N/S
flipped. Previous attempts to fix N/S also changed rotation handling
which broke tiles. This commit reverts tile processing (no flip),
reverts rotation (exact UB values), and only adds Y negation to
Version 1's working coordinates. No other changes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 16:10:58 +02:00
Erik
8b605a4cae fix: horizontally flip tile images + negate rotation
UB's tiles were authored for a mirrored-X rendering space. Instead of
mirroring coordinates (which breaks positioning), flip each tile image
horizontally during pre-processing and negate the cell rotation angles
to compensate. Cell and object positions remain direct (no mirroring).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 16:00:57 +02:00
Erik
8d2e74397b fix: remove X mirror, fix rotation float tolerance
UB mirrors both cell positions and player position within layer space,
so relative offset is direct (mirrors cancel out). Removed X negation.
Added float tolerance for rotation quaternion W component comparison
(was using strict equality which fails on floating point values).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 15:48:07 +02:00
Erik
b067a148f3 fix: flip dungeon Y for north-up, guard COM exceptions
- Negate Y delta for dungeon tiles and objects so north points up
  (AC Y+ = north, canvas Y+ = down)
- Wrap early COM calls in try/catch to prevent RPC_E_SERVERFAULT
  during state transitions (portal loading, etc.)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 15:43:15 +02:00
Erik
3857c0de79 fix: mirror X axis for dungeon tiles to match UB coordinate system
UB uses mirrored X: x = -(cell.X - playerX), direct Y: y = cell.Y - playerY.
Applied same transform to tile rendering, object positioning, and
entity list distance calculations in dungeon mode.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 15:31:23 +02:00
Erik
683d1cf337 feat: UB-style tile processing — white transparent, color remapping
Process each tile through canvas pixel manipulation:
- White pixels → transparent (same as UB's MakeTransparent)
- Remap UB's 5 source colors (walls, inner walls, ramps, floors, stairs)
  to readable display colors on dark background
- Black outlines made semi-transparent
- Current floor at 85% opacity, other floors at 12%
- Non-current floors drawn first, current floor on top

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 15:21:58 +02:00
Erik
e2982e34b5 feat: render actual dungeon tile textures in radar
Extract 614 UB tile BMPs into dungeon_tiles.json (287KB base64 bundle).
Frontend loads tiles once, then draws them rotated per-cell using
environment IDs. Falls back to colored rectangles if tiles not loaded.
Current floor at 70% opacity, other floors at 15%.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 15:14:52 +02:00
Erik
b941a29f04 feat: add dungeon map streaming and rendering in radar
- Backend: dungeon_map event handler with permanent in-memory cache
  by landblock ID, request_dungeon_map for late-joining browsers
- Frontend: render dungeon cells as colored rectangles when in dungeon,
  multi-level Z support (current floor bright, others dimmed),
  automatic overworld/dungeon switching based on is_dungeon flag,
  raw physics coordinate positioning for dungeon objects

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 13:16:36 +02:00
Erik
2f21159acb feat: add dereth.png map background to radar canvas
Draws a rotated/scaled slice of the overworld map behind radar dots.
Map clips to the radar circle, rotates with heading-up mode, and
renders at 40% opacity so dots remain visible on top.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 12:49:38 +02:00
Erik
60eab15fff feat: scroll-wheel zoom and click-to-select in radar
- Replace range dropdown with smooth scroll-wheel zoom on canvas
- Click dot on canvas to select it (white ring + name label)
- Click row in entity list to select on canvas
- Click again to deselect
- Selected row highlighted with blue accent in list
- Auto-scrolls list to keep selected row visible

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 12:28:09 +02:00
Erik
359d255730 fix: correct compass E/W and object rotation
AC heading is standard clockwise (0=N, 90=E). Both compass labels
and object rotation need positive heading — previous negation broke
the compass while fixing objects. Now both use the same sign.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 12:20:35 +02:00
Erik
eaa5b5c48d fix: negate AC heading for correct E/W compass orientation
AC's Actions.Heading uses opposite rotation from standard math
angles (confirmed by UtilityBelt's HeadingToQuaternion negation).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 12:14:51 +02:00
Erik
502467e075 fix: radar compass always heading-up with rotating N/E/S/W labels, fix reopen bug
- Compass is now always heading-up: player facing direction is fixed
  pointing up, N/E/S/W labels rotate around the edge as player turns
- Fix: reopening a closed radar window now resends start_radar command
  so streaming resumes without needing a full page refresh

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 12:07:40 +02:00
Erik
3852cf205e Add real-time radar feature for nearby objects
Browser can open a radar window per character that streams nearby
monsters, players, NPCs, portals, and other objects in real-time.
On-demand activation via start_radar/stop_radar commands through
the existing WebSocket command channel.

- Backend: nearby_objects event handler with in-memory cache and broadcast
- Frontend: canvas mini-map + entity list table in draggable window
- Radar button added to player list alongside Chat/Stats/Inventory/Char

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 23:01:05 +02:00
Erik
cff99f9b87 refactor: 3-column inventory layout (paperdoll+items | packs | mana) 2026-03-13 20:34:36 +01:00
Erik
83deb20a7f fix: move backpack contents below paperdoll, not below mana panel 2026-03-13 20:03:17 +01:00
Erik
a6e941eb01 fix: simplify burden meter to pure inline styles 2026-03-13 19:52:49 +01:00
Erik
a3c3d0286e fix: separate burden label from meter 2026-03-13 16:29:30 +01:00
Erik
ca88f90476 fix: unclip burden meter label and fill 2026-03-13 16:26:22 +01:00
Erik
c3f5450e0d fix: force burden meter visibility 2026-03-13 11:26:35 +01:00
Erik
b318c04fd6 fix: restore burden meter colors 2026-03-13 11:17:45 +01:00
Erik
8bea346a57 fix: refine burden meter display 2026-03-13 11:08:30 +01:00
Erik
692a92128c fix: compute burden percent from capacity 2026-03-13 10:29:43 +01:00
Erik
26624a302b fix: show true character burden 2026-03-13 10:04:25 +01:00
Erik
7013288152 fix: use the correct main pack icon 2026-03-13 09:55:44 +01:00
Erik
a7e2d4d404 feat: stream live equipment cantrip states 2026-03-13 08:59:43 +01:00
Erik
0cb8e2f75a fix: refine mana panel item filtering 2026-03-13 08:31:16 +01:00
Erik
b204ba8e75 fix: improve mana tracker state matching 2026-03-13 08:25:37 +01:00
Erik
84da2a8752 fix: refine mana panel layout and state display
Widen the inventory layout so the backpack column no longer crowds the paperdoll, and base mana active/inactive display on the live data currently available from inventory payloads.
2026-03-13 07:32:57 +01:00
Erik
4972b342d2 fix: size inventory window to fit mana rows
Grow the inventory window and mana panel dynamically based on tracked item count so all mana entries remain visible without introducing a scrollable panel.
2026-03-13 07:23:35 +01:00
Erik
dc7b26676d fix: tighten mana panel layout and icon sizing
Adjust the inventory mana panel to fit beside the backpack column without overlap, prevent the panel from scrolling, shrink composite icons correctly, and refine mana-state derivation using existing item spell data.
2026-03-12 07:54:56 +01:00
Erik
63ea242167 refactor: tighten inventory mana panel layout
Move the Mana panel to the right of the backpack column, widen the inventory window, and switch to a smaller Mag-Tools-style row layout with compact icons and status dots.
2026-03-11 20:09:05 +01:00
Erik
0e8186b8e5 feat: add mana tracker panel to inventory
Derive equipped item mana state and time-remaining data in inventory-service, then render a Mana panel inside the inventory window with live icon, state, mana, and countdown display.
2026-03-11 20:02:52 +01:00
erik
fc557ab1d5 feat: update inventory frontend and services to current production state 2026-03-07 08:37:32 +00:00
erik
973c3722bc fix: address code review findings for inventory delta feature
- Fix remaining f-string SQL injection in process_inventory (same pattern
  as single-item endpoints: parameterized ANY(:ids) queries)
- Add null guard for item_id in backend delta remove handler
- Add response status logging for inventory service HTTP calls
- Fix frontend ID fallback consistency in updateInventoryLive
- Replace debug print() with logger.debug()
- Add comment for Decal Slot_Decal magic number

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 15:58:10 +00:00
erik
f145e6e131 feat: fix inventory service SQL injection, add slot population, and live frontend updates
- Replace f-string SQL interpolation with parameterized ANY(:ids) queries
- Populate slot column from IntValues[231735296] (Decal Slot key)
- Add startup migration to add container_id/slot columns to existing DB
- Extract createInventorySlot() for reuse by initial load and live deltas
- Add updateInventoryLive() handler for WebSocket inventory_delta messages
- Add inventory_delta case to browser WebSocket message dispatcher

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 15:51:20 +00:00
erik
176fb020ec Redesign character window to match TreeStats layout and style
Replace the AC stone-themed single-scroll character window with a TreeStats-
style tabbed interface. Two side-by-side tab containers: left (Attributes,
Skills, Titles) and right (Augmentations, Ratings, Other), plus an Allegiance
section below. Exact TreeStats color palette (#000022 bg, #af7a30 gold
borders, purple specialized, teal trained). Backend accepts new properties
and titles fields in character_stats message for JSONB storage.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 14:39:20 +00:00
erik
a545a8b920 Add full character window with live stats, vitals, skills, and allegiance display
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 15:10:48 +00:00