use std::sync::Arc; use crate::dynamic_data::models::pokemon::Pokemon; /// A list of Pokemon belonging to a trainer. #[derive(Debug)] #[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))] pub struct PokemonParty { /// The underlying list of Pokemon. pokemon: Vec>>, } impl PokemonParty { /// Instantiates a party with a set size. pub fn new(size: usize) -> Self { let mut pokemon = Vec::with_capacity(size); for _i in 0..size { pokemon.push(None); } Self { pokemon } } /// Instantiates a party with a list. pub fn new_from_vec(pokemon: Vec>>) -> Self { Self { pokemon } } /// Gets a Pokemon at an index in the party. pub fn at(&self, index: usize) -> &Option> { let opt = self.pokemon.get(index); if let Some(v) = opt { v } else { &None } } /// Swaps two Pokemon in the party around. pub fn switch(&mut self, a: usize, b: usize) { self.pokemon.swap(a, b); } /// Sets the Pokemon at an index to a Pokemon, returning the old Pokemon. pub fn swap_into(&mut self, index: usize, pokemon: Option>) -> Option> { if index >= self.pokemon.len() { return pokemon; } let old = self.pokemon[index].as_ref().cloned(); self.pokemon[index] = pokemon; old } /// Whether or not the party still has Pokemon that can be used in battle. pub fn has_usable_pokemon(&self) -> bool { for pokemon in self.pokemon.iter().flatten() { if pokemon.is_usable() { return true; } } false } /// Get the length of the underlying list of Pokemon. pub fn length(&self) -> usize { self.pokemon.len() } /// Gets the underlying list of Pokemon. pub fn pokemon(&self) -> &Vec>> { &self.pokemon } /// Makes sure there are no empty spots in the party anymore, leaving the length the same. pub fn pack_party(&mut self) { let mut first_empty = None; let mut i = 0; loop { if self.pokemon[i].is_none() { if first_empty.is_none() { first_empty = Some(i) } } else if first_empty.is_some() { self.pokemon.swap(first_empty.unwrap(), i); i = first_empty.unwrap(); first_empty = None; } i += 1; if i >= self.pokemon.len() { break; } } } /// Checks if the party contains a given pokemon. pub fn has_pokemon(&self, pokemon: &Pokemon) -> bool { for p in &self.pokemon { if let Some(p) = p { if std::ptr::eq(p.as_ref(), pokemon) { return true; } } } false } }