animations
This commit is contained in:
+23
-29
@@ -1,7 +1,6 @@
|
||||
use ratatui::crossterm::event::{Event, KeyCode, MouseEventKind};
|
||||
use kiln_core::Direction;
|
||||
use kiln_core::game::{GameState, ScrollLine};
|
||||
use crate::scroll_overlay::ScrollAnimState;
|
||||
use crate::ui::Ui;
|
||||
|
||||
/// Moves the player and, if the move crosses a portal, captures both board Rcs
|
||||
@@ -20,29 +19,23 @@ fn try_move_with_transition(game: &mut GameState, ui: &mut Ui, dir: Direction) {
|
||||
/// Which input mode the front-end is currently in.
|
||||
pub enum InputMode {
|
||||
/// Normal gameplay: arrow keys move the player, `l` toggles the log.
|
||||
/// The `bool` is whether the log panel is open (affects PageUp/Down and mouse).
|
||||
Board,
|
||||
/// A scroll overlay is active; all input is captured for scroll navigation.
|
||||
Scroll,
|
||||
/// A board-wipe animation is running; all events are silently discarded.
|
||||
Transition,
|
||||
/// The wipe just finished; game is frozen until the player presses any key.
|
||||
/// An animation is running; all input is discarded.
|
||||
Animating,
|
||||
/// Reserved for a post-transition freeze; nothing currently produces this mode.
|
||||
#[allow(dead_code)]
|
||||
Frozen,
|
||||
}
|
||||
|
||||
/// Determines the current input mode from game and UI state.
|
||||
pub(crate) fn current_input_mode(game: &GameState, ui: &Ui) -> InputMode {
|
||||
// Transition takes highest priority (pending or animating).
|
||||
if ui.transition.is_some() || ui.pending_transition.is_some() {
|
||||
return InputMode::Transition;
|
||||
// Any active animation (or a pending transition waiting for its area) blocks input.
|
||||
if ui.active_animation.is_some() || ui.pending_transition.is_some() {
|
||||
return InputMode::Animating;
|
||||
}
|
||||
// Post-wipe freeze: show the new board but don't tick or move until a key is pressed.
|
||||
if ui.post_transition_wait {
|
||||
return InputMode::Frozen;
|
||||
}
|
||||
let scroll_active = game.active_scroll.is_some()
|
||||
&& !matches!(ui.overlay.anim, Some(ScrollAnimState::Closing(_) | ScrollAnimState::Done));
|
||||
if scroll_active { InputMode::Scroll } else { InputMode::Board }
|
||||
if game.active_scroll.is_some() { InputMode::Scroll } else { InputMode::Board }
|
||||
}
|
||||
|
||||
/// Handles an input event in [`InputMode::Board`]. Returns `true` if the player quit.
|
||||
@@ -88,23 +81,24 @@ fn resolve_choice(lines: &[ScrollLine], c: char) -> Option<String> {
|
||||
|
||||
/// Handles an input event in [`InputMode::Scroll`].
|
||||
pub(crate) fn handle_scroll_input(event: Event, game: &mut GameState, ui: &mut Ui) {
|
||||
let lines: Vec<ScrollLine> = game.active_scroll.as_ref()
|
||||
.map(|s| s.lines.clone())
|
||||
.unwrap_or_default();
|
||||
let has_choices = lines.iter().any(|l| matches!(l, ScrollLine::Choice { .. }));
|
||||
|
||||
match event {
|
||||
Event::Key(key) => {
|
||||
let scroll = game.active_scroll.as_ref().unwrap();
|
||||
let has_choices = scroll.lines.iter().any(|l| matches!(l, ScrollLine::Choice { .. }));
|
||||
match key.code {
|
||||
// Esc dismisses only when there are no choices; with choices the player must select.
|
||||
KeyCode::Esc if !has_choices => ui.begin_close(None),
|
||||
KeyCode::Up => ui.scroll_lines(-1),
|
||||
KeyCode::Down => ui.scroll_lines(1),
|
||||
KeyCode::Char(c) => {
|
||||
if let Some(ch) = resolve_choice(&scroll.lines, c) {
|
||||
ui.begin_close(Some(ch));
|
||||
}
|
||||
Event::Key(key) => match key.code {
|
||||
// Esc dismisses only when there are no choices.
|
||||
KeyCode::Esc if !has_choices => ui.begin_close(None, game),
|
||||
KeyCode::Up => ui.scroll_lines(-1),
|
||||
KeyCode::Down => ui.scroll_lines(1),
|
||||
KeyCode::Char(c) => {
|
||||
if let Some(ch) = resolve_choice(&lines, c) {
|
||||
ui.begin_close(Some(ch), game);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
Event::Mouse(m) => match m.kind {
|
||||
MouseEventKind::ScrollUp => ui.scroll_lines(-1),
|
||||
MouseEventKind::ScrollDown => ui.scroll_lines(1),
|
||||
|
||||
Reference in New Issue
Block a user