|
|
|
|
@ -12,7 +12,7 @@ pub struct PlayPlugin;
|
|
|
|
|
impl Plugin for PlayPlugin {
|
|
|
|
|
fn build(&self, app: &mut App) {
|
|
|
|
|
app.add_event::<ServeCards>()
|
|
|
|
|
.add_observer(serve_cards)
|
|
|
|
|
.add_systems(Update, serve_cards)
|
|
|
|
|
.add_systems(OnEnter(ViewState::Play), deal_cards)
|
|
|
|
|
.add_systems(Update, deal_cards.run_if(set_added))
|
|
|
|
|
.add_systems(Update, delayed_animation);
|
|
|
|
|
@ -28,7 +28,7 @@ pub(crate) struct Selected;
|
|
|
|
|
pub(crate) struct DeckOrder(pub u8);
|
|
|
|
|
|
|
|
|
|
/// Where on the board/table/play-space a card is
|
|
|
|
|
#[derive(Component)]
|
|
|
|
|
#[derive(Component, Debug)]
|
|
|
|
|
pub(crate) struct PlayLocation {
|
|
|
|
|
pub x: u8,
|
|
|
|
|
pub y: u8,
|
|
|
|
|
@ -54,7 +54,7 @@ pub(crate) fn toggle_selected(
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub(crate) fn play_selected_animation(
|
|
|
|
|
trigger: Trigger<OnAdd, Selected>,
|
|
|
|
|
trigger: Trigger<OnInsert, Selected>,
|
|
|
|
|
mut query: Query<&mut AnimationPlayer>,
|
|
|
|
|
store: Res<AnimationStore>,
|
|
|
|
|
mut commands: Commands,
|
|
|
|
|
@ -196,66 +196,67 @@ struct ServeCards;
|
|
|
|
|
|
|
|
|
|
/// When requested, fill in empty spots on the board with cards
|
|
|
|
|
fn serve_cards(
|
|
|
|
|
_trigger: Trigger<ServeCards>,
|
|
|
|
|
mut events: EventReader<ServeCards>,
|
|
|
|
|
in_deck: Query<(Entity, &Card, &DeckOrder)>,
|
|
|
|
|
spots: Query<&PlayLocation>,
|
|
|
|
|
mut top_card: Single<&mut Visibility, With<TopCard>>,
|
|
|
|
|
mut commands: Commands,
|
|
|
|
|
) {
|
|
|
|
|
info!(
|
|
|
|
|
"Serving cards from deck ({} cards left)",
|
|
|
|
|
in_deck.iter().len()
|
|
|
|
|
);
|
|
|
|
|
if in_deck.is_empty() {
|
|
|
|
|
commands.trigger(UiMessage("Deck's empty!".into()));
|
|
|
|
|
top_card.toggle_visible_hidden();
|
|
|
|
|
top_card.toggle_inherited_hidden();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
events.read().for_each(|_| {
|
|
|
|
|
info!(
|
|
|
|
|
"Serving cards from deck ({} cards left)",
|
|
|
|
|
in_deck.iter().len()
|
|
|
|
|
);
|
|
|
|
|
if in_deck.is_empty() {
|
|
|
|
|
commands.trigger(UiMessage("Deck's empty!".into()));
|
|
|
|
|
**top_card = Visibility::Hidden;
|
|
|
|
|
return;
|
|
|
|
|
} else {
|
|
|
|
|
**top_card = Visibility::Inherited;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let mut n = in_deck.iter().len().saturating_sub(1);
|
|
|
|
|
if n == 0 {
|
|
|
|
|
top_card.toggle_visible_hidden();
|
|
|
|
|
top_card.toggle_inherited_hidden();
|
|
|
|
|
}
|
|
|
|
|
let mut n = in_deck.iter().len().saturating_sub(1);
|
|
|
|
|
if n == 0 {
|
|
|
|
|
**top_card = Visibility::Hidden;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Iterate over every x, y play location
|
|
|
|
|
for this_x in 0..=3 {
|
|
|
|
|
for this_y in 0..=3 {
|
|
|
|
|
// If this spot does not have a card
|
|
|
|
|
if spots
|
|
|
|
|
.iter()
|
|
|
|
|
.find(|PlayLocation { x, y }| *x == (this_x as u8) && *y == (this_y as u8))
|
|
|
|
|
.is_none()
|
|
|
|
|
{
|
|
|
|
|
// If we have more than 9 cards on the board
|
|
|
|
|
let candidate = in_deck
|
|
|
|
|
// Iterate over every x, y play location
|
|
|
|
|
for this_x in 0..=3 {
|
|
|
|
|
for this_y in 0..=3 {
|
|
|
|
|
// If this spot does not have a card
|
|
|
|
|
if spots
|
|
|
|
|
.iter()
|
|
|
|
|
.find(|(_entity, _deck_card, order)| order.0 == n as u8);
|
|
|
|
|
n = n.saturating_sub(1);
|
|
|
|
|
if n == 0 {
|
|
|
|
|
top_card.toggle_visible_hidden();
|
|
|
|
|
top_card.toggle_inherited_hidden();
|
|
|
|
|
}
|
|
|
|
|
.find(|PlayLocation { x, y }| *x == (this_x as u8) && *y == (this_y as u8))
|
|
|
|
|
.is_none()
|
|
|
|
|
{
|
|
|
|
|
// 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 n == 0 {
|
|
|
|
|
**top_card = Visibility::Hidden;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If that search was fruitful, pull the card from the deck and play it
|
|
|
|
|
if let Some((e, _, _)) = candidate {
|
|
|
|
|
commands
|
|
|
|
|
.entity(e)
|
|
|
|
|
.remove::<DeckOrder>()
|
|
|
|
|
.insert(PlayLocation {
|
|
|
|
|
x: this_x,
|
|
|
|
|
y: this_y,
|
|
|
|
|
});
|
|
|
|
|
// If that search was fruitful, pull the card from the deck and play it
|
|
|
|
|
if let Some((e, _, _)) = candidate {
|
|
|
|
|
commands
|
|
|
|
|
.entity(e)
|
|
|
|
|
.remove::<DeckOrder>()
|
|
|
|
|
.insert(PlayLocation {
|
|
|
|
|
x: this_x,
|
|
|
|
|
y: this_y,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Trigger dealing cards when the game starts
|
|
|
|
|
fn deal_cards(mut commands: Commands) {
|
|
|
|
|
commands.trigger(ServeCards);
|
|
|
|
|
fn deal_cards(mut events: EventWriter<ServeCards>) {
|
|
|
|
|
events.send(ServeCards);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn set_added(query: Query<Entity, Added<SetNumber>>) -> bool {
|
|
|
|
|
@ -263,7 +264,7 @@ fn set_added(query: Query<Entity, Added<SetNumber>>) -> bool {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Component)]
|
|
|
|
|
struct DelayedAnimation {
|
|
|
|
|
pub(crate) struct DelayedAnimation {
|
|
|
|
|
graph: AnimationGraphHandle,
|
|
|
|
|
animation_index: AnimationNodeIndex,
|
|
|
|
|
delay: Timer,
|
|
|
|
|
@ -274,7 +275,7 @@ pub(crate) struct AnimationComplete;
|
|
|
|
|
|
|
|
|
|
/// When a card is added to the board, place it on the screen
|
|
|
|
|
pub(crate) fn place_card(
|
|
|
|
|
trigger: Trigger<OnAdd, PlayLocation>,
|
|
|
|
|
trigger: Trigger<OnInsert, PlayLocation>,
|
|
|
|
|
mut query: Query<(Entity, &PlayLocation, &mut Visibility)>,
|
|
|
|
|
animation_store: Res<AnimationStore>,
|
|
|
|
|
mut commands: Commands,
|
|
|
|
|
@ -287,6 +288,8 @@ pub(crate) fn place_card(
|
|
|
|
|
.get(&format!("deck->{:?}", (play_location.x, play_location.y)))
|
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
|
|
info!("Placing card {:?} at {:?}", entity, play_location);
|
|
|
|
|
|
|
|
|
|
let delay = ((random_state.hash_one(entity) % 9) as f32 / 10.0) + 0.1;
|
|
|
|
|
commands.entity(entity).insert(DelayedAnimation {
|
|
|
|
|
animation_index: animation_index.clone(),
|
|
|
|
|
@ -308,6 +311,7 @@ fn delayed_animation(
|
|
|
|
|
.for_each(|(entity, mut delayed_animation, mut animation_player)| {
|
|
|
|
|
delayed_animation.delay.tick(time.delta());
|
|
|
|
|
if delayed_animation.delay.just_finished() {
|
|
|
|
|
animation_player.rewind_all();
|
|
|
|
|
animation_player.play(delayed_animation.animation_index);
|
|
|
|
|
commands
|
|
|
|
|
.entity(entity)
|
|
|
|
|
|