PkmnLib_rs/src/dynamic_data/models/pokemon_party.rs

106 lines
3.0 KiB
Rust
Executable File

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<Option<Arc<Pokemon>>>,
}
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<Option<Arc<Pokemon>>>) -> Self {
Self { pokemon }
}
/// Gets a Pokemon at an index in the party.
pub fn at(&self, index: usize) -> &Option<Arc<Pokemon>> {
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<Arc<Pokemon>>) -> Option<Arc<Pokemon>> {
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<Option<Arc<Pokemon>>> {
&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
}
}