DEVELOPMENT ENVIRONMENT

~liljamo/deck-builder

e09fcc3b0fe1575540988ea9672edaa0a1d90aa7 — Jonni Liljamo 1 year, 5 months ago 02d92df
feat(client): sane-ish supply pile spawning
M client/src/plugins/game/mod.rs => client/src/plugins/game/mod.rs +2 -0
@@ 17,6 17,7 @@ use super::GameDetailsCallEvent;

mod ui;
mod card;
mod supply;

pub struct GamePlugin;



@@ 25,6 26,7 @@ impl Plugin for GamePlugin {
        app.insert_resource(GameData::default())
            .add_plugin(ui::GameUIPlugin)
            .add_plugin(card::CardPlugin)
            .add_plugin(supply::SupplyPlugin)
            .add_system(game_setup.in_schedule(OnEnter(AppState::InGame)));
    }
}

A client/src/plugins/game/supply/mod.rs => client/src/plugins/game/supply/mod.rs +83 -0
@@ 0,0 1,83 @@
/*
 * 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 super::{GameData, card::{VisualCardBundle, VisualCard, visual_card_kind}};

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

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;
    }
}

M client/src/plugins/game/ui/mod.rs => client/src/plugins/game/ui/mod.rs +6 -1
@@ 11,7 11,7 @@ use bevy_egui::{egui, EguiContexts};

use crate::{plugins::{GameDetailsCallEvent, GameActionCreateCallEvent}, Global, api::game::{Action, Command, Game}, game_status::{Card, PlayerState}, AppState};

use super::GameData;
use super::{GameData, supply::SpawnSupplyPilesEvent};

pub struct GameUIPlugin;



@@ 27,6 27,7 @@ pub fn details_ui(
    game_data: Res<GameData>,
    mut details_ev_w: EventWriter<GameDetailsCallEvent>,
    mut create_action_ev_w: EventWriter<GameActionCreateCallEvent>,
    mut ssp_ev_w: EventWriter<SpawnSupplyPilesEvent>,
) {
    egui::Window::new("Game Details")
        .show(contexts.ctx_mut(), |ui| {


@@ 57,6 58,10 @@ pub fn details_ui(
                }
            }

            if ui.button("spawn things").clicked() {
                ssp_ev_w.send(SpawnSupplyPilesEvent);
            }

            ui.separator();

            egui::CollapsingHeader::new("Game")