Further massive amounts of work

This commit is contained in:
2022-06-06 13:54:59 +02:00
parent df662ce6b5
commit ce33ec0649
33 changed files with 848 additions and 80 deletions

View File

@@ -22,6 +22,10 @@ impl GrowthRate for LookupGrowthRate {
}
fn calculate_experience(&self, level: LevelInt) -> u32 {
self.experience[(level - 1) as usize]
if level >= self.experience.len() as LevelInt {
*self.experience.last().unwrap()
} else {
self.experience[(level - 1) as usize]
}
}
}

View File

@@ -1,5 +1,5 @@
use crate::utils::random::Random;
use std::collections::HashMap;
use hashbrown::HashMap;
pub trait DataLibrary<'a, T: 'a> {
fn map(&self) -> &HashMap<String, T>;

View File

@@ -1,6 +1,6 @@
use crate::defines::LevelInt;
use crate::static_data::growth_rates::growth_rate::GrowthRate;
use std::collections::HashMap;
use hashbrown::HashMap;
use std::fmt;
use std::fmt::{Debug, Formatter};
@@ -42,7 +42,10 @@ pub mod tests {
// Borrow as mut so we can insert
let w = &mut lib;
w.add_growth_rate("foo", Box::new(LookupGrowthRate::new(vec![0, 5, 10, 100])));
w.add_growth_rate(
"test_growthrate",
Box::new(LookupGrowthRate::new(vec![0, 5, 10, 100])),
);
// Drops borrow as mut
lib
@@ -51,14 +54,14 @@ pub mod tests {
#[test]
fn add_growth_rate_to_library_and_calculate_level() {
let lib = build();
assert_eq!(lib.calculate_level("foo", 3), 1);
assert_eq!(lib.calculate_level("foo", 50), 3);
assert_eq!(lib.calculate_level("test_growthrate", 3), 1);
assert_eq!(lib.calculate_level("test_growthrate", 50), 3);
}
#[test]
fn add_growth_rate_to_library_and_calculate_experience() {
let lib = build();
assert_eq!(lib.calculate_experience("foo", 1), 0);
assert_eq!(lib.calculate_experience("foo", 3), 10);
assert_eq!(lib.calculate_experience("test_growthrate", 1), 0);
assert_eq!(lib.calculate_experience("test_growthrate", 3), 10);
}
}

View File

@@ -1,6 +1,6 @@
use crate::static_data::items::item::Item;
use crate::static_data::libraries::data_library::DataLibrary;
use std::collections::HashMap;
use hashbrown::HashMap;
#[derive(Debug)]
pub struct ItemLibrary {

View File

@@ -1,6 +1,6 @@
use crate::static_data::libraries::data_library::DataLibrary;
use crate::static_data::moves::move_data::MoveData;
use std::collections::HashMap;
use hashbrown::HashMap;
#[derive(Debug)]
pub struct MoveLibrary {

View File

@@ -1,6 +1,6 @@
use crate::static_data::libraries::data_library::DataLibrary;
use crate::static_data::species_data::species::Species;
use std::collections::HashMap;
use hashbrown::HashMap;
#[derive(Debug)]
pub struct SpeciesLibrary<'a> {
@@ -39,14 +39,14 @@ pub mod tests {
use crate::static_data::species_data::learnable_moves::LearnableMoves;
use crate::static_data::species_data::species::Species;
use crate::static_data::statistic_set::StatisticSet;
use std::collections::HashSet;
use hashbrown::HashSet;
fn build_species<'a>() -> Species<'a> {
Species::new(
0,
"foo",
0.5,
"",
"test_growthrate",
0,
Form::new(
"default",

View File

@@ -4,6 +4,7 @@ use crate::static_data::libraries::library_settings::LibrarySettings;
use crate::static_data::libraries::move_library::MoveLibrary;
use crate::static_data::libraries::species_library::SpeciesLibrary;
use crate::static_data::libraries::type_library::TypeLibrary;
use crate::static_data::natures::NatureLibrary;
use derive_getters::Getters;
#[derive(Getters, Debug)]
@@ -14,6 +15,7 @@ pub struct StaticData<'a> {
items: ItemLibrary,
growth_rates: GrowthRateLibrary,
types: TypeLibrary,
natures: NatureLibrary,
}
#[cfg(test)]
@@ -23,6 +25,7 @@ pub mod test {
use crate::static_data::libraries::{
growth_rate_library, item_library, move_library, species_library, type_library,
};
use crate::static_data::natures;
pub fn build<'a>() -> StaticData<'a> {
StaticData {
@@ -32,6 +35,7 @@ pub mod test {
items: item_library::tests::build(),
growth_rates: growth_rate_library::tests::build(),
types: type_library::tests::build(),
natures: natures::tests::build(),
}
}
}

View File

@@ -1,4 +1,4 @@
use std::collections::HashMap;
use hashbrown::HashMap;
#[derive(Debug)]
pub struct TypeLibrary {

View File

@@ -2,6 +2,7 @@ pub mod growth_rates;
pub mod items;
pub mod libraries;
pub mod moves;
pub mod natures;
pub mod species_data;
pub mod statistic_set;
pub mod statistics;

131
src/static_data/natures.rs Normal file
View File

@@ -0,0 +1,131 @@
use crate::static_data::statistics::Statistic;
use hashbrown::HashMap;
#[derive(Debug)]
pub struct Nature {
increase_stat: Statistic,
decrease_stat: Statistic,
increase_modifier: f32,
decrease_modifier: f32,
}
impl Nature {
pub fn new(
increase_stat: Statistic,
decrease_stat: Statistic,
increase_modifier: f32,
decrease_modifier: f32,
) -> Self {
Self {
increase_stat,
decrease_stat,
increase_modifier,
decrease_modifier,
}
}
pub fn increased_stat(&self) -> Statistic {
self.increase_stat
}
pub fn decreased_stat(&self) -> Statistic {
self.decrease_stat
}
pub fn get_stat_modifier(&self, stat: Statistic) -> f32 {
if stat == self.increase_stat {
self.increase_modifier
} else if stat == self.decrease_stat {
self.decrease_modifier
} else {
1.0
}
}
}
#[derive(Debug)]
pub struct NatureLibrary {
map: HashMap<String, Nature>,
}
impl NatureLibrary {
pub fn new(capacity: usize) -> Self {
NatureLibrary {
map: HashMap::with_capacity(capacity),
}
}
pub fn load_nature(&mut self, name: &str, nature: Nature) {
self.map.insert(name.to_string(), nature);
}
pub fn get_nature(&self, key: &str) -> Option<&Nature> {
self.map.get(key)
}
pub fn get_nature_name(&self, nature: &Nature) -> String {
for kv in &self.map {
// As natures can't be copied, and should always be the same reference as the value
// in the map, we just compare by reference.
if (kv.1 as *const Nature) == (nature as *const Nature) {
return kv.0.to_string();
}
}
panic!("No name was found for the given nature. This should never happen.");
}
}
#[cfg(test)]
pub mod tests {
use crate::static_data::natures::{Nature, NatureLibrary};
use crate::static_data::statistics::Statistic;
pub fn build() -> NatureLibrary {
let mut lib = NatureLibrary::new(2);
lib.load_nature(
"test_nature",
Nature::new(Statistic::HP, Statistic::Attack, 1.1, 0.9),
);
lib
}
#[test]
fn create_nature_library_insert_and_retrieve() {
let mut lib = NatureLibrary::new(2);
lib.load_nature(
"foo",
Nature::new(Statistic::HP, Statistic::Attack, 1.1, 0.9),
);
lib.load_nature(
"bar",
Nature::new(Statistic::Attack, Statistic::Defense, 1.1, 0.9),
);
let n1 = lib.get_nature("foo").expect("Nature was not found");
assert_eq!(n1.increase_stat, Statistic::HP);
assert_eq!(n1.decrease_stat, Statistic::Attack);
assert_eq!(n1.increase_modifier, 1.1);
assert_eq!(n1.decrease_modifier, 0.9);
}
#[test]
fn create_nature_library_insert_and_get_name() {
let mut lib = NatureLibrary::new(2);
lib.load_nature(
"foo",
Nature::new(Statistic::HP, Statistic::Attack, 1.1, 0.9),
);
lib.load_nature(
"bar",
Nature::new(Statistic::Attack, Statistic::Defense, 1.1, 0.9),
);
let n1 = lib.get_nature("foo").expect("Nature was not found");
let name = lib.get_nature_name(n1);
assert_eq!(name, "foo");
let n2 = lib.get_nature("bar").expect("Nature was not found");
let name2 = lib.get_nature_name(n2);
assert_eq!(name2, "bar");
}
}

View File

@@ -4,7 +4,7 @@ use crate::static_data::statistic_set::StatisticSet;
use crate::static_data::statistics::Statistic;
use crate::utils::random::Random;
use derive_getters::Getters;
use std::collections::HashSet;
use hashbrown::HashSet;
#[derive(Getters, Debug)]
pub struct Form<'a> {

View File

@@ -1,7 +1,7 @@
use crate::defines::LevelInt;
use crate::static_data::moves::move_data::MoveData;
use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::collections::HashMap;
use hashbrown::hash_map::Entry::{Occupied, Vacant};
use hashbrown::HashMap;
#[derive(Default, PartialEq, Debug)]
pub struct LearnableMoves<'a> {
@@ -45,7 +45,6 @@ mod tests {
#[test]
fn adds_level_moves() {
let mut moves = LearnableMoves::new();
let move1 = MoveData::new(
"foo",
0,
@@ -70,6 +69,8 @@ mod tests {
SecondaryEffect::empty(),
Default::default(),
);
let mut moves = LearnableMoves::new();
moves.add_level_move(1, &move1);
moves.add_level_move(1, &move2);
@@ -81,7 +82,6 @@ mod tests {
#[test]
fn adds_two_same_moves_at_different_level() {
let mut moves = LearnableMoves::new();
let move1 = MoveData::new(
"foo",
0,
@@ -94,6 +94,8 @@ mod tests {
SecondaryEffect::empty(),
Default::default(),
);
let mut moves = LearnableMoves::new();
moves.add_level_move(1, &move1);
moves.add_level_move(5, &move1);

View File

@@ -2,7 +2,7 @@ use self::super::form::Form;
use crate::static_data::species_data::gender::Gender;
use crate::utils::random::Random;
use derive_getters::Getters;
use std::collections::{HashMap, HashSet};
use hashbrown::{HashMap, HashSet};
#[derive(Debug, Getters)]
pub struct Species<'a> {
@@ -25,15 +25,15 @@ impl<'a> Species<'a> {
default_form: Form<'a>,
flags: HashSet<String>,
) -> Species<'a> {
let mut forms = HashMap::with_capacity(1);
forms.insert("default".to_string(), default_form);
Species {
id,
name: name.to_string(),
gender_rate,
growth_rate: growth_rate.to_string(),
capture_rate,
forms: hashmap! {
"default".to_string() => default_form,
},
forms,
flags,
}
}

View File

@@ -19,6 +19,24 @@ impl<T> StatisticSet<T>
where
T: PrimInt,
{
pub fn new(
hp: T,
attack: T,
defense: T,
special_attack: T,
special_defense: T,
speed: T,
) -> Self {
Self {
hp,
attack,
defense,
special_attack,
special_defense,
speed,
}
}
pub const fn get_stat(&self, stat: Statistic) -> T {
match stat {
Statistic::HP => self.hp,
@@ -63,3 +81,91 @@ where
}
}
}
#[derive(Default, Eq, PartialEq, Copy, Clone, Debug, Getters)]
pub struct ClampedStatisticSet<T, const MIN: i64, const MAX: i64>
where
T: PrimInt,
{
hp: T,
attack: T,
defense: T,
special_attack: T,
special_defense: T,
speed: T,
}
impl<T, const MIN: i64, const MAX: i64> ClampedStatisticSet<T, MIN, MAX>
where
T: PrimInt,
{
pub const fn get_stat(&self, stat: Statistic) -> T {
match stat {
Statistic::HP => self.hp,
Statistic::Attack => self.attack,
Statistic::Defense => self.defense,
Statistic::SpecialAttack => self.special_attack,
Statistic::SpecialDefense => self.special_defense,
Statistic::Speed => self.speed,
}
}
pub fn set_stat(&mut self, stat: Statistic, mut value: T) {
if value < T::from(MIN).unwrap() {
value = T::from(MIN).unwrap();
} else if value > T::from(MAX).unwrap() {
value = T::from(MAX).unwrap();
}
match stat {
Statistic::HP => self.hp = value,
Statistic::Attack => self.attack = value,
Statistic::Defense => self.defense = value,
Statistic::SpecialAttack => self.special_attack = value,
Statistic::SpecialDefense => self.special_defense = value,
Statistic::Speed => self.speed = value,
}
}
fn change_stat(mut new_value: T, original_value: &mut T) -> bool {
if new_value < T::from(MIN).unwrap() {
new_value = T::from(MIN).unwrap();
} else if new_value > T::from(MAX).unwrap() {
new_value = T::from(MAX).unwrap();
}
if *original_value == new_value {
return false;
}
*original_value = new_value;
true
}
pub fn increase_stat(&mut self, stat: Statistic, value: T) -> bool {
match stat {
Statistic::HP => Self::change_stat(self.hp + value, &mut self.hp),
Statistic::Attack => Self::change_stat(self.attack + value, &mut self.attack),
Statistic::Defense => Self::change_stat(self.defense + value, &mut self.defense),
Statistic::SpecialAttack => {
Self::change_stat(self.special_attack + value, &mut self.special_attack)
}
Statistic::SpecialDefense => {
Self::change_stat(self.special_defense + value, &mut self.special_defense)
}
Statistic::Speed => Self::change_stat(self.speed + value, &mut self.speed),
}
}
pub fn decrease_stat(&mut self, stat: Statistic, value: T) -> bool {
match stat {
Statistic::HP => Self::change_stat(self.hp - value, &mut self.hp),
Statistic::Attack => Self::change_stat(self.attack - value, &mut self.attack),
Statistic::Defense => Self::change_stat(self.defense - value, &mut self.defense),
Statistic::SpecialAttack => {
Self::change_stat(self.special_attack - value, &mut self.special_attack)
}
Statistic::SpecialDefense => {
Self::change_stat(self.special_defense - value, &mut self.special_defense)
}
Statistic::Speed => Self::change_stat(self.speed - value, &mut self.speed),
}
}
}

View File

@@ -1,4 +1,4 @@
#[derive(Debug, PartialEq)]
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum Statistic {
HP,
Attack,