Compare commits
No commits in common. "5504db4e0fdbad2c53465f4fcd88dd3af35100c0" and "78029687d7d8ed85c2ac65f1b4ffebd8d5e7a1d1" have entirely different histories.
5504db4e0f
...
78029687d7
17 changed files with 101 additions and 362 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
|
@ -3274,10 +3274,8 @@ dependencies = [
|
||||||
"bevy_ratatui",
|
"bevy_ratatui",
|
||||||
"clap",
|
"clap",
|
||||||
"log",
|
"log",
|
||||||
"rand 0.9.2",
|
|
||||||
"ratatui",
|
"ratatui",
|
||||||
"strum",
|
"strum",
|
||||||
"tracing",
|
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
"tui-logger",
|
"tui-logger",
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -18,10 +18,8 @@ log = { version = "0.4.29", features = [
|
||||||
"release_max_level_error",
|
"release_max_level_error",
|
||||||
"max_level_trace",
|
"max_level_trace",
|
||||||
] }
|
] }
|
||||||
rand = "0.9.2"
|
|
||||||
ratatui = "0.30.0"
|
ratatui = "0.30.0"
|
||||||
strum = { version = "0.27.2", features = ["derive"] }
|
strum = { version = "0.27.2", features = ["derive"] }
|
||||||
tracing = "0.1.44"
|
|
||||||
tracing-subscriber = "0.3.22"
|
tracing-subscriber = "0.3.22"
|
||||||
tui-logger = { version = "0.18.0", features = ["tracing-support", "crossterm"] }
|
tui-logger = { version = "0.18.0", features = ["tracing-support", "crossterm"] }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,54 +0,0 @@
|
||||||
use bevy::prelude::*;
|
|
||||||
|
|
||||||
use crate::{game::wall::WallTiles, tiles::Tile};
|
|
||||||
|
|
||||||
#[derive(Component)]
|
|
||||||
pub struct Hand;
|
|
||||||
|
|
||||||
#[derive(Component)]
|
|
||||||
#[relationship(relationship_target = HandTiles)]
|
|
||||||
pub struct InHand(pub Entity);
|
|
||||||
|
|
||||||
#[derive(Component)]
|
|
||||||
#[relationship_target(relationship = InHand, linked_spawn)]
|
|
||||||
pub struct HandTiles(Vec<Entity>);
|
|
||||||
|
|
||||||
pub(crate) fn deal_hands(
|
|
||||||
mut commands: Commands,
|
|
||||||
walltiles: Single<&WallTiles>,
|
|
||||||
walltiles_entity: Single<Entity, With<WallTiles>>,
|
|
||||||
) -> Result {
|
|
||||||
let hand = walltiles.iter().collect::<Vec<_>>();
|
|
||||||
|
|
||||||
commands
|
|
||||||
.get_entity(*walltiles_entity)?
|
|
||||||
.remove_children(hand.last_chunk::<13>().unwrap());
|
|
||||||
|
|
||||||
commands.spawn((Hand, HandTiles(hand)));
|
|
||||||
|
|
||||||
trace!("dealt hands");
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn sort_hand(
|
|
||||||
mut commands: Commands,
|
|
||||||
tiles: Populated<&Tile>,
|
|
||||||
handtiles_entity: Single<Entity, With<HandTiles>>,
|
|
||||||
handtiles: Single<&HandTiles, Changed<HandTiles>>,
|
|
||||||
) -> Result {
|
|
||||||
let mut hand: Vec<_> = handtiles
|
|
||||||
.iter()
|
|
||||||
.map(|e| -> Result<(_, _)> { Ok((tiles.get(e)?, e)) })
|
|
||||||
.collect::<Result<_>>()?;
|
|
||||||
|
|
||||||
hand.sort_by_key(|(t, _)| t.suit);
|
|
||||||
|
|
||||||
let hand: Vec<_> = hand.iter().map(|(_, e)| *e).collect();
|
|
||||||
|
|
||||||
commands
|
|
||||||
.get_entity(*handtiles_entity)?
|
|
||||||
.replace_children(&hand);
|
|
||||||
|
|
||||||
trace!("sort_hand");
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
@ -1,40 +1,22 @@
|
||||||
|
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
|
||||||
use crate::tiles::{self, *};
|
use crate::tiles::{self, *};
|
||||||
|
|
||||||
pub mod hand;
|
mod player;
|
||||||
pub mod player;
|
pub(crate) mod wall;
|
||||||
pub mod wall;
|
|
||||||
|
|
||||||
#[derive(States, Default, Hash, Clone, Eq, Debug, PartialEq, Copy)]
|
|
||||||
pub enum GameState {
|
|
||||||
#[default]
|
|
||||||
None,
|
|
||||||
Setup,
|
|
||||||
// Deal,
|
|
||||||
Play,
|
|
||||||
Score,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Riichi;
|
pub struct Riichi;
|
||||||
|
|
||||||
impl Plugin for Riichi {
|
impl Plugin for Riichi {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.init_resource::<Compass>()
|
app.init_resource::<Compass>()
|
||||||
.add_systems(Startup, init_match)
|
.add_systems(Startup, init_match)
|
||||||
.add_systems(Startup, tiles::init_tiles)
|
.add_systems(Startup, tiles::init_tiles)
|
||||||
.init_state::<GameState>()
|
.add_systems(Startup, wall::build_wall);
|
||||||
.add_systems(OnEnter(GameState::Setup), (wall::build_wall, hand::deal_hands, setup_done).chain())
|
|
||||||
.add_systems(Update, (hand::sort_hand).run_if(in_state(GameState::Play)))
|
|
||||||
// semicolon stopper
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_done(mut next: ResMut<NextState<GameState>>) {
|
|
||||||
next.set(GameState::Play);
|
|
||||||
trace!("setup_done");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub(crate) struct Dice(u8, u8);
|
pub(crate) struct Dice(u8, u8);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,9 @@
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
|
||||||
use crate::{
|
|
||||||
game::wall::{InWall, Wall},
|
|
||||||
tiles::Tile,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub(crate) struct Player {
|
pub(crate) struct Player {
|
||||||
pub(crate) name: String,
|
pub(crate) name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn spawn_players(mut commands: Commands) {}
|
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub(crate) struct Points(pub isize);
|
pub(crate) struct Points(pub isize);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,11 @@
|
||||||
|
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use rand::seq::SliceRandom;
|
|
||||||
|
|
||||||
use crate::tiles::Tile;
|
use crate::tiles::Tile;
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub struct Wall;
|
pub(crate) struct Wall(Vec<Entity>);
|
||||||
|
|
||||||
#[derive(Component)]
|
pub(crate) fn build_wall(_tiles: Query<&Tile>) {
|
||||||
#[relationship_target(relationship = InWall, linked_spawn)]
|
info!("built a wall!")
|
||||||
pub struct WallTiles(Vec<Entity>);
|
|
||||||
|
|
||||||
#[derive(Component)]
|
|
||||||
#[relationship(relationship_target = WallTiles)]
|
|
||||||
pub struct InWall(pub Entity);
|
|
||||||
|
|
||||||
pub(crate) fn build_wall(mut commands: Commands, tiles: Query<Entity, With<Tile>>) {
|
|
||||||
let mut rng = rand::rng();
|
|
||||||
|
|
||||||
let mut shuffled = tiles.iter().collect::<Vec<_>>();
|
|
||||||
shuffled.shuffle(&mut rng);
|
|
||||||
|
|
||||||
commands.spawn((Wall, WallTiles(shuffled)));
|
|
||||||
|
|
||||||
trace!("build_wall");
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
#![allow(unused)]
|
|
||||||
|
|
||||||
pub mod game;
|
|
||||||
pub mod tiles;
|
pub mod tiles;
|
||||||
pub mod yakus;
|
pub mod yakus;
|
||||||
|
|
||||||
|
pub mod game;
|
||||||
|
|
|
||||||
28
src/main.rs
28
src/main.rs
|
|
@ -1,9 +1,6 @@
|
||||||
#![allow(unused)]
|
use bevy::prelude::*;
|
||||||
|
|
||||||
use bevy::{log::LogPlugin, prelude::*};
|
|
||||||
use clap::{Parser, Subcommand};
|
use clap::{Parser, Subcommand};
|
||||||
use tracing::Level;
|
use tracing_subscriber::{layer::SubscriberExt, registry::LookupSpan, util::SubscriberInitExt};
|
||||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
|
||||||
|
|
||||||
mod gui;
|
mod gui;
|
||||||
mod tui;
|
mod tui;
|
||||||
|
|
@ -20,30 +17,25 @@ enum Mode {
|
||||||
RunTui,
|
RunTui,
|
||||||
}
|
}
|
||||||
|
|
||||||
const FILTERSTRING: &str = "warn,jong=trace";
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
// tracing_subscriber::fmt()
|
||||||
|
// .with_writer(std::io::stderr)
|
||||||
|
// .with_env_filter("warn,jong=trace")
|
||||||
|
// .init();
|
||||||
|
|
||||||
let args = Args::parse();
|
let args = Args::parse();
|
||||||
|
|
||||||
let mut app = App::new();
|
let mut app = App::new();
|
||||||
let app = match args.mode {
|
let app = match args.mode {
|
||||||
Mode::RunGui => {
|
Mode::RunGui => app.add_plugins(DefaultPlugins),
|
||||||
app.add_plugins(DefaultPlugins.set(LogPlugin {
|
|
||||||
filter: FILTERSTRING.into(),
|
|
||||||
level: Level::TRACE,
|
|
||||||
// custom_layer: todo!(),
|
|
||||||
// fmt_layer: todo!(),
|
|
||||||
..Default::default()
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
Mode::RunTui => {
|
Mode::RunTui => {
|
||||||
tracing_subscriber::registry()
|
tracing_subscriber::registry()
|
||||||
.with(tui_logger::TuiTracingSubscriberLayer)
|
.with(tui_logger::TuiTracingSubscriberLayer)
|
||||||
.init();
|
.init();
|
||||||
tui_logger::init_logger(tui_logger::LevelFilter::Trace).unwrap();
|
tui_logger::init_logger(tui_logger::LevelFilter::Trace).unwrap();
|
||||||
tui_logger::set_env_filter_from_string(FILTERSTRING);
|
tui_logger::set_env_filter_from_string("warn,jong=trace");
|
||||||
|
|
||||||
app.add_plugins(tui::RiichiTui::default())
|
app.add_plugins(tui::RiichiTui)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
28
src/tiles.rs
28
src/tiles.rs
|
|
@ -1,24 +1,36 @@
|
||||||
use bevy::{ecs::entity::MapEntities, prelude::*};
|
use bevy::{ecs::entity::MapEntities, prelude::*};
|
||||||
use strum::FromRepr;
|
use strum::FromRepr;
|
||||||
|
|
||||||
#[derive(Component, Debug)]
|
|
||||||
|
// #[derive(Component)]
|
||||||
|
// #[derive(relasionship(re))]
|
||||||
|
// pub struct TileEntity {
|
||||||
|
// #[relationship]
|
||||||
|
// pub parent: Entity,
|
||||||
|
|
||||||
|
// r#type: Tile,
|
||||||
|
// }
|
||||||
|
|
||||||
|
struct Hand;
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
pub struct Tile {
|
pub struct Tile {
|
||||||
pub suit: Suit,
|
suit: Suit,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(MapEntities, Debug, PartialEq, PartialOrd, Eq, Ord, Clone, Copy)]
|
#[derive(MapEntities)]
|
||||||
pub enum Suit {
|
pub enum Suit {
|
||||||
Man(Rank),
|
|
||||||
Pin(Rank),
|
Pin(Rank),
|
||||||
Sou(Rank),
|
Sou(Rank),
|
||||||
|
Man(Rank),
|
||||||
Wind(Wind),
|
Wind(Wind),
|
||||||
Dragon(Dragon),
|
Dragon(Dragon),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deref, DerefMut, Debug, PartialEq, PartialOrd, Eq, Ord, Clone, Copy)]
|
#[derive(Deref, DerefMut)]
|
||||||
pub struct Rank(pub u8);
|
pub struct Rank(u8);
|
||||||
|
|
||||||
#[derive(FromRepr, Debug, PartialEq, PartialOrd, Eq, Ord, Clone, Copy)]
|
#[derive(FromRepr)]
|
||||||
pub enum Wind {
|
pub enum Wind {
|
||||||
Ton,
|
Ton,
|
||||||
Nan,
|
Nan,
|
||||||
|
|
@ -26,7 +38,7 @@ pub enum Wind {
|
||||||
Pei,
|
Pei,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, FromRepr, PartialEq, PartialOrd, Eq, Ord, Clone, Copy)]
|
#[derive(FromRepr)]
|
||||||
pub enum Dragon {
|
pub enum Dragon {
|
||||||
Haku,
|
Haku,
|
||||||
Hatsu,
|
Hatsu,
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,14 @@
|
||||||
use bevy::prelude::*;
|
|
||||||
use bevy_ratatui::RatatuiContext;
|
|
||||||
use ratatui::widgets::Block;
|
|
||||||
use tui_logger::TuiLoggerWidget;
|
use tui_logger::TuiLoggerWidget;
|
||||||
|
|
||||||
|
use bevy_ratatui::RatatuiContext;
|
||||||
|
|
||||||
|
use bevy::input::keyboard::Key;
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Default, States)]
|
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Default, States)]
|
||||||
pub(crate) enum ConsoleState {
|
pub(crate) enum ConsoleState {
|
||||||
|
Open,
|
||||||
#[default]
|
#[default]
|
||||||
Closed,
|
Closed,
|
||||||
Open,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::ops::Not for ConsoleState {
|
impl std::ops::Not for ConsoleState {
|
||||||
|
|
@ -21,10 +22,20 @@ impl std::ops::Not for ConsoleState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn toggle_console(
|
||||||
|
input: Res<ButtonInput<Key>>,
|
||||||
|
curr_state: Res<State<ConsoleState>>,
|
||||||
|
mut next_state: ResMut<NextState<ConsoleState>>,
|
||||||
|
) {
|
||||||
|
if input.just_pressed(Key::Character("`".into())) {
|
||||||
|
trace!("toggled");
|
||||||
|
next_state.set(!*curr_state.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn draw_console(mut tui_ctx: ResMut<RatatuiContext>) -> Result {
|
pub(crate) fn draw_console(mut tui_ctx: ResMut<RatatuiContext>) -> Result {
|
||||||
tui_ctx.draw(|frame| {
|
tui_ctx.draw(|frame| {
|
||||||
let block = Block::bordered().title("console");
|
frame.render_widget(TuiLoggerWidget::default(), frame.area());
|
||||||
frame.render_widget(TuiLoggerWidget::default().block(block), frame.area());
|
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
22
src/tui/input.rs
Normal file
22
src/tui/input.rs
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
// use bevy::ecs::message::MessageReader;
|
||||||
|
use bevy::app::AppExit;
|
||||||
|
use bevy::input::keyboard::{Key, KeyboardInput};
|
||||||
|
use bevy::prelude::*;
|
||||||
|
|
||||||
|
use crate::tui::console::ConsoleState;
|
||||||
|
|
||||||
|
pub(crate) fn keyboard_input_system(
|
||||||
|
// keycode_input: Option<Res<ButtonInput<KeyCode>>>,
|
||||||
|
// key_input: Option<Res<ButtonInput<Key>>>,
|
||||||
|
// mut next_state: ResMut<State<TuiState>>,
|
||||||
|
mut keyboard_events: MessageReader<KeyboardInput>,
|
||||||
|
) {
|
||||||
|
// if let Some(keycode_input) = keycode_input {
|
||||||
|
// if keycode_input.just_pressed(KeyCode::Backquote) {
|
||||||
|
// // console_state.set;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
for keyboard_input in keyboard_events.read() {
|
||||||
|
trace!("{:?}", keyboard_input);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
use bevy::prelude::*;
|
|
||||||
use bevy_ratatui::RatatuiContext;
|
|
||||||
use bevy_ratatui::event::KeyMessage;
|
|
||||||
use ratatui::crossterm::event::KeyCode;
|
|
||||||
use ratatui::layout::Constraint;
|
|
||||||
use ratatui::layout::Layout;
|
|
||||||
|
|
||||||
use jong::game::GameState;
|
|
||||||
|
|
||||||
use crate::tui::TuiState;
|
|
||||||
|
|
||||||
const MAINMENU_OPTIONS: [&str; 2] = ["(p)lay", "(q)uit"];
|
|
||||||
// const MAINMENU_INPUTS: [char;2] = ['p', 'q'];
|
|
||||||
|
|
||||||
pub(crate) fn draw_mainmenu(
|
|
||||||
mut tui_ctx: ResMut<RatatuiContext>,
|
|
||||||
// mut tui_state: ResMut<NextState<TuiState>>,
|
|
||||||
// mut game_state: ResMut<NextState<GameState>>,
|
|
||||||
) {
|
|
||||||
let options = MAINMENU_OPTIONS;
|
|
||||||
let layout = Layout::vertical(vec![Constraint::Min(1); options.len()]);
|
|
||||||
|
|
||||||
tui_ctx.draw(|frame| {
|
|
||||||
let areas = layout.split(frame.area());
|
|
||||||
for (opt, area) in options.into_iter().zip(areas.iter()) {
|
|
||||||
frame.render_widget(opt, *area)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
114
src/tui/mod.rs
114
src/tui/mod.rs
|
|
@ -1,42 +1,15 @@
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use bevy::{app::ScheduleRunnerPlugin, prelude::*, state::app::StatesPlugin};
|
use bevy::{app::ScheduleRunnerPlugin, input::keyboard::Key, prelude::*, state::app::StatesPlugin};
|
||||||
use bevy_ratatui::RatatuiPlugins;
|
use bevy_ratatui::{RatatuiContext, RatatuiPlugins};
|
||||||
use bevy_ratatui::event::KeyMessage;
|
use jong::tiles::Tile;
|
||||||
use ratatui::{text::ToSpan, widgets::Paragraph};
|
use tui_logger::TuiLoggerSmartWidget;
|
||||||
|
|
||||||
use jong::game::GameState;
|
|
||||||
use jong::game::wall::InWall;
|
|
||||||
|
|
||||||
use crate::tui::console::ConsoleState;
|
|
||||||
|
|
||||||
mod console;
|
mod console;
|
||||||
mod menu;
|
mod input;
|
||||||
mod render;
|
|
||||||
|
|
||||||
#[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::MainMenu => None,
|
|
||||||
TuiState::InGame => Some(Self),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct RiichiTui;
|
pub struct RiichiTui;
|
||||||
|
|
||||||
impl Plugin for RiichiTui {
|
impl Plugin for RiichiTui {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.add_plugins((
|
app.add_plugins((
|
||||||
|
|
@ -45,78 +18,33 @@ impl Plugin for RiichiTui {
|
||||||
))),
|
))),
|
||||||
RatatuiPlugins {
|
RatatuiPlugins {
|
||||||
// enable_kitty_protocol: todo!(),
|
// enable_kitty_protocol: todo!(),
|
||||||
enable_mouse_capture: true,
|
// enable_mouse_capture: todo!(),
|
||||||
enable_input_forwarding: true,
|
enable_input_forwarding: true,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
.add_plugins(StatesPlugin)
|
.add_plugins(StatesPlugin)
|
||||||
|
|
||||||
// console
|
|
||||||
.init_state::<console::ConsoleState>()
|
.init_state::<console::ConsoleState>()
|
||||||
|
.add_systems(Update, console::toggle_console)
|
||||||
.add_systems(Update, console::draw_console.run_if(in_state(console::ConsoleState::Open)))
|
.add_systems(Update, console::draw_console.run_if(in_state(console::ConsoleState::Open)))
|
||||||
|
.add_systems(Update, input::keyboard_input_system)
|
||||||
// general setup
|
.add_systems(Update, draw_system)
|
||||||
.init_state::<TuiState>()
|
|
||||||
.add_computed_state::<InGame>()
|
|
||||||
.add_systems(Update, input_system)
|
|
||||||
|
|
||||||
// main menu
|
|
||||||
.add_systems(Update, menu::draw_mainmenu.run_if(in_state(TuiState::MainMenu)))
|
|
||||||
|
|
||||||
// gaming
|
|
||||||
.init_resource::<render::hand::RenderedHand>()
|
|
||||||
.add_systems(Update, render::ingame::draw_ingame.run_if(in_state(InGame)))
|
|
||||||
.add_systems(Update, render::hand::render_changed_hand.run_if(in_state(InGame).and(in_state(GameState::Play))))
|
|
||||||
|
|
||||||
// semicolon stopper
|
// semicolon stopper
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
// #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, States)]
|
||||||
pub(crate) fn input_system(
|
// enum TuiState {
|
||||||
mut messages: MessageReader<KeyMessage>,
|
// MainMenu,
|
||||||
|
// InGame,
|
||||||
|
// }
|
||||||
|
|
||||||
curr_tuistate: Res<State<TuiState>>,
|
pub(crate) fn draw_system(mut tui_ctx: ResMut<RatatuiContext>, query: Query<&Tile>) -> Result {
|
||||||
curr_consolestate: Res<State<ConsoleState>>,
|
tui_ctx.draw(|frame| {
|
||||||
curr_gamestate: Res<State<GameState>>,
|
let text = ratatui::text::Text::raw("tiny riichi");
|
||||||
|
frame.render_widget(text, frame.area());
|
||||||
|
})?;
|
||||||
|
|
||||||
mut next_tuistate: ResMut<NextState<TuiState>>,
|
Ok(())
|
||||||
mut next_consolestate: ResMut<NextState<ConsoleState>>,
|
|
||||||
mut next_gamestate: ResMut<NextState<GameState>>,
|
|
||||||
|
|
||||||
mut exit: MessageWriter<AppExit>,
|
|
||||||
) {
|
|
||||||
use bevy_ratatui::crossterm::event::KeyCode;
|
|
||||||
|
|
||||||
let (ts, cs, gs) = (curr_tuistate.get(), curr_consolestate.get(), curr_gamestate.get());
|
|
||||||
|
|
||||||
for message in messages.read() {
|
|
||||||
if let KeyCode::Char('`') = message.code {
|
|
||||||
next_consolestate.set(!*curr_consolestate.get());
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
match ts {
|
|
||||||
TuiState::MainMenu => match message.code {
|
|
||||||
KeyCode::Char('p') => {
|
|
||||||
next_tuistate.set(TuiState::InGame);
|
|
||||||
next_gamestate.set(GameState::Setup);
|
|
||||||
}
|
|
||||||
KeyCode::Char('q') => {
|
|
||||||
exit.write_default();
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
},
|
|
||||||
TuiState::InGame => match gs {
|
|
||||||
// GameState::None => todo!(),
|
|
||||||
GameState::Setup => todo!(),
|
|
||||||
GameState::Play => todo!(),
|
|
||||||
GameState::Score => todo!(),
|
|
||||||
_ => todo!()
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
use bevy::prelude::*;
|
|
||||||
use ratatui::widgets::Paragraph;
|
|
||||||
|
|
||||||
use jong::game::hand::HandTiles;
|
|
||||||
use jong::tiles::Tile;
|
|
||||||
|
|
||||||
use crate::tui::render::tiles;
|
|
||||||
|
|
||||||
#[derive(Resource, Default)]
|
|
||||||
pub(crate) struct RenderedHand(pub(crate) Vec<Paragraph<'static>>);
|
|
||||||
|
|
||||||
pub(crate) fn render_changed_hand(
|
|
||||||
hand: Single<&HandTiles, Changed<HandTiles>>,
|
|
||||||
tiles: Populated<&Tile>,
|
|
||||||
mut target: ResMut<RenderedHand>,
|
|
||||||
) -> Result {
|
|
||||||
trace!("render_changed_hand");
|
|
||||||
|
|
||||||
render_hand(hand, tiles, target)?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn render_hand(
|
|
||||||
hand: Single<&HandTiles, Changed<HandTiles>>,
|
|
||||||
tiles: Populated<&Tile>,
|
|
||||||
mut target: ResMut<RenderedHand>,
|
|
||||||
) -> Result {
|
|
||||||
trace!("render_hand");
|
|
||||||
|
|
||||||
let hand_tiles = hand
|
|
||||||
.iter()
|
|
||||||
.map(|inhand| -> Result<_> { Ok(tiles.get(inhand).map(tiles::draw_tile)?) })
|
|
||||||
.collect::<Result<Vec<_>>>()?;
|
|
||||||
target.0 = hand_tiles;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
use bevy::prelude::*;
|
|
||||||
use bevy_ratatui::RatatuiContext;
|
|
||||||
|
|
||||||
use crate::tui::render::hand;
|
|
||||||
|
|
||||||
pub(crate) fn draw_ingame(
|
|
||||||
rendered_hand: Res<hand::RenderedHand>,
|
|
||||||
mut tui_ctx: ResMut<RatatuiContext>,
|
|
||||||
) -> Result {
|
|
||||||
use ratatui::layout::Flex;
|
|
||||||
use ratatui::prelude::*;
|
|
||||||
|
|
||||||
tui_ctx.draw(|frame| {
|
|
||||||
// debug!("{}", frame.area());
|
|
||||||
|
|
||||||
let layout = Layout::horizontal(vec![Constraint::Max(5); 13]).flex(Flex::Start);
|
|
||||||
let mut area = frame.area();
|
|
||||||
area.height = 4;
|
|
||||||
let areas = layout.areas::<13>(area);
|
|
||||||
for (tile, area) in rendered_hand.0.iter().zip(areas.iter()) {
|
|
||||||
frame.render_widget(tile, *area);
|
|
||||||
}
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
pub(crate) mod hand;
|
|
||||||
pub(crate) mod ingame;
|
|
||||||
mod tiles;
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
use ratatui::widgets::Paragraph;
|
|
||||||
|
|
||||||
use jong::tiles::Tile;
|
|
||||||
|
|
||||||
pub(crate) fn draw_tile(tile: &Tile) -> Paragraph<'static> {
|
|
||||||
use ratatui::prelude::*;
|
|
||||||
|
|
||||||
let block = ratatui::widgets::Block::bordered();
|
|
||||||
|
|
||||||
Paragraph::new(match &tile.suit {
|
|
||||||
jong::tiles::Suit::Pin(rank) => format!("{}\np", rank.0),
|
|
||||||
jong::tiles::Suit::Sou(rank) => format!("{}\ns", rank.0),
|
|
||||||
jong::tiles::Suit::Man(rank) => format!("{}\nm", rank.0),
|
|
||||||
jong::tiles::Suit::Wind(wind) => (match wind {
|
|
||||||
jong::tiles::Wind::Ton => "e\nw",
|
|
||||||
jong::tiles::Wind::Nan => "s\nw",
|
|
||||||
jong::tiles::Wind::Shaa => "w\nw",
|
|
||||||
jong::tiles::Wind::Pei => "n\nw",
|
|
||||||
})
|
|
||||||
.into(),
|
|
||||||
jong::tiles::Suit::Dragon(dragon) => (match dragon {
|
|
||||||
jong::tiles::Dragon::Haku => "w\nd",
|
|
||||||
jong::tiles::Dragon::Hatsu => "g\nd",
|
|
||||||
jong::tiles::Dragon::Chun => "r\nd",
|
|
||||||
})
|
|
||||||
.into(),
|
|
||||||
})
|
|
||||||
.block(block)
|
|
||||||
.centered()
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue