PkmnLib_rs/src/ffi/dynamic_data/models/battle_party.rs

74 lines
2.5 KiB
Rust

use crate::dynamic_data::{BattleParty, Pokemon, PokemonParty};
use crate::ffi::{ExternPointer, IdentifiablePointer, NativeResult};
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: ExternPointer<Arc<PokemonParty>>,
responsible_indices_ptr: *const u8,
responsible_indices_length: usize,
) -> NativeResult<IdentifiablePointer<Arc<BattleParty>>> {
if responsible_indices_length % 2 != 0 {
return NativeResult::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 NativeResult::err(e),
}
}
match BattleParty::new(party.as_ref().clone(), responsible_indices) {
Ok(v) => NativeResult::ok(Arc::new(v).into()),
Err(e) => NativeResult::err(e),
}
}
/// Checks whether the party is responsible for the given index.
#[no_mangle]
extern "C" fn battle_party_is_responsible_for_index(ptr: ExternPointer<Arc<BattleParty>>, 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<Arc<BattleParty>>) -> 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<Arc<BattleParty>>,
index: usize,
) -> IdentifiablePointer<Arc<Pokemon>> {
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<Arc<BattleParty>>) -> IdentifiablePointer<Arc<PokemonParty>> {
ptr.as_ref().party().clone().into()
}