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

137 lines
4.4 KiB
Rust

use crate::app_interface::{LearnedMove, Pokemon};
use crate::handling::cached_value::CachedValue;
use crate::handling::temporary::Temporary;
use crate::{cached_value, wasm_value_getters, ExternRef, ExternalReferenceType, Script};
use alloc::boxed::Box;
use alloc::rc::Rc;
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)]
struct MoveTurnChoiceDataTemporary {
inner: Rc<MoveTurnChoiceDataInner>,
}
pub struct MoveTurnChoiceData {
temp: Temporary<MoveTurnChoiceDataTemporary>,
}
pub enum TurnChoice {
Move(MoveTurnChoiceData),
Item(),
Switch(),
Flee,
Pass,
}
impl TurnChoice {
fn base(&self) -> &BaseTurnChoiceData {
match self {
TurnChoice::Move(d) => &d.temp.value_ref().inner.base,
TurnChoice::Item() => unimplemented!(),
TurnChoice::Switch() => unimplemented!(),
TurnChoice::Flee => unimplemented!(),
TurnChoice::Pass => unimplemented!(),
}
}
pub fn user(&self) -> Pokemon {
self.base().user.value()
}
pub fn speed(&self) -> u32 {
unsafe { turn_choice_get_speed(self.base().reference) }
}
pub fn has_failed(&self) -> bool {
unsafe { turn_choice_has_failed(self.base().reference) }
}
pub fn fail(&self) {
unsafe { turn_choice_fail(self.base().reference) }
}
}
impl MoveTurnChoiceData {
pub fn used_move(&self) -> LearnedMove {
self.temp.value().inner.used_move.value()
}
pub fn target_side(&self) -> u8 {
self.temp.value().inner.target_side.value()
}
pub fn target_index(&self) -> u8 {
self.temp.value().inner.target_index.value()
}
pub fn priority(&self) -> i8 {
unsafe { turn_choice_move_priority(self.temp.value().inner.base.reference.cast()) }
}
pub fn move_script(&self) -> Option<&Box<dyn Script>> {
unsafe { turn_choice_move_script(self.temp.value().inner.base.reference.cast()).as_ref() }
}
}
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 {
temp: Temporary::from_reference(reference.cast()),
}),
_ => panic!("Unknown turn choice type"),
}
}
}
impl ExternalReferenceType for MoveTurnChoiceDataTemporary {
fn from_extern_value(reference: ExternRef<Self>) -> Self {
Self {
inner: Rc::new(MoveTurnChoiceDataInner {
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()) }),
}),
}
}
}
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;
fn turn_choice_move_script(r: ExternRef<MoveTurnChoiceData>) -> *const Box<dyn Script>;
}
#[no_mangle]
unsafe extern "wasm" fn turn_choice_mark_deleted(r: ExternRef<TurnChoice>, kind: u8) {
match kind {
0 => Temporary::<MoveTurnChoiceDataTemporary>::mark_as_deleted(r.cast()),
_ => panic!("Unknown turn choice type"),
}
}