From 25619d3656b571f8dfd08f43ad93eba01aadd6a7 Mon Sep 17 00:00:00 2001 From: xenua Date: Mon, 27 Nov 2023 12:18:08 +0100 Subject: [PATCH] wip 5 --- src/general.rs | 71 +++++++++++++++++++++++++++-- src/lib.rs | 32 +------------ src/pokemon/gen5.rs | 76 ++++++++++++++++++++++++++++++- src/pokemon/mod.rs | 107 ++++++++++++++++---------------------------- 4 files changed, 183 insertions(+), 103 deletions(-) diff --git a/src/general.rs b/src/general.rs index f261657..e174cec 100644 --- a/src/general.rs +++ b/src/general.rs @@ -1,3 +1,5 @@ +use std::fmt::Display; + pub enum Generation { One = 1, Two = 2, @@ -162,6 +164,7 @@ pub enum StatusCondition { Toxic, } +#[derive(Debug)] pub enum Species { Bulbasaur, Ivysaur, @@ -1182,6 +1185,7 @@ pub enum Species { Ogerpon, } +#[derive(Debug)] pub enum Ability { Stench, Drizzle, @@ -2559,6 +2563,67 @@ pub struct LearnedMove { pub pp_up: u8, } -pub struct MoveSet( - LearnedMove -) \ No newline at end of file +pub struct MoveSet(LearnedMove, LearnedMove, LearnedMove, LearnedMove); + +#[derive(Debug, Clone)] +pub struct Trainer { + pub name: String, + pub id: TrainerId, +} + +#[derive(Debug, Clone)] +pub enum TrainerId { + /// used in gens 1-2. no secret id + SixteenBitSingle(u16), + /// gens 3-6 + SixteenBit(u16, u16), + /// gens 7+ + SixDigit(u32), +} + +impl Display for TrainerId { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "{:06}", + match self { + TrainerId::SixteenBitSingle(v) => *v as u32, + TrainerId::SixteenBit(v, _) => *v as u32, + TrainerId::SixDigit(v) => v % 100_000, + } + ) + } +} + +pub struct StatSpread { + pub hp: K, + pub attack: K, + pub defense: K, + pub speed: K, + pub sp_attack: K, + pub sp_def: K, +} + +pub type EVs = StatSpread; + +pub struct IV(u8); + +impl TryFrom for IV { + type Error = (); + + fn try_from(value: u8) -> Result { + if value > 31 { + return Err(()); + } + + Ok(Self(value)) + } +} + +impl From for u8 { + fn from(value: IV) -> Self { + value.0 + } +} + +pub type IVs = StatSpread; diff --git a/src/lib.rs b/src/lib.rs index 3e50e0e..f021aea 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,37 +7,7 @@ use std::{ sync::atomic::{AtomicU32, Ordering}, }; -pub struct Pokemon { - species: u32, - trainer_id: TrainerId, - generation: Generation, - nickname: Option, - language: Language, - gender: Gender, -} - -pub enum TrainerId { - /// used in gens 1-2. no secret id - SixteenBitSingle(u16), - /// gens 3-6, and 1-2 transferred to 7+ - SixteenBit(u16, u16), - /// gens 7+ - SixDigit(u32), -} - -impl Display for TrainerId { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!( - f, - "{:06}", - match self { - TrainerId::SixteenBitSingle(v) => *v as u32, - TrainerId::SixteenBit(v, _) => *v as u32, - TrainerId::SixDigit(v) => v % 100_000, - } - ) - } -} +use general::{Gender, Generation, Language, Stat}; pub trait RNG { fn get(&self) -> u32; diff --git a/src/pokemon/gen5.rs b/src/pokemon/gen5.rs index 1f9dddb..d4ed454 100644 --- a/src/pokemon/gen5.rs +++ b/src/pokemon/gen5.rs @@ -1,4 +1,7 @@ -use crate::general::BinaryGender; +use crate::{ + general::{BinaryGender, Trainer, TrainerId}, + pokemon::PKM, +}; /// https://projectpokemon.org/home/docs/gen-5/bw-save-structure-r60/ pub struct PK5 { @@ -82,6 +85,77 @@ pub struct PK5 { mail_message: Mail5, } +impl PKM for PK5 { + fn ot(&self) -> &Trainer { + &Trainer { + name: self.ot_name, + id: TrainerId::SixteenBit(self.ot_id, self.ot_secret_id), + } + } + + fn gain_xp(&mut self, xp: u32) -> Vec { + self.experience += xp; + // + todo!() + } + + fn defeated(&mut self, other: crate::general::Species) { + todo!() + } + + fn use_item(&mut self, item: Item) -> Result<(), ItemUseError> { + todo!() + } + + fn damage(&mut self, hp: u16) { + todo!() + } + + fn apply_status(&mut self, status: crate::general::StatusCondition) { + todo!() + } + + fn species(&self) -> crate::general::Species { + todo!() + } + + fn ivs(&self) -> crate::general::IVs { + todo!() + } + + fn evs(&self) -> crate::general::EVs { + todo!() + } + + fn is_shiny(&self) -> bool { + todo!() + } + + fn nickname(&self) -> Option { + todo!() + } + + fn held_item(&self) -> Option { + todo!() + } + + fn current_hp(&self) -> u16 { + todo!() + } + + fn max_hp(&self) -> u16 { + todo!() + } + + fn effective_base_stats(&self) -> crate::general::StatSpread { + todo!() + } + + fn move_set(&self) -> crate::general::MoveSet { + todo!() + } +} + pub struct Mail5 { author_tid: u16, author_sid: u16, diff --git a/src/pokemon/mod.rs b/src/pokemon/mod.rs index ca43458..a888df5 100644 --- a/src/pokemon/mod.rs +++ b/src/pokemon/mod.rs @@ -1,6 +1,9 @@ use std::io::Read; -use crate::general::{Ability, BinaryGender, Gender, Language, Move, Nature, PokeBall, Species}; +use crate::general::{ + Ability, BinaryGender, EVs, Gender, IVs, Language, Move, MoveSet, Nature, PokeBall, Species, + StatSpread, StatusCondition, Trainer, +}; pub mod gen5; @@ -18,6 +21,33 @@ pub trait PKM { fn ot(&self) -> &Trainer; fn gain_xp(&mut self, xp: u32) -> Vec; + fn defeated(&mut self, other: Species); + fn use_item(&mut self, item: Item) -> Result<(), ItemUseError>; + fn damage(&mut self, hp: u16); + fn apply_status(&mut self, status: StatusCondition); + + fn species(&self) -> Species; + fn ivs(&self) -> IVs; + fn evs(&self) -> EVs; + fn is_shiny(&self) -> bool; + fn nickname(&self) -> Option; + fn held_item(&self) -> Option; + + fn current_hp(&self) -> u16; + fn max_hp(&self) -> u16; + fn effective_base_stats(&self) -> StatSpread; + fn move_set(&self) -> MoveSet; + + fn display_name(&self) -> String { + self.nickname() + .unwrap_or_else(|| format!("{:?}", self.species())) // todo: multi lang + } + fn fainted(&self) -> bool { + self.current_hp() == 0 + } + fn health(&self) -> f32 { + self.current_hp() as f32 / self.max_hp() as f32 + } } pub enum Progression { @@ -35,70 +65,11 @@ where } } -// pub trait Pokemon { -// // main -// fn species(&self) -> Species; -// fn nickname(&self) -> String; -// fn held_item(&self) -> Item; -// fn gender(&self) -> Gender; -// fn nature(&self) -> Nature; -// fn ability(&self) -> Ability; -// fn form(&self) -> PokemonForm; -// fn is_egg(&self) -> bool; -// fn is_nicknamed(&self) -> bool; -// fn exp(&self) -> u32; -// fn ot_name(&self) -> String; -// fn ot_gender(&self) -> BinaryGender; -// fn level(&self) -> u8; -// fn met_level(&self) -> u8; - -// // internal -// fn tid16(&self) -> u16; -// fn sid16(&self) -> u16; -// fn id32(&self) -> u32; -// fn ball(&self) -> PokeBall; -// fn current_friendship(&self) -> i32; -// fn version(&self) -> i32; -// fn pokerus_strain(&self) -> i32; -// fn pokerus_days(&self) -> i32; -// fn encryption_constant(&self) -> u32; -// fn pid(&self) -> u32; - -// // misc -// fn language(&self) -> Language; -// fn is_fateful_encounter(&self) -> bool; - -// // battle -// fn move1(&self) -> u16; -// fn move2(&self) -> u16; -// fn move3(&self) -> u16; -// fn move4(&self) -> u16; -// fn pp_move1(&self) -> u8; -// fn pp_move2(&self) -> u8; -// fn pp_move3(&self) -> u8; -// fn pp_move4(&self) -> u8; -// fn pp_up_move1(&self) -> u8; -// fn pp_up_move2(&self) -> u8; -// fn pp_up_move3(&self) -> u8; -// fn pp_up_move4(&self) -> u8; -// fn ev_hp(&self) -> u8; -// fn ev_attack(&self) -> u8; -// fn ev_defense(&self) -> u8; -// fn ev_speed(&self) -> u8; -// fn ev_sp_attack(&self) -> u8; -// fn ev_sp_defense(&self) -> u8; -// fn iv_hp(&self) -> IV; -// fn iv_attack(&self) -> IV; -// fn iv_defense(&self) -> IV; -// fn iv_speed(&self) -> IV; -// fn iv_sp_attack(&self) -> IV; -// fn iv_sp_defense(&self) -> IV; -// fn status_condition(&self) -> StatusCondition; -// fn stat_hp_max(&self) -> u16; -// fn stat_hp_current(&self) -> u16; -// fn stat_attack(&self) -> u16; -// fn stat_defense(&self) -> u16; -// fn stat_speed(&self) -> u16; -// fn stat_sp_attack(&self) -> u16; -// fn stat_sp_defense(&self) -> u16; -// } +impl

From

for Pokemon

{ + fn from(value: P) -> Self { + Self { + pkm: value, + pending_progressions: Vec::new(), + } + } +}