Skip to content

feat(all): Dynamic Map Renderer & Genie Cross-Reference for ElanthiaMap v2.0.0#2234

Closed
MahtraDR wants to merge 11 commits intoelanthia-online:masterfrom
MahtraDR:dynamic_map_renderer_v2
Closed

feat(all): Dynamic Map Renderer & Genie Cross-Reference for ElanthiaMap v2.0.0#2234
MahtraDR wants to merge 11 commits intoelanthia-online:masterfrom
MahtraDR:dynamic_map_renderer_v2

Conversation

@MahtraDR
Copy link
Contributor

@MahtraDR MahtraDR commented Feb 4, 2026

Dynamic Map Renderer & Genie Cross-Reference for ElanthiaMap v2.0.0

Summary

Adds a Cairo-based dynamic map renderer and Genie cross-database commands to ElanthiaMap v2.0.0 (PR #2207). This PR is designed to be merged on top of feat/map-v2.0.0.

Changes

Base branch: feat/map-v2.0.0 (PR #2207)
Files changed: scripts/map.lic (+564 lines), spec/map/map_dynamic_spec.rb (new, 40 tests)

New Modules

Module Lines Purpose
ElanthiaMap::ZoneResolver ~65 Determines which rooms belong to the same "zone" using a 4-layer fallback: genie_zone -> @image -> @location -> BFS flood-fill. Results are cached.
ElanthiaMap::LayoutEngine ~155 Computes room positions for rendering. Mode A: uses Genie genie_pos coordinates directly. Mode B: BFS auto-layout using compass directions from wayto data. Includes post-processing collision resolution.

Window Modifications

Method Type Purpose
update_dynamic_display public Zone resolve -> layout compute/cache -> z-level update -> queue_draw
dynamic_map_enabled? public Returns @settings[:dynamic_map]
render_dynamic_map private 4-pass Cairo renderer: connection lines, off-level rooms (dimmed), current-level rooms, current room (magenta)
find_dynamic_room_at private Hit detection for click handling in dynamic mode
toggle_dynamic_mode private Swaps visibility of static widgets (@map_image/@room_marker) vs @drawing_area
handle_dynamic_click private Click -> find room -> shift-click shows info, regular click runs go2
resize_drawing_area private Matches @drawing_area size to @scroller allocation
calculate_dynamic_scale private Returns global scale factor for dynamic mode

Settings & Menu

  • dynamic_map setting added to load_settings, save_settings, reset_all_settings
  • "Dynamic Map" CheckMenuItem added to context menu (after "Dynamic Indicator Size", with separator)

Genie Commands

  • ;map genie — displays zone:node for the current room (DR only, returns early)
  • ;map g<zone>:<node> — opens map centered on the room matching that Genie reference
  • Help text updated with both commands
  • determine_display_room updated to handle genie and g\w+:\w+ patterns

Other Changes

  • create_map_display: adds @drawing_area (Gtk::DrawingArea) to layout, hidden by default
  • show: properly toggles static/dynamic widget visibility after show_all
  • handle_click: early return to handle_dynamic_click when dynamic mode is active
  • destroy: cleans up @drawing_area before menu/window destroy (macOS Quartz fix)
  • Main loop: branches on dynamic_map_enabled? for dynamic vs static rendering path
  • Initial display: uses update_dynamic_display when dynamic mode is active

Architecture

ElanthiaMap (module)
├── MapData          (class)    — map metadata from room tags
├── MapCache         (class)    — image caching with dark mode
├── ZoneResolver     (module)   — NEW: zone detection with 4-layer fallback
├── LayoutEngine     (module)   — NEW: room position computation
└── Window           (class)    — main window
    ├── @drawing_area            — NEW: Gtk::DrawingArea for Cairo rendering
    ├── @layout_cache            — NEW: zone_id -> {positions, rooms}
    ├── @current_z_level         — NEW: current z-level for multi-floor zones
    ├── @dynamic_zone_data       — NEW: active zone data for rendering
    ├── render_dynamic_map()     — NEW: 4-pass Cairo renderer
    ├── update_dynamic_display() — NEW: room change handler for dynamic mode
    └── toggle_dynamic_mode()    — NEW: static <-> dynamic mode switch

Dependencies

  • lich-5 PR Testing  #10 (MahtraDR/lich-5#10): Adds genie_id, genie_zone, genie_pos fields to map_dr.rb and json_extra_fields hook to map_base.rb. The Genie commands use Room.by_genie_ref which is defined there. Dynamic map rendering works without this PR but Genie-specific features (Mode A positioning, ;map genie, ;map g1:335) require it.
  • PR feat(map.lic): v2.0.0 refactor #2207 (feat/map-v2.0.0): This PR is branched from and targets the ElanthiaMap v2.0.0 refactor.

Test Plan

  • rspec spec/map/map_dynamic_spec.rb — 40 examples, 0 failures
  • ruby -c scripts/map.lic — Syntax OK
  • Launch ;map — static mode works unchanged
  • Right-click -> "Dynamic Map" -> Cairo rendering with rooms + connections
  • Room changes -> view follows in dynamic mode
  • Click room in dynamic mode -> go2 navigation
  • Shift-click room in dynamic mode -> shows room description
  • Toggle back to static mode -> static rendering restored
  • ;map genie -> shows Genie zone:node reference (DR only)
  • ;map g1:335 -> opens map centered on that room
  • macOS: window close without segfault
  • Settings persist across restarts (dynamic_map on/off)
  • ;map reset resets dynamic_map to false

mrhoribu and others added 11 commits January 21, 2026 13:49
Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
change from +28 to +32 pixel for macos
change global scale default from true back to false
change room indicator to be fixed size (58x58) with a new toggle for "dynamic indicator size" OFF by default
increase scale factor below 100% for dynamic indactor (2x to 5x)
add Char.name back to Map title bar
Add Cairo-based dynamic map renderer (ZoneResolver, LayoutEngine) and
Genie cross-database commands (;map genie, ;map g<zone>:<node>) to the
ElanthiaMap v2.0.0 architecture.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@mrhoribu
Copy link
Contributor

mrhoribu commented Feb 4, 2026

Changed to #2235 so that PR goes into PR branch instead of main branch.

@mrhoribu mrhoribu closed this Feb 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants