/* * This file is part of laurelin_client * Copyright (C) 2023 Jonni Liljamo * * Licensed under GPL-3.0-only. * See LICENSE for licensing information. */ use bevy::prelude::*; use bevy_mod_picking::prelude::*; use bevy_rapier3d::prelude::*; use crate::{ api::game::{Action, Command}, game_status::PlayerState, plugins::GameActionCreateCallEvent, Global, }; use super::{ card::{visual_card_kind, ClickedCard, VisualCard, VisualCardBundle}, GameData, }; pub struct HandPlugin; impl Plugin for HandPlugin { fn build(&self, app: &mut App) { app.add_event::() .add_event::() .add_systems( ( spawn_hand.run_if(on_event::()), apply_system_buffers, position_hand.run_if(on_event::()), ) .chain(), ) .add_system(handle_clicked_hand_card); } } pub struct SpawnHandEvent; fn spawn_hand( mut commands: Commands, game_data: Res, global: Res, mut ph_ev_w: EventWriter, hand_query: Query>, ) { 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)) .insert(OnPointer::::target_component_mut::( |_over, transform| { transform.translation.y += 0.2; }, )) .insert(OnPointer::::target_component_mut::( |_over, transform| { transform.translation.y -= 0.2; }, )); } ph_ev_w.send(PositionHandEvent); } pub struct PositionHandEvent; fn position_hand( mut card_query: Query<(&VisualCard, &mut Transform), With>, ) { let mut cards: Vec<(&VisualCard, Mut)> = card_query.iter_mut().collect::>(); 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, card_query: Query< (Entity, &visual_card_kind::Hand), (With, With), >, mut gac_ev_w: EventWriter, mut game_data: ResMut, global: Res, ) { if game_data.locked { return; } let Ok((entity, card_kind)) = card_query.get_single() else { return; }; commands.entity(entity).remove::(); let player = game_data .game_status .as_ref() .unwrap() .players .get(&global.user.as_ref().unwrap().id) .unwrap(); #[allow(clippy::if_same_then_else)] if player.state != PlayerState::PlayPhase { // we ain't playing rn return; } else if player.plays == 0 { // not enough plays return; } game_data.locked = true; 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::PlayCard { index: card_kind.0 }, None, ), }); }