1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
use core::ops::Range;
use serde::{Deserialize, Serialize};

use crate::{
    moves::MoveId,
    pokemon::{Level, Experience},
};


#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub enum Gender {
    Male,
    Female,
}

impl Gender {
    pub(crate) const RANGE: Range<u8> = 0..8;
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub struct LearnableMove(pub Level, pub MoveId);

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Training {
    pub base_exp: u16,
    #[serde(default)]
    pub growth_rate: GrowthRate,
    //pub ev_yield: Option<(String, usize)>,
    //pub catch_rate: Option<u8>,
    //pub base_friendship: Option<u8>,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Breeding {
    // pub groups: Vec<EggGroup>,
    /// Pokemon gender chance: None = no gender, 0 = 100% female, 7 = 100% male (0-8 scale)
    pub gender: Option<u8>,
    // pub cycles: Option<u8>,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum GrowthRate {
    Slow,
    Fast,
    Medium,
    MediumSlow,
    FastThenVerySlow,
    SlowThenVeryFast,
}

impl Default for GrowthRate {
    fn default() -> Self {
        Self::MediumSlow
    }
}

impl GrowthRate {
    pub fn max_exp(self, level: Level) -> Experience {
        (match level as i32 {
            0 => 0,
            1 => 1,
            level => match self {
                GrowthRate::Slow => 5 * (level.pow(3) >> 2),
                GrowthRate::Fast => (level.pow(3) << 2) / 5,
                GrowthRate::Medium => level.pow(3),
                GrowthRate::MediumSlow => {
                    (6 * level.pow(3)) / 5 - (15 * level.pow(2)) + (100 * level) - 140
                }
                _ => {
                    (1.2 * level.pow(3) as f32) as i32 - 15 * level.pow(2) as i32
                        + 100 * level as i32
                        - 140
                } // MediumSlow
            },
        }) as Experience
    }
}