Compare commits

..

8 commits

4 changed files with 405 additions and 41 deletions

197
src/billy_objects.rs Normal file
View file

@ -0,0 +1,197 @@
use crate::billy_objects::Weapons::*;
use crate::sheet::CharacteristicType;
use crate::sheet::CharacteristicType::*;
use serde::{Deserialize, Serialize};
pub trait GenericObject {
fn add_armor(&self) -> u32 {
0
}
fn add_critique(&self) -> u32 {
0
}
fn add_damage(&self) -> u32 {
0
}
fn add_materiel(&self, in_type: &CharacteristicType) -> i32;
}
#[derive(Debug, Serialize, Deserialize, Hash, Eq, PartialEq, Clone)]
pub enum Weapons {
Sword,
Lance,
Morgenstern,
Bow,
}
#[derive(Debug, Serialize, Deserialize, Hash, Eq, PartialEq, Clone)]
pub enum Equipments {
Chainmail,
CookingPot,
PamphletTourist,
MedicKit,
}
#[derive(Debug, Serialize, Deserialize, Hash, Eq, PartialEq, Clone)]
pub enum Tools {
Fourche,
Dagger,
RockClimbingKit,
SackOfGrain,
}
#[derive(Debug, Serialize, Deserialize, Hash, Eq, PartialEq, Clone)]
pub enum Objects {
Weapons(Weapons),
Equipments(Equipments),
Tools(Tools),
}
impl GenericObject for Weapons {
fn add_damage(&self) -> u32 {
if let Morgenstern = &self {
1
} else {
0
}
}
fn add_materiel(&self, in_type: &CharacteristicType) -> i32 {
match self {
Sword => {
if let Skill(_) = &in_type {
4
} else {
0
}
}
Lance => match in_type {
Address(_) => 1,
Skill(_) => 3,
_ => 0,
},
Morgenstern => match in_type {
Stamina(_) | Skill(_) => 1,
_ => 0,
},
Bow => match in_type {
Address(_) => 1,
Skill(_) => 3,
_ => 0,
},
}
}
}
impl GenericObject for Equipments {
fn add_armor(&self) -> u32 {
match self {
Equipments::Chainmail => 2,
Equipments::CookingPot => 1,
_ => 0,
}
}
fn add_materiel(&self, in_type: &CharacteristicType) -> i32 {
match self {
Equipments::Chainmail => match in_type {
Address(_) | Skill(_) => -1,
Stamina(_) => 1,
_ => 0,
},
Equipments::CookingPot => {
if let Stamina(_) = in_type {
2
} else {
0
}
}
Equipments::PamphletTourist => {
if let Luck(_) = in_type {
4
} else {
0
}
}
Equipments::MedicKit => {
if let Luck(_) = in_type {
1
} else {
0
}
}
}
}
}
impl GenericObject for Tools {
fn add_critique(&self) -> u32 {
if let Tools::Dagger = &self {
6
} else {
0
}
}
fn add_materiel(&self, in_type: &CharacteristicType) -> i32 {
match self {
Tools::Fourche => match in_type {
Stamina(_) => 3,
Skill(_) => 1,
_ => 0,
},
Tools::Dagger => {
if let Skill(_) = in_type {
1
} else {
0
}
}
Tools::RockClimbingKit => {
if let Address(_) = in_type {
1
} else {
0
}
}
Tools::SackOfGrain => match in_type {
Stamina(_) | Luck(_) => 2,
_ => 0,
},
}
}
}
impl GenericObject for Objects {
fn add_armor(&self) -> u32 {
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 {
match self {
Objects::Weapons(a) => a.add_critique(),
Objects::Equipments(a) => a.add_critique(),
Objects::Tools(a) => a.add_critique(),
}
}
fn add_damage(&self) -> u32 {
match self {
Objects::Weapons(a) => a.add_damage(),
Objects::Equipments(a) => a.add_damage(),
Objects::Tools(a) => a.add_damage(),
}
}
fn add_materiel(&self, in_type: &CharacteristicType) -> i32 {
match self {
Objects::Weapons(a) => a.add_materiel(in_type),
Objects::Equipments(a) => a.add_materiel(in_type),
Objects::Tools(a) => a.add_materiel(in_type),
}
}
}

View file

@ -1,2 +1,3 @@
pub mod billy_objects;
pub mod gui;
pub mod sheet;

View file

@ -2,7 +2,7 @@ use std::path::PathBuf;
use eframe::egui;
use eframe::egui::KeyboardShortcut;
use log::{info, warn, error};
use log::{error, info, warn};
use billy_sheet::gui::SheetGui;

View file

@ -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 {
@ -14,11 +31,11 @@ pub enum Classe {
}
#[derive(Debug, Serialize, Deserialize)]
enum CharacteristicType {
Address,
Stamina,
Luck,
Skill,
pub enum CharacteristicType {
Address(Characteristic),
Stamina(Characteristic),
Luck(Characteristic),
Skill(Characteristic),
}
#[derive(Debug, Serialize, Deserialize)]
@ -26,15 +43,94 @@ pub struct CharacterSheet {
character_class: Classe,
/// Field to write the personality/
pub character: String,
address: Characteristic,
stamina: Characteristic,
luck: Characteristic,
skill: Characteristic,
address: CharacteristicType,
stamina: CharacteristicType,
luck: CharacteristicType,
skill: CharacteristicType,
objects: hash_set::HashSet<Objects>,
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<Objects>,
}
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<()> {
@ -51,16 +147,61 @@ impl CharacterSheet {
&self.character
}
pub fn address(&self) -> &Characteristic {
&self.address
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 {
&self.stamina
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 {
&self.luck
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 {
&self.skill
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
@ -79,6 +220,17 @@ impl CharacterSheet {
}
}
impl CharacteristicType {
fn check(&self) {
match self {
CharacteristicType::Address(_) => todo!("Rules for address"),
CharacteristicType::Stamina(_) => todo!("Rules for stamina"),
CharacteristicType::Luck(_) => todo!("Rules for luck"),
CharacteristicType::Skill(_) => todo!("Rules for skill"),
}
}
}
impl SheetGui for CharacterSheet {
fn shortcut(
&self,
@ -107,27 +259,39 @@ impl SheetGui for CharacterSheet {
fn gui_address(&mut self, ui: &mut Ui) {
let workaround = self as &CharacterSheet;
(self.address.base, self.address.carac, self.address.materiel) =
self.shortcut(ui, "Adresse", workaround.address());
(
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.base, self.stamina.carac, self.stamina.materiel) =
self.shortcut(ui, "Endurance", workaround.stamina());
(
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.base, self.luck.carac, self.luck.materiel) =
self.shortcut(ui, "Chance", workaround.luck());
(
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.base, self.skill.carac, self.skill.materiel) =
self.shortcut(ui, "Habileté", workaround.skill());
(
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) {
@ -146,12 +310,13 @@ impl SheetGui for CharacterSheet {
ui.add(DragValue::new(&mut armor));
});
ui.label("Critique");
self.damage = damage;
self.armor = armor;
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct Characteristic {
characteristic_type: CharacteristicType,
pub base: u32,
pub carac: u32,
pub materiel: u32,
@ -163,39 +328,40 @@ impl Default for CharacterSheet {
Self {
character_class: Classe::Warrior,
character: "Billy".to_string(),
address: Characteristic {
characteristic_type: CharacteristicType::Address,
base: 0,
address: CharacteristicType::Address(Characteristic {
base: 1,
carac: 0,
materiel: 0,
additional: 1,
},
stamina: Characteristic {
characteristic_type: CharacteristicType::Stamina,
additional: 0,
}),
stamina: CharacteristicType::Stamina(Characteristic {
base: 2,
carac: 0,
materiel: 0,
additional: 0,
},
luck: Characteristic {
characteristic_type: CharacteristicType::Luck,
}),
luck: CharacteristicType::Luck(Characteristic {
base: 3,
carac: 0,
materiel: 0,
additional: 0,
},
skill: Characteristic {
characteristic_type: CharacteristicType::Skill,
}),
skill: CharacteristicType::Skill(Characteristic {
base: 2,
carac: 0,
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,
}
}
}