|
|
|
|
@ -8,8 +8,8 @@ impl Plugin for PlayPlugin {
|
|
|
|
|
fn build(&self, app: &mut App) {
|
|
|
|
|
app.add_event::<ServeCards>()
|
|
|
|
|
.add_observer(serve_cards)
|
|
|
|
|
.add_observer(fill_cards)
|
|
|
|
|
.add_systems(OnEnter(GameState::Main), deal_table)
|
|
|
|
|
.add_systems(OnEnter(GameState::Main), deal_cards)
|
|
|
|
|
.add_systems(Update, deal_cards.run_if(set_added))
|
|
|
|
|
.add_systems(Update, spin_cards);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@ -68,6 +68,7 @@ pub(crate) fn reset_rotation(
|
|
|
|
|
pub(crate) fn check_set(
|
|
|
|
|
_trigger: Trigger<Pointer<Click>>,
|
|
|
|
|
mut query: Query<(Entity, &Card, &mut Visibility, &mut Transform), With<Selected>>,
|
|
|
|
|
mut sets: Query<&SetNumber>,
|
|
|
|
|
mut commands: Commands,
|
|
|
|
|
) {
|
|
|
|
|
let mut cards = query.iter();
|
|
|
|
|
@ -83,10 +84,11 @@ pub(crate) fn check_set(
|
|
|
|
|
.for_each(|(entity, _, mut visibility, mut transform)| {
|
|
|
|
|
*visibility = Visibility::Hidden;
|
|
|
|
|
*transform = Transform::default();
|
|
|
|
|
let set_number = 1;
|
|
|
|
|
let set_number = sets.iter().len() as u8 / 3 + 1;
|
|
|
|
|
commands
|
|
|
|
|
.entity(entity)
|
|
|
|
|
.remove::<PlayLocation>()
|
|
|
|
|
.remove::<Selected>()
|
|
|
|
|
.insert(SetNumber(set_number));
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
@ -124,12 +126,16 @@ struct ServeCards;
|
|
|
|
|
/// When requested, fill in empty spots on the board with cards
|
|
|
|
|
fn serve_cards(
|
|
|
|
|
_trigger: Trigger<ServeCards>,
|
|
|
|
|
cards: Query<(Entity, &DeckOrder)>,
|
|
|
|
|
in_deck: Query<(Entity, &Card, &DeckOrder)>,
|
|
|
|
|
spots: Query<&PlayLocation>,
|
|
|
|
|
mut commands: Commands,
|
|
|
|
|
) {
|
|
|
|
|
info!("Serving cards");
|
|
|
|
|
let mut target = (cards.iter().len() - 1) as u8;
|
|
|
|
|
info!(
|
|
|
|
|
"Serving cards from deck ({} cards left)",
|
|
|
|
|
in_deck.iter().len()
|
|
|
|
|
);
|
|
|
|
|
let mut n = in_deck.iter().len().saturating_sub(1);
|
|
|
|
|
|
|
|
|
|
// Iterate over every x, y play location
|
|
|
|
|
for this_x in 0..=3 {
|
|
|
|
|
for this_y in 0..=3 {
|
|
|
|
|
@ -139,8 +145,13 @@ fn serve_cards(
|
|
|
|
|
.find(|PlayLocation { x, y }| *x == (this_x as u8) && *y == (this_y as u8))
|
|
|
|
|
.is_none()
|
|
|
|
|
{
|
|
|
|
|
if let Some((e, _)) = cards.iter().find(|(_, deck_order)| deck_order.0 == target) {
|
|
|
|
|
// Set the selected card to this play location and remove from the deck
|
|
|
|
|
// If we have more than 9 cards on the board
|
|
|
|
|
let candidate = in_deck
|
|
|
|
|
.iter()
|
|
|
|
|
.find(|(_entity, _deck_card, order)| order.0 == n as u8);
|
|
|
|
|
n = n.saturating_sub(1);
|
|
|
|
|
// If that search was fruitful, pull the card from the deck and play it
|
|
|
|
|
if let Some((e, _, _)) = candidate {
|
|
|
|
|
commands
|
|
|
|
|
.entity(e)
|
|
|
|
|
.remove::<DeckOrder>()
|
|
|
|
|
@ -148,7 +159,6 @@ fn serve_cards(
|
|
|
|
|
x: this_x,
|
|
|
|
|
y: this_y,
|
|
|
|
|
});
|
|
|
|
|
target = target - 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@ -156,15 +166,12 @@ fn serve_cards(
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Trigger dealing cards when the game starts
|
|
|
|
|
fn deal_table(mut commands: Commands) {
|
|
|
|
|
info!("Dealing table");
|
|
|
|
|
fn deal_cards(mut commands: Commands) {
|
|
|
|
|
commands.trigger(ServeCards);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Trigger serving cards when a new set is created
|
|
|
|
|
fn fill_cards(_trigger: Trigger<OnAdd, SetNumber>, mut commands: Commands) {
|
|
|
|
|
info!("Filling cards");
|
|
|
|
|
commands.trigger(ServeCards);
|
|
|
|
|
fn set_added(query: Query<Entity, Added<SetNumber>>) -> bool {
|
|
|
|
|
!query.is_empty()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// When a card is added to the board, place it on the screen
|
|
|
|
|
@ -213,7 +220,7 @@ pub(crate) fn check_for_sets(
|
|
|
|
|
_ => panic!("WTF?"),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
_ => panic!("Impossible!"),
|
|
|
|
|
_ => false,
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
// return the first valid set
|
|
|
|
|
|