use crate::dynamic_data::{FleeChoice, LearnedMove, MoveChoice, PassChoice, Pokemon, TurnChoice}; use crate::ffi::{ExternPointer, IdentifiablePointer, NativeResult, OwnedPtr}; use anyhow::anyhow; use std::ptr::drop_in_place; use std::sync::Arc; /// Disposes a turn choice. #[no_mangle] extern "C" fn turn_choice_drop(choice: OwnedPtr) { unsafe { drop_in_place(choice) } } /// Get the user of the given choice. #[no_mangle] extern "C" fn turn_choice_user(choice: ExternPointer) -> IdentifiablePointer> { choice.as_ref().user().clone().into() } /// Get the speed of the user for the choice. Note that this speed is the speed of the Pokemon /// at the start of the turn! #[no_mangle] extern "C" fn turn_choice_speed(choice: ExternPointer) -> u32 { choice.as_ref().speed() } /// Gets whether or not the choice has failed. If we notice this when we execute the choice, we /// will not execute it. #[no_mangle] extern "C" fn turn_choice_has_failed(choice: ExternPointer) -> u8 { u8::from(choice.as_ref().has_failed()) } /// Fails the choice. This will prevent it from executing and run a specific fail handling during /// execution. Note that this can not be undone. #[no_mangle] extern "C" fn turn_choice_fail(choice: ExternPointer) { choice.as_ref().fail() } /// Creates a new Turn Choice with a move to use. #[no_mangle] extern "C" fn turn_choice_move_new( user: ExternPointer>, learned_move: ExternPointer>, target_side: u8, target_index: u8, ) -> IdentifiablePointer { Box::new(TurnChoice::Move(MoveChoice::new( user.as_ref().clone(), learned_move.as_ref().clone(), target_side, target_index, ))) .into() } /// The actual learned move on the Pokemon we use for this choice. #[no_mangle] extern "C" fn turn_choice_move_learned_move( choice: ExternPointer, ) -> NativeResult>> { if let TurnChoice::Move(c) = choice.as_ref() { return NativeResult::ok(c.used_move().clone().into()); } NativeResult::err(anyhow!("Turn choice was not a learned move")) } /// The target side the move is aimed at. #[no_mangle] extern "C" fn turn_choice_move_target_side(choice: ExternPointer) -> NativeResult { if let TurnChoice::Move(c) = choice.as_ref() { return NativeResult::ok(c.target_side()); } NativeResult::err(anyhow!("Turn choice was not a learned move")) } /// The Pokemon index on the side we're aiming at. #[no_mangle] extern "C" fn turn_choice_move_target_index(choice: ExternPointer) -> NativeResult { if let TurnChoice::Move(c) = choice.as_ref() { return NativeResult::ok(c.target_index()); } NativeResult::err(anyhow!("Turn choice was not a learned move")) } /// The priority of the move choice at the beginning of the turn. #[no_mangle] extern "C" fn turn_choice_move_priority(choice: ExternPointer) -> NativeResult { if let TurnChoice::Move(c) = choice.as_ref() { return NativeResult::ok(c.priority()); } NativeResult::err(anyhow!("Turn choice was not a learned move")) } /// Creates a new Turn Choice for the user to flee. #[no_mangle] extern "C" fn turn_choice_flee_new(user: ExternPointer>) -> IdentifiablePointer { Box::new(TurnChoice::Flee(FleeChoice::new(user.as_ref().clone()))).into() } /// Creates a new Turn Choice for the user to pass the turn. #[no_mangle] extern "C" fn turn_choice_pass_new(user: ExternPointer>) -> IdentifiablePointer { Box::new(TurnChoice::Pass(PassChoice::new(user.as_ref().clone()))).into() }