DEVELOPMENT ENVIRONMENT

~liljamo/deck-builder

ref: 1900e665248f30683184565079aaf0dea02563ae deck-builder/client/src/plugins/game/supply/mod.rs -rw-r--r-- 3.2 KiB
1900e665 — skye feat(client): add hand type for cards 1 year, 5 months ago
                                                                                
de6cc159 skye
de6cc159 skye
de6cc159 skye
de6cc159 skye
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/*
 * 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 SupplyPlugin;

impl Plugin for SupplyPlugin {
    fn build(&self, app: &mut App) {
        app.add_event::<SpawnSupplyPilesEvent>()
            .add_event::<PositionSupplyPilesEvent>()
            .add_system(spawn_supply_piles.run_if(on_event::<SpawnSupplyPilesEvent>()))
            .add_system(position_supply_piles.run_if(on_event::<PositionSupplyPilesEvent>()))
            .add_system(handle_clicked_supply_pile);
    }
}

pub struct SpawnSupplyPilesEvent;

fn spawn_supply_piles(
    mut commands: Commands,
    game_data: Res<GameData>,
    mut psp_ev_w: EventWriter<PositionSupplyPilesEvent>,
) {
    let Some(status) = &game_data.game_status else {
        warn!("game_status was none");
        return;
    };

    for (index, pile) in status.supply_piles.iter().enumerate() {
        commands
            .spawn(VisualCardBundle {
                visual_card: VisualCard {
                    card: pile.card.clone(),
                },
                rigid_body: RigidBody::Fixed,
                ..Default::default()
            })
            .insert(visual_card_kind::Supply(index));
    }

    psp_ev_w.send(PositionSupplyPilesEvent);
}

pub struct PositionSupplyPilesEvent;

fn position_supply_piles(
    mut pile_query: Query<(&VisualCard, &mut Transform), With<visual_card_kind::Supply>>,
) {
    let mut piles: Vec<(&VisualCard, Mut<Transform>)> = pile_query.iter_mut().collect::<Vec<_>>();

    piles.sort_by_key(|(vc, _t)| vc.card.name.clone());
    piles.sort_by_key(|(vc, _t)| vc.card.cost);

    // split piles into top and bottom row
    let mid = piles.len() / 2;
    let (p1, p2) = piles.split_at_mut(mid);

    // keep track of offset between cards
    let mut offset = 0.;

    // top row
    for (_, t) in p1 {
        t.translation.x += offset;
        offset += 1.0;
    }

    // reset offset when changing rows
    offset = 0.;

    // bottom row
    for (_, t) in p2 {
        t.translation.z += 1.5;
        t.translation.x += offset;
        offset += 1.0;
    }
}

fn handle_clicked_supply_pile(
    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),
        ),
    });
}