PkmnLib_rs/src/ffi/dynamic_data/choices.rs

106 lines
3.7 KiB
Rust

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<TurnChoice>) {
unsafe { drop_in_place(choice) }
}
/// Get the user of the given choice.
#[no_mangle]
extern "C" fn turn_choice_user(choice: ExternPointer<TurnChoice>) -> IdentifiablePointer<Arc<Pokemon>> {
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<TurnChoice>) -> 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<TurnChoice>) -> 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<TurnChoice>) {
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<Arc<Pokemon>>,
learned_move: ExternPointer<Arc<LearnedMove>>,
target_side: u8,
target_index: u8,
) -> IdentifiablePointer<TurnChoice> {
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<TurnChoice>,
) -> NativeResult<IdentifiablePointer<Arc<LearnedMove>>> {
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<TurnChoice>) -> NativeResult<u8> {
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<TurnChoice>) -> NativeResult<u8> {
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<TurnChoice>) -> NativeResult<i8> {
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<Arc<Pokemon>>) -> IdentifiablePointer<TurnChoice> {
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<Arc<Pokemon>>) -> IdentifiablePointer<TurnChoice> {
Box::new(TurnChoice::Pass(PassChoice::new(user.as_ref().clone()))).into()
}