some stuff

This commit is contained in:
Tao Tien 2026-03-02 22:43:49 -08:00
parent 0713d6869b
commit 0c3fe6f87a
3 changed files with 113 additions and 166 deletions

View file

@ -46,25 +46,20 @@ impl Plugin for Riichi {
app.add_plugins(plugins) app.add_plugins(plugins)
.init_state::<jong_types::states::GameState>() .init_state::<jong_types::states::GameState>()
.add_sub_state::<jong_types::states::TurnState>() .add_sub_state::<jong_types::states::TurnState>()
.add_message::<SyncPlayer>() .init_resource::<Lobby>()
.add_message::<SyncOpenHand>()
.add_message::<SyncBot>()
.add_systems(Startup, subscriptions) .add_systems(Startup, subscriptions)
.add_systems(Update, (connection::on_connect, connection::on_disconnect)) .add_systems(Update, (connection::on_connect, connection::on_disconnect))
.add_systems( .add_systems(
Update, Update,
( (
( on_lobby_insert_update,
on_lobby_insert_update, on_player_insert_update,
on_player_insert_update, on_bot_insert_update,
on_bot_insert_update,
),
(sync_player, sync_bot),
), ),
) )
.add_systems( .add_systems(
Update, Update,
((on_view_hand_insert, on_view_hand_update), (sync_open_hand)) (on_view_hand_insert, on_view_hand_update)
.run_if(in_state(GameState::Play).or(in_state(GameState::Deal))), .run_if(in_state(GameState::Play).or(in_state(GameState::Deal))),
); );
} }
@ -115,135 +110,6 @@ fn subscriptions(stdb: SpacetimeDB, mut commands: Commands) {
} }
} }
#[derive(Message)]
struct SyncPlayer(u32);
#[derive(Message)]
struct SyncBot(u32);
#[derive(Message)]
struct SyncOpenHand(u32);
#[derive(Message)]
struct SyncClosedHand(PlayerOrBot);
#[derive(Message)]
struct SyncPlayerClock(u32);
fn sync_player(
stdb: SpacetimeDB,
mut messages: MessageReader<SyncPlayer>,
mut commands: Commands,
players: Query<(Entity, &Player)>,
) {
for SyncPlayer(id) in messages.read() {
trace!("sync_player");
let Some(player) = stdb.db().player().id().find(id) else {
todo!()
};
let player_ent = players
.iter()
.find_map(|(e, p)| (p.id == PlayerOrBot::Player { id: player.id }).then_some(e))
.unwrap_or_else(|| {
commands
.spawn(Player {
id: PlayerOrBot::Player { id: player.id },
})
.id()
});
if player.identity == stdb.identity() {
commands.entity(player_ent).insert(MainPlayer);
} else {
}
}
}
fn sync_bot(
stdb: SpacetimeDB,
mut messages: MessageReader<SyncBot>,
mut commands: Commands,
players: Query<(Entity, &Player)>,
) {
}
fn sync_open_hand(
stdb: SpacetimeDB,
mut messages: MessageReader<SyncOpenHand>,
mut commands: Commands,
tiles: Query<(Entity, &TileId)>,
hands: Query<(Entity, &Hand)>,
ponds: Query<(Entity, &Pond)>,
mut next_turnstate: ResMut<NextState<TurnState>>,
) {
for SyncOpenHand(id) in messages.read() {
trace!("sync_open_hand");
let Some(player_hand) = stdb.db().view_hand().iter().find(|hand| hand.id == *id) else {
todo!()
};
let hand_ent = hands
.iter()
.find_map(|(e, h)| (h.owner == PlayerOrBot::Player { id: *id }).then_some(e))
.unwrap_or_else(|| {
commands
.spawn(Hand {
owner: PlayerOrBot::Player { id: *id },
})
.id()
});
let pond_ent = ponds
.iter()
.find_map(|(e, p)| (p.owner == PlayerOrBot::Player { id: *id }).then_some(e))
.unwrap_or_else(|| {
commands
.spawn(Pond {
owner: PlayerOrBot::Player { id: *id },
})
.id()
});
// hand and pond both still need ability to spawn for the reconnect case
let hand: Vec<Entity> = player_hand
.hand
.iter()
.map(|dbt| {
tiles
.iter()
.find_map(|(e, i)| (i.0 == dbt.id).then_some(e))
.unwrap_or_else(|| commands.spawn((Tile::from(&dbt.tile), TileId(dbt.id))).id())
})
.collect();
let pond: Vec<Entity> = player_hand
.pond
.iter()
.map(|dbt| {
tiles
.iter()
.find_map(|(e, i)| (i.0 == dbt.id).then_some(e))
.unwrap_or_else(|| commands.spawn((Tile::from(&dbt.tile), TileId(dbt.id))).id())
})
.collect();
commands.entity(hand_ent).replace_children(&hand);
commands.entity(pond_ent).replace_children(&pond);
if let Some(dbt) = player_hand.working_tile
&& player_hand.turn_state == jong_db::TurnState::Tsumo
{
commands.spawn((Drawn, Tile::from(&dbt.tile), TileId(dbt.id)));
}
next_turnstate.set(player_hand.turn_state.into());
}
}
fn sync_closed_hand( fn sync_closed_hand(
stdb: SpacetimeDB, stdb: SpacetimeDB,
@ -298,28 +164,42 @@ fn sync_closed_hand(
fn sync_player_clock() {} fn sync_player_clock() {}
fn on_player_insert_update( fn on_player_insert_update(
mut db_messages: ReadInsertUpdateMessage<jong_db::Player>, stdb: SpacetimeDB,
mut messages: ReadInsertUpdateMessage<jong_db::Player>,
mut writer: MessageWriter<SyncPlayer>, mut commands: Commands,
players: Query<(Entity, &Player)>,
) { ) {
for msg in db_messages.read() { for msg in messages.read() {
trace!("on_player_insert_update"); trace!("on_player_insert_update");
writer.write(SyncPlayer(msg.new.id)); let player = &msg.new;
let player_ent = players
.iter()
.find_map(|(e, p)| (p.id == PlayerOrBot::Player { id: player.id }).then_some(e))
.unwrap_or_else(|| {
commands
.spawn(Player {
id: PlayerOrBot::Player { id: msg.new.id },
})
.id()
});
if player.identity == stdb.identity() {
commands.entity(player_ent).insert(MainPlayer);
} else {
}
} }
} }
fn on_bot_insert_update( fn on_bot_insert_update(stdb: SpacetimeDB, mut messages: ReadInsertUpdateMessage<jong_db::Bot>) {
mut db_messages: ReadInsertUpdateMessage<jong_db::Bot>, for msg in messages.read() {}
mut writer: MessageWriter<SyncBot>,
) {
for msg in db_messages.read() {
writer.write(SyncBot(msg.new.id));
}
} }
#[derive(Resource)] #[derive(Resource, Default)]
struct Lobby { pub struct Lobby {
players: Vec<PlayerOrBot>, pub players: Vec<PlayerOrBot>,
} }
fn on_lobby_insert_update( fn on_lobby_insert_update(
@ -327,6 +207,10 @@ fn on_lobby_insert_update(
mut messages: ReadInsertUpdateMessage<jong_db::Lobby>, mut messages: ReadInsertUpdateMessage<jong_db::Lobby>,
mut commands: Commands, mut commands: Commands,
mut lobby: ResMut<Lobby>,
players: Query<(Entity, &Player)>,
mut next_gamestate: ResMut<NextState<jong_types::states::GameState>>, mut next_gamestate: ResMut<NextState<jong_types::states::GameState>>,
) { ) {
for msg in messages.read() { for msg in messages.read() {
@ -367,26 +251,85 @@ fn on_lobby_insert_update(
} }
} }
lobby.players = msg.new.players.iter().map(|p| p.into()).collect();
next_gamestate.set(msg.new.game_state.into()); next_gamestate.set(msg.new.game_state.into());
} }
} }
fn on_view_hand_insert( fn on_view_hand_insert(mut messages: ReadInsertMessage<jong_db::PlayerHand>) {
mut messages: ReadInsertMessage<jong_db::PlayerHand>,
mut writer: MessageWriter<SyncOpenHand>,
) {
for msg in messages.read() { for msg in messages.read() {
trace!("on_view_hand_insert"); trace!("on_view_hand_insert");
writer.write(SyncOpenHand(msg.row.id));
} }
} }
fn on_view_hand_update( fn on_view_hand_update(mut messages: ReadUpdateMessage<jong_db::PlayerHand>) {
mut messages: ReadUpdateMessage<jong_db::PlayerHand>,
mut writer: MessageWriter<SyncOpenHand>,
) {
for msg in messages.read() { for msg in messages.read() {
trace!("on_view_hand_update"); trace!("on_view_hand_update");
writer.write(SyncOpenHand(msg.new.player_id));
} }
} }
fn sync_open_hand(
commands: Commands,
tiles: Query<(Entity, &TileId)>,
hands: Query<(Entity, &Hand)>,
ponds: Query<(Entity, &Pond)>,
next_turnstate: &mut ResMut<NextState<TurnState>>,
player_hand: PlayerHand,
) {
let hand_ent = hands
.iter()
.find_map(|(e, h)| (h.owner == player_hand.player_id).then_some(e))
.unwrap_or_else(|| {
commands
.spawn(Hand {
owner: PlayerOrBot::Player { id: *id },
})
.id()
});
let pond_ent = ponds
.iter()
.find_map(|(e, p)| (p.owner == PlayerOrBot::Player { id: *id }).then_some(e))
.unwrap_or_else(|| {
commands
.spawn(Pond {
owner: PlayerOrBot::Player { id: *id },
})
.id()
});
// hand and pond both still need ability to spawn for the reconnect case
let hand: Vec<Entity> = player_hand
.hand
.iter()
.map(|dbt| {
tiles
.iter()
.find_map(|(e, i)| (i.0 == dbt.id).then_some(e))
.unwrap_or_else(|| commands.spawn((Tile::from(&dbt.tile), TileId(dbt.id))).id())
})
.collect();
let pond: Vec<Entity> = player_hand
.pond
.iter()
.map(|dbt| {
tiles
.iter()
.find_map(|(e, i)| (i.0 == dbt.id).then_some(e))
.unwrap_or_else(|| commands.spawn((Tile::from(&dbt.tile), TileId(dbt.id))).id())
})
.collect();
commands.entity(hand_ent).replace_children(&hand);
commands.entity(pond_ent).replace_children(&pond);
if let Some(dbt) = player_hand.working_tile
&& player_hand.turn_state == jong_db::TurnState::Tsumo
{
commands.spawn((Drawn, Tile::from(&dbt.tile), TileId(dbt.id)));
}
next_turnstate.set(player_hand.turn_state.into());
}

View file

@ -8,9 +8,6 @@ pub(crate) fn on_connect(stdb: SpacetimeDB, mut messages: ReadStdbConnectedMessa
for msg in messages.read() { for msg in messages.read() {
info!("you're now jongline"); info!("you're now jongline");
// FIXME hack that doesn't work for startup crash?
while stdb.try_identity().is_none() {}
debug!("with identity: {}", stdb.identity()); debug!("with identity: {}", stdb.identity());
creds_store() creds_store()
.save(&msg.access_token) .save(&msg.access_token)

View file

@ -13,6 +13,13 @@ pub struct MainPlayer;
#[derive(Component)] #[derive(Component)]
pub struct CurrentPlayer; pub struct CurrentPlayer;
#[derive(Component)]
pub struct TopLord;
#[derive(Component)]
pub struct RightLord;
#[derive(Component)]
pub struct LeftLord;
#[derive(Component, PartialEq, Eq, Debug)] #[derive(Component, PartialEq, Eq, Debug)]
pub struct TileId(pub u32); pub struct TileId(pub u32);