2026-01-08 20:49:19 -08:00
|
|
|
use bevy::prelude::*;
|
2026-01-13 12:38:41 -08:00
|
|
|
use strum::{EnumCount, FromRepr};
|
2026-01-08 20:49:19 -08:00
|
|
|
|
2026-01-12 21:57:08 -08:00
|
|
|
use crate::{
|
2026-01-13 12:38:41 -08:00
|
|
|
EnumNextCycle,
|
2026-01-13 00:01:38 -08:00
|
|
|
game::{
|
2026-01-13 12:38:41 -08:00
|
|
|
hand::{Drawn, Hand},
|
2026-01-13 00:01:38 -08:00
|
|
|
player::{MainPlayer, Player},
|
2026-01-13 12:38:41 -08:00
|
|
|
round::{CurrentPlayer, TurnState, Wind},
|
2026-01-13 00:01:38 -08:00
|
|
|
wall::Wall,
|
|
|
|
|
},
|
2026-01-13 03:32:08 -08:00
|
|
|
tile::{self, *},
|
2026-01-12 21:57:08 -08:00
|
|
|
};
|
2026-01-08 20:49:19 -08:00
|
|
|
|
2026-01-12 01:54:59 -08:00
|
|
|
pub mod hand;
|
2026-01-11 20:10:30 -08:00
|
|
|
pub mod player;
|
2026-01-13 00:01:38 -08:00
|
|
|
pub mod round;
|
2026-01-09 06:54:17 -08:00
|
|
|
pub mod wall;
|
2026-01-08 23:58:26 -08:00
|
|
|
|
2026-01-11 23:41:27 -08:00
|
|
|
#[derive(States, Default, Hash, Clone, Eq, Debug, PartialEq, Copy)]
|
2026-01-11 20:10:30 -08:00
|
|
|
pub enum GameState {
|
|
|
|
|
#[default]
|
2026-01-12 01:08:27 -08:00
|
|
|
None,
|
2026-01-11 20:10:30 -08:00
|
|
|
Setup,
|
2026-01-13 00:01:38 -08:00
|
|
|
Deal,
|
2026-01-11 20:10:30 -08:00
|
|
|
Play,
|
|
|
|
|
}
|
2026-01-08 20:49:19 -08:00
|
|
|
|
2026-01-11 20:10:30 -08:00
|
|
|
pub struct Riichi;
|
2026-01-08 20:49:19 -08:00
|
|
|
impl Plugin for Riichi {
|
|
|
|
|
fn build(&self, app: &mut App) {
|
2026-01-13 00:01:38 -08:00
|
|
|
app
|
|
|
|
|
// start stopper
|
2026-01-11 20:10:30 -08:00
|
|
|
.init_state::<GameState>()
|
2026-01-13 12:38:41 -08:00
|
|
|
.add_sub_state::<TurnState>()
|
2026-01-13 00:01:38 -08:00
|
|
|
.init_resource::<round::MatchSettings>()
|
|
|
|
|
.init_resource::<round::Compass>()
|
2026-01-13 03:32:08 -08:00
|
|
|
.add_systems(Startup, tile::init_tiles)
|
2026-01-13 00:01:38 -08:00
|
|
|
.add_systems(OnEnter(GameState::Setup), setup)
|
2026-01-13 12:38:41 -08:00
|
|
|
.add_systems(OnEnter(GameState::Deal), hand::shuffle_deal)
|
2026-01-13 00:01:38 -08:00
|
|
|
.add_systems(Update, hand::sort_hands.run_if(in_state(GameState::Play)))
|
2026-01-13 12:38:41 -08:00
|
|
|
// .add_systems(Update, turn_manager.run_if(in_state(GameState::Play)))
|
|
|
|
|
.add_systems(OnEnter(TurnState::Tsumo), tsumo)
|
2026-01-09 06:54:17 -08:00
|
|
|
// semicolon stopper
|
|
|
|
|
;
|
2026-01-08 20:49:19 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-13 12:38:41 -08:00
|
|
|
// struct TurnEvent {
|
|
|
|
|
// pub next: Option<Entity>,
|
|
|
|
|
// pub prev: Option<Entity>,
|
|
|
|
|
// }
|
2026-01-08 20:49:19 -08:00
|
|
|
|
2026-01-13 12:38:41 -08:00
|
|
|
// fn turn_manager() {}
|
2026-01-13 01:08:14 -08:00
|
|
|
|
2026-01-13 12:38:41 -08:00
|
|
|
fn tsumo(
|
|
|
|
|
mut commands: Commands,
|
|
|
|
|
curr_player: Res<CurrentPlayer>,
|
|
|
|
|
// players: Populated<Entity, With<Player>>,
|
|
|
|
|
wall_ent: Single<Entity, With<Wall>>,
|
|
|
|
|
walltiles: Single<&Children, With<Wall>>,
|
|
|
|
|
curr_turnstate: Res<State<TurnState>>,
|
|
|
|
|
mut next_turnstate: ResMut<NextState<TurnState>>,
|
|
|
|
|
) {
|
|
|
|
|
trace!("tsumo for: {:?}", curr_player.0);
|
2026-01-13 01:08:14 -08:00
|
|
|
|
2026-01-13 12:38:41 -08:00
|
|
|
let drawn = walltiles.last().unwrap();
|
|
|
|
|
commands.entity(*wall_ent).remove_child(*drawn);
|
|
|
|
|
commands.entity(curr_player.0).insert(Drawn(*drawn));
|
2026-01-08 20:49:19 -08:00
|
|
|
|
2026-01-13 12:38:41 -08:00
|
|
|
debug!("wall: {:?}", *walltiles);
|
2026-01-13 01:08:14 -08:00
|
|
|
|
2026-01-13 12:38:41 -08:00
|
|
|
next_turnstate.set(curr_turnstate.next());
|
2026-01-08 20:49:19 -08:00
|
|
|
}
|
|
|
|
|
|
2026-01-13 00:01:38 -08:00
|
|
|
pub(crate) fn setup(
|
2026-01-08 20:49:19 -08:00
|
|
|
mut commands: Commands,
|
2026-01-13 00:01:38 -08:00
|
|
|
matchsettings: Res<round::MatchSettings>,
|
2026-01-08 23:58:26 -08:00
|
|
|
// mut compass: ResMut<Compass>
|
2026-01-13 00:01:38 -08:00
|
|
|
tiles: Query<Entity, With<Tile>>,
|
|
|
|
|
mut next_gamestate: ResMut<NextState<GameState>>,
|
2026-01-08 20:49:19 -08:00
|
|
|
) {
|
2026-01-13 00:01:38 -08:00
|
|
|
for i in 1..=matchsettings.player_count {
|
|
|
|
|
let player = player::Player {
|
|
|
|
|
name: format!("Player {}", i),
|
|
|
|
|
};
|
|
|
|
|
let points = player::Points(matchsettings.starting_points);
|
|
|
|
|
|
2026-01-13 12:38:41 -08:00
|
|
|
let bundle = (
|
|
|
|
|
player,
|
|
|
|
|
points,
|
|
|
|
|
Hand,
|
|
|
|
|
Wind::from_repr((i - 1) as usize).unwrap(),
|
|
|
|
|
);
|
2026-01-08 20:49:19 -08:00
|
|
|
|
2026-01-13 00:01:38 -08:00
|
|
|
if i == 1 {
|
2026-01-13 12:38:41 -08:00
|
|
|
let player = commands.spawn((bundle, MainPlayer)).id();
|
|
|
|
|
commands.insert_resource(CurrentPlayer(player));
|
2026-01-13 00:01:38 -08:00
|
|
|
} else {
|
|
|
|
|
commands.spawn(bundle);
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-01-08 20:49:19 -08:00
|
|
|
|
2026-01-13 00:01:38 -08:00
|
|
|
commands.spawn(Wall);
|
2026-01-08 20:49:19 -08:00
|
|
|
|
2026-01-13 00:01:38 -08:00
|
|
|
next_gamestate.set(GameState::Deal);
|
2026-01-08 20:49:19 -08:00
|
|
|
}
|