use hashbrown::HashSet; use crate::static_data::LearnableMoves; use crate::static_data::Statistic; use crate::static_data::{Ability, StaticStatisticSet}; use crate::static_data::{AbilityIndex, TypeIdentifier}; use crate::Random; use crate::StringKey; /// A form is a variant of a specific species. A species always has at least one form, but can have /// many more. #[derive(Debug)] pub struct Form { /// The name of the form. name: StringKey, /// The height of the form in meters. height: f32, /// The weight of the form in kilograms. weight: f32, /// The base amount of experience that is gained when beating a Pokemon with this form. base_experience: u32, /// The normal types a Pokemon with this form has. types: Vec, /// The inherent values of a form of species that are used for the stats of a Pokemon. base_stats: StaticStatisticSet, /// The possible abilities a Pokemon with this form can have. abilities: Vec, /// The possible hidden abilities a Pokemon with this form can have. hidden_abilities: Vec, /// The moves a Pokemon with this form can learn. moves: LearnableMoves, /// Arbitrary flags can be set on a form for scripting use. flags: HashSet, } impl Form { /// Instantiates a new form. pub fn new( name: &StringKey, height: f32, weight: f32, base_experience: u32, types: Vec, base_stats: StaticStatisticSet, abilities: Vec, hidden_abilities: Vec, moves: LearnableMoves, flags: HashSet, ) -> Form { Form { name: name.clone(), height, weight, base_experience, types, base_stats, abilities, hidden_abilities, moves, flags, } } /// The name of the form. pub fn name(&self) -> &StringKey { &self.name } /// The height of the form in meters. pub fn height(&self) -> f32 { self.height } /// The weight of the form in kilograms. pub fn weight(&self) -> f32 { self.weight } /// The base amount of experience that is gained when beating a Pokemon with this form. pub fn base_experience(&self) -> u32 { self.base_experience } /// The normal types a Pokemon with this form has. pub fn types(&self) -> &Vec { &self.types } /// The inherent values of a form of species that are used for the stats of a Pokemon. pub fn base_stats(&self) -> &StaticStatisticSet { &self.base_stats } /// The possible abilities a Pokemon with this form can have. pub fn abilities(&self) -> &Vec { &self.abilities } /// The possible hidden abilities a Pokemon with this form can have. pub fn hidden_abilities(&self) -> &Vec { &self.hidden_abilities } /// The moves a Pokemon with this form can learn. pub fn moves(&self) -> &LearnableMoves { &self.moves } /// Arbitrary flags can be set on a form for scripting use. pub fn flags(&self) -> &HashSet { &self.flags } /// Get a type of the move at a certain index. pub fn get_type(&self, index: usize) -> TypeIdentifier { self.types[index] } /// Gets a single base stat value. pub fn get_base_stat(&self, stat: Statistic) -> u16 { self.base_stats.get_stat(stat) } /// Find the index of an ability that can be on this form. pub fn find_ability_index(&self, ability: &Ability) -> Option { for (index, a) in self.abilities.iter().enumerate() { if a == ability.name() { return Some(AbilityIndex { hidden: false, index: index as u8, }); } } for (index, a) in self.hidden_abilities.iter().enumerate() { if a == ability.name() { return Some(AbilityIndex { hidden: true, index: index as u8, }); } } None } /// Gets an ability from the form. pub fn get_ability(&self, index: AbilityIndex) -> &StringKey { if index.hidden { &self.hidden_abilities[index.index as usize] } else { &self.abilities[index.index as usize] } } /// Gets a random ability from the form. pub fn get_random_ability(&self, rand: &mut Random) -> &StringKey { &self.abilities[rand.get_between_unsigned(0, self.abilities.len() as u32) as usize] } /// Gets a random hidden ability from the form. pub fn get_random_hidden_ability(&self, rand: &mut Random) -> &StringKey { &self.hidden_abilities[rand.get_between_unsigned(0, self.hidden_abilities.len() as u32) as usize] } /// Check if the form has a specific flag set. pub fn has_flag(&self, key: &StringKey) -> bool { self.flags.contains(key) } }