diff --git a/src/billy_objects.rs b/src/billy_objects.rs index f133028..b422b43 100644 --- a/src/billy_objects.rs +++ b/src/billy_objects.rs @@ -16,7 +16,7 @@ pub trait GenericObject { fn add_materiel(&self, in_type: &CharacteristicType) -> i32; } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize, Hash, Eq, PartialEq, Clone)] pub enum Weapons { Sword, Lance, @@ -24,7 +24,7 @@ pub enum Weapons { Bow, } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize, Hash, Eq, PartialEq, Clone)] pub enum Equipments { Chainmail, CookingPot, @@ -32,7 +32,7 @@ pub enum Equipments { MedicKit, } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize, Hash, Eq, PartialEq, Clone)] pub enum Tools { Fourche, Dagger, @@ -40,7 +40,7 @@ pub enum Tools { SackOfGrain, } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize, Hash, Eq, PartialEq, Clone)] pub enum Objects { Weapons(Weapons), Equipments(Equipments), @@ -164,7 +164,11 @@ impl GenericObject for Tools { impl GenericObject for Objects { fn add_armor(&self) -> u32 { - todo!() + match self { + Objects::Weapons(a) => a.add_armor(), + Objects::Equipments(a) => a.add_armor(), + Objects::Tools(a) => a.add_armor(), + } } fn add_critique(&self) -> u32 { diff --git a/src/sheet.rs b/src/sheet.rs index 5bb3ff1..5c924e8 100644 --- a/src/sheet.rs +++ b/src/sheet.rs @@ -1,9 +1,26 @@ -use eframe::egui::widgets::DragValue; -use eframe::egui::Ui; +use crate::billy_objects::{Equipments::*, GenericObject, Objects, Tools::*, Weapons::*}; +use crate::gui::SheetGui; +use eframe::egui::{widgets::DragValue, Ui}; use serde::{Deserialize, Serialize}; +use std::collections::hash_set; use std::io::Write as _; -use crate::gui::SheetGui; +const ALL_OBJECTS: [Objects; 12] = [ + Objects::Weapons(Sword), + Objects::Weapons(Lance), + Objects::Weapons(Morgenstern), + Objects::Weapons(Bow), + Objects::Equipments(Chainmail), + Objects::Equipments(CookingPot), + Objects::Equipments(PamphletTourist), + Objects::Equipments(MedicKit), + Objects::Tools(Fourche), + Objects::Tools(Dagger), + Objects::Tools(RockClimbingKit), + Objects::Tools(SackOfGrain), +]; + +const MAX_OBJ: usize = 3; #[derive(Debug, Serialize, Deserialize)] pub enum Classe { @@ -30,11 +47,90 @@ pub struct CharacterSheet { stamina: CharacteristicType, luck: CharacteristicType, skill: CharacteristicType, + objects: hash_set::HashSet, health: u32, armor: u32, damage: u32, glory: u32, money: u32, + critique: u32, + nb_weapons: u8, + nb_equipments: u8, + nb_tools: u8, +} + +#[derive(Debug)] +pub struct SheetRuler { + pub available_objects: hash_set::HashSet, +} + +impl Default for SheetRuler { + fn default() -> Self { + Self { + available_objects: hash_set::HashSet::from_iter(ALL_OBJECTS), + } + } +} + +impl SheetRuler { + fn change_carac( + object: &Objects, + sheet: &mut CharacterSheet, + operation: impl Fn(u32, i32) -> u32, + ) { + sheet.address_mut().materiel = operation( + sheet.address_mut().materiel, + object.add_materiel(&sheet.address), + ); + sheet.skill_mut().materiel = operation( + sheet.skill_mut().materiel, + object.add_materiel(&sheet.skill), + ); + sheet.luck_mut().materiel = + operation(sheet.luck_mut().materiel, object.add_materiel(&sheet.luck)); + sheet.stamina_mut().materiel = operation( + sheet.stamina_mut().materiel, + object.add_materiel(&sheet.stamina), + ); + sheet.armor = operation(sheet.armor, object.add_armor() as i32); + sheet.damage = operation(sheet.armor, object.add_damage() as i32); + sheet.critique = operation(sheet.critique, object.add_critique() as i32); + } + pub fn insert_object(&mut self, sheet: &mut CharacterSheet, object: Objects) -> bool { + if self.available_objects.len() >= MAX_OBJ || sheet.objects.contains(&object) { + false + } else { + Self::change_carac(&object, sheet, |a, b| a + b as u32); + let remove = self.available_objects.remove(&object); + let r = sheet.objects.insert(object.clone()) && remove; + if r { + match object { + Objects::Weapons(_) => sheet.nb_weapons += 1, + Objects::Equipments(_) => sheet.nb_equipments += 1, + Objects::Tools(_) => sheet.nb_tools += 1, + } + } + r + } + } + + pub fn erase_object(&mut self, sheet: &mut CharacterSheet, object: Objects) -> bool { + if sheet.objects.contains(&object) { + Self::change_carac(&object, sheet, |a, b| a - b as u32); + let remove = sheet.objects.remove(&object); + let r = self.available_objects.insert(object.clone()) && remove; + if r { + match object { + Objects::Weapons(_) => sheet.nb_weapons -= 1, + Objects::Equipments(_) => sheet.nb_equipments -= 1, + Objects::Tools(_) => sheet.nb_tools -= 1, + } + } + r + } else { + false + } + } } pub fn write_sheet(path: &std::path::Path, sheet: &CharacterSheet) -> std::io::Result<()> { @@ -256,11 +352,16 @@ impl Default for CharacterSheet { materiel: 0, additional: 0, }), + objects: hash_set::HashSet::default(), health: 0, armor: 0, damage: 0, glory: 0, money: 0, + critique: 0, + nb_weapons: 0, + nb_equipments: 0, + nb_tools: 0, } } }