Object passable/opaque: editor checkboxes + doc/simplify cleanup
- ObjectDef gains passable/opaque fields (defaults: false/true); Board::is_passable consults the object before the grid cell, so objects block movement independently of the floor tile beneath them - Editor Objects tab exposes Passable and Opaque checkboxes; changes survive save/load - Add ObjectDef::new(x, y) to centralise placement defaults; remove triple default_glyph() call and unused Glyph import from main.rs - Fix stale Behavior doc comment; update CLAUDE.md and ARCHITECTURE.md Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -48,11 +48,12 @@ The game is a single Rust binary using **eframe 0.33 / egui 0.33** for the GUI.
|
||||
- `Glyph` (`Copy`, `Eq`, `Hash`) — per-cell visual: `tile: u32` (tilesheet index), `fg/bg: Color32`. `Glyph::player()` is a `const fn`; all other glyphs come from the map file. Derives `Hash` so boards can deduplicate glyphs into a palette.
|
||||
- `FontSpec` — optional per-board bitmap font override: `path: String`, `tile_w: u32`, `tile_h: u32`. When `None`, the app default font is used.
|
||||
- `Behavior` — plain data struct of runtime behavioral properties: `passable: bool`, `opaque: bool`. Returned by `Archetype::behavior()`; new properties added here require no match arms elsewhere.
|
||||
- `Archetype` (`Copy`, `PartialEq`) — enum of named element types: `Empty`, `Wall`, `Object`, `ErrorBlock`. Each variant provides `behavior()`, `name()` (used in map files), and `default_glyph()` (used by the editor when stamping a cell). `ErrorBlock` is a sentinel for unknown archetype names — renders as yellow `?` on red.
|
||||
- `Archetype` (`Copy`, `PartialEq`) — enum of named element types: `Empty`, `Wall`, `ErrorBlock`. Each variant provides `behavior()`, `name()` (used in map files), and `default_glyph()` (used by the editor when stamping a cell). `ErrorBlock` is a sentinel for unknown archetype names — renders as yellow `?` on red.
|
||||
- `ALL_ARCHETYPES: &[Archetype]` — ordered list of valid editor choices (excludes `ErrorBlock`).
|
||||
- `Board` — the complete game unit (ZZT-style "board"): `width`, `height`, `cells: Vec<(Glyph, Archetype)>` (row-major; each cell owns its visual and behavioral class directly), `player: Player`, `objects: Vec<ObjectDef>`, `portals: Vec<PortalDef>`, `font: Option<FontSpec>`. `cells` is `pub(crate)`.
|
||||
- `Board` — the complete game unit (ZZT-style "board"): `width`, `height`, `cells: Vec<(Glyph, Archetype)>` (row-major; each cell owns its visual and behavioral class directly), `player: Player`, `objects: Vec<ObjectDef>`, `portals: Vec<PortalDef>`, `font: Option<FontSpec>`. `cells` is `pub(crate)`. `is_passable(x, y)` checks objects before the grid cell: an impassable object blocks even over a passable floor tile.
|
||||
- `Player` — `x: i32, y: i32`
|
||||
- `ObjectDef` / `PortalDef` — parsed from map files, stored on Board; not yet runtime-wired
|
||||
- `ObjectDef` — scripted object placed on the board: `x`, `y`, `glyph: Glyph`, `passable: bool`, `opaque: bool`, `script_name: Option<String>`. `passable` defaults `false` and `opaque` defaults `true` in map files. Scripts not yet runtime-wired.
|
||||
- `PortalDef` — parsed from map files, stored on Board; not yet runtime-wired
|
||||
- `GameState` — holds `board: Board`; `try_move(dx, dy)` checks passability before moving the player
|
||||
|
||||
**`src/font.rs`** — bitmap font loading and UV mapping:
|
||||
@@ -74,6 +75,7 @@ The game is a single Rust binary using **eframe 0.33 / egui 0.33** for the GUI.
|
||||
- `FontHeader` — deserializes the optional `[font]` section (`path`, `tile_w`, `tile_h`)
|
||||
- `impl From<MapFile> for Board` — converts a parsed file into a ready-to-use `Board`; unknown archetype names produce `ErrorBlock`
|
||||
- `pub fn load(path: &str) -> Result<Board, Box<dyn std::error::Error>>` — reads and converts a `.toml` map file
|
||||
- `pub fn save(board: &Board, path: &Path) -> Result<(), Box<dyn std::error::Error>>` — serializes `Board` back to TOML and writes to disk
|
||||
|
||||
**`src/main.rs`** — app entry point and frame loop:
|
||||
- `AppMode` enum (`Play` | `Edit`) — gates arrow-key input; toggles the side panel and viewport mode
|
||||
@@ -89,13 +91,14 @@ The game is a single Rust binary using **eframe 0.33 / egui 0.33** for the GUI.
|
||||
- `paint_glyph(painter, rect, glyph, font)` — `rect_filled` with `glyph.bg`, then `painter.image` tinted by `glyph.fg`
|
||||
- `draw_glyph(painter, origin, x, y, glyph, font)` — sizes cell from `font.tile_w/tile_h`, delegates to `paint_glyph`
|
||||
- `draw_board(painter, origin, board, font)` — draws all cells then player overlay
|
||||
- `draw_object_overlays(painter, origin, board, font, selected)` — highlights all object cells in the Objects editor tab; the selected object gets a brighter border
|
||||
- `board_origin(available, board_w, board_h, player, font)` — centers board or clamps to player with no empty space
|
||||
- `pos_to_cell(origin, pos, tile_w, tile_h) -> (i32, i32)` — pixel → cell coordinates; negatives signal out-of-bounds
|
||||
|
||||
**`src/editor.rs`** — editor state and side panel:
|
||||
- `EditorTab` enum (`Palette` | `Board` | `World`) — which tab is active
|
||||
- `EditorState` — holds `selected: Archetype`, `glyph: Glyph`, `glyph_picker_open: bool`, `tab: EditorTab`, `font_dialog_open: bool`, `font_dialog_state: FontDialogState`; selecting a new archetype resets `glyph` to that archetype's default
|
||||
- `show_editor_panel(ctx, editor, font_spec, active_font)` — resizable right-side panel (default 200 px); Palette tab shows archetype list and glyph preview button; Board tab shows current font path and "Font…" button that opens `font_dialog::show`; World tab is a placeholder
|
||||
- `EditorTab` enum (`Palette` | `Board` | `Objects` | `World`) — which tab is active
|
||||
- `EditorState` — holds `selected: Archetype`, `glyph: Glyph`, `glyph_picker_open: bool`, `tab: EditorTab`, `font_dialog_open: bool`, `font_dialog_state: FontDialogState`, `selected_object: Option<usize>`, `object_glyph_picker_open: bool`, `object_editing_glyph: Glyph`, `placing_object: bool`; selecting a new archetype resets `glyph` to that archetype's default
|
||||
- `show_editor_panel(ctx, editor, board, active_font)` — resizable right-side panel (default 200 px); Palette tab shows archetype list and glyph preview button; Board tab shows current font path and "Font…" button; Objects tab lists all board objects with click-to-select, glyph preview, **Passable/Opaque checkboxes**, and script combobox; World tab is a placeholder
|
||||
|
||||
**`src/glyph_picker.rs`** — floating glyph picker dialog:
|
||||
- `show(ctx, open, glyph, board_cells, font)` — takes `open: &mut bool` and `glyph: &mut Glyph` directly; no dependency on `EditorState`
|
||||
|
||||
Reference in New Issue
Block a user