use crate::dynamic_data::{BattleParty, Pokemon, PokemonParty}; use crate::ffi::ffi_handle::{FFIHandle, FromFFIHandle}; use crate::ffi::FFIResult; use crate::VecExt; use anyhow::{anyhow, Result}; 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: FFIHandle>, responsible_indices_ptr: *const u8, responsible_indices_length: usize, ) -> FFIResult>> { if responsible_indices_length % 2 != 0 { return FFIResult::err(anyhow!("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); let mut split = |i| -> Result<()> { *responsible_indices.get_mut_res(i)? = ( *responsible_indices_slice.get_res(i * 2)?, *responsible_indices_slice.get_res(i * 2 + 1)?, ); Ok(()) }; for i in 0..responsible_indices_length / 2 { match split(i) { Ok(_) => (), Err(e) => return FFIResult::err(e), } } match BattleParty::new(party.from_ffi_handle(), responsible_indices) { Ok(v) => FFIResult::ok(FFIHandle::get_handle(Arc::new(v).into())), Err(e) => FFIResult::err(e), } } /// Checks whether the party is responsible for the given index. #[no_mangle] extern "C" fn battle_party_is_responsible_for_index(ptr: FFIHandle>, side: u8, index: u8) -> u8 { u8::from(ptr.from_ffi_handle().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: FFIHandle>) -> u8 { u8::from(ptr.from_ffi_handle().has_pokemon_not_in_field()) } /// Gets a Pokemon at an index. #[no_mangle] extern "C" fn battle_party_get_pokemon(ptr: FFIHandle>, index: usize) -> FFIHandle { if let Some(v) = ptr.from_ffi_handle().get_pokemon(index) { FFIHandle::get_handle(v.into()) } else { FFIHandle::none() } } /// Gets the underlying Pokemon Party #[no_mangle] extern "C" fn battle_party_party(ptr: FFIHandle>) -> FFIHandle> { FFIHandle::get_handle(ptr.from_ffi_handle().party().clone().into()) }