DEVELOPMENT ENVIRONMENT

~liljamo/deck-builder

13a40ec572fd4363e7868b3b4892571980e6013a — Jonni Liljamo 1 year, 7 months ago 781c443
chore(client): fmt, clippy
M client/src/api/game/mod.rs => client/src/api/game/mod.rs +12 -3
@@ 6,11 6,14 @@
 * See LICENSE for licensing information.
 */

use bevy::reflect::{Reflect, FromReflect};
use bevy::reflect::{FromReflect, Reflect};
use serde::{Deserialize, Serialize};
use serde_repr::Deserialize_repr;

use crate::{game_status::{Card, PlayerState}, seed_gen};
use crate::{
    game_status::{Card, PlayerState},
    seed_gen,
};

use super::user::User;



@@ 83,7 86,13 @@ pub struct Action {
}

impl Action {
    pub fn new(game_id: &str, invoker: &str, target: &str, command: &Command, seed: Option<u64>) -> Self {
    pub fn new(
        game_id: &str,
        invoker: &str,
        target: &str,
        command: &Command,
        seed: Option<u64>,
    ) -> Self {
        let seed = if seed.is_none() {
            seed_gen!()
        } else {

M client/src/api/user/mod.rs => client/src/api/user/mod.rs +1 -1
@@ 6,7 6,7 @@
 * See LICENSE for licensing information.
 */

use bevy::reflect::{Reflect, FromReflect};
use bevy::reflect::{FromReflect, Reflect};
use serde::Deserialize;

mod login;

M client/src/game_status/parser.rs => client/src/game_status/parser.rs +4 -2
@@ 12,7 12,8 @@ use fastrand::Rng;

use crate::{
    api::game::{Action, Command, Game},
    game_status::SupplyPile, util::action_to_log,
    game_status::SupplyPile,
    util::action_to_log,
};

use super::{GameStatus, PlayerState, PlayerStatus};


@@ 231,7 232,8 @@ fn parse_action(action: &Action, game: &Game, game_status: &mut GameStatus) {
        }
        Command::RollForCurrency { amount, sides } => {
            for _ in 0..*amount {
                target.currency += Rng::with_seed(action.seed.parse::<u64>().unwrap()).usize(1..=*sides);
                target.currency +=
                    Rng::with_seed(action.seed.parse::<u64>().unwrap()).usize(1..=*sides);
            }
        }
        #[allow(unreachable_patterns)]

M client/src/plugins/game/mod.rs => client/src/plugins/game/mod.rs +5 -1
@@ 9,7 9,11 @@
use bevy::prelude::*;
use bevy_rapier3d::prelude::*;

use crate::{api::game::{Game, GameState}, game_status::GameStatus, AppState, Global};
use crate::{
    api::game::{Game, GameState},
    game_status::GameStatus,
    AppState, Global,
};

use self::{hand::SpawnHandEvent, supply::SpawnSupplyPilesEvent, ui::log::UpdateLogEvent};


M client/src/plugins/game/supply/mod.rs => client/src/plugins/game/supply/mod.rs +2 -1
@@ 79,7 79,8 @@ fn spawn_supply_piles(
                |_over, transform| {
                    transform.translation.y -= 0.1;
                },
            )).with_children(|parent| {
            ))
            .with_children(|parent| {
                parent.spawn(TextMeshBundle {
                    text_mesh: TextMesh {
                        text: format!("left: {}", pile.amount),

M client/src/plugins/game/ui/log.rs => client/src/plugins/game/ui/log.rs +31 -29
@@ 6,9 6,13 @@
 * See LICENSE for licensing information.
 */

use bevy::{prelude::*, input::mouse::{MouseScrollUnit, MouseWheel}, a11y::{AccessibilityNode, accesskit::NodeBuilder}};
use bevy::{
    a11y::{accesskit::NodeBuilder, AccessibilityNode},
    input::mouse::{MouseScrollUnit, MouseWheel},
    prelude::*,
};

use crate::{AppState, plugins::GameData, game_status::LogSection};
use crate::{game_status::LogSection, plugins::GameData, AppState};

pub struct LogPlugin;



@@ 74,16 78,14 @@ fn setup_log(mut commands: Commands, asset_server: Res<AssetServer>) {
                    LogButton,
                ))
                .with_children(|parent| {
                    parent.spawn((
                        TextBundle::from_section(
                            "Log",
                            TextStyle {
                                font: font.clone(),
                                font_size: 20.,
                                color: Color::WHITE,
                            },
                        ),
                    ));
                    parent.spawn((TextBundle::from_section(
                        "Log",
                        TextStyle {
                            font: font.clone(),
                            font_size: 20.,
                            color: Color::WHITE,
                        },
                    ),));
                });
        });



@@ 146,14 148,16 @@ fn setup_log(mut commands: Commands, asset_server: Res<AssetServer>) {
                        .with_children(|parent| {
                            parent.spawn((
                                TextBundle::from_section(
                                    format!("Empty"),
                                    "Empty".to_string(),
                                    TextStyle {
                                        font: font.clone(),
                                        font_size: 20.,
                                        color: Color::WHITE,
                                    },
                                ),
                                AccessibilityNode(NodeBuilder::new(bevy::a11y::accesskit::Role::ListItem)),
                                AccessibilityNode(NodeBuilder::new(
                                    bevy::a11y::accesskit::Role::ListItem,
                                )),
                                LogListEntry,
                            ));
                        });


@@ 184,9 188,7 @@ fn update_log_button(
    }
}

fn toggle_log(
    mut log_parent_query: Query<&mut Visibility, With<LogListParent>>,
) {
fn toggle_log(mut log_parent_query: Query<&mut Visibility, With<LogListParent>>) {
    for mut visibility in &mut log_parent_query {
        if *visibility == Visibility::Hidden {
            *visibility = Visibility::Inherited;


@@ 255,18 257,18 @@ fn update_log(
                }
            }

            commands.spawn((
                TextBundle::from_sections(sections)
                .with_style(Style {
                    max_size: Size {
                        width: Val::Px(450.),
                        height: Val::Undefined,
                    },
                    ..Default::default()
                }),
                AccessibilityNode(NodeBuilder::new(bevy::a11y::accesskit::Role::ListItem)),
                LogListEntry,
            ))
            commands
                .spawn((
                    TextBundle::from_sections(sections).with_style(Style {
                        max_size: Size {
                            width: Val::Px(450.),
                            height: Val::Undefined,
                        },
                        ..Default::default()
                    }),
                    AccessibilityNode(NodeBuilder::new(bevy::a11y::accesskit::Role::ListItem)),
                    LogListEntry,
                ))
                .set_parent(entity);
        }
    }

M client/src/plugins/game/ui/mod.rs => client/src/plugins/game/ui/mod.rs +29 -24
@@ 340,41 340,43 @@ pub fn dev_details_ui(
    mut create_action_ev_w: EventWriter<GameActionCreateCallEvent>,
    mut rg_ev_w: EventWriter<RefreshGameEvent>,
) {
    egui::Window::new("Game Details").title_bar(false).show(contexts.ctx_mut(), |ui| {
        let Some(game) = &game_data.game else {
    egui::Window::new("Game Details")
        .title_bar(false)
        .show(contexts.ctx_mut(), |ui| {
            let Some(game) = &game_data.game else {
                // early return if game is None
                return;
            };
        let Some(status) = &game_data.game_status else {
            let Some(status) = &game_data.game_status else {
                // early return if game_status is None
                return;
            };

        ui.add_enabled_ui(!game_data.locked, |ui| {
            #[allow(clippy::collapsible_if)]
            if status.actions.is_empty() && game.host_id == global.user.as_ref().unwrap().id {
                if ui.button("Init Game").clicked() {
                    // NOTE/FIXME: hardcoded game init
                    hardcoded_init(game, &mut create_action_ev_w);
                    rg_ev_w.send(RefreshGameEvent);
            ui.add_enabled_ui(!game_data.locked, |ui| {
                #[allow(clippy::collapsible_if)]
                if status.actions.is_empty() && game.host_id == global.user.as_ref().unwrap().id {
                    if ui.button("Init Game").clicked() {
                        // NOTE/FIXME: hardcoded game init
                        hardcoded_init(game, &mut create_action_ev_w);
                        rg_ev_w.send(RefreshGameEvent);
                    }
                }
            }

            if ui.button("Force Refresh").clicked() {
                rg_ev_w.send(RefreshGameEvent);
            }
        });
                if ui.button("Force Refresh").clicked() {
                    rg_ev_w.send(RefreshGameEvent);
                }
            });

        ui.separator();
            ui.separator();

        egui::CollapsingHeader::new("Game")
            .default_open(true)
            .show(ui, |ui| {
                ui.label(format!("Host: {}", game.host.as_ref().unwrap().username));
                ui.label(format!("Guest: {}", game.guest.as_ref().unwrap().username));
            egui::CollapsingHeader::new("Game")
                .default_open(true)
                .show(ui, |ui| {
                    ui.label(format!("Host: {}", game.host.as_ref().unwrap().username));
                    ui.label(format!("Guest: {}", game.guest.as_ref().unwrap().username));

                ui.label(format!("State: {:?}", game.state));
            });
                    ui.label(format!("State: {:?}", game.state));
                });
        });
}



@@ 410,7 412,10 @@ fn hardcoded_init(game: &Game, create_action_ev_w: &mut EventWriter<GameActionCr
                    long_details: vec![],
                    cost: 0,
                    actions: vec![CardAction {
                        command: Command::RollForCurrency { amount: 1, sides: 6 },
                        command: Command::RollForCurrency {
                            amount: 1,
                            sides: 6,
                        },
                    }],
                },
                amount: 10,

M client/src/util/action_to_log.rs => client/src/util/action_to_log.rs +66 -60
@@ 6,25 6,31 @@
 * See LICENSE for licensing information.
 */

use crate::{api::game::{Action, Command}, game_status::{GameStatus, LogEntry, LogSection}};
use crate::{
    api::game::{Action, Command},
    game_status::{GameStatus, LogEntry, LogSection},
};

pub fn action_to_log(
    action: &Action,
    game_status: &GameStatus,
) -> LogEntry {
    let invoker_name = &game_status.players.get(&action.invoker).unwrap().display_name;
    let target_name = &game_status.players.get(&action.target).unwrap().display_name;
pub fn action_to_log(action: &Action, game_status: &GameStatus) -> LogEntry {
    let invoker_name = &game_status
        .players
        .get(&action.invoker)
        .unwrap()
        .display_name;
    let target_name = &game_status
        .players
        .get(&action.target)
        .unwrap()
        .display_name;

    match &action.command {
        Command::InitSupplyPile { card, amount } => {
            LogEntry::from_sections(vec![
                LogSection::normal("Created supply pile of "),
                LogSection::bold(&card.name),
                LogSection::normal(" with "),
                LogSection::bold(&amount.to_string()),
                LogSection::normal(" cards"),
            ])
        }
        Command::InitSupplyPile { card, amount } => LogEntry::from_sections(vec![
            LogSection::normal("Created supply pile of "),
            LogSection::bold(&card.name),
            LogSection::normal(" with "),
            LogSection::bold(&amount.to_string()),
            LogSection::normal(" cards"),
        ]),
        Command::TakeFromPile { index, for_cost: _ } => {
            let card_name = &game_status.supply_piles.get(*index).unwrap().card.name;
            LogEntry::from_sections(vec![


@@ 34,63 40,63 @@ pub fn action_to_log(
            ])
        }
        Command::PlayCard { index } => {
            let card_name = &game_status.players.get(&action.invoker).unwrap().hand.get(*index).unwrap().name;
            let card_name = &game_status
                .players
                .get(&action.invoker)
                .unwrap()
                .hand
                .get(*index)
                .unwrap()
                .name;
            LogEntry::from_sections(vec![
                LogSection::bold(invoker_name),
                LogSection::normal(" played "),
                LogSection::bold(card_name),
            ])
        }
        Command::Draw { amount } => {
            LogEntry::from_sections(vec![
                LogSection::bold(invoker_name),
                LogSection::normal(" drew "),
                LogSection::bold(&amount.to_string()),
                LogSection::normal(" cards"),
            ])
        }
        Command::Draw { amount } => LogEntry::from_sections(vec![
            LogSection::bold(invoker_name),
            LogSection::normal(" drew "),
            LogSection::bold(&amount.to_string()),
            LogSection::normal(" cards"),
        ]),
        Command::Discard { index } => {
            let card_name = &game_status.players.get(&action.invoker).unwrap().hand.get(*index).unwrap().name;
            let card_name = &game_status
                .players
                .get(&action.invoker)
                .unwrap()
                .hand
                .get(*index)
                .unwrap()
                .name;
            LogEntry::from_sections(vec![
                LogSection::bold(invoker_name),
                LogSection::normal(" discarded "),
                LogSection::bold(card_name),
            ])
        }
        Command::EndTurn {} => {
            LogEntry::from_sections(vec![
                LogSection::bold(invoker_name),
                LogSection::normal(" ended their turn"),
            ])
        }
        Command::StartTurn {} => {
            LogEntry::from_sections(vec![
                LogSection::bold(target_name),
                LogSection::normal(" started their turn"),
            ])
        }
        Command::ChangePlayerState { state } => {
            LogEntry::from_sections(vec![
                LogSection::bold(invoker_name),
                LogSection::normal(" changed state to "),
                LogSection::bold(&format!("{:?}", state)),
            ])
        }
        Command::RollForCurrency { amount, sides } => {
            LogEntry::from_sections(vec![
                LogSection::bold(invoker_name),
                LogSection::normal(" rolled "),
                LogSection::bold(&format!("{}d{}", amount, sides)),
                LogSection::normal(" for currency"),
            ])
        }
        Command::EndTurn {} => LogEntry::from_sections(vec![
            LogSection::bold(invoker_name),
            LogSection::normal(" ended their turn"),
        ]),
        Command::StartTurn {} => LogEntry::from_sections(vec![
            LogSection::bold(target_name),
            LogSection::normal(" started their turn"),
        ]),
        Command::ChangePlayerState { state } => LogEntry::from_sections(vec![
            LogSection::bold(invoker_name),
            LogSection::normal(" changed state to "),
            LogSection::bold(&format!("{:?}", state)),
        ]),
        Command::RollForCurrency { amount, sides } => LogEntry::from_sections(vec![
            LogSection::bold(invoker_name),
            LogSection::normal(" rolled "),
            LogSection::bold(&format!("{}d{}", amount, sides)),
            LogSection::normal(" for currency"),
        ]),
        #[allow(unreachable_patterns)]
        _ => {
            LogEntry {
                sections: vec![
                    LogSection::normal("No log configuration for this command"),
                ]
            }
        }
        _ => LogEntry {
            sections: vec![LogSection::normal("No log configuration for this command")],
        },
    }
}