xenua 1 year ago
parent
commit
25619d3656
Signed by: xenua
GPG Key ID: 8F93B68BD37255B8
  1. 71
      src/general.rs
  2. 32
      src/lib.rs
  3. 76
      src/pokemon/gen5.rs
  4. 107
      src/pokemon/mod.rs

71
src/general.rs

@ -1,3 +1,5 @@
use std::fmt::Display;
pub enum Generation { pub enum Generation {
One = 1, One = 1,
Two = 2, Two = 2,
@ -162,6 +164,7 @@ pub enum StatusCondition {
Toxic, Toxic,
} }
#[derive(Debug)]
pub enum Species { pub enum Species {
Bulbasaur, Bulbasaur,
Ivysaur, Ivysaur,
@ -1182,6 +1185,7 @@ pub enum Species {
Ogerpon, Ogerpon,
} }
#[derive(Debug)]
pub enum Ability { pub enum Ability {
Stench, Stench,
Drizzle, Drizzle,
@ -2559,6 +2563,67 @@ pub struct LearnedMove {
pub pp_up: u8, pub pp_up: u8,
} }
pub struct MoveSet( pub struct MoveSet(LearnedMove, 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<K> {
pub hp: K,
pub attack: K,
pub defense: K,
pub speed: K,
pub sp_attack: K,
pub sp_def: K,
}
pub type EVs = StatSpread<u8>;
pub struct IV(u8);
impl TryFrom<u8> for IV {
type Error = ();
fn try_from(value: u8) -> Result<Self, Self::Error> {
if value > 31 {
return Err(());
}
Ok(Self(value))
}
}
impl From<IV> for u8 {
fn from(value: IV) -> Self {
value.0
}
}
pub type IVs = StatSpread<IV>;

32
src/lib.rs

@ -7,37 +7,7 @@ use std::{
sync::atomic::{AtomicU32, Ordering}, sync::atomic::{AtomicU32, Ordering},
}; };
pub struct Pokemon { use general::{Gender, Generation, Language, Stat};
species: u32,
trainer_id: TrainerId,
generation: Generation,
nickname: Option<String>,
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,
}
)
}
}
pub trait RNG { pub trait RNG {
fn get(&self) -> u32; fn get(&self) -> u32;

76
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/ /// https://projectpokemon.org/home/docs/gen-5/bw-save-structure-r60/
pub struct PK5 { pub struct PK5 {
@ -82,6 +85,77 @@ pub struct PK5 {
mail_message: Mail5, 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<super::Progression> {
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<String> {
todo!()
}
fn held_item(&self) -> Option<Item> {
todo!()
}
fn current_hp(&self) -> u16 {
todo!()
}
fn max_hp(&self) -> u16 {
todo!()
}
fn effective_base_stats(&self) -> crate::general::StatSpread<u16> {
todo!()
}
fn move_set(&self) -> crate::general::MoveSet {
todo!()
}
}
pub struct Mail5 { pub struct Mail5 {
author_tid: u16, author_tid: u16,
author_sid: u16, author_sid: u16,

107
src/pokemon/mod.rs

@ -1,6 +1,9 @@
use std::io::Read; 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; pub mod gen5;
@ -18,6 +21,33 @@ pub trait PKM {
fn ot(&self) -> &Trainer; fn ot(&self) -> &Trainer;
fn gain_xp(&mut self, xp: u32) -> Vec<Progression>; fn gain_xp(&mut self, xp: u32) -> Vec<Progression>;
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<String>;
fn held_item(&self) -> Option<Item>;
fn current_hp(&self) -> u16;
fn max_hp(&self) -> u16;
fn effective_base_stats(&self) -> StatSpread<u16>;
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 { pub enum Progression {
@ -35,70 +65,11 @@ where
} }
} }
// pub trait Pokemon { impl<P> From<P> for Pokemon<P> {
// // main fn from(value: P) -> Self {
// fn species(&self) -> Species; Self {
// fn nickname(&self) -> String; pkm: value,
// fn held_item(&self) -> Item; pending_progressions: Vec::new(),
// 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;
// }

Loading…
Cancel
Save