Compare commits
No commits in common. "b512e38b266bc4e1b01edbb8ed679590e14426c4" and "550ae73287fc22aa5ff7e1b11fa94c1e2bd290cb" have entirely different histories.
b512e38b26
...
550ae73287
6 changed files with 68 additions and 90 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -1,5 +1,3 @@
|
||||||
*.log
|
|
||||||
|
|
||||||
target
|
target
|
||||||
|
|
||||||
# Devenv
|
# Devenv
|
||||||
|
|
@ -12,3 +10,5 @@ devenv.local.yaml
|
||||||
|
|
||||||
# pre-commit
|
# pre-commit
|
||||||
.pre-commit-config.yaml
|
.pre-commit-config.yaml
|
||||||
|
|
||||||
|
mprocs.log
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#![feature(if_let_guard)]
|
#![feature(if_let_guard)]
|
||||||
|
|
||||||
use log::{debug, trace};
|
use log::debug;
|
||||||
use spacetimedb::{ReducerContext, Table, reducer};
|
use spacetimedb::{ReducerContext, Table, reducer};
|
||||||
|
|
||||||
use crate::tables::*;
|
use crate::tables::*;
|
||||||
|
|
@ -34,7 +34,6 @@ pub fn connect(ctx: &ReducerContext) -> Result<(), String> {
|
||||||
ctx.db.logged_out_player().identity().delete(ctx.sender);
|
ctx.db.logged_out_player().identity().delete(ctx.sender);
|
||||||
player
|
player
|
||||||
} else {
|
} else {
|
||||||
debug!("inserting new player with identity {:?}", ctx.sender);
|
|
||||||
ctx.db.player().try_insert(Player {
|
ctx.db.player().try_insert(Player {
|
||||||
identity: ctx.sender,
|
identity: ctx.sender,
|
||||||
id: 0,
|
id: 0,
|
||||||
|
|
@ -57,14 +56,10 @@ pub fn disconnect(ctx: &ReducerContext) -> Result<(), String> {
|
||||||
.player()
|
.player()
|
||||||
.identity()
|
.identity()
|
||||||
.find(ctx.sender)
|
.find(ctx.sender)
|
||||||
.ok_or_else(|| format!("can't find player {} to disconnect", ctx.sender))?;
|
.ok_or_else(|| format!("can't find player {}", ctx.sender))?;
|
||||||
|
|
||||||
let player = ctx.db.logged_out_player().insert(player);
|
ctx.db.logged_out_player().insert(player);
|
||||||
if !ctx.db.player().identity().delete(ctx.sender) {
|
ctx.db.player().identity().delete(ctx.sender);
|
||||||
Err("can't delete row")?
|
|
||||||
}
|
|
||||||
|
|
||||||
debug!("player disconnected: {:?}", player);
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,7 @@
|
||||||
use std::fs::File;
|
|
||||||
|
|
||||||
use bevy::{log::LogPlugin, prelude::*};
|
use bevy::{log::LogPlugin, prelude::*};
|
||||||
use clap::{Parser, Subcommand};
|
use clap::{Parser, Subcommand};
|
||||||
use tracing::Level;
|
use tracing::Level;
|
||||||
use tracing_subscriber::{
|
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||||
Layer,
|
|
||||||
fmt::{self, layer},
|
|
||||||
layer::SubscriberExt,
|
|
||||||
util::SubscriberInitExt,
|
|
||||||
};
|
|
||||||
|
|
||||||
// mod gui;
|
// mod gui;
|
||||||
mod tui;
|
mod tui;
|
||||||
|
|
@ -40,7 +33,6 @@ fn main() {
|
||||||
Mode::RunTui => {
|
Mode::RunTui => {
|
||||||
tracing_subscriber::registry()
|
tracing_subscriber::registry()
|
||||||
.with(tui_logger::TuiTracingSubscriberLayer)
|
.with(tui_logger::TuiTracingSubscriberLayer)
|
||||||
.with(fmt::layer().with_writer(File::create("jong.log").unwrap()))
|
|
||||||
.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(FILTERSTRING);
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,15 @@
|
||||||
|
use bevy::platform::collections::HashMap;
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy_spacetimedb::{
|
use bevy_spacetimedb::{
|
||||||
ReadInsertUpdateMessage, ReadStdbConnectedMessage, ReadStdbDisconnectedMessage,
|
ReadInsertUpdateMessage, ReadStdbConnectedMessage, ReadStdbDisconnectedMessage,
|
||||||
ReadUpdateMessage, StdbPlugin,
|
ReadUpdateMessage, StdbPlugin,
|
||||||
};
|
};
|
||||||
|
|
||||||
use jong_db::{self, add_bot, set_ready};
|
|
||||||
use jong_db::{
|
use jong_db::{
|
||||||
BotTableAccess, DbConnection, LobbyTableAccess, PlayerHand, PlayerTableAccess, RemoteTables,
|
self, BotTableAccess, DbConnection, LobbyTableAccess, PlayerHand, PlayerTableAccess,
|
||||||
ViewClosedHandsTableAccess, ViewHandTableAccess,
|
RemoteTables, ViewClosedHandsTableAccess, ViewHandTableAccess as _,
|
||||||
};
|
};
|
||||||
|
use jong_db::{add_bot, set_ready};
|
||||||
use jong_types::*;
|
use jong_types::*;
|
||||||
use spacetimedb_sdk::Table;
|
use spacetimedb_sdk::Table;
|
||||||
|
|
||||||
|
|
@ -45,7 +46,8 @@ impl Plugin for Riichi {
|
||||||
.add_systems(Startup, subscriptions)
|
.add_systems(Startup, subscriptions)
|
||||||
.add_observer(on_subscribed)
|
.add_observer(on_subscribed)
|
||||||
.add_systems(Update, (on_connect, on_disconnect))
|
.add_systems(Update, (on_connect, on_disconnect))
|
||||||
.add_systems(Update, (on_lobby_insert_update, on_player_insert_update))
|
.add_systems(Update, on_lobby_insert_update)
|
||||||
|
.add_systems(Update, on_player_insert_update)
|
||||||
.add_systems(
|
.add_systems(
|
||||||
Update,
|
Update,
|
||||||
(on_view_hand_update)
|
(on_view_hand_update)
|
||||||
|
|
@ -54,7 +56,7 @@ impl Plugin for Riichi {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_connect(stdb: SpacetimeDB, mut messages: ReadStdbConnectedMessage) {
|
fn on_connect(stdb: SpacetimeDB, mut messages: ReadStdbConnectedMessage, _commands: Commands) {
|
||||||
for msg in messages.read() {
|
for msg in messages.read() {
|
||||||
info!("you're now jongline");
|
info!("you're now jongline");
|
||||||
|
|
||||||
|
|
@ -137,13 +139,10 @@ fn on_subscribed(
|
||||||
|
|
||||||
fn spawn_main_player(
|
fn spawn_main_player(
|
||||||
stdb: &SpacetimeDB,
|
stdb: &SpacetimeDB,
|
||||||
|
|
||||||
commands: &mut Commands,
|
commands: &mut Commands,
|
||||||
next_turnstate: &mut ResMut<NextState<TurnState>>,
|
next_turnstate: &mut ResMut<NextState<TurnState>>,
|
||||||
|
|
||||||
player: &jong_db::Player,
|
player: &jong_db::Player,
|
||||||
) {
|
) {
|
||||||
trace!("spawn_main_player");
|
|
||||||
let main_player = commands
|
let main_player = commands
|
||||||
.spawn((
|
.spawn((
|
||||||
Player {
|
Player {
|
||||||
|
|
@ -153,55 +152,42 @@ fn spawn_main_player(
|
||||||
))
|
))
|
||||||
.id();
|
.id();
|
||||||
if let Some(player_hand) = stdb.db().view_hand().iter().next() {
|
if let Some(player_hand) = stdb.db().view_hand().iter().next() {
|
||||||
spawn_main_hand(commands, next_turnstate, main_player, &player_hand);
|
let hand_tiles: Vec<_> = player_hand
|
||||||
|
.hand
|
||||||
|
.iter()
|
||||||
|
.map(|dbt| commands.spawn((Tile::from(&dbt.tile), TileId(dbt.id))).id())
|
||||||
|
.collect();
|
||||||
|
let pond_tiles: Vec<_> = player_hand
|
||||||
|
.pond
|
||||||
|
.iter()
|
||||||
|
.map(|dbt| commands.spawn((Tile::from(&dbt.tile), TileId(dbt.id))).id())
|
||||||
|
.collect();
|
||||||
|
let pond = commands.spawn(Hand).add_children(&pond_tiles).id();
|
||||||
|
let hand = commands.spawn(Pond).add_children(&hand_tiles).id();
|
||||||
|
commands.entity(main_player).add_children(&[pond, hand]);
|
||||||
|
|
||||||
|
if player_hand.turn_state == jong_db::TurnState::Tsumo
|
||||||
|
&& let Some(drawn_dbt) = player_hand.working_tile
|
||||||
|
{
|
||||||
|
let drawn = commands
|
||||||
|
.spawn((Drawn, Tile::from(&drawn_dbt.tile), TileId(drawn_dbt.id)))
|
||||||
|
.id();
|
||||||
|
commands.entity(main_player).add_child(drawn);
|
||||||
|
}
|
||||||
|
next_turnstate.set(player_hand.turn_state.into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn spawn_main_hand(
|
|
||||||
commands: &mut Commands,
|
|
||||||
next_turnstate: &mut ResMut<NextState<TurnState>>,
|
|
||||||
main_player: Entity,
|
|
||||||
|
|
||||||
player_hand: &PlayerHand,
|
|
||||||
) {
|
|
||||||
let hand_tiles: Vec<_> = player_hand
|
|
||||||
.hand
|
|
||||||
.iter()
|
|
||||||
.map(|dbt| commands.spawn((Tile::from(&dbt.tile), TileId(dbt.id))).id())
|
|
||||||
.collect();
|
|
||||||
let pond_tiles: Vec<_> = player_hand
|
|
||||||
.pond
|
|
||||||
.iter()
|
|
||||||
.map(|dbt| commands.spawn((Tile::from(&dbt.tile), TileId(dbt.id))).id())
|
|
||||||
.collect();
|
|
||||||
let pond = commands.spawn(Hand).add_children(&pond_tiles).id();
|
|
||||||
let hand = commands.spawn(Pond).add_children(&hand_tiles).id();
|
|
||||||
let children = commands.entity(main_player).add_children(&[pond, hand]).id();
|
|
||||||
|
|
||||||
debug!("main_hand: {:?}\n main_pond: {:?}, children: {:?}", hand_tiles, pond_tiles, children);
|
|
||||||
|
|
||||||
if player_hand.turn_state == jong_db::TurnState::Tsumo
|
|
||||||
&& let Some(drawn_dbt) = &player_hand.working_tile
|
|
||||||
{
|
|
||||||
let drawn = commands
|
|
||||||
.spawn((Drawn, Tile::from(&drawn_dbt.tile), TileId(drawn_dbt.id)))
|
|
||||||
.id();
|
|
||||||
commands.entity(main_player).add_child(drawn);
|
|
||||||
}
|
|
||||||
next_turnstate.set(player_hand.turn_state.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
fn spawn_other_player(stdb: &SpacetimeDB, commands: &mut Commands, player: &jong_db::Player) {
|
fn spawn_other_player(stdb: &SpacetimeDB, commands: &mut Commands, player: &jong_db::Player) {
|
||||||
let id = PlayerOrBot::Player { id: player.id };
|
let id = PlayerOrBot::Player { id: player.id };
|
||||||
if let Some(hand_view) = stdb
|
let hand_view = stdb
|
||||||
.db()
|
.db()
|
||||||
.view_closed_hands()
|
.view_closed_hands()
|
||||||
.iter()
|
.iter()
|
||||||
.find(|v| PlayerOrBot::from(&v.player) == id)
|
.find(|v| PlayerOrBot::from(&v.player) == id)
|
||||||
{
|
.unwrap();
|
||||||
let hand_ent = commands.spawn((Hand, Closed(hand_view.hand_length))).id();
|
let hand_ent = commands.spawn((Hand, Closed(hand_view.hand_length))).id();
|
||||||
commands.spawn(Player { id }).add_child(hand_ent);
|
commands.spawn(Player { id }).add_child(hand_ent);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_player_insert_update(
|
fn on_player_insert_update(
|
||||||
|
|
@ -217,7 +203,6 @@ fn on_player_insert_update(
|
||||||
) {
|
) {
|
||||||
for msg in messages.read() {
|
for msg in messages.read() {
|
||||||
if main_player.is_none() && msg.new.identity == stdb.identity() {
|
if main_player.is_none() && msg.new.identity == stdb.identity() {
|
||||||
trace!("spawn_main_player");
|
|
||||||
spawn_main_player(&stdb, &mut commands, &mut next_turnstate, &msg.new);
|
spawn_main_player(&stdb, &mut commands, &mut next_turnstate, &msg.new);
|
||||||
} else if other_players.iter().any(|p| {
|
} else if other_players.iter().any(|p| {
|
||||||
if let PlayerOrBot::Player { id } = &p.id {
|
if let PlayerOrBot::Player { id } = &p.id {
|
||||||
|
|
@ -289,23 +274,19 @@ fn on_view_hand_update(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
tiles: Query<(Entity, &TileId)>,
|
tiles: Query<(Entity, &TileId)>,
|
||||||
|
|
||||||
main_player: Single<(Entity, Option<&Children>), With<MainPlayer>>,
|
main_player: Single<&Children, With<MainPlayer>>,
|
||||||
|
|
||||||
hand: Query<Entity, With<Hand>>,
|
hand: Query<Entity, With<Hand>>,
|
||||||
pond: Query<Entity, With<Pond>>,
|
pond: Query<Entity, With<Pond>>,
|
||||||
// drawn: Option<Single<Entity, With<Drawn>>>,
|
// drawn: Option<Single<Entity, With<Drawn>>>,
|
||||||
mut next_turnstate: ResMut<NextState<jong_types::states::TurnState>>,
|
mut next_turnstate: ResMut<NextState<jong_types::states::TurnState>>,
|
||||||
) {
|
) {
|
||||||
|
trace!("on_view_hand_update");
|
||||||
|
|
||||||
// TODO can this and similar run at startup or on play/reconnect?
|
// TODO can this and similar run at startup or on play/reconnect?
|
||||||
for msg in messages.read() {
|
for msg in messages.read() {
|
||||||
trace!("new hand: {:?}", msg.new);
|
trace!("new hand: {:?}", msg.new);
|
||||||
|
|
||||||
if main_player.1.is_none() {
|
|
||||||
trace!("spawn_main_hand, {:?}", *main_player);
|
|
||||||
spawn_main_hand(&mut commands, &mut next_turnstate, main_player.0, &msg.new);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let hand_tiles: Vec<_> = msg
|
let hand_tiles: Vec<_> = msg
|
||||||
.new
|
.new
|
||||||
.hand
|
.hand
|
||||||
|
|
@ -317,6 +298,10 @@ fn on_view_hand_update(
|
||||||
.unwrap_or_else(|| commands.spawn((Tile::from(&dbt.tile), TileId(dbt.id))).id())
|
.unwrap_or_else(|| commands.spawn((Tile::from(&dbt.tile), TileId(dbt.id))).id())
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
commands
|
||||||
|
.entity(hand.iter().find(|e| main_player.contains(e)).unwrap())
|
||||||
|
.replace_children(&hand_tiles);
|
||||||
|
|
||||||
let pond_tiles: Vec<_> = msg
|
let pond_tiles: Vec<_> = msg
|
||||||
.new
|
.new
|
||||||
.pond
|
.pond
|
||||||
|
|
@ -328,20 +313,8 @@ fn on_view_hand_update(
|
||||||
.unwrap_or_else(|| commands.spawn((Tile::from(&dbt.tile), TileId(dbt.id))).id())
|
.unwrap_or_else(|| commands.spawn((Tile::from(&dbt.tile), TileId(dbt.id))).id())
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
commands
|
commands
|
||||||
.entity(
|
.entity(pond.iter().find(|e| main_player.contains(e)).unwrap())
|
||||||
hand.iter()
|
|
||||||
.find(|e| main_player.1.is_some_and(|mp| mp.contains(e)))
|
|
||||||
.unwrap(),
|
|
||||||
)
|
|
||||||
.replace_children(&hand_tiles);
|
|
||||||
commands
|
|
||||||
.entity(
|
|
||||||
pond.iter()
|
|
||||||
.find(|e| main_player.1.is_some_and(|mp| mp.contains(e)))
|
|
||||||
.unwrap(),
|
|
||||||
)
|
|
||||||
.replace_children(&pond_tiles);
|
.replace_children(&pond_tiles);
|
||||||
|
|
||||||
match msg.new.turn_state {
|
match msg.new.turn_state {
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,7 @@ impl Plugin for TuiPlugin {
|
||||||
(render::render_main_hand, render::render_main_pond)
|
(render::render_main_hand, render::render_main_pond)
|
||||||
.run_if(in_state(GameState::Play)),
|
.run_if(in_state(GameState::Play)),
|
||||||
render::render,
|
render::render,
|
||||||
|
query_tester,
|
||||||
)
|
)
|
||||||
.chain()
|
.chain()
|
||||||
.in_set(TuiSet::Render),
|
.in_set(TuiSet::Render),
|
||||||
|
|
@ -95,6 +96,24 @@ impl Plugin for TuiPlugin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn query_tester(
|
||||||
|
main_player: Single<&Children, With<MainPlayer>>,
|
||||||
|
// hand: Query<(&Children, Entity), With<Hand>>,
|
||||||
|
) {
|
||||||
|
trace!("owo");
|
||||||
|
// let hand = hand
|
||||||
|
// .iter()
|
||||||
|
// .find_map(|(c, e)| {
|
||||||
|
// if main_player.contains(&e) {
|
||||||
|
// Some(c)
|
||||||
|
// } else {
|
||||||
|
// None
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// .unwrap();
|
||||||
|
// debug!("{hand:?}");
|
||||||
|
}
|
||||||
|
|
||||||
fn discard_tile(
|
fn discard_tile(
|
||||||
stdb: SpacetimeDB,
|
stdb: SpacetimeDB,
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -115,7 +115,6 @@ pub(crate) fn render_main_hand(
|
||||||
let hand: Vec<_> = hand
|
let hand: Vec<_> = hand
|
||||||
.iter()
|
.iter()
|
||||||
.find_map(|(c, e)| {
|
.find_map(|(c, e)| {
|
||||||
debug!("main_player children: {:?}", *main_player);
|
|
||||||
if main_player.contains(&e) {
|
if main_player.contains(&e) {
|
||||||
Some(c)
|
Some(c)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue