diff --git a/.helix/config.toml b/.helix/config.toml index 8b13789..07545b2 100644 --- a/.helix/config.toml +++ b/.helix/config.toml @@ -1 +1,2 @@ - +[editor] +workspace-lsp-roots = ["jongline"] diff --git a/.helix/languages.toml b/.helix/languages.toml deleted file mode 100644 index 3b9df02..0000000 --- a/.helix/languages.toml +++ /dev/null @@ -1,6 +0,0 @@ -# [language-server.lspmux] -# command = "lspmux" - -# [[language]] -# name = "rust" -# language-servers = ["lspmux"] diff --git a/devenv.nix b/devenv.nix index 656bae8..89cd3ec 100644 --- a/devenv.nix +++ b/devenv.nix @@ -4,7 +4,6 @@ ... }: rec { # https://devenv.sh/processes/ - # processes.lspmux.exec = "lspmux server"; processes.spacetimedb_start.exec = "spacetime start"; processes.spacetimedb_generate_bindings = { exec = "spacetime dev --module-bindings-path jong/src/stdb jongline --delete-data=always"; @@ -18,7 +17,7 @@ # https://devenv.sh/packages/ packages = with pkgs; [ - # lspmux + # process-compose pkg-config # spacetimedb diff --git a/jong-types/src/lib.rs b/jong-types/src/lib.rs index 4d38b2d..bc2c1b4 100644 --- a/jong-types/src/lib.rs +++ b/jong-types/src/lib.rs @@ -11,14 +11,13 @@ use derive_aliases::derive; use bevy::prelude::*; use spacetimedb::SpacetimeType; -use strum::{EnumCount, FromRepr}; +use strum::FromRepr; #[derive(..Base, Hash, Default)] #[derive(States, SpacetimeType)] pub enum GameState { #[default] None, - Lobby, Setup, Deal, Play, @@ -113,24 +112,3 @@ pub fn tiles() -> Vec { } tiles } - -#[derive( - Default, - ..Copy, - PartialEq, - Eq, - Hash, - Debug, -)] -#[derive(SubStates, FromRepr, EnumCount, SpacetimeType)] -#[source(GameState = GameState::Play)] -pub enum TurnState { - #[default] - None, - Tsumo, - Menzen, - RiichiKan, - Discard, - RonChiiPonKan, - End, -} diff --git a/jong/src/game.rs b/jong/src/game.rs index cb4d61f..c45ee3b 100644 --- a/jong/src/game.rs +++ b/jong/src/game.rs @@ -8,18 +8,19 @@ use bevy_spacetimedb::{ use spacetimedb::Identity; use spacetimedb_sdk::{DbContext, Table, credentials}; -use crate::stdb::{ - self, DbConnection, HandTableAccess, LobbyTableAccess, PlayerTableAccess, RemoteTables, - ViewPlayerHandTableAccess, add_bot, join_or_create_lobby, login_or_add_player, set_ready, - shuffle_deal, start_game, +use crate::{ + SpacetimeDB, creds_store, game, + stdb::{ + self, DbConnection, HandTableAccess, LobbyTableAccess, PlayerTableAccess, RemoteTables, + ViewPlayerHandTableAccess, add_bot, join_or_create_lobby, login_or_add_player, + shuffle_deal, + }, }; use crate::{ - SpacetimeDB, creds_store, game::{ - self, hand::{Hand, Pond}, - player::{CurrentPlayer, MainPlayer, Player}, - round::Wind, + player::{CurrentPlayer, MainPlayer}, + round::{TurnState, Wind}, wall::Wall, }, tile::{self}, @@ -63,7 +64,7 @@ impl Plugin for Riichi { app.add_plugins(plugins) .init_state::() - .add_sub_state::() + // .add_sub_state::() // .init_resource::() // .init_resource::() .add_message::() @@ -82,12 +83,24 @@ impl Plugin for Riichi { .add_systems(Update, on_disconnect) .add_systems(Update, on_player_insert_update) .add_systems(Update, on_lobby_insert_update) - // .add_systems(OnEnter(GameState::Lobby), join_or_create_lobby) + .add_systems(OnEnter(GameState::Setup), join_or_create_lobby) .add_systems(Update, view_hand.run_if(in_state(GameState::Play))) + .add_systems(Update, (view_hand).run_if(in_state(GameState::Play))) // semicolon stopper ; } } + +fn view_hand( + stdb: SpacetimeDB, + mut commands: Commands, + // hand: Populated<&mut Children, With>, +) { + if let Some(view) = stdb.db().view_player_hand().iter().next() { + // hand.get_mut(entity) + } +} + fn on_connect(stdb: SpacetimeDB, mut messages: ReadStdbConnectedMessage, mut commands: Commands) { for msg in messages.read() { info!("you're now jongline"); @@ -125,47 +138,26 @@ fn on_player_insert_update( mut messages: ReadInsertUpdateMessage, mut commands: Commands, - mut player: Option>, ) { - use player::*; - for msg in messages.read() { debug!("player_insert_update msg:\n{:#?}", msg.new); - if let Some(ref player) = player { - // if msg.old.as_ref().is_some_and(|m| !m.ready) && msg.new.ready { - // trace!("entered ready"); - // // TODO add a start game button in the future - // stdb.reducers().start_game().unwrap(); - // } - } else { - let player = Player { - name: msg - .new - .name - .as_ref() - .unwrap_or(&"nameless".to_string()) - .clone(), - }; - let bundle = (player, Hand, Pond, MainPlayer, CurrentPlayer); - commands.spawn(bundle); - } } } -// fn join_or_create_lobby(stdb: SpacetimeDB) { -// let player = stdb -// .db() -// .player() -// .identity() -// .find(&stdb.identity()) -// .unwrap(); +fn join_or_create_lobby(stdb: SpacetimeDB) { + let player = stdb + .db() + .player() + .identity() + .find(&stdb.identity()) + .unwrap(); -// if player.lobby_id == 0 { -// stdb.reducers().join_or_create_lobby(0).unwrap(); -// } else { -// info!("in lobby: {}", player.lobby_id) -// } -// } + if player.lobby_id == 0 { + stdb.reducers().join_or_create_lobby(0).unwrap(); + } else { + info!("in lobby: {}", player.lobby_id) + } +} fn on_lobby_insert_update( stdb: SpacetimeDB, @@ -177,71 +169,53 @@ fn on_lobby_insert_update( for msg in messages.read() { trace!("on_lobby_insert_update msg:\n{:#?}", msg.new); - let player = stdb - .db() - .player() - .identity() - .find(&stdb.identity()) - .unwrap(); - next_gamestate.set(msg.new.game_state.into()); match msg.new.game_state { stdb::GameState::None => { trace!("game entered none"); } - stdb::GameState::Lobby => { - trace!("game in lobby"); - if !player.ready { + stdb::GameState::Setup => { + trace!("game entered setup"); + + let player = stdb + .db() + .player() + .identity() + .find(&stdb.identity()) + .unwrap(); + + if player.lobby_id == msg.new.id { + stdb.reducers().shuffle_deal(player.lobby_id).unwrap(); for _ in 0..3 { stdb.reducers().add_bot(player.lobby_id).unwrap(); } - stdb.reducers().set_ready(true).unwrap(); - stdb.reducers().start_game().unwrap(); + } else { + error!("no player but game in setup") } } - stdb::GameState::Setup => { - trace!("game entered setup"); - stdb.reducers().shuffle_deal(player.lobby_id).unwrap(); - } stdb::GameState::Deal => { trace!("game entered deal"); } stdb::GameState::Play => { trace!("game entered play"); + + // TODO this should run once to spawn the hand? or do elsewhere + if let Some(hand) = stdb.db().view_player_hand().iter().next() { + debug!("hand: {hand:?}"); + let tiles = hand + .tiles + .iter() + .map(Into::into) + .map(|t: Tile| commands.spawn(t).id()) + .collect::>(); + commands.spawn(Hand).add_children(&tiles); + } else { + error!("entered play without a hand") + } } stdb::GameState::Exit => { trace!("game enetered exit"); } } - - next_gamestate.set(msg.new.game_state.into()); - } -} - -fn view_hand( - stdb: SpacetimeDB, - - mut commands: Commands, - tiles: Query<(&Tile, Entity)>, - hand_ent: Single>, -) { - // trace!("view_hand"); - if let Some(view) = stdb.db().view_player_hand().iter().next() { - let mut view = view.tiles.iter().map(Tile::from).collect::>(); - - let tiles = tiles - .iter() - .filter(|(tt, _)| { - if let Some((i, _)) = view.iter().enumerate().find(|(_, t)| t == tt) { - view.swap_remove(i); - true - } else { - false - } - }) - .map(|(_, e)| e) - .collect::>(); - - commands.entity(*hand_ent).replace_children(&tiles); } } diff --git a/jong/src/game/round.rs b/jong/src/game/round.rs index 9953c57..9a76ac1 100644 --- a/jong/src/game/round.rs +++ b/jong/src/game/round.rs @@ -12,7 +12,6 @@ use crate::{ wall::Wall, }, }; -use jong_types::TurnState; // #[derive(Resource)] // pub struct CurrentPlayer(pub Entity); @@ -49,6 +48,18 @@ pub enum WindRelation { Kamicha, } +#[derive(SubStates, Default, Clone, Copy, PartialEq, Eq, Hash, Debug, FromRepr, EnumCount)] +#[source(GameState = GameState::Play)] +pub(crate) enum TurnState { + #[default] + Tsumo, + Menzen, + RiichiKan, + Discard, + RonChiiPonKan, + End, +} + #[derive(Component, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] pub(crate) enum CallType { Skip, diff --git a/jong/src/lib.rs b/jong/src/lib.rs index dc56646..ac78c87 100644 --- a/jong/src/lib.rs +++ b/jong/src/lib.rs @@ -5,10 +5,11 @@ use bevy_spacetimedb::StdbConnection; use spacetimedb_sdk::credentials; pub mod game; -pub mod stdb; pub mod tile; pub mod yakus; +mod stdb; + trait EnumNextCycle { fn next(&self) -> Self; } @@ -23,7 +24,6 @@ impl From for jong_types::GameState { fn from(value: stdb::GameState) -> Self { match value { stdb::GameState::None => Self::None, - stdb::GameState::Lobby => Self::Lobby, stdb::GameState::Setup => Self::Setup, stdb::GameState::Deal => Self::Deal, stdb::GameState::Play => Self::Play, diff --git a/jong/src/stdb/game_state_type.rs b/jong/src/stdb/game_state_type.rs index b8cafa4..2e26076 100644 --- a/jong/src/stdb/game_state_type.rs +++ b/jong/src/stdb/game_state_type.rs @@ -10,8 +10,6 @@ use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; pub enum GameState { None, - Lobby, - Setup, Deal, diff --git a/jong/src/stdb/lobby_table.rs b/jong/src/stdb/lobby_table.rs index 98b9f62..ab1d881 100644 --- a/jong/src/stdb/lobby_table.rs +++ b/jong/src/stdb/lobby_table.rs @@ -5,7 +5,6 @@ use super::game_state_type::GameState; use super::lobby_type::Lobby; use super::player_or_bot_type::PlayerOrBot; -use super::turn_state_type::TurnState; use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; /// Table handle for the table `lobby`. diff --git a/jong/src/stdb/lobby_type.rs b/jong/src/stdb/lobby_type.rs index ce82250..110a274 100644 --- a/jong/src/stdb/lobby_type.rs +++ b/jong/src/stdb/lobby_type.rs @@ -6,7 +6,6 @@ use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; use super::game_state_type::GameState; use super::player_or_bot_type::PlayerOrBot; -use super::turn_state_type::TurnState; #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] @@ -15,7 +14,6 @@ pub struct Lobby { pub host_player_id: u32, pub players: Vec, pub game_state: GameState, - pub turn_state: TurnState, } impl __sdk::InModule for Lobby { diff --git a/jong/src/stdb/mod.rs b/jong/src/stdb/mod.rs index 356ab0c..6c87060 100644 --- a/jong/src/stdb/mod.rs +++ b/jong/src/stdb/mod.rs @@ -23,12 +23,9 @@ pub mod player_type; pub mod pond_table; pub mod pond_type; pub mod rank_type; -pub mod set_ready_reducer; pub mod shuffle_deal_reducer; -pub mod start_game_reducer; pub mod suit_type; pub mod tile_type; -pub mod turn_state_type; pub mod view_player_hand_table; pub mod wall_table; pub mod wall_type; @@ -55,12 +52,9 @@ pub use player_type::Player; pub use pond_table::*; pub use pond_type::Pond; pub use rank_type::Rank; -pub use set_ready_reducer::{set_flags_for_set_ready, set_ready, SetReadyCallbackId}; pub use shuffle_deal_reducer::{set_flags_for_shuffle_deal, shuffle_deal, ShuffleDealCallbackId}; -pub use start_game_reducer::{set_flags_for_start_game, start_game, StartGameCallbackId}; pub use suit_type::Suit; pub use tile_type::Tile; -pub use turn_state_type::TurnState; pub use view_player_hand_table::*; pub use wall_table::*; pub use wall_type::Wall; @@ -77,9 +71,7 @@ pub enum Reducer { AddBot { lobby_id: u32 }, JoinOrCreateLobby { lobby_id: u32 }, LoginOrAddPlayer, - SetReady { ready: bool }, ShuffleDeal { lobby_id: u32 }, - StartGame, } impl __sdk::InModule for Reducer { @@ -92,9 +84,7 @@ impl __sdk::Reducer for Reducer { Reducer::AddBot { .. } => "add_bot", Reducer::JoinOrCreateLobby { .. } => "join_or_create_lobby", Reducer::LoginOrAddPlayer => "login_or_add_player", - Reducer::SetReady { .. } => "set_ready", Reducer::ShuffleDeal { .. } => "shuffle_deal", - Reducer::StartGame => "start_game", _ => unreachable!(), } } @@ -116,13 +106,6 @@ impl TryFrom<__ws::ReducerCallInfo<__ws::BsatnFormat>> for Reducer { login_or_add_player_reducer::LoginOrAddPlayerArgs, >("login_or_add_player", &value.args)? .into()), - "set_ready" => Ok( - __sdk::parse_reducer_args::( - "set_ready", - &value.args, - )? - .into(), - ), "shuffle_deal" => Ok( __sdk::parse_reducer_args::( "shuffle_deal", @@ -130,13 +113,6 @@ impl TryFrom<__ws::ReducerCallInfo<__ws::BsatnFormat>> for Reducer { )? .into(), ), - "start_game" => Ok( - __sdk::parse_reducer_args::( - "start_game", - &value.args, - )? - .into(), - ), unknown => { Err( __sdk::InternalError::unknown_name("reducer", unknown, "ReducerCallInfo") diff --git a/jong/src/stdb/player_type.rs b/jong/src/stdb/player_type.rs index 311ac9b..0e651ec 100644 --- a/jong/src/stdb/player_type.rs +++ b/jong/src/stdb/player_type.rs @@ -13,7 +13,6 @@ pub struct Player { pub lobby_id: u32, pub hand_id: u32, pub pond_id: u32, - pub ready: bool, } impl __sdk::InModule for Player { diff --git a/jong/src/stdb/set_ready_reducer.rs b/jong/src/stdb/set_ready_reducer.rs deleted file mode 100644 index bebd7cf..0000000 --- a/jong/src/stdb/set_ready_reducer.rs +++ /dev/null @@ -1,102 +0,0 @@ -// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE -// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. - -#![allow(unused, clippy::all)] -use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; - -#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] -#[sats(crate = __lib)] -pub(super) struct SetReadyArgs { - pub ready: bool, -} - -impl From for super::Reducer { - fn from(args: SetReadyArgs) -> Self { - Self::SetReady { ready: args.ready } - } -} - -impl __sdk::InModule for SetReadyArgs { - type Module = super::RemoteModule; -} - -pub struct SetReadyCallbackId(__sdk::CallbackId); - -#[allow(non_camel_case_types)] -/// Extension trait for access to the reducer `set_ready`. -/// -/// Implemented for [`super::RemoteReducers`]. -pub trait set_ready { - /// Request that the remote module invoke the reducer `set_ready` to run as soon as possible. - /// - /// This method returns immediately, and errors only if we are unable to send the request. - /// The reducer will run asynchronously in the future, - /// and its status can be observed by listening for [`Self::on_set_ready`] callbacks. - fn set_ready(&self, ready: bool) -> __sdk::Result<()>; - /// Register a callback to run whenever we are notified of an invocation of the reducer `set_ready`. - /// - /// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`] - /// to determine the reducer's status. - /// - /// The returned [`SetReadyCallbackId`] can be passed to [`Self::remove_on_set_ready`] - /// to cancel the callback. - fn on_set_ready( - &self, - callback: impl FnMut(&super::ReducerEventContext, &bool) + Send + 'static, - ) -> SetReadyCallbackId; - /// Cancel a callback previously registered by [`Self::on_set_ready`], - /// causing it not to run in the future. - fn remove_on_set_ready(&self, callback: SetReadyCallbackId); -} - -impl set_ready for super::RemoteReducers { - fn set_ready(&self, ready: bool) -> __sdk::Result<()> { - self.imp.call_reducer("set_ready", SetReadyArgs { ready }) - } - fn on_set_ready( - &self, - mut callback: impl FnMut(&super::ReducerEventContext, &bool) + Send + 'static, - ) -> SetReadyCallbackId { - SetReadyCallbackId(self.imp.on_reducer( - "set_ready", - Box::new(move |ctx: &super::ReducerEventContext| { - #[allow(irrefutable_let_patterns)] - let super::ReducerEventContext { - event: - __sdk::ReducerEvent { - reducer: super::Reducer::SetReady { ready }, - .. - }, - .. - } = ctx - else { - unreachable!() - }; - callback(ctx, ready) - }), - )) - } - fn remove_on_set_ready(&self, callback: SetReadyCallbackId) { - self.imp.remove_on_reducer("set_ready", callback.0) - } -} - -#[allow(non_camel_case_types)] -#[doc(hidden)] -/// Extension trait for setting the call-flags for the reducer `set_ready`. -/// -/// Implemented for [`super::SetReducerFlags`]. -/// -/// This type is currently unstable and may be removed without a major version bump. -pub trait set_flags_for_set_ready { - /// Set the call-reducer flags for the reducer `set_ready` to `flags`. - /// - /// This type is currently unstable and may be removed without a major version bump. - fn set_ready(&self, flags: __ws::CallReducerFlags); -} - -impl set_flags_for_set_ready for super::SetReducerFlags { - fn set_ready(&self, flags: __ws::CallReducerFlags) { - self.imp.set_call_reducer_flags("set_ready", flags); - } -} diff --git a/jong/src/stdb/start_game_reducer.rs b/jong/src/stdb/start_game_reducer.rs deleted file mode 100644 index 5eb59c1..0000000 --- a/jong/src/stdb/start_game_reducer.rs +++ /dev/null @@ -1,100 +0,0 @@ -// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE -// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. - -#![allow(unused, clippy::all)] -use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; - -#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] -#[sats(crate = __lib)] -pub(super) struct StartGameArgs {} - -impl From for super::Reducer { - fn from(args: StartGameArgs) -> Self { - Self::StartGame - } -} - -impl __sdk::InModule for StartGameArgs { - type Module = super::RemoteModule; -} - -pub struct StartGameCallbackId(__sdk::CallbackId); - -#[allow(non_camel_case_types)] -/// Extension trait for access to the reducer `start_game`. -/// -/// Implemented for [`super::RemoteReducers`]. -pub trait start_game { - /// Request that the remote module invoke the reducer `start_game` to run as soon as possible. - /// - /// This method returns immediately, and errors only if we are unable to send the request. - /// The reducer will run asynchronously in the future, - /// and its status can be observed by listening for [`Self::on_start_game`] callbacks. - fn start_game(&self) -> __sdk::Result<()>; - /// Register a callback to run whenever we are notified of an invocation of the reducer `start_game`. - /// - /// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`] - /// to determine the reducer's status. - /// - /// The returned [`StartGameCallbackId`] can be passed to [`Self::remove_on_start_game`] - /// to cancel the callback. - fn on_start_game( - &self, - callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, - ) -> StartGameCallbackId; - /// Cancel a callback previously registered by [`Self::on_start_game`], - /// causing it not to run in the future. - fn remove_on_start_game(&self, callback: StartGameCallbackId); -} - -impl start_game for super::RemoteReducers { - fn start_game(&self) -> __sdk::Result<()> { - self.imp.call_reducer("start_game", StartGameArgs {}) - } - fn on_start_game( - &self, - mut callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, - ) -> StartGameCallbackId { - StartGameCallbackId(self.imp.on_reducer( - "start_game", - Box::new(move |ctx: &super::ReducerEventContext| { - #[allow(irrefutable_let_patterns)] - let super::ReducerEventContext { - event: - __sdk::ReducerEvent { - reducer: super::Reducer::StartGame {}, - .. - }, - .. - } = ctx - else { - unreachable!() - }; - callback(ctx) - }), - )) - } - fn remove_on_start_game(&self, callback: StartGameCallbackId) { - self.imp.remove_on_reducer("start_game", callback.0) - } -} - -#[allow(non_camel_case_types)] -#[doc(hidden)] -/// Extension trait for setting the call-flags for the reducer `start_game`. -/// -/// Implemented for [`super::SetReducerFlags`]. -/// -/// This type is currently unstable and may be removed without a major version bump. -pub trait set_flags_for_start_game { - /// Set the call-reducer flags for the reducer `start_game` to `flags`. - /// - /// This type is currently unstable and may be removed without a major version bump. - fn start_game(&self, flags: __ws::CallReducerFlags); -} - -impl set_flags_for_start_game for super::SetReducerFlags { - fn start_game(&self, flags: __ws::CallReducerFlags) { - self.imp.set_call_reducer_flags("start_game", flags); - } -} diff --git a/jong/src/stdb/turn_state_type.rs b/jong/src/stdb/turn_state_type.rs deleted file mode 100644 index 1bbd7d5..0000000 --- a/jong/src/stdb/turn_state_type.rs +++ /dev/null @@ -1,28 +0,0 @@ -// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE -// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. - -#![allow(unused, clippy::all)] -use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; - -#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] -#[sats(crate = __lib)] -#[derive(Copy, Eq, Hash)] -pub enum TurnState { - None, - - Tsumo, - - Menzen, - - RiichiKan, - - Discard, - - RonChiiPonKan, - - End, -} - -impl __sdk::InModule for TurnState { - type Module = super::RemoteModule; -} diff --git a/jong/src/tui.rs b/jong/src/tui.rs index 3c2bade..b0d60d4 100644 --- a/jong/src/tui.rs +++ b/jong/src/tui.rs @@ -26,32 +26,6 @@ pub enum TuiSet { Render, } -mod states { - use bevy::prelude::*; - use tui_logger::TuiWidgetState; - - #[derive(Resource)] - pub(crate) struct ConsoleWidget { - pub(crate) state: TuiWidgetState, - pub(crate) open: bool, - } - - #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, States, Default)] - pub(crate) enum TuiState { - #[default] - MainMenu, - InGame, - } - - // #[derive(SubStates, Default, Clone, Copy, PartialEq, Eq, Hash, Debug)] - // #[source(TuiState = TuiState::MainMenu)] - // pub(crate) enum ZenState { - // #[default] - // Menu, - // Zen, - // } -} - impl Plugin for TuiPlugin { fn build(&self, app: &mut App) { app.add_plugins(( @@ -86,7 +60,7 @@ impl Plugin for TuiPlugin { .add_systems( Update, ( - (render::render_hands, render::render_arg_check).run_if(in_state(GameState::Play)), + render::render_hands.run_if(in_state(GameState::Play)), render::render, ) .chain() @@ -121,3 +95,29 @@ fn discard_tile( writer.write(GameMessage::Discarded(message.0)); } } + +mod states { + use bevy::prelude::*; + use tui_logger::TuiWidgetState; + + #[derive(Resource)] + pub(crate) struct ConsoleWidget { + pub(crate) state: TuiWidgetState, + pub(crate) open: bool, + } + + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, States, Default)] + pub(crate) enum TuiState { + #[default] + MainMenu, + InGame, + } + + // #[derive(SubStates, Default, Clone, Copy, PartialEq, Eq, Hash, Debug)] + // #[source(TuiState = TuiState::MainMenu)] + // pub(crate) enum ZenState { + // #[default] + // Menu, + // Zen, + // } +} diff --git a/jong/src/tui/input/keyboard.rs b/jong/src/tui/input/keyboard.rs index 722d6fb..d2415bc 100644 --- a/jong/src/tui/input/keyboard.rs +++ b/jong/src/tui/input/keyboard.rs @@ -1,21 +1,15 @@ use bevy::prelude::*; use bevy_ratatui::crossterm::event::KeyCode; use bevy_ratatui::event::KeyMessage; -use jong::stdb::PlayerTableAccess; -use jong::stdb::join_or_create_lobby; -use jong::stdb::start_game; +// use ratatui::crossterm::event::KeyCode; use tui_logger::TuiWidgetEvent; -use jong::SpacetimeDB; -use jong_types::GameState; - use crate::tui::layout::Overlays; use crate::tui::states::ConsoleWidget; use crate::tui::states::TuiState; +use jong_types::GameState; pub(crate) fn keyboard( - stdb: SpacetimeDB, - mut messages: MessageReader, mut overlays: ResMut, mut consolewidget: ResMut, @@ -23,6 +17,7 @@ pub(crate) fn keyboard( curr_gamestate: Res>, curr_tuistate: Res>, + mut next_gamestate: ResMut>, mut next_tuistate: ResMut>, ) { @@ -43,8 +38,8 @@ pub(crate) fn keyboard( match curr_tuistate.get() { TuiState::MainMenu => match key { KeyCode::Char('p') => { - stdb.reducers().join_or_create_lobby(0).unwrap(); next_tuistate.set(TuiState::InGame); + next_gamestate.set(GameState::Setup); } KeyCode::Char('z') => { // if let Some(ref curr_zenstate) = curr_zenstate { diff --git a/jong/src/tui/render.rs b/jong/src/tui/render.rs index 42a0fd2..a81588d 100644 --- a/jong/src/tui/render.rs +++ b/jong/src/tui/render.rs @@ -95,23 +95,6 @@ pub(crate) fn render( Ok(()) } -pub(crate) fn render_arg_check( - mut commands: Commands, - mut tui: ResMut, - - hovered: Query>, - layouts: Res, - - tiles: Query<&jong_types::Tile>, - // main_player: Single<(&Player, Entity, &Wind), With>, - curr_player: Single>, - players: Query<(&Player, Entity, &Children)>, - hands: Query<(&Children, Entity), (With, Without)>, - // drawn_tile: Single>, -) { - // trace!("arg!"); -} - #[allow(clippy::too_many_arguments, clippy::type_complexity)] pub(crate) fn render_hands( mut commands: Commands, @@ -127,8 +110,6 @@ pub(crate) fn render_hands( hands: Query<(&Children, Entity), (With, Without)>, drawn_tile: Single>, ) -> Result { - trace!("render_hands"); - let mut frame = tui.get_frame(); debug_blocks(*layouts, &mut frame); diff --git a/justfile b/justfile index 8962781..0d4b9f7 100644 --- a/justfile +++ b/justfile @@ -8,8 +8,8 @@ default: just --list run-tui: - # mprocs -s localhost:4050 --ctl $"({c: restart-proc, name: spacetimedb_generate_bindings} | to yaml)" - # sleep 3sec + mprocs -s localhost:4050 --ctl $"({c: restart-proc, name: spacetimedb_generate_bindings} | to yaml)" + sleep 3sec cargo run -- run-tui update: diff --git a/spacetimedb/src/game.rs b/spacetimedb/src/game.rs index 37a6a69..1266e64 100644 --- a/spacetimedb/src/game.rs +++ b/spacetimedb/src/game.rs @@ -1,5 +1,5 @@ -use log::{info, trace}; -use spacetimedb::{ReducerContext, Table, reducer}; +use log::info; +use spacetimedb::{ReducerContext, Table, rand::seq::SliceRandom, reducer}; use crate::tables::*; use jong_types::*; @@ -22,8 +22,7 @@ pub fn join_or_create_lobby(ctx: &ReducerContext, mut lobby_id: u32) -> Result<( id: 0, host_player_id: player.id, players: vec![PlayerOrBot::Player { id: player.id }], - game_state: GameState::Lobby, - turn_state: TurnState::None, + game_state: GameState::Setup, }); info!("created lobby: {:?}", lobby); @@ -42,10 +41,10 @@ pub fn join_or_create_lobby(ctx: &ReducerContext, mut lobby_id: u32) -> Result<( pub fn add_bot(ctx: &ReducerContext, lobby_id: u32) -> Result<(), String> { if lobby_id == 0 { Err("cannot add a bot without a lobby".into()) - } else if let Some(mut lobby) = ctx.db.lobby().id().find(lobby_id) + } else if let Some(lobby) = ctx.db.lobby().id().find(lobby_id) && (ctx.db.player().lobby_id().filter(lobby_id).count() + ctx.db.bot().lobby_id().filter(lobby_id).count() - < 4) + <= 4) { let bot = ctx.db.bot().insert(Bot { id: 0, @@ -53,34 +52,9 @@ pub fn add_bot(ctx: &ReducerContext, lobby_id: u32) -> Result<(), String> { hand_id: 0, pond_id: 0, }); - lobby.players.push(PlayerOrBot::Bot { id: bot.id }); - ctx.db.lobby().id().update(lobby); info!("added bot {} to lobby {}", bot.id, lobby_id); Ok(()) } else { Err("lobby doesn't exist".into()) } } - -#[reducer] -pub fn set_ready(ctx: &ReducerContext, ready: bool) { - let mut player = ctx.db.player().identity().find(ctx.sender).unwrap(); - player.ready = ready; - - let player = ctx.db.player().identity().update(player); -} - -#[reducer] -pub fn start_game(ctx: &ReducerContext) { - let player = ctx.db.player().identity().find(ctx.sender).unwrap(); - if let Some(mut lobby) = ctx.db.lobby().host_player_id().find(player.id) - && lobby.players.len() == 4 - && lobby.players.iter().all(|p| match p { - PlayerOrBot::Player { id } => ctx.db.player().id().find(id).is_some_and(|p| p.ready), - PlayerOrBot::Bot { id } => ctx.db.bot().id().find(id).is_some(), - }) - { - lobby.game_state = GameState::Deal; - ctx.db.lobby().id().update(lobby); - } -} diff --git a/spacetimedb/src/game/wall.rs b/spacetimedb/src/game/wall.rs index f33c898..dca40d4 100644 --- a/spacetimedb/src/game/wall.rs +++ b/spacetimedb/src/game/wall.rs @@ -10,20 +10,21 @@ pub fn shuffle_deal(ctx: &ReducerContext, lobby_id: u32) { debug!("lobby_id: {lobby_id}"); let mut lobby = ctx.db.lobby().id().find(lobby_id).unwrap(); - if lobby.game_state == GameState::Deal { - let tiles = new_shuffled_wall(ctx); - ctx.db.wall().insert(Wall { - // id: 0, - lobby_id, - tiles, - }); + lobby.game_state = GameState::Deal; + let mut lobby = ctx.db.lobby().id().update(lobby); - deal_hands(ctx, lobby_id); - lobby.game_state = GameState::Play; - lobby.turn_state = TurnState::Tsumo; - ctx.db.lobby().id().update(lobby); - } + let tiles = new_shuffled_wall(ctx); + ctx.db.wall().insert(Wall { + // id: 0, + lobby_id, + tiles, + }); + + deal_hands(ctx, lobby_id); + + lobby.game_state = GameState::Play; + ctx.db.lobby().id().update(lobby); } pub fn new_shuffled_wall(ctx: &ReducerContext) -> Vec { diff --git a/spacetimedb/src/lib.rs b/spacetimedb/src/lib.rs index 505db51..e1669d6 100644 --- a/spacetimedb/src/lib.rs +++ b/spacetimedb/src/lib.rs @@ -1,7 +1,10 @@ -use log::info; -use spacetimedb::{ReducerContext, Table, reducer}; +use log::{debug, info}; +use spacetimedb::{ + ReducerContext, Table, ViewContext, rand::seq::SliceRandom, reducer, table, view, +}; use crate::tables::*; +use jong_types::*; mod game; mod tables; @@ -18,7 +21,6 @@ pub fn login_or_add_player(ctx: &ReducerContext) { lobby_id: 0, hand_id: 0, pond_id: 0, - ready: false, }) { info!("added player: {:?}", player); } else { diff --git a/spacetimedb/src/tables.rs b/spacetimedb/src/tables.rs index 02efc8e..c53daf7 100644 --- a/spacetimedb/src/tables.rs +++ b/spacetimedb/src/tables.rs @@ -18,8 +18,6 @@ pub struct Player { pub lobby_id: u32, pub hand_id: u32, pub pond_id: u32, - - pub ready: bool, } #[table(name = bot)] @@ -52,7 +50,6 @@ pub struct Lobby { pub players: Vec, pub game_state: GameState, - pub turn_state: TurnState, } #[table(name = wall)] diff --git a/states b/states deleted file mode 100644 index 13e0595..0000000 --- a/states +++ /dev/null @@ -1,18 +0,0 @@ -gamestate - - none - join_or_create_lobby() - - lobby - set_ready() - add_bot() - start_game() - - setup - shuffle_deal() - - deal - animations?? - - play - discards??