A lot of work on type registration
This commit is contained in:
72
pkmn_lib_interface/src/app_interface/dynamic_data/battle.rs
Normal file
72
pkmn_lib_interface/src/app_interface/dynamic_data/battle.rs
Normal file
@@ -0,0 +1,72 @@
|
||||
use crate::app_interface::{BattleParty, BattleRandom, BattleSide, Pokemon};
|
||||
use crate::handling::cached_value::CachedValue;
|
||||
use crate::handling::Cacheable;
|
||||
use crate::{
|
||||
cached_value, cached_value_getters, wasm_value_getters, DynamicLibrary, ExternRef,
|
||||
ExternalReferenceType, ImmutableList, VecExternRef,
|
||||
};
|
||||
use alloc::rc::Rc;
|
||||
|
||||
struct BattleInner {
|
||||
reference: ExternRef<Battle>,
|
||||
library: CachedValue<DynamicLibrary>,
|
||||
parties: CachedValue<ImmutableList<BattleParty>>,
|
||||
sides: CachedValue<ImmutableList<BattleSide>>,
|
||||
random: CachedValue<BattleRandom>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Battle {
|
||||
inner: Rc<BattleInner>,
|
||||
}
|
||||
|
||||
impl Battle {
|
||||
pub fn new(reference: ExternRef<Battle>) -> Self {
|
||||
Self::from_ref(reference, &|reference| Self {
|
||||
inner: Rc::new(BattleInner {
|
||||
reference,
|
||||
library: cached_value!({ battle_get_library(reference).get_value().unwrap() }),
|
||||
parties: cached_value!({ battle_get_parties(reference).get_immutable_list() }),
|
||||
sides: cached_value!({ battle_get_sides(reference).get_immutable_list() }),
|
||||
random: cached_value!({ battle_get_random(reference).get_value().unwrap() }),
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
cached_value_getters! {
|
||||
pub fn library(&self) -> DynamicLibrary;
|
||||
pub fn parties(&self) -> ImmutableList<BattleParty>;
|
||||
pub fn sides(&self) -> ImmutableList<BattleSide>;
|
||||
}
|
||||
|
||||
pub fn get_pokemon(&self, side: u8, index: u8) -> Option<Pokemon> {
|
||||
unsafe { battle_get_pokemon(self.inner.reference, side, index).get_value() }
|
||||
}
|
||||
}
|
||||
|
||||
wasm_value_getters! {
|
||||
Battle,
|
||||
pub fn can_flee(&self) -> bool;
|
||||
pub fn number_of_sides(&self) -> u8;
|
||||
pub fn pokemon_per_side(&self) -> u8;
|
||||
pub fn has_ended(&self) -> bool;
|
||||
pub fn has_ended_conclusively(&self) -> bool;
|
||||
pub fn winning_side(&self) -> u8;
|
||||
pub fn current_turn(&self) -> u32;
|
||||
}
|
||||
|
||||
crate::handling::cacheable::cacheable!(Battle);
|
||||
|
||||
impl ExternalReferenceType for Battle {
|
||||
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
||||
Self::new(reference)
|
||||
}
|
||||
}
|
||||
|
||||
extern "wasm" {
|
||||
fn battle_get_library(r: ExternRef<Battle>) -> ExternRef<DynamicLibrary>;
|
||||
fn battle_get_parties(r: ExternRef<Battle>) -> VecExternRef<BattleParty>;
|
||||
fn battle_get_sides(r: ExternRef<Battle>) -> VecExternRef<BattleSide>;
|
||||
fn battle_get_random(r: ExternRef<Battle>) -> ExternRef<BattleRandom>;
|
||||
fn battle_get_pokemon(r: ExternRef<Battle>, side: u8, index: u8) -> ExternRef<Pokemon>;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
use crate::app_interface::Party;
|
||||
use crate::handling::cached_value::CachedValue;
|
||||
use crate::handling::Cacheable;
|
||||
use crate::{cached_value, cached_value_getters, ExternRef, ExternalReferenceType};
|
||||
use alloc::rc::Rc;
|
||||
|
||||
struct BattlePartyInner {
|
||||
reference: ExternRef<BattleParty>,
|
||||
party: CachedValue<Party>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct BattleParty {
|
||||
inner: Rc<BattlePartyInner>,
|
||||
}
|
||||
|
||||
impl BattleParty {
|
||||
pub fn new(reference: ExternRef<BattleParty>) -> Self {
|
||||
Self::from_ref(reference, &|reference| Self {
|
||||
inner: Rc::new(BattlePartyInner {
|
||||
reference,
|
||||
party: cached_value!({ battle_party_get_party(reference).get_value().unwrap() }),
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
cached_value_getters! {
|
||||
pub fn party(&self) -> Party;
|
||||
}
|
||||
}
|
||||
|
||||
crate::handling::cacheable::cacheable!(BattleParty);
|
||||
|
||||
impl ExternalReferenceType for BattleParty {
|
||||
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
||||
Self::new(reference)
|
||||
}
|
||||
}
|
||||
|
||||
extern "wasm" {
|
||||
fn battle_party_get_party(r: ExternRef<BattleParty>) -> ExternRef<Party>;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
use crate::{ExternRef, ExternalReferenceType};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct BattleRandom {
|
||||
reference: ExternRef<Self>,
|
||||
}
|
||||
|
||||
impl BattleRandom {
|
||||
pub fn get(&self) -> i32 {
|
||||
unsafe { battle_random_get(self.reference) }
|
||||
}
|
||||
pub fn get_max(&self, max: i32) -> i32 {
|
||||
unsafe { battle_random_get_max(self.reference, max) }
|
||||
}
|
||||
pub fn get_between(&self, min: i32, max: i32) -> i32 {
|
||||
unsafe { battle_random_get_between(self.reference, min, max) }
|
||||
}
|
||||
// TODO: effect_chance()
|
||||
}
|
||||
|
||||
impl ExternalReferenceType for BattleRandom {
|
||||
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
||||
Self { reference }
|
||||
}
|
||||
}
|
||||
|
||||
extern "wasm" {
|
||||
fn battle_random_get(r: ExternRef<BattleRandom>) -> i32;
|
||||
fn battle_random_get_max(r: ExternRef<BattleRandom>, max: i32) -> i32;
|
||||
fn battle_random_get_between(r: ExternRef<BattleRandom>, min: i32, max: i32) -> i32;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
use crate::app_interface::{Battle, Pokemon};
|
||||
use crate::handling::cached_value::CachedValue;
|
||||
use crate::handling::Cacheable;
|
||||
use crate::{
|
||||
cached_value, cached_value_getters, wasm_value_getters, ExternRef, ExternalReferenceType,
|
||||
};
|
||||
use alloc::rc::Rc;
|
||||
|
||||
struct BattleSideInner {
|
||||
reference: ExternRef<BattleSide>,
|
||||
side_index: CachedValue<u8>,
|
||||
pokemon_per_side: CachedValue<u8>,
|
||||
battle: CachedValue<Battle>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct BattleSide {
|
||||
inner: Rc<BattleSideInner>,
|
||||
}
|
||||
|
||||
impl BattleSide {
|
||||
pub fn new(reference: ExternRef<Self>) -> Self {
|
||||
Self::from_ref(reference, &|reference| Self {
|
||||
inner: Rc::new(BattleSideInner {
|
||||
reference,
|
||||
side_index: cached_value!({ battleside_get_side_index(reference) }),
|
||||
pokemon_per_side: cached_value!({ battleside_get_pokemon_per_side(reference) }),
|
||||
battle: cached_value!({ battleside_get_battle(reference).get_value().unwrap() }),
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
cached_value_getters! {
|
||||
pub fn side_index(&self) -> u8;
|
||||
pub fn pokemon_per_side(&self) -> u8;
|
||||
pub fn battle(&self) -> Battle;
|
||||
}
|
||||
|
||||
pub fn get_pokemon(&self, index: usize) -> Option<Pokemon> {
|
||||
unsafe { battleside_get_pokemon(self.inner.reference, index).get_value() }
|
||||
}
|
||||
}
|
||||
|
||||
wasm_value_getters! {
|
||||
BattleSide,
|
||||
pub fn has_fled_battle(&self) -> bool;
|
||||
pub fn is_defeated(&self) -> bool;
|
||||
}
|
||||
|
||||
crate::handling::cacheable::cacheable!(BattleSide);
|
||||
|
||||
impl ExternalReferenceType for BattleSide {
|
||||
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
||||
Self::new(reference)
|
||||
}
|
||||
}
|
||||
|
||||
extern "wasm" {
|
||||
fn battleside_get_side_index(r: ExternRef<BattleSide>) -> u8;
|
||||
fn battleside_get_pokemon_per_side(r: ExternRef<BattleSide>) -> u8;
|
||||
fn battleside_get_battle(r: ExternRef<BattleSide>) -> ExternRef<Battle>;
|
||||
fn battleside_get_pokemon(r: ExternRef<BattleSide>, index: usize) -> ExternRef<Pokemon>;
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
use crate::app_interface::StaticData;
|
||||
use crate::handling::cached_value::CachedValue;
|
||||
use crate::handling::Cacheable;
|
||||
use crate::{cached_value, ExternRef, ExternalReferenceType};
|
||||
use alloc::rc::Rc;
|
||||
|
||||
struct DynamicLibraryInner {
|
||||
ptr: ExternRef<DynamicLibrary>,
|
||||
static_data: CachedValue<StaticData>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct DynamicLibrary {
|
||||
inner: Rc<DynamicLibraryInner>,
|
||||
}
|
||||
|
||||
crate::handling::cacheable::cacheable!(DynamicLibrary);
|
||||
|
||||
impl DynamicLibrary {
|
||||
pub(crate) fn new(ptr: ExternRef<Self>) -> Self {
|
||||
Self::from_ref(ptr, &|ptr| Self {
|
||||
inner: Rc::new(DynamicLibraryInner {
|
||||
ptr,
|
||||
static_data: cached_value!({
|
||||
dynamic_library_get_static_data(ptr).get_value().unwrap()
|
||||
}),
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn data_library(&self) -> StaticData {
|
||||
self.inner.static_data.value()
|
||||
}
|
||||
}
|
||||
|
||||
impl ExternalReferenceType for DynamicLibrary {
|
||||
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
||||
DynamicLibrary::new(reference)
|
||||
}
|
||||
}
|
||||
|
||||
extern "wasm" {
|
||||
fn dynamic_library_get_static_data(ptr: ExternRef<DynamicLibrary>) -> ExternRef<StaticData>;
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
use crate::app_interface::MoveData;
|
||||
use crate::handling::cacheable::Cacheable;
|
||||
use crate::handling::cached_value::CachedValue;
|
||||
use crate::{
|
||||
cached_value, cached_value_getters, wasm_value_getters, ExternRef, ExternalReferenceType,
|
||||
};
|
||||
|
||||
use alloc::rc::Rc;
|
||||
|
||||
struct LearnedMoveInner {
|
||||
reference: ExternRef<LearnedMove>,
|
||||
move_data: CachedValue<MoveData>,
|
||||
learn_method: CachedValue<MoveLearnMethod>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Default)]
|
||||
#[repr(u8)]
|
||||
pub enum MoveLearnMethod {
|
||||
/// We do not know the learn method.
|
||||
#[default]
|
||||
Unknown = 0,
|
||||
/// The move was learned through level up.
|
||||
Level = 1,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct LearnedMove {
|
||||
inner: Rc<LearnedMoveInner>,
|
||||
}
|
||||
|
||||
crate::handling::cacheable::cacheable!(LearnedMove);
|
||||
|
||||
impl ExternalReferenceType for LearnedMove {
|
||||
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
||||
Self::new(reference)
|
||||
}
|
||||
}
|
||||
|
||||
impl LearnedMove {
|
||||
pub fn new(reference: ExternRef<Self>) -> Self {
|
||||
Self::from_ref(reference, &|reference| Self {
|
||||
inner: Rc::new(LearnedMoveInner {
|
||||
reference,
|
||||
move_data: cached_value!({
|
||||
learned_move_get_move_data(reference).get_value().unwrap()
|
||||
}),
|
||||
learn_method: cached_value!({ learned_move_get_learn_method(reference) }),
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
cached_value_getters! {
|
||||
pub fn move_data(&self) -> MoveData;
|
||||
pub fn learn_method(&self) -> MoveLearnMethod;
|
||||
}
|
||||
|
||||
pub fn restore_all_uses(&self) {
|
||||
unsafe {
|
||||
learned_move_restore_all_uses(self.inner.reference);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn restore_uses(&self, uses: u8) {
|
||||
unsafe {
|
||||
learned_move_restore_uses(self.inner.reference, uses);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wasm_value_getters! {
|
||||
LearnedMove,
|
||||
pub fn max_pp(&self) -> u8;
|
||||
pub fn remaining_pp(&self) -> u8;
|
||||
}
|
||||
|
||||
extern "wasm" {
|
||||
fn learned_move_get_move_data(r: ExternRef<LearnedMove>) -> ExternRef<MoveData>;
|
||||
fn learned_move_get_learn_method(r: ExternRef<LearnedMove>) -> MoveLearnMethod;
|
||||
fn learned_move_restore_uses(r: ExternRef<LearnedMove>, uses: u8);
|
||||
fn learned_move_restore_all_uses(r: ExternRef<LearnedMove>);
|
||||
}
|
||||
21
pkmn_lib_interface/src/app_interface/dynamic_data/mod.rs
Normal file
21
pkmn_lib_interface/src/app_interface/dynamic_data/mod.rs
Normal file
@@ -0,0 +1,21 @@
|
||||
mod battle;
|
||||
mod battle_party;
|
||||
mod battle_random;
|
||||
mod battle_side;
|
||||
mod dynamic_library;
|
||||
mod learned_move;
|
||||
mod party;
|
||||
mod pokemon;
|
||||
mod statistic_set;
|
||||
mod turn_choices;
|
||||
|
||||
pub use battle::*;
|
||||
pub use battle_party::*;
|
||||
pub use battle_random::*;
|
||||
pub use battle_side::*;
|
||||
pub use dynamic_library::DynamicLibrary;
|
||||
pub use learned_move::*;
|
||||
pub use party::*;
|
||||
pub use pokemon::*;
|
||||
pub use statistic_set::*;
|
||||
pub use turn_choices::*;
|
||||
27
pkmn_lib_interface/src/app_interface/dynamic_data/party.rs
Normal file
27
pkmn_lib_interface/src/app_interface/dynamic_data/party.rs
Normal file
@@ -0,0 +1,27 @@
|
||||
use crate::app_interface::Pokemon;
|
||||
use crate::{ExternRef, ExternalReferenceType};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Party {
|
||||
reference: ExternRef<Party>,
|
||||
}
|
||||
|
||||
impl Party {
|
||||
pub fn new(reference: ExternRef<Party>) -> Self {
|
||||
Self { reference }
|
||||
}
|
||||
|
||||
pub fn get_pokemon(&self, index: usize) -> Option<Pokemon> {
|
||||
unsafe { party_get_pokemon(self.reference, index).get_value() }
|
||||
}
|
||||
}
|
||||
|
||||
impl ExternalReferenceType for Party {
|
||||
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
||||
Self::new(reference)
|
||||
}
|
||||
}
|
||||
|
||||
extern "wasm" {
|
||||
fn party_get_pokemon(r: ExternRef<Party>, index: usize) -> ExternRef<Pokemon>;
|
||||
}
|
||||
236
pkmn_lib_interface/src/app_interface/dynamic_data/pokemon.rs
Normal file
236
pkmn_lib_interface/src/app_interface/dynamic_data/pokemon.rs
Normal file
@@ -0,0 +1,236 @@
|
||||
use crate::app_interface::ability::{Ability, AbilityIndex};
|
||||
use crate::app_interface::{
|
||||
Battle, ClampedStatisticSet, Form, Gender, Item, LearnedMove, LevelInt, Nature, Species,
|
||||
Statistic, StatisticSet,
|
||||
};
|
||||
use crate::handling::cached_value::CachedValue;
|
||||
use crate::handling::Cacheable;
|
||||
use crate::{
|
||||
cached_value, cached_value_getters, wasm_optional_reference_getters, wasm_reference_getters,
|
||||
wasm_value_getters, DynamicLibrary, ExternRef, ExternalReferenceType, Script,
|
||||
};
|
||||
use alloc::boxed::Box;
|
||||
use alloc::rc::Rc;
|
||||
use cstr_core::{c_char, CString};
|
||||
|
||||
struct PokemonInner {
|
||||
reference: ExternRef<Pokemon>,
|
||||
library: CachedValue<DynamicLibrary>,
|
||||
// We cache the reference to the data, not the values stored inside, which are dynamic.
|
||||
flat_stats: CachedValue<StatisticSet<u32>>,
|
||||
// We cache the reference to the data, not the values stored inside, which are dynamic.
|
||||
stat_boosts: CachedValue<ClampedStatisticSet<i8>>,
|
||||
// We cache the reference to the data, not the values stored inside, which are dynamic.
|
||||
boosted_stats: CachedValue<StatisticSet<u32>>,
|
||||
// We cache the reference to the data, not the values stored inside, which are dynamic.
|
||||
individual_values: CachedValue<ClampedStatisticSet<u8>>,
|
||||
// We cache the reference to the data, not the values stored inside, which are dynamic.
|
||||
effort_values: CachedValue<ClampedStatisticSet<u8>>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Pokemon {
|
||||
inner: Rc<PokemonInner>,
|
||||
}
|
||||
|
||||
impl Pokemon {
|
||||
pub(crate) fn new(reference: ExternRef<Self>) -> Self {
|
||||
Self::from_ref(reference, &|reference| Self {
|
||||
inner: Rc::new(PokemonInner {
|
||||
reference,
|
||||
library: cached_value!({ pokemon_get_library(reference).get_value().unwrap() }),
|
||||
flat_stats: cached_value!({
|
||||
pokemon_get_flat_stats(reference).get_value().unwrap()
|
||||
}),
|
||||
stat_boosts: cached_value!({
|
||||
pokemon_get_stat_boosts(reference).get_value().unwrap()
|
||||
}),
|
||||
boosted_stats: cached_value!({
|
||||
pokemon_get_boosted_stats(reference).get_value().unwrap()
|
||||
}),
|
||||
individual_values: cached_value!({
|
||||
pokemon_get_individual_values(reference)
|
||||
.get_value()
|
||||
.unwrap()
|
||||
}),
|
||||
effort_values: cached_value!({
|
||||
pokemon_get_effort_values(reference).get_value().unwrap()
|
||||
}),
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
cached_value_getters! {
|
||||
pub fn library(&self) -> DynamicLibrary;
|
||||
pub fn flat_stats(&self) -> StatisticSet<u32>;
|
||||
pub fn stat_boosts(&self) -> ClampedStatisticSet<i8>;
|
||||
pub fn boosted_stats(&self) -> StatisticSet<u32>;
|
||||
pub fn individual_values(&self) -> ClampedStatisticSet<u8>;
|
||||
pub fn effort_values(&self) -> ClampedStatisticSet<u8>;
|
||||
}
|
||||
|
||||
pub fn has_held_item(&self, name: &str) -> bool {
|
||||
let cstr = CString::new(name).unwrap();
|
||||
unsafe { pokemon_has_held_item(self.inner.reference, cstr.as_ptr()) }
|
||||
}
|
||||
|
||||
pub fn set_held_item(&self, item: &Item) -> Option<Item> {
|
||||
unsafe { pokemon_set_held_item(self.inner.reference, item.reference()).get_value() }
|
||||
}
|
||||
|
||||
pub fn remove_held_item(&self) -> Option<Item> {
|
||||
unsafe { pokemon_remove_held_item(self.inner.reference).get_value() }
|
||||
}
|
||||
|
||||
pub fn consume_held_item(&self) -> bool {
|
||||
unsafe { pokemon_consume_held_item(self.inner.reference) }
|
||||
}
|
||||
|
||||
pub fn max_health(&self) -> u32 {
|
||||
self.boosted_stats().hp()
|
||||
}
|
||||
|
||||
pub fn get_type(&self, index: usize) -> u8 {
|
||||
unsafe { pokemon_get_type(self.inner.reference, index) }
|
||||
}
|
||||
pub fn has_type(&self, type_identifier: u8) -> bool {
|
||||
unsafe { pokemon_has_type(self.inner.reference, type_identifier) }
|
||||
}
|
||||
pub fn has_type_by_name(&self, type_name: &str) -> bool {
|
||||
let type_identifier = self
|
||||
.library()
|
||||
.data_library()
|
||||
.type_library()
|
||||
.get_type_from_name(type_name);
|
||||
if let Some(type_identifier) = type_identifier {
|
||||
return self.has_type(type_identifier);
|
||||
}
|
||||
false
|
||||
}
|
||||
pub fn get_learned_move(&self, index: usize) -> Option<LearnedMove> {
|
||||
unsafe { pokemon_get_learned_move(self.inner.reference, index).get_value() }
|
||||
}
|
||||
pub fn change_stat_boost(
|
||||
&self,
|
||||
stat: Statistic,
|
||||
diff_amount: i8,
|
||||
self_inflicted: bool,
|
||||
) -> bool {
|
||||
unsafe {
|
||||
pokemon_change_stat_boost(self.inner.reference, stat, diff_amount, self_inflicted)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ability_script(&self) -> Option<&Box<dyn Script>> {
|
||||
unsafe { pokemon_get_ability_script(self.inner.reference).as_ref() }
|
||||
}
|
||||
|
||||
pub fn change_species(&self, species: Species, form: Form) {
|
||||
unsafe {
|
||||
pokemon_change_species(self.inner.reference, species.reference(), form.reference());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn change_form(&self, form: Form) {
|
||||
unsafe {
|
||||
pokemon_change_form(self.inner.reference, form.reference());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_fainted(&self) -> bool {
|
||||
self.current_health() == 0
|
||||
}
|
||||
|
||||
pub fn damage(&self, damage: u32, source: DamageSource) {
|
||||
unsafe { pokemon_damage(self.inner.reference, damage, source) }
|
||||
}
|
||||
|
||||
pub fn heal(&self, amount: u32, allow_revive: bool) -> bool {
|
||||
unsafe { pokemon_heal(self.inner.reference, amount, allow_revive) }
|
||||
}
|
||||
}
|
||||
|
||||
wasm_reference_getters! {
|
||||
Pokemon,
|
||||
pub fn species(&self) -> Species;
|
||||
pub fn form(&self) -> Form;
|
||||
pub fn active_ability(&self) -> Ability;
|
||||
pub fn nature(&self) -> Nature;
|
||||
}
|
||||
|
||||
wasm_optional_reference_getters! {
|
||||
Pokemon,
|
||||
pub fn display_species(&self) -> Option<Species>;
|
||||
pub fn display_form(&self) -> Option<Form>;
|
||||
pub fn held_item(&self) -> Option<Item>;
|
||||
pub fn battle(&self) -> Option<Battle>;
|
||||
}
|
||||
|
||||
wasm_value_getters! {
|
||||
Pokemon,
|
||||
pub fn level(&self) -> LevelInt;
|
||||
pub fn experience(&self) -> u32;
|
||||
pub fn unique_identifier(&self) -> u32;
|
||||
pub fn gender(&self) -> Gender;
|
||||
pub fn coloring(&self) -> u8;
|
||||
pub fn current_health(&self) -> u32;
|
||||
pub fn weight(&self) -> f32;
|
||||
pub fn height(&self) -> f32;
|
||||
pub fn nickname(&self) -> *const c_char;
|
||||
pub fn real_ability(&self) -> AbilityIndex;
|
||||
pub fn types_length(&self) -> usize;
|
||||
pub fn battle_side_index(&self) -> u8;
|
||||
pub fn battle_index(&self) -> u8;
|
||||
pub fn is_ability_overriden(&self) -> u8;
|
||||
pub fn allowed_experience_gain(&self) -> bool;
|
||||
pub fn is_usable(&self) -> bool;
|
||||
}
|
||||
|
||||
/// A source of damage. This should be as unique as possible.
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[repr(u8)]
|
||||
pub enum DamageSource {
|
||||
/// The damage is done by a move.
|
||||
MoveDamage = 0,
|
||||
/// The damage is done by something else.
|
||||
Misc = 1,
|
||||
}
|
||||
|
||||
crate::handling::cacheable::cacheable!(Pokemon);
|
||||
|
||||
impl ExternalReferenceType for Pokemon {
|
||||
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
||||
Self::new(reference)
|
||||
}
|
||||
}
|
||||
|
||||
extern "wasm" {
|
||||
fn pokemon_get_library(r: ExternRef<Pokemon>) -> ExternRef<DynamicLibrary>;
|
||||
fn pokemon_get_flat_stats(r: ExternRef<Pokemon>) -> ExternRef<StatisticSet<u32>>;
|
||||
fn pokemon_get_stat_boosts(r: ExternRef<Pokemon>) -> ExternRef<ClampedStatisticSet<i8>>;
|
||||
fn pokemon_get_boosted_stats(r: ExternRef<Pokemon>) -> ExternRef<StatisticSet<u32>>;
|
||||
fn pokemon_get_individual_values(r: ExternRef<Pokemon>) -> ExternRef<ClampedStatisticSet<u8>>;
|
||||
fn pokemon_get_effort_values(r: ExternRef<Pokemon>) -> ExternRef<ClampedStatisticSet<u8>>;
|
||||
fn pokemon_has_held_item(r: ExternRef<Pokemon>, name: *const c_char) -> bool;
|
||||
fn pokemon_set_held_item(r: ExternRef<Pokemon>, item: ExternRef<Item>) -> ExternRef<Item>;
|
||||
fn pokemon_remove_held_item(r: ExternRef<Pokemon>) -> ExternRef<Item>;
|
||||
fn pokemon_consume_held_item(r: ExternRef<Pokemon>) -> bool;
|
||||
fn pokemon_get_type(r: ExternRef<Pokemon>, index: usize) -> u8;
|
||||
fn pokemon_has_type(r: ExternRef<Pokemon>, identifier: u8) -> bool;
|
||||
fn pokemon_get_learned_move(r: ExternRef<Pokemon>, index: usize) -> ExternRef<LearnedMove>;
|
||||
fn pokemon_change_stat_boost(
|
||||
r: ExternRef<Pokemon>,
|
||||
tat: Statistic,
|
||||
diff_amount: i8,
|
||||
self_inflicted: bool,
|
||||
) -> bool;
|
||||
fn pokemon_get_ability_script(r: ExternRef<Pokemon>) -> *const Box<dyn Script>;
|
||||
fn pokemon_change_species(
|
||||
r: ExternRef<Pokemon>,
|
||||
species: ExternRef<Species>,
|
||||
form: ExternRef<Form>,
|
||||
);
|
||||
fn pokemon_change_form(r: ExternRef<Pokemon>, form: ExternRef<Form>);
|
||||
fn pokemon_damage(r: ExternRef<Pokemon>, damage: u32, source: DamageSource);
|
||||
fn pokemon_heal(r: ExternRef<Pokemon>, amount: u32, allow_revive: bool) -> bool;
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
use crate::app_interface::Statistic;
|
||||
use crate::{ExternRef, ExternalReferenceType};
|
||||
use core::convert::{TryFrom, TryInto};
|
||||
use core::fmt::Debug;
|
||||
use core::marker::PhantomData;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct StatisticSet<T>
|
||||
where
|
||||
T: TryFrom<i64>,
|
||||
T: TryInto<i64>,
|
||||
{
|
||||
reference: ExternRef<Self>,
|
||||
_p: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T> StatisticSet<T>
|
||||
where
|
||||
T: TryFrom<i64>,
|
||||
T: TryInto<i64>,
|
||||
<T as TryFrom<i64>>::Error: Debug,
|
||||
<T as TryInto<i64>>::Error: Debug,
|
||||
{
|
||||
pub(crate) fn new(reference: ExternRef<Self>) -> Self {
|
||||
Self {
|
||||
reference,
|
||||
_p: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn hp(&self) -> T {
|
||||
self.get_stat(Statistic::HP)
|
||||
}
|
||||
pub fn attack(&self) -> T {
|
||||
self.get_stat(Statistic::Attack)
|
||||
}
|
||||
pub fn defense(&self) -> T {
|
||||
self.get_stat(Statistic::Defense)
|
||||
}
|
||||
pub fn special_attack(&self) -> T {
|
||||
self.get_stat(Statistic::SpecialAttack)
|
||||
}
|
||||
pub fn special_defense(&self) -> T {
|
||||
self.get_stat(Statistic::SpecialDefense)
|
||||
}
|
||||
pub fn speed(&self) -> T {
|
||||
self.get_stat(Statistic::Speed)
|
||||
}
|
||||
|
||||
pub fn get_stat(&self, stat: Statistic) -> T {
|
||||
unsafe {
|
||||
statistic_set_get(self.reference.cast(), stat)
|
||||
.try_into()
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_stat(&self, stat: Statistic, value: T) {
|
||||
unsafe { statistic_set_set(self.reference.cast(), stat, value.try_into().unwrap()) }
|
||||
}
|
||||
|
||||
pub fn increase_stat(&self, stat: Statistic, value: T) {
|
||||
unsafe {
|
||||
statistic_set_increase_stat(self.reference.cast(), stat, value.try_into().unwrap())
|
||||
}
|
||||
}
|
||||
pub fn decrease_stat(&self, stat: Statistic, value: T) {
|
||||
unsafe {
|
||||
statistic_set_decrease_stat(self.reference.cast(), stat, value.try_into().unwrap())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> ExternalReferenceType for StatisticSet<T>
|
||||
where
|
||||
T: TryFrom<i64>,
|
||||
T: TryInto<i64>,
|
||||
<T as TryFrom<i64>>::Error: Debug,
|
||||
<T as TryInto<i64>>::Error: Debug,
|
||||
{
|
||||
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
||||
StatisticSet::<T>::new(reference)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ClampedStatisticSet<T>
|
||||
where
|
||||
T: TryFrom<i64>,
|
||||
T: TryInto<i64>,
|
||||
{
|
||||
reference: ExternRef<Self>,
|
||||
_p: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T> ClampedStatisticSet<T>
|
||||
where
|
||||
T: TryFrom<i64>,
|
||||
T: TryInto<i64>,
|
||||
<T as TryFrom<i64>>::Error: Debug,
|
||||
<T as TryInto<i64>>::Error: Debug,
|
||||
{
|
||||
pub(crate) fn new(reference: ExternRef<Self>) -> Self {
|
||||
Self {
|
||||
reference,
|
||||
_p: Default::default(),
|
||||
}
|
||||
}
|
||||
pub fn hp(&self) -> T {
|
||||
self.get_stat(Statistic::HP)
|
||||
}
|
||||
pub fn attack(&self) -> T {
|
||||
self.get_stat(Statistic::Attack)
|
||||
}
|
||||
pub fn defense(&self) -> T {
|
||||
self.get_stat(Statistic::Defense)
|
||||
}
|
||||
pub fn special_attack(&self) -> T {
|
||||
self.get_stat(Statistic::SpecialAttack)
|
||||
}
|
||||
pub fn special_defense(&self) -> T {
|
||||
self.get_stat(Statistic::SpecialDefense)
|
||||
}
|
||||
pub fn speed(&self) -> T {
|
||||
self.get_stat(Statistic::Speed)
|
||||
}
|
||||
|
||||
pub fn get_stat(&self, stat: Statistic) -> T {
|
||||
unsafe {
|
||||
clamped_statistic_set_get(self.reference.cast(), stat)
|
||||
.try_into()
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_stat(&self, stat: Statistic, value: T) {
|
||||
unsafe { clamped_statistic_set_set(self.reference.cast(), stat, value.try_into().unwrap()) }
|
||||
}
|
||||
|
||||
pub fn increase_stat(&self, stat: Statistic, value: T) -> bool {
|
||||
unsafe {
|
||||
clamped_statistic_set_increase_stat(
|
||||
self.reference.cast(),
|
||||
stat,
|
||||
value.try_into().unwrap(),
|
||||
)
|
||||
}
|
||||
}
|
||||
pub fn decrease_stat(&self, stat: Statistic, value: T) -> bool {
|
||||
unsafe {
|
||||
clamped_statistic_set_decrease_stat(
|
||||
self.reference.cast(),
|
||||
stat,
|
||||
value.try_into().unwrap(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> ExternalReferenceType for ClampedStatisticSet<T>
|
||||
where
|
||||
T: TryFrom<i64>,
|
||||
T: TryInto<i64>,
|
||||
<T as TryFrom<i64>>::Error: Debug,
|
||||
<T as TryInto<i64>>::Error: Debug,
|
||||
{
|
||||
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
||||
ClampedStatisticSet::<T>::new(reference)
|
||||
}
|
||||
}
|
||||
|
||||
extern "wasm" {
|
||||
fn statistic_set_get(r: ExternRef<StatisticSet<i64>>, stat: Statistic) -> i64;
|
||||
fn statistic_set_set(r: ExternRef<StatisticSet<i64>>, stat: Statistic, value: i64);
|
||||
fn statistic_set_increase_stat(r: ExternRef<StatisticSet<i64>>, stat: Statistic, value: i64);
|
||||
fn statistic_set_decrease_stat(r: ExternRef<StatisticSet<i64>>, stat: Statistic, value: i64);
|
||||
|
||||
fn clamped_statistic_set_get(r: ExternRef<ClampedStatisticSet<i64>>, stat: Statistic) -> i64;
|
||||
fn clamped_statistic_set_set(
|
||||
r: ExternRef<ClampedStatisticSet<i64>>,
|
||||
stat: Statistic,
|
||||
value: i64,
|
||||
);
|
||||
fn clamped_statistic_set_increase_stat(
|
||||
r: ExternRef<ClampedStatisticSet<i64>>,
|
||||
stat: Statistic,
|
||||
value: i64,
|
||||
) -> bool;
|
||||
fn clamped_statistic_set_decrease_stat(
|
||||
r: ExternRef<ClampedStatisticSet<i64>>,
|
||||
stat: Statistic,
|
||||
value: i64,
|
||||
) -> bool;
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
use crate::app_interface::Pokemon;
|
||||
use crate::handling::cached_value::CachedValue;
|
||||
use crate::handling::temporary::Temporary;
|
||||
use crate::{cached_value, ExternRef, ExternalReferenceType};
|
||||
use alloc::rc::Rc;
|
||||
|
||||
struct BaseTurnChoiceData {
|
||||
reference: ExternRef<TurnChoice>,
|
||||
user: CachedValue<Pokemon>,
|
||||
}
|
||||
|
||||
struct MoveTurnChoiceDataInner {
|
||||
base: BaseTurnChoiceData,
|
||||
}
|
||||
#[derive(Clone)]
|
||||
struct MoveTurnChoiceDataTemporary {
|
||||
inner: Rc<MoveTurnChoiceDataInner>,
|
||||
}
|
||||
pub struct MoveTurnChoiceData {
|
||||
temp: Temporary<MoveTurnChoiceDataTemporary>,
|
||||
}
|
||||
|
||||
pub enum TurnChoice {
|
||||
Move(MoveTurnChoiceData),
|
||||
Item(),
|
||||
Switch(),
|
||||
Flee,
|
||||
Pass,
|
||||
}
|
||||
|
||||
impl TurnChoice {
|
||||
pub fn user(&self) -> Pokemon {
|
||||
match self {
|
||||
TurnChoice::Move(data) => data.temp.value().inner.base.user.value(),
|
||||
_ => panic!("Unknown turn choice type"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
}),
|
||||
},
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern "wasm" {
|
||||
fn turn_choice_get_kind(r: ExternRef<TurnChoice>) -> u8;
|
||||
fn turn_choice_get_user(r: ExternRef<TurnChoice>) -> ExternRef<Pokemon>;
|
||||
}
|
||||
|
||||
#[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"),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user