jong/src/tui/mod.rs
2026-01-14 20:27:24 -08:00

95 lines
2.8 KiB
Rust

use std::time::Duration;
use bevy::{app::ScheduleRunnerPlugin, prelude::*, state::app::StatesPlugin};
use bevy_ratatui::RatatuiPlugins;
use jong::game::GameState;
use crate::tui::render::{WidgetStack, menu::Splash};
// use jong::game::wall::InWall;
mod console;
mod render;
mod input;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, States, Default)]
pub(crate) enum TuiState {
#[default]
MainMenu,
InGame,
}
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
struct InGame;
impl ComputedStates for InGame {
type SourceStates = TuiState;
fn compute(sources: Self::SourceStates) -> Option<Self> {
match sources {
TuiState::InGame => Some(Self),
_ => None,
}
}
}
#[derive(SubStates, Default, Clone, Copy, PartialEq, Eq, Hash, Debug,)]
#[source(TuiState = TuiState::MainMenu)]
pub(crate) enum ZenState {
#[default]
Menu,
Zen,
}
#[derive(Default)]
pub struct RiichiTui;
impl Plugin for RiichiTui {
fn build(&self, app: &mut App) {
app.add_plugins((
MinimalPlugins.set(ScheduleRunnerPlugin::run_loop(Duration::from_secs_f32(
1. / 60.,
))),
RatatuiPlugins {
// enable_kitty_protocol: todo!(),
enable_mouse_capture: true,
enable_input_forwarding: true,
..Default::default()
},
))
.add_plugins(StatesPlugin)
// general setup
.init_state::<TuiState>()
.add_computed_state::<InGame>()
.init_resource::<WidgetStack>()
.add_sub_state::<ZenState>()
.init_resource::<Splash>()
.init_state::<console::ConsoleState>()
.add_systems(PostUpdate, console::draw_console.run_if(in_state(console::ConsoleState::Open)))
// input
.add_systems(PreUpdate, input::keyboard::input_system)
.add_systems(PreUpdate, input::mouse::input_system)
// main menu
.add_systems(PostStartup, render::menu::init_splash)
.insert_resource(Time::<Fixed>::from_seconds(1.0))
.add_systems(FixedUpdate, render::menu::render_splash.run_if(in_state(TuiState::MainMenu)))
.add_systems(Update, render::menu::draw_splash.run_if(in_state(TuiState::MainMenu)))
.add_systems(Update, render::menu::draw_mainmenu.after(render::menu::draw_splash).run_if(in_state(TuiState::MainMenu).and(in_state(ZenState::Menu))))
// gaming
.init_resource::<render::hand::RenderedHand>()
.add_systems(Update, render::hand::render_hands.run_if(in_state(InGame).and(in_state(GameState::Play))))
.add_systems(Update, render::ingame::draw_ingame.run_if(in_state(InGame)))
// render
.add_systems(Last, render::draw_system.run_if(not(in_state(InGame))))
// semicolon stopper
;
}
}