use eframe::egui::widgets::DragValue; use eframe::egui::Ui; use serde::{Deserialize, Serialize}; use std::io::Write as _; use crate::gui::SheetGui; #[derive(Debug, Serialize, Deserialize)] pub enum Classe { Warrior, Cautious, Farmer, Resourceful, } #[derive(Debug, Serialize, Deserialize)] pub enum CharacteristicType { Address(Characteristic), Stamina(Characteristic), Luck(Characteristic), Skill(Characteristic), } #[derive(Debug, Serialize, Deserialize)] pub struct CharacterSheet { character_class: Classe, /// Field to write the personality/ pub character: String, address: CharacteristicType, stamina: CharacteristicType, luck: CharacteristicType, skill: CharacteristicType, health: u32, armor: u32, damage: u32, glory: u32, money: u32, } pub fn write_sheet(path: &std::path::Path, sheet: &CharacterSheet) -> std::io::Result<()> { let sheet_str = serde_json::to_string_pretty(&sheet)?; let mut file = std::fs::File::create(path)?; write!(file, "{sheet_str}") } impl CharacterSheet { pub fn character_class(&self) -> &Classe { &self.character_class } pub fn character(&self) -> &str { &self.character } pub fn address(&self) -> &Characteristic { if let CharacteristicType::Address(addr) = &self.address { addr } else { unreachable!() } } fn address_mut(&mut self) -> &mut Characteristic { if let CharacteristicType::Address(addr) = &mut self.address { addr } else { unreachable!() } } pub fn stamina(&self) -> &Characteristic { if let CharacteristicType::Stamina(sta) = &self.stamina { sta } else { unreachable!() } } fn stamina_mut(&mut self) -> &mut Characteristic { if let CharacteristicType::Stamina(sta) = &mut self.stamina { sta } else { unreachable!() } } pub fn luck(&self) -> &Characteristic { if let CharacteristicType::Luck(luck) = &self.luck { luck } else { unreachable!() } } fn luck_mut(&mut self) -> &mut Characteristic { if let CharacteristicType::Luck(luck) = &mut self.luck { luck } else { unreachable!() } } pub fn skill(&self) -> &Characteristic { if let CharacteristicType::Skill(sk) = &self.skill { sk } else { unreachable!() } } fn skill_mut(&mut self) -> &mut Characteristic { if let CharacteristicType::Skill(sk) = &mut self.skill { sk } else { unreachable!() } } pub fn health(&self) -> u32 { self.health } pub fn armor(&self) -> u32 { self.armor } pub fn damage(&self) -> u32 { self.damage } pub fn glory(&self) -> u32 { self.glory } pub fn money(&self) -> u32 { self.money } } impl CharacteristicType { fn check(&self) { match self { CharacteristicType::Address(_) => println!("Rules for address"), CharacteristicType::Stamina(_) => println!("Rules for stamina"), CharacteristicType::Luck(_) => println!("Rules for luck"), CharacteristicType::Skill(_) => println!("Rules for skill"), } } } impl SheetGui for CharacterSheet { fn shortcut( &self, ui: &mut Ui, category: &str, character_field: &Characteristic, ) -> (u32, u32, u32) { let mut base = character_field.base; let mut carac = character_field.carac; let mut materiel = character_field.materiel; ui.heading(category); ui.horizontal(|ui| { ui.label("Base"); ui.add(DragValue::new(&mut base)); }); ui.horizontal(|ui| { ui.label("Carac."); ui.add(DragValue::new(&mut carac)); }); ui.horizontal(|ui| { ui.label("Matériel"); ui.add(DragValue::new(&mut materiel)); }); (base, carac, materiel) } fn gui_address(&mut self, ui: &mut Ui) { let workaround = self as &CharacterSheet; ( self.address_mut().base, self.address_mut().carac, self.address_mut().materiel, ) = self.shortcut(ui, "Adresse", workaround.address()); ui.label("Ne peut dépasser 5"); } fn gui_stamina(&mut self, ui: &mut Ui) { let workaround = self as &CharacterSheet; ( self.stamina_mut().base, self.stamina_mut().carac, self.stamina_mut().materiel, ) = self.shortcut(ui, "Endurance", workaround.stamina()); } fn gui_luck(&mut self, ui: &mut Ui) { let workaround = self as &CharacterSheet; ( self.luck_mut().base, self.luck_mut().carac, self.luck_mut().materiel, ) = self.shortcut(ui, "Chance", workaround.luck()); } fn gui_skill(&mut self, ui: &mut Ui) { let workaround = self as &CharacterSheet; ( self.skill_mut().base, self.skill_mut().carac, self.skill_mut().materiel, ) = self.shortcut(ui, "Habileté", workaround.skill()); } fn secondary_stats(&mut self, ui: &mut Ui) { let workaround = self as &CharacterSheet; let mut damage = workaround.damage; let mut armor = workaround.armor; ui.heading("Stat. secondaires"); ui.horizontal(|ui| { ui.label("Dégâts"); ui.add(DragValue::new(&mut damage)); }); ui.horizontal(|ui| { ui.label("Armure"); ui.add(DragValue::new(&mut armor)); }); ui.label("Critique"); self.damage = damage; self.armor = armor; } } #[derive(Debug, Serialize, Deserialize)] pub struct Characteristic { pub base: u32, pub carac: u32, pub materiel: u32, pub additional: u32, } impl Default for CharacterSheet { fn default() -> Self { Self { character_class: Classe::Warrior, character: "Billy".to_string(), address: CharacteristicType::Address(Characteristic { base: 1, carac: 0, materiel: 0, additional: 0, }), stamina: CharacteristicType::Stamina(Characteristic { base: 2, carac: 0, materiel: 0, additional: 0, }), luck: CharacteristicType::Luck(Characteristic { base: 3, carac: 0, materiel: 0, additional: 0, }), skill: CharacteristicType::Skill(Characteristic { base: 2, carac: 0, materiel: 0, additional: 0, }), health: 0, armor: 0, damage: 0, glory: 0, money: 0, } } }