diff --git a/src/dynamic_data/models/battle_party.rs b/src/dynamic_data/models/battle_party.rs index 58a9cbc..2fcd692 100755 --- a/src/dynamic_data/models/battle_party.rs +++ b/src/dynamic_data/models/battle_party.rs @@ -2,12 +2,15 @@ use std::sync::Arc; use crate::dynamic_data::models::pokemon::Pokemon; use crate::dynamic_data::models::pokemon_party::PokemonParty; +use crate::{ValueIdentifiable, ValueIdentifier}; /// A battle party is a wrapper around a party, with the indices for which the party is responsible /// on the field attached. #[derive(Debug)] #[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))] pub struct BattleParty { + /// A unique identifier so we know what value this is. + identifier: ValueIdentifier, /// The party the BattleParty is holding. party: Arc, /// The indices for which the party is responsible, in the format (side, index) @@ -19,6 +22,7 @@ impl BattleParty { /// for. pub fn new(party: Arc, responsible_indices: Vec<(u8, u8)>) -> Self { Self { + identifier: Default::default(), party, responsible_indices, } @@ -54,3 +58,9 @@ impl BattleParty { &self.party } } + +impl ValueIdentifiable for BattleParty { + fn value_identifier(&self) -> ValueIdentifier { + self.identifier + } +} diff --git a/src/ffi/dynamic_data/models/battle_party.rs b/src/ffi/dynamic_data/models/battle_party.rs new file mode 100644 index 0000000..2e761fc --- /dev/null +++ b/src/ffi/dynamic_data/models/battle_party.rs @@ -0,0 +1,55 @@ +use crate::dynamic_data::{BattleParty, Pokemon, PokemonParty}; +use crate::ffi::{ExternPointer, IdentifiablePointer}; +use std::sync::Arc; + +/// A battle party is a wrapper around a party, with the indices for which the party is responsible +/// on the field attached. The indices are stored +#[no_mangle] +extern "C" fn battle_party_new( + party: ExternPointer>, + responsible_indices_ptr: *const u8, + responsible_indices_length: usize, +) -> IdentifiablePointer> { + if responsible_indices_length % 2 == 1 { + panic!("The length of responsible indices should be dividable by two"); + } + let responsible_indices_slice = + unsafe { std::slice::from_raw_parts(responsible_indices_ptr, responsible_indices_length) }; + let mut responsible_indices: Vec<(u8, u8)> = Vec::with_capacity(responsible_indices_length / 2); + for i in 0..responsible_indices_length / 2 { + responsible_indices[i] = (responsible_indices_slice[i * 2], responsible_indices_slice[i * 2 + 1]) + } + + Arc::new(BattleParty::new(party.as_ref().clone(), responsible_indices)).into() +} + +/// Checks whether the party is responsible for the given index. +#[no_mangle] +extern "C" fn battle_party_is_responsible_for_index(ptr: ExternPointer>, side: u8, index: u8) -> u8 { + u8::from(ptr.as_ref().is_responsible_for_index(side, index)) +} + +/// Whether or not the party has non fainted Pokemon that could be thrown out into the field. +#[no_mangle] +extern "C" fn battle_party_has_pokemon_not_in_field(ptr: ExternPointer>) -> u8 { + u8::from(ptr.as_ref().has_pokemon_not_in_field()) +} + +/// Gets a Pokemon at an index. +#[no_mangle] +extern "C" fn battle_party_get_pokemon( + ptr: ExternPointer>, + index: usize, +) -> IdentifiablePointer> { + if let Some(v) = ptr.as_ref().get_pokemon(index) { + v.into() + } else { + IdentifiablePointer::none() + } +} + +/// Gets the underlying Pokemon Party +#[no_mangle] +extern "C" fn battle_party_party(ptr: ExternPointer>) -> IdentifiablePointer> { + ptr.as_ref().party().clone().into() +} diff --git a/src/ffi/dynamic_data/models/mod.rs b/src/ffi/dynamic_data/models/mod.rs index d79f48f..089d13a 100644 --- a/src/ffi/dynamic_data/models/mod.rs +++ b/src/ffi/dynamic_data/models/mod.rs @@ -1,3 +1,5 @@ +/// The foreign function interface for a battle wrapper of a party. +mod battle_party; /// The foreign function interface for a Learned Move. mod learned_move; /// The foreign function interface for a Pokemon.