Gen7ScriptsRs/pkmn_lib_interface/src/app_interface/dynamic_data/turn_choices.rs

139 lines
4.4 KiB
Rust
Executable File

use crate::app_interface::{LearnedMove, Pokemon};
use crate::handling::cached_value::CachedValue;
use crate::handling::temporary::Temporary;
use crate::ExternRef;
#[cfg(not(feature = "mock_data"))]
use crate::{cached_value, ExternalReferenceType, Script};
#[cfg(not(feature = "mock_data"))]
use alloc::boxed::Box;
struct BaseTurnChoiceData {
reference: ExternRef<TurnChoice>,
user: CachedValue<Pokemon>,
}
struct MoveTurnChoiceDataInner {
base: BaseTurnChoiceData,
used_move: CachedValue<LearnedMove>,
target_side: CachedValue<u8>,
target_index: CachedValue<u8>,
}
#[derive(Clone)]
pub struct MoveTurnChoiceData {
inner: Temporary<MoveTurnChoiceDataInner>,
}
pub enum TurnChoice {
Move(MoveTurnChoiceData),
Item(),
Switch(),
Flee,
Pass,
}
impl TurnChoice {
fn base(&self) -> &BaseTurnChoiceData {
match self {
TurnChoice::Move(d) => &d.inner.value_ref().base,
TurnChoice::Item() => unimplemented!(),
TurnChoice::Switch() => unimplemented!(),
TurnChoice::Flee => unimplemented!(),
TurnChoice::Pass => unimplemented!(),
}
}
pub fn user(&self) -> Pokemon {
self.base().user.value()
}
#[cfg(not(feature = "mock_data"))]
pub fn speed(&self) -> u32 {
unsafe { turn_choice_get_speed(self.base().reference) }
}
#[cfg(not(feature = "mock_data"))]
pub fn has_failed(&self) -> bool {
unsafe { turn_choice_has_failed(self.base().reference) }
}
#[cfg(not(feature = "mock_data"))]
pub fn fail(&self) {
unsafe { turn_choice_fail(self.base().reference) }
}
}
impl MoveTurnChoiceData {
pub fn used_move(&self) -> LearnedMove {
self.inner.value().used_move.value()
}
pub fn target_side(&self) -> u8 {
self.inner.value().target_side.value()
}
pub fn target_index(&self) -> u8 {
self.inner.value().target_index.value()
}
#[cfg(not(feature = "mock_data"))]
pub fn priority(&self) -> i8 {
unsafe { turn_choice_move_priority(self.inner.value().base.reference.cast()) }
}
#[cfg(not(feature = "mock_data"))]
pub fn move_script(&self) -> Option<&Box<dyn Script>> {
unsafe { turn_choice_move_script(self.inner.value().base.reference.cast()).as_ref() }
}
}
#[cfg(not(feature = "mock_data"))]
impl ExternalReferenceType for TurnChoice {
fn from_extern_value(reference: ExternRef<Self>) -> Self {
let kind = unsafe { turn_choice_get_kind(reference) };
match kind {
0 => TurnChoice::Move(MoveTurnChoiceData {
inner: Temporary::new(
reference.get_internal_index(),
MoveTurnChoiceDataInner::from_reference(reference.cast()),
),
}),
_ => panic!("Unknown turn choice type"),
}
}
}
#[cfg(not(feature = "mock_data"))]
impl MoveTurnChoiceDataInner {
fn from_reference(reference: ExternRef<MoveTurnChoiceData>) -> Self {
Self {
base: BaseTurnChoiceData {
reference: reference.cast(),
user: cached_value!({
turn_choice_get_user(reference.cast()).get_value().unwrap()
}),
},
used_move: cached_value!({
turn_choice_move_used_move(reference.cast())
.get_value()
.unwrap()
}),
target_side: cached_value!({ turn_choice_move_target_side(reference.cast()) }),
target_index: cached_value!({ turn_choice_move_target_index(reference.cast()) }),
}
}
}
#[cfg(not(feature = "mock_data"))]
extern "wasm" {
fn turn_choice_get_kind(r: ExternRef<TurnChoice>) -> u8;
fn turn_choice_get_user(r: ExternRef<TurnChoice>) -> ExternRef<Pokemon>;
fn turn_choice_get_speed(r: ExternRef<TurnChoice>) -> u32;
fn turn_choice_has_failed(r: ExternRef<TurnChoice>) -> bool;
fn turn_choice_fail(r: ExternRef<TurnChoice>);
fn turn_choice_move_used_move(r: ExternRef<MoveTurnChoiceData>) -> ExternRef<LearnedMove>;
fn turn_choice_move_target_side(r: ExternRef<MoveTurnChoiceData>) -> u8;
fn turn_choice_move_target_index(r: ExternRef<MoveTurnChoiceData>) -> u8;
fn turn_choice_move_priority(r: ExternRef<MoveTurnChoiceData>) -> i8;
#[allow(improper_ctypes)]
fn turn_choice_move_script(r: ExternRef<MoveTurnChoiceData>) -> *const Box<dyn Script>;
}