/* * 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_egui::{egui, EguiContexts}; use crate::{ api::game::{Action, Command, Game}, game_status::{Card, PlayerState}, plugins::{GameActionCreateCallEvent, GameDetailsCallEvent}, AppState, Global, }; use super::{supply::SpawnSupplyPilesEvent, GameData}; pub struct GameUIPlugin; impl Plugin for GameUIPlugin { fn build(&self, app: &mut App) { app.add_system(dev_details_ui.run_if(in_state(AppState::InGame))); } } pub fn dev_details_ui( mut contexts: EguiContexts, global: Res, game_data: Res, mut details_ev_w: EventWriter, mut create_action_ev_w: EventWriter, mut ssp_ev_w: EventWriter, ) { egui::Window::new("Game Details").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 { if game_data.parsing_data { // early return if game_status is None, and we're parsing it return; } // game_status is None, but we're not parsing it... // should be unreachable, I think? return; }; if ui.button("Refresh").clicked() { details_ev_w.send(GameDetailsCallEvent { game_id: game_data.game.as_ref().unwrap().id.clone(), }); } 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); } } if ui.button("spawn things").clicked() { ssp_ev_w.send(SpawnSupplyPilesEvent); } 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)); ui.label(format!("State: {:?}", game.state)); }); egui::CollapsingHeader::new("Supply Piles") .default_open(false) .show(ui, |ui| { for pile in &status.supply_piles { egui::CollapsingHeader::new(&pile.card.name) .default_open(true) .show(ui, |ui| { ui.label(format!("Amount: {}", pile.amount)); }); } }); egui::CollapsingHeader::new("Log") .default_open(false) .show(ui, |ui| { egui::ScrollArea::vertical() .max_width(f32::INFINITY) .show(ui, |ui| { for (i, action) in status.actions.iter().enumerate() { egui::CollapsingHeader::new(format!("{}", i)) .default_open(false) .show(ui, |ui| { ui.add( egui::TextEdit::multiline( &mut serde_json::to_string_pretty(action).unwrap(), ) .code_editor() .interactive(false) .desired_width(f32::INFINITY), ); }); } }); }); }); } fn hardcoded_init(game: &Game, create_action_ev_w: &mut EventWriter) { // first, piles create_action_ev_w.send(GameActionCreateCallEvent { action: Action::new( &game.id, &game.host_id, &game.host_id, &Command::InitSupplyPile { card: Card { name: "Narcissistic Cannibal".to_string(), short_details: vec![], long_details: vec![], cost: 4, actions: vec![], }, amount: 10, }, fastrand::u64(u64::MIN..=u64::MAX), ), }); create_action_ev_w.send(GameActionCreateCallEvent { action: Action::new( &game.id, &game.host_id, &game.host_id, &Command::InitSupplyPile { card: Card { name: "Test Card 2".to_string(), short_details: vec![], long_details: vec![], cost: 0, actions: vec![], }, amount: 10, }, fastrand::u64(u64::MIN..=u64::MAX), ), }); create_action_ev_w.send(GameActionCreateCallEvent { action: Action::new( &game.id, &game.host_id, &game.host_id, &Command::InitSupplyPile { card: Card { name: "Test Card 3".to_string(), short_details: vec![], long_details: vec![], cost: 4, actions: vec![], }, amount: 10, }, fastrand::u64(u64::MIN..=u64::MAX), ), }); create_action_ev_w.send(GameActionCreateCallEvent { action: Action::new( &game.id, &game.host_id, &game.host_id, &Command::InitSupplyPile { card: Card { name: "Test Card 4".to_string(), short_details: vec![], long_details: vec![], cost: 2, actions: vec![], }, amount: 10, }, fastrand::u64(u64::MIN..=u64::MAX), ), }); // second, set a player to the action phase, to start the game create_action_ev_w.send(GameActionCreateCallEvent { action: Action::new( &game.id, &game.host_id, &game.host_id, &Command::ChangePlayerState { state: PlayerState::ActionPhase, }, fastrand::u64(u64::MIN..=u64::MAX), ), }); }