transporters
This commit is contained in:
+1
-1
@@ -22,7 +22,7 @@ Renders the board as text: each `Glyph.tile` index is reinterpreted as a charact
|
||||
|
||||
**`kiln-tui/src/editor.rs`** — world editor mode:
|
||||
- `EditorState` — a non-ticking editing session over a freshly reloaded `World`: `world`, `board_name` (board being edited), `menu: Vec<MenuLevel>` (sidebar menu stack, for breadcrumb + escape-to-parent), `dialog: Option<Dialog<EditorState>>`, `code_editor: Option<CodeEditor>` (the open script editor; replaces the board view), `glyph_dialog: Option<GlyphDialog<EditorState>>` (the open glyph picker overlay), a blinking `cursor`, the **drawing tool** (`current_archetype` + `current_glyph` — the thing stamped on `space`, defaulting to a wall — and `draw_mode`, the toggle that re-stamps on every cursor move), `sidebar_width` (mouse-resizable), blink state, `last_board_area` (written at draw, read for right-click hit-testing), editor-side `log`, and `pending_playtest: Option<GameState>` (a playtest game parked for the run loop to swap into `Mode::Play`).
|
||||
- `MenuLevel` (`Main`/`World`/`Floor`/`Terrain`/`Machines`/`Pushers`/`Items`) — a sidebar menu level; (`Main` → `[i] Items` → `[t] ♦ Gem` / `[h] ♥ Heart`, which call `set_current(Archetype::Builtin(Builtin::Gem, "gem"))` / `set_current(Archetype::Builtin(Builtin::Heart, "heart"))` respectively); `title()` (breadcrumb segment) and `entries() -> Vec<MenuEntry>` (the level's lines). A `MenuEntry` is a key-activated `Item` (`[k] Label` + a boxed `FnOnce(&mut EditorState)` action), a `CurrentValue` (a boxed `Fn(&EditorState) -> String` shown indented beneath an item, e.g. the world name), or a `Blank`/`Separator` spacer. An item's action **opens a dialog** (`World`/scripts/boards), **pushes a child level** (`Main` → `World`/`Floor`/`Terrain`/`Machines`; `Machines` → `Pushers`), **sets the drawing tool** (`Terrain`/`Pushers` → `set_current(arch)`, plus `Machines` → `[s]` CW / `[c]` CCW spinner, all using `Archetype::Builtin(Builtin::…, "alias")`), or **launches a playtest** (`Main` → `[p] Play board` → `playtest()`). The menu is a static letter-keyed stack — picking from a list is always a dialog, so arrow keys never conflict with the board cursor.
|
||||
- `MenuLevel` (`Main`/`World`/`Floor`/`Terrain`/`Machines`/`Pushers`/`Transporters`/`Items`) — a sidebar menu level; (`Main` → `[i] Items` → `[t] ♦ Gem` / `[h] ♥ Heart`, which call `set_current(Archetype::Builtin(Builtin::Gem, "gem"))` / `set_current(Archetype::Builtin(Builtin::Heart, "heart"))` respectively); `title()` (breadcrumb segment) and `entries() -> Vec<MenuEntry>` (the level's lines). A `MenuEntry` is a key-activated `Item` (`[k] Label` + a boxed `FnOnce(&mut EditorState)` action), a `CurrentValue` (a boxed `Fn(&EditorState) -> String` shown indented beneath an item, e.g. the world name), or a `Blank`/`Separator` spacer. An item's action **opens a dialog** (`World`/scripts/boards), **pushes a child level** (`Main` → `World`/`Floor`/`Terrain`/`Machines`; `Machines` → `Pushers`/`Transporters`), **sets the drawing tool** (`Terrain`/`Pushers`/`Transporters` → `set_current(arch)`, plus `Machines` → `[s]` CW / `[c]` CCW spinner, all using `Archetype::Builtin(Builtin::…, "alias")`), or **launches a playtest** (`Main` → `[p] Play board` → `playtest()`). The menu is a static letter-keyed stack — picking from a list is always a dialog, so arrow keys never conflict with the board cursor.
|
||||
- Methods: `breadcrumb()`, `current_menu()`, `menu_escape(ui)` (pop a level, or at the root open the overlay `editor_menu_items()`), `menu_key(c)` (dispatch a letter → the matched `entries()` item's action via `MenuLevel::perform_key`), `playtest()` (deep-clones the world, sets its start to the edited board, **expands script-backed archetypes** in every board via `Board::expand_builtin_archetypes` so editor-stamped spinners/pushers run, builds a `GameState` + runs `init()`, and parks it in `pending_playtest` for the run loop), and the `open_{name,entry,scripts,boards}_dialog` builders (name → text dialog writing `world.name`; entry → list dialog writing `world.start`; boards → select-only; scripts → **opens the script in `code_editor`**). `open_script_editor(name)` builds a `CodeEditor` from `world.scripts[name]`; `close_script_editor()` saves its text back into `world.scripts` (in-memory, like the other dialogs).
|
||||
- Drawing: `set_current(arch)` sets `current_archetype` and resets `current_glyph` to its default; `open_glyph_picker()` seeds a `GlyphDialog` from `current_glyph` and writes the chosen glyph back (bound to **`g`**); `place_current()` stamps the current archetype+glyph at the cursor via `Board::place_archetype`; `toggle_draw_mode()` flips `draw_mode`. `place_current` is bound to **`space`** and `toggle_draw_mode` to **`tab`** in `handle_editor_input`; `move_cursor`/`set_cursor_at_screen` also call `place_current` when `draw_mode` is on and the cursor enters a new cell. The sidebar's bottom **drawing-controls footer** (`draw_footer_lines`) shows the archetype name, `[g] Glyph` + a live colored preview, `[spc] Place`, and `[tab] Draw mode (on/off)`.
|
||||
- `editor_menu_items()` — the overlay editor menu (`[p]` play, `[q]` quit, `[esc]` resume), opened at the root of the menu tree. `handle_dialog_input(event, ed)` — forwards to the open dialog and, on `Submit`/`Cancel`, `take`s it out and calls `finish(.., ed)`. `handle_glyph_dialog_input(event, ed)` — the same pattern for the open `glyph_dialog`. `handle_code_editor_input(event, ed)` — forwards to the open code editor and, on `Exit` (Esc), calls `close_script_editor()`. `draw_editor(frame, ed, ui)` / `editor_layout(..)` — the **code editor (when open) else** the board (with blinking cursor + coord readout) in the left area, a resizable right-hand sidebar (breadcrumb title + the menu choices, each with its optional current-value line), and the optional full-width log panel.
|
||||
|
||||
@@ -28,6 +28,8 @@ pub(crate) enum MenuLevel {
|
||||
Machines,
|
||||
/// Various directions of pushers
|
||||
Pushers,
|
||||
/// Various directions of transporters
|
||||
Transporters,
|
||||
/// Collectible items the player picks up (e.g. gems)
|
||||
Items,
|
||||
}
|
||||
@@ -42,6 +44,7 @@ impl MenuLevel {
|
||||
MenuLevel::Terrain => "Terrain",
|
||||
MenuLevel::Machines => "Machines",
|
||||
MenuLevel::Pushers => "Pushers",
|
||||
MenuLevel::Transporters => "Transporters",
|
||||
MenuLevel::Items => "Items",
|
||||
}
|
||||
}
|
||||
@@ -81,6 +84,9 @@ impl MenuLevel {
|
||||
],
|
||||
MenuLevel::Machines => vec![
|
||||
MenuEntry::item('p', "Pushers...", |ed| ed.menu.push(MenuLevel::Pushers)),
|
||||
MenuEntry::item('t', "Transporters...", |ed| {
|
||||
ed.menu.push(MenuLevel::Transporters)
|
||||
}),
|
||||
MenuEntry::item('s', "/ CW spinner", |ed| {
|
||||
ed.set_current(Archetype::Builtin(Builtin::Spinner, "spinner_cw"))
|
||||
}),
|
||||
@@ -102,6 +108,20 @@ impl MenuLevel {
|
||||
ed.set_current(Archetype::Builtin(Builtin::Pusher, "pusher_west"))
|
||||
}),
|
||||
],
|
||||
MenuLevel::Transporters => vec![
|
||||
MenuEntry::item('n', "▲ Transporter", |ed| {
|
||||
ed.set_current(Archetype::Builtin(Builtin::Transporter, "transporter_north"))
|
||||
}),
|
||||
MenuEntry::item('s', "▼ Transporter", |ed| {
|
||||
ed.set_current(Archetype::Builtin(Builtin::Transporter, "transporter_south"))
|
||||
}),
|
||||
MenuEntry::item('e', "► Transporter", |ed| {
|
||||
ed.set_current(Archetype::Builtin(Builtin::Transporter, "transporter_east"))
|
||||
}),
|
||||
MenuEntry::item('w', "◄ Transporter", |ed| {
|
||||
ed.set_current(Archetype::Builtin(Builtin::Transporter, "transporter_west"))
|
||||
}),
|
||||
],
|
||||
MenuLevel::Items => vec![
|
||||
MenuEntry::glyph('t', Archetype::Builtin(Builtin::Gem, "gem").default_glyph(), "Gem", |ed| {
|
||||
// 't' for 'treasure' — 'g' conflicts with glyph picker
|
||||
|
||||
Reference in New Issue
Block a user