@@ 0,0 1,114 @@
+/*
+ * This file is part of laurelin_client
+ * Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
+ *
+ * Licensed under GPL-3.0-only.
+ * See LICENSE for licensing information.
+ */
+
+use bevy::prelude::*;
+use bevy_rapier3d::prelude::*;
+
+use crate::{plugins::GameActionCreateCallEvent, api::game::{Action, Command}, Global};
+
+use super::{
+ card::{visual_card_kind, VisualCard, VisualCardBundle, ClickedCard},
+ GameData,
+};
+
+pub struct HandPlugin;
+
+impl Plugin for HandPlugin {
+ fn build(&self, app: &mut App) {
+ app.add_event::<SpawnHandEvent>()
+ .add_event::<PositionHandEvent>()
+ .add_system(spawn_hand.run_if(on_event::<SpawnHandEvent>()))
+ .add_system(position_hand.run_if(on_event::<PositionHandEvent>()))
+ ;//.add_system(handle_clicked_hand_card);
+ }
+}
+
+pub struct SpawnHandEvent;
+
+fn spawn_hand(
+ mut commands: Commands,
+ game_data: Res<GameData>,
+ global: Res<Global>,
+ mut ph_ev_w: EventWriter<PositionHandEvent>,
+ mut hand_query: Query<Entity, With<visual_card_kind::Hand>>,
+) {
+ let Some(status) = &game_data.game_status else {
+ warn!("game_status was none");
+ return;
+ };
+
+ // despawn possible existing supply piles
+ for entity in hand_query.iter() {
+ commands.entity(entity).despawn_recursive();
+ }
+
+ for (index, card) in status.players
+ .get(&global.user.as_ref().unwrap().id).unwrap()
+ .hand.iter().enumerate() {
+ commands
+ .spawn(VisualCardBundle {
+ visual_card: VisualCard {
+ card: card.clone(),
+ },
+ rigid_body: RigidBody::Fixed,
+ ..Default::default()
+ })
+ .insert(visual_card_kind::Hand(index));
+ }
+
+ ph_ev_w.send(PositionHandEvent);
+}
+
+pub struct PositionHandEvent;
+
+fn position_hand(
+ mut card_query: Query<(&VisualCard, &mut Transform), With<visual_card_kind::Hand>>,
+) {
+ let mut cards: Vec<(&VisualCard, Mut<Transform>)> = card_query.iter_mut().collect::<Vec<_>>();
+
+ cards.sort_by_key(|(vc, _t)| vc.card.name.clone());
+ cards.sort_by_key(|(vc, _t)| vc.card.cost);
+
+ // keep track of offset between cards
+ let mut offset = 0.;
+
+ for (_, mut t) in cards {
+ t.translation.z += 1.5 * 3.; // leave room for 3 cards from z0.0
+ t.translation.x += offset;
+ offset += 1.0;
+ }
+}
+
+/*
+fn handle_clicked_hand_card(
+ mut commands: Commands,
+ mut card_query: Query<(Entity, &VisualCard, &visual_card_kind::Supply), (With<visual_card_kind::Supply>, With<ClickedCard>)>,
+ mut gac_ev_w: EventWriter<GameActionCreateCallEvent>,
+ game_data: Res<GameData>,
+ global: Res<Global>,
+) {
+ let Ok((entity, card, card_kind)) = card_query.get_single() else {
+ return;
+ };
+
+ commands.entity(entity).remove::<ClickedCard>();
+
+ gac_ev_w.send(GameActionCreateCallEvent {
+ action: Action::new(
+ &game_data.game.as_ref().unwrap().id,
+ &global.user.as_ref().unwrap().id,
+ &global.user.as_ref().unwrap().id,
+ &Command::TakeFromPile {
+ index: card_kind.0,
+ for_cost: card.card.cost,
+ },
+ fastrand::u64(u64::MIN..=u64::MAX),
+ ),
+ });
+}
+*/
@@ 16,6 16,7 @@ use self::card::VisualCardBundle;
use super::GameDetailsCallEvent;
mod card;
+mod hand;
mod supply;
mod ui;
@@ 27,6 28,7 @@ impl Plugin for GamePlugin {
.add_plugin(ui::GameUIPlugin)
.add_plugin(card::CardPlugin)
.add_plugin(supply::SupplyPlugin)
+ .add_plugin(hand::HandPlugin)
.add_system(game_setup.in_schedule(OnEnter(AppState::InGame)));
}
}