discard out of hand, many new bugs

This commit is contained in:
Tao Tien 2026-02-15 08:45:42 -08:00
parent f71e32b0b9
commit 4a833da757
3 changed files with 111 additions and 126 deletions

View file

@ -31,13 +31,6 @@ pub mod player;
pub mod round;
pub mod wall;
#[derive(Message)]
pub enum GameMessage {
Discarded(Entity),
CallPending,
Called { player: Entity, calltype: Entity },
}
pub struct Riichi;
impl Plugin for Riichi {
fn build(&self, app: &mut App) {
@ -66,7 +59,6 @@ impl Plugin for Riichi {
.add_sub_state::<TurnState>()
// .init_resource::<round::MatchSettings>()
// .init_resource::<round::Compass>()
.add_message::<GameMessage>()
// .add_systems(Startup, tile::init_tiles)
// .add_systems(Update, hand::sort_hands.run_if(in_state(GameState::Play)))
// .add_systems(OnEnter(TurnState::Tsumo), round::tsumo)
@ -91,6 +83,9 @@ impl Plugin for Riichi {
fn on_connect(stdb: SpacetimeDB, mut messages: ReadStdbConnectedMessage, mut commands: Commands) {
for msg in messages.read() {
info!("you're now jongline");
while stdb.try_identity().is_none() {}
debug!("with identity: {}", stdb.identity());
creds_store()
.save(&msg.access_token)

View file

@ -6,7 +6,7 @@ use strum::{EnumCount, FromRepr};
use crate::{
EnumNextCycle,
game::{
GameMessage, GameState,
GameState,
hand::{Discarded, Drawn, Hand, Pond},
player::{CurrentPlayer, Player},
wall::Wall,
@ -111,85 +111,85 @@ impl EnumNextCycle for TurnState {
}
}
pub(crate) fn tsumo(
mut commands: Commands,
// pub(crate) fn tsumo(
// mut commands: Commands,
// curr_player: Res<CurrentPlayer>,
curr_player: Single<Entity, With<CurrentPlayer>>,
wall: Single<Entity, With<Wall>>,
walltiles: Single<&Children, With<Wall>>,
// // curr_player: Res<CurrentPlayer>,
// curr_player: Single<Entity, With<CurrentPlayer>>,
// wall: Single<Entity, With<Wall>>,
// walltiles: Single<&Children, With<Wall>>,
curr_turnstate: Res<State<TurnState>>,
mut next_turnstate: ResMut<NextState<TurnState>>,
) {
let drawn = walltiles.last().unwrap();
commands.entity(*wall).remove_child(*drawn);
// curr_turnstate: Res<State<TurnState>>,
// mut next_turnstate: ResMut<NextState<TurnState>>,
// ) {
// let drawn = walltiles.last().unwrap();
// commands.entity(*wall).remove_child(*drawn);
let drawn = commands.entity(*drawn).insert(Drawn).id();
commands.entity(*curr_player).add_child(drawn);
// let drawn = commands.entity(*drawn).insert(Drawn).id();
// commands.entity(*curr_player).add_child(drawn);
debug!("tsumo for: {:?}, tile: {:?}", *curr_player, drawn);
next_turnstate.set(curr_turnstate.next());
}
// debug!("tsumo for: {:?}, tile: {:?}", *curr_player, drawn);
// next_turnstate.set(curr_turnstate.next());
// }
pub(crate) fn menzen(
curr_turnstate: Res<State<TurnState>>,
mut next_turnstate: ResMut<NextState<TurnState>>,
) {
trace!("menzen check");
next_turnstate.set(curr_turnstate.next());
}
// pub(crate) fn menzen(
// curr_turnstate: Res<State<TurnState>>,
// mut next_turnstate: ResMut<NextState<TurnState>>,
// ) {
// trace!("menzen check");
// next_turnstate.set(curr_turnstate.next());
// }
pub(crate) fn riichi_kan(
curr_turnstate: Res<State<TurnState>>,
mut next_turnstate: ResMut<NextState<TurnState>>,
) {
trace!("riichi_kan");
next_turnstate.set(curr_turnstate.next());
}
// pub(crate) fn riichi_kan(
// curr_turnstate: Res<State<TurnState>>,
// mut next_turnstate: ResMut<NextState<TurnState>>,
// ) {
// trace!("riichi_kan");
// next_turnstate.set(curr_turnstate.next());
// }
#[allow(clippy::too_many_arguments, irrefutable_let_patterns)]
pub(crate) fn discard(
mut commands: Commands,
mut reader: MessageReader<GameMessage>,
// #[allow(clippy::too_many_arguments, irrefutable_let_patterns)]
// pub(crate) fn discard(
// mut commands: Commands,
// mut reader: MessageReader<GameMessage>,
curr_player: Single<Entity, With<CurrentPlayer>>,
players: Query<&Children, With<Player>>,
mut hands: Query<(&Children, Entity), (With<Hand>, Without<Player>)>,
drawn: Single<Entity, With<Drawn>>,
// curr_player: Single<Entity, With<CurrentPlayer>>,
// players: Query<&Children, With<Player>>,
// mut hands: Query<(&Children, Entity), (With<Hand>, Without<Player>)>,
// drawn: Single<Entity, With<Drawn>>,
curr_turnstate: Res<State<TurnState>>,
mut next_turnstate: ResMut<NextState<TurnState>>,
) -> Result {
// trace!("discard");
let (handtiles, hand) = hands.get_mut(players.get(*curr_player)?.iter().next().unwrap())?;
// curr_turnstate: Res<State<TurnState>>,
// mut next_turnstate: ResMut<NextState<TurnState>>,
// ) -> Result {
// // trace!("discard");
// let (handtiles, hand) = hands.get_mut(players.get(*curr_player)?.iter().next().unwrap())?;
let mut done = false;
while let Some(message) = reader.read().next() {
if let GameMessage::Discarded(discarded) = message {
debug!("discarded: {discarded:?}");
if *discarded == *drawn {
} else if handtiles.contains(discarded) {
commands
.entity(hand)
.remove_child(*discarded)
.add_child(*drawn);
} else {
panic!("current hand nor drawn tile contains discarded tile")
}
commands.entity(*drawn).remove::<Drawn>();
commands.entity(*discarded).insert(Discarded);
// let mut done = false;
// while let Some(message) = reader.read().next() {
// if let GameMessage::Discarded(discarded) = message {
// debug!("discarded: {discarded:?}");
// if *discarded == *drawn {
// } else if handtiles.contains(discarded) {
// commands
// .entity(hand)
// .remove_child(*discarded)
// .add_child(*drawn);
// } else {
// panic!("current hand nor drawn tile contains discarded tile")
// }
// commands.entity(*drawn).remove::<Drawn>();
// commands.entity(*discarded).insert(Discarded);
done = true;
break;
}
}
// done = true;
// break;
// }
// }
if done {
next_turnstate.set(curr_turnstate.next());
}
Ok(())
}
// if done {
// next_turnstate.set(curr_turnstate.next());
// }
// Ok(())
// }
#[derive(Resource)]
pub struct PendingCalls {
@ -197,45 +197,45 @@ pub struct PendingCalls {
calls: HashMap<Entity, CallType>,
}
pub(crate) fn notify_callable() {}
// pub(crate) fn notify_callable() {}
pub(crate) fn ron_chi_pon_kan(
mut commands: Commands,
mut reader: MessageReader<GameMessage>,
// pub(crate) fn ron_chi_pon_kan(
// mut commands: Commands,
// mut reader: MessageReader<GameMessage>,
discarded: Single<Entity, With<Discarded>>,
mut ponds: Query<(&Children, Entity), (With<Pond>, Without<Player>)>,
calls: Query<&CallType>,
// discarded: Single<Entity, With<Discarded>>,
// mut ponds: Query<(&Children, Entity), (With<Pond>, Without<Player>)>,
// calls: Query<&CallType>,
curr_turnstate: Res<State<TurnState>>,
mut next_turnstate: ResMut<NextState<TurnState>>,
) {
// check if can call?
// message players?
// collect then prioritize
// curr_turnstate: Res<State<TurnState>>,
// mut next_turnstate: ResMut<NextState<TurnState>>,
// ) {
// // check if can call?
// // message players?
// // collect then prioritize
// let mut received = vec![];
let mut received: Vec<_> = reader
.read()
.filter_map(|m| {
if let GameMessage::Called { player, calltype } = m
&& let Ok(calltype) = calls.get(*calltype)
{
Some((calltype, player))
} else {
None
}
})
.collect();
// received.sort_unstable_by_key(|(c, t)| c);
// received.sort_unstable_by_key(|m| m.);
// // let mut received = vec![];
// let mut received: Vec<_> = reader
// .read()
// .filter_map(|m| {
// if let GameMessage::Called { player, calltype } = m
// && let Ok(calltype) = calls.get(*calltype)
// {
// Some((calltype, player))
// } else {
// None
// }
// })
// .collect();
// // received.sort_unstable_by_key(|(c, t)| c);
// // received.sort_unstable_by_key(|m| m.);
next_turnstate.set(curr_turnstate.next());
}
// next_turnstate.set(curr_turnstate.next());
// }
pub(crate) fn end(
curr_turnstate: Res<State<TurnState>>,
mut next_turnstate: ResMut<NextState<TurnState>>,
) {
next_turnstate.set(curr_turnstate.next());
}
// pub(crate) fn end(
// curr_turnstate: Res<State<TurnState>>,
// mut next_turnstate: ResMut<NextState<TurnState>>,
// ) {
// next_turnstate.set(curr_turnstate.next());
// }

View file

@ -13,7 +13,6 @@ use jong::stdb::{self, discard_tile as _};
use jong::{
SpacetimeDB,
game::{
GameMessage,
hand::{Drawn, Hand},
player::{CurrentPlayer, Player},
},
@ -106,7 +105,6 @@ impl Plugin for TuiPlugin {
fn discard_tile(
stdb: SpacetimeDB,
mut writer: MessageWriter<GameMessage>,
mut selected: MessageReader<ConfirmSelect>,
mut commands: Commands,
@ -115,8 +113,8 @@ fn discard_tile(
// player_hands: Populated<(&Player, &Children), With<Hand>>,
// hands: Populated<&Children, (With<Hand>, Without<Player>)>,
main_player: Single<(&Player, Entity), With<MainPlayer>>,
hands: Query<(&mut Children, Entity), With<Hand> >,
tiles: Populated<&TileId>,
hands: Query<(&Children, Entity), With<Hand>>,
tiles: Query<&TileId>,
) {
// trace!("discard_tile");
@ -125,17 +123,9 @@ fn discard_tile(
while let Some(message) = selected.read().next()
// && (message.0 == drawn.0 || hand.contains(&message.0))
{
if message.0 == drawn.0 {
stdb.reducers().discard_tile(drawn.1.0).unwrap();
// commands.get_entity(drawn.0).unwrap().remove_parent_in_place();
if let Ok(tile_id) = tiles.get(message.0) {
stdb.reducers().discard_tile(tile_id.0).unwrap();
commands.get_entity(drawn.0).unwrap().despawn();
} else if let Some(tile_ent) = hand.iter().find(|t| *t == message.0) {
stdb.reducers()
.discard_tile(tiles.get(tile_ent).unwrap().0)
.unwrap();
}
// FIXME check if discard actually in hand?
writer.write(GameMessage::Discarded(message.0));
}
}
}