DEVELOPMENT ENVIRONMENT

~liljamo/deck-builder

9352c9d4a3e602c3542668ecadf39ecef3bb32ec — skye 1 year, 7 months ago f4d2db4
feat(client): sorta wip hand plugin
2 files changed, 116 insertions(+), 0 deletions(-)

A client/src/plugins/game/hand/mod.rs
M client/src/plugins/game/mod.rs
A client/src/plugins/game/hand/mod.rs => client/src/plugins/game/hand/mod.rs +114 -0
@@ 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),
        ),
    });
}
*/

M client/src/plugins/game/mod.rs => client/src/plugins/game/mod.rs +2 -0
@@ 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)));
    }
}