Style and Clippy fixes.
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
9efe1b4e22
commit
691bf7c12e
|
@ -24,6 +24,12 @@ pub struct Gen7BattleStatCalculator {
|
||||||
identifier: ValueIdentifier,
|
identifier: ValueIdentifier,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for Gen7BattleStatCalculator {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Gen7BattleStatCalculator {
|
impl Gen7BattleStatCalculator {
|
||||||
/// Creates a new Gen 7 battle stat calculator
|
/// Creates a new Gen 7 battle stat calculator
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
|
|
|
@ -224,11 +224,7 @@ impl DamageLibrary for Gen7DamageLibrary {
|
||||||
|
|
||||||
float_damage = (float_damage * hit_data.effectiveness()).floor();
|
float_damage = (float_damage * hit_data.effectiveness()).floor();
|
||||||
let mut damage = if float_damage <= 0.0 {
|
let mut damage = if float_damage <= 0.0 {
|
||||||
if hit_data.effectiveness() == 0.0 {
|
u32::from(hit_data.effectiveness() != 0.0)
|
||||||
0
|
|
||||||
} else {
|
|
||||||
1
|
|
||||||
}
|
|
||||||
} else if float_damage >= u32::MAX as f32 {
|
} else if float_damage >= u32::MAX as f32 {
|
||||||
u32::MAX
|
u32::MAX
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -345,7 +345,7 @@ impl Battle {
|
||||||
.library()
|
.library()
|
||||||
.load_script(self.into(), ScriptCategory::Weather, &weather)
|
.load_script(self.into(), ScriptCategory::Weather, &weather)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.expect(format!("Couldn't find weather script by name {}", weather).as_str());
|
.unwrap_or_else(|| panic!("Couldn't find weather script by name {}", weather));
|
||||||
self.weather.set(script);
|
self.weather.set(script);
|
||||||
} else {
|
} else {
|
||||||
self.weather.clear();
|
self.weather.clear();
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use std::sync::atomic::{AtomicU8, Ordering};
|
use std::sync::atomic::{AtomicU8, Ordering};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::dynamic_data::Pokemon;
|
|
||||||
use crate::static_data::MoveData;
|
use crate::static_data::MoveData;
|
||||||
use crate::{ValueIdentifiable, ValueIdentifier};
|
use crate::{ValueIdentifiable, ValueIdentifier};
|
||||||
|
|
||||||
|
|
|
@ -457,7 +457,8 @@ impl Pokemon {
|
||||||
.calculate_flat_stats(self, &self.flat_stats);
|
.calculate_flat_stats(self, &self.flat_stats);
|
||||||
self.recalculate_boosted_stats();
|
self.recalculate_boosted_stats();
|
||||||
}
|
}
|
||||||
/// Calculates the boosted stats on the Pokemon. This should be called when a stat boost changes.
|
/// Calculates the boosted stats on the Pokemon, _without_ recalculating the flat stats.
|
||||||
|
/// This should be called when a stat boost changes.
|
||||||
pub fn recalculate_boosted_stats(&self) {
|
pub fn recalculate_boosted_stats(&self) {
|
||||||
self.library
|
self.library
|
||||||
.stat_calculator()
|
.stat_calculator()
|
||||||
|
@ -516,7 +517,7 @@ impl Pokemon {
|
||||||
|
|
||||||
let ability_script = self
|
let ability_script = self
|
||||||
.library
|
.library
|
||||||
.load_script((&*self).into(), ScriptCategory::Ability, self.active_ability().name())
|
.load_script(self.into(), ScriptCategory::Ability, self.active_ability().name())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
if let Some(ability_script) = ability_script {
|
if let Some(ability_script) = ability_script {
|
||||||
self.ability_script
|
self.ability_script
|
||||||
|
@ -614,7 +615,7 @@ impl Pokemon {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Damages the Pokemon by a certain amount of damage, from a specific damage source.
|
/// Damages the Pokemon by a certain amount of damage, from a damage source.
|
||||||
pub fn damage(&self, mut damage: u32, source: DamageSource) {
|
pub fn damage(&self, mut damage: u32, source: DamageSource) {
|
||||||
if damage > self.current_health() {
|
if damage > self.current_health() {
|
||||||
damage = self.current_health();
|
damage = self.current_health();
|
||||||
|
@ -820,7 +821,7 @@ pub mod test {
|
||||||
fn construct_pokemon() {
|
fn construct_pokemon() {
|
||||||
let lib = Arc::new(crate::dynamic_data::libraries::dynamic_library::test::build());
|
let lib = Arc::new(crate::dynamic_data::libraries::dynamic_library::test::build());
|
||||||
let species = lib.static_data().species().get(&"foo".into()).unwrap().clone();
|
let species = lib.static_data().species().get(&"foo".into()).unwrap().clone();
|
||||||
let form = species.get_form(&"default".into()).unwrap().clone();
|
let form = species.get_form(&"default".into()).unwrap();
|
||||||
|
|
||||||
let pokemon = Pokemon::new(
|
let pokemon = Pokemon::new(
|
||||||
lib,
|
lib,
|
||||||
|
|
|
@ -47,7 +47,7 @@ impl PokemonBuilder {
|
||||||
};
|
};
|
||||||
|
|
||||||
let species = self.library.static_data().species().get(&self.species).unwrap().clone();
|
let species = self.library.static_data().species().get(&self.species).unwrap().clone();
|
||||||
let form = species.get_default_form().clone();
|
let form = species.get_default_form();
|
||||||
let p = Pokemon::new(
|
let p = Pokemon::new(
|
||||||
self.library,
|
self.library,
|
||||||
species,
|
species,
|
||||||
|
|
|
@ -93,11 +93,9 @@ impl PokemonParty {
|
||||||
|
|
||||||
/// Checks if the party contains a given pokemon.
|
/// Checks if the party contains a given pokemon.
|
||||||
pub fn has_pokemon(&self, pokemon: &Pokemon) -> bool {
|
pub fn has_pokemon(&self, pokemon: &Pokemon) -> bool {
|
||||||
for p in &self.pokemon {
|
for p in self.pokemon.iter().flatten() {
|
||||||
if let Some(p) = p {
|
if std::ptr::eq(p.as_ref(), pokemon) {
|
||||||
if std::ptr::eq(p.as_ref(), pokemon) {
|
return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
|
|
|
@ -239,7 +239,7 @@ mod tests {
|
||||||
impl TestScript {
|
impl TestScript {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
name: StringKey::new("test".into()),
|
name: "test".into(),
|
||||||
is_marked_for_deletion: Default::default(),
|
is_marked_for_deletion: Default::default(),
|
||||||
suppressed_count: AtomicUsize::new(0),
|
suppressed_count: AtomicUsize::new(0),
|
||||||
test_count: AtomicUsize::new(0),
|
test_count: AtomicUsize::new(0),
|
||||||
|
@ -247,7 +247,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
fn new_with_name(name: &str) -> Self {
|
fn new_with_name(name: &str) -> Self {
|
||||||
Self {
|
Self {
|
||||||
name: StringKey::new(name.into()),
|
name: name.into(),
|
||||||
is_marked_for_deletion: Default::default(),
|
is_marked_for_deletion: Default::default(),
|
||||||
suppressed_count: AtomicUsize::new(0),
|
suppressed_count: AtomicUsize::new(0),
|
||||||
test_count: AtomicUsize::new(0),
|
test_count: AtomicUsize::new(0),
|
||||||
|
@ -424,7 +424,7 @@ mod tests {
|
||||||
"test_b"
|
"test_b"
|
||||||
);
|
);
|
||||||
|
|
||||||
set.remove(&StringKey::new("test_c".into()));
|
set.remove(&"test_c".into());
|
||||||
assert!(aggregator.get_next().is_none());
|
assert!(aggregator.get_next().is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -451,7 +451,7 @@ mod tests {
|
||||||
"test_a"
|
"test_a"
|
||||||
);
|
);
|
||||||
|
|
||||||
set.remove(&StringKey::new("test_b".into()));
|
set.remove(&"test_b".into());
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
aggregator
|
aggregator
|
||||||
|
|
|
@ -398,7 +398,7 @@ mod tests {
|
||||||
impl TestScript {
|
impl TestScript {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
name: StringKey::new("test".into()),
|
name: "test".into(),
|
||||||
container: AtomicPtr::<ScriptContainer>::default(),
|
container: AtomicPtr::<ScriptContainer>::default(),
|
||||||
suppressed_count: AtomicUsize::new(0),
|
suppressed_count: AtomicUsize::new(0),
|
||||||
marked_for_deletion: Default::default(),
|
marked_for_deletion: Default::default(),
|
||||||
|
@ -537,10 +537,7 @@ mod tests {
|
||||||
h.join().unwrap();
|
h.join().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(container.script.read().as_ref().unwrap().name(), &"script2".into());
|
||||||
container.script.read().as_ref().unwrap().name(),
|
|
||||||
&StringKey::new("script2".into())
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -556,20 +553,20 @@ pub enum ScriptOwnerData {
|
||||||
None,
|
None,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<ScriptOwnerData> for &Pokemon {
|
impl From<&Pokemon> for ScriptOwnerData {
|
||||||
fn into(self) -> ScriptOwnerData {
|
fn from(p: &Pokemon) -> Self {
|
||||||
ScriptOwnerData::Pokemon(AtomicPtr::new(self as *const Pokemon as *mut Pokemon))
|
ScriptOwnerData::Pokemon(AtomicPtr::new(p as *const Pokemon as *mut Pokemon))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<ScriptOwnerData> for &BattleSide {
|
impl From<&BattleSide> for ScriptOwnerData {
|
||||||
fn into(self) -> ScriptOwnerData {
|
fn from(p: &BattleSide) -> Self {
|
||||||
ScriptOwnerData::BattleSide(AtomicPtr::new(self as *const BattleSide as *mut BattleSide))
|
ScriptOwnerData::BattleSide(AtomicPtr::new(p as *const BattleSide as *mut BattleSide))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<ScriptOwnerData> for &Battle {
|
impl From<&Battle> for ScriptOwnerData {
|
||||||
fn into(self) -> ScriptOwnerData {
|
fn from(p: &Battle) -> Self {
|
||||||
ScriptOwnerData::Battle(AtomicPtr::new(self as *const Battle as *mut Battle))
|
ScriptOwnerData::Battle(AtomicPtr::new(p as *const Battle as *mut Battle))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::dynamic_data::{BattleStatCalculator, Gen7BattleStatCalculator};
|
use crate::dynamic_data::{BattleStatCalculator, Gen7BattleStatCalculator};
|
||||||
use crate::ffi::IdentifiablePointer;
|
use crate::ffi::IdentifiablePointer;
|
||||||
|
|
||||||
|
/// Creates a new Gen 7 battle stat calculator
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn gen_7_battle_stat_calculator_new() -> IdentifiablePointer<Box<dyn BattleStatCalculator>> {
|
extern "C" fn gen_7_battle_stat_calculator_new() -> IdentifiablePointer<Box<dyn BattleStatCalculator>> {
|
||||||
let v: Box<dyn BattleStatCalculator> = Box::new(Gen7BattleStatCalculator::new());
|
let v: Box<dyn BattleStatCalculator> = Box::new(Gen7BattleStatCalculator::new());
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
use crate::dynamic_data::{DamageLibrary, Gen7DamageLibrary};
|
use crate::dynamic_data::{DamageLibrary, Gen7DamageLibrary};
|
||||||
use crate::ffi::IdentifiablePointer;
|
use crate::ffi::IdentifiablePointer;
|
||||||
|
|
||||||
|
/// Creates a new generation 7 damage library. `has_randomness` defines whether a random damage
|
||||||
|
/// modifier (0.85x - 1.00x) is applied to the calculated damage.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn gen_7_damage_library_new(randomness: u8) -> IdentifiablePointer<Box<dyn DamageLibrary>> {
|
extern "C" fn gen_7_damage_library_new(randomness: u8) -> IdentifiablePointer<Box<dyn DamageLibrary>> {
|
||||||
let v: Box<dyn DamageLibrary> = Box::new(Gen7DamageLibrary::new(randomness == 1));
|
let v: Box<dyn DamageLibrary> = Box::new(Gen7DamageLibrary::new(randomness == 1));
|
||||||
|
|
|
@ -3,6 +3,7 @@ use crate::ffi::{IdentifiablePointer, OwnedPtr};
|
||||||
use crate::static_data::StaticData;
|
use crate::static_data::StaticData;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
/// Instantiates a new DynamicLibrary with given parameters.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn dynamic_library_new(
|
extern "C" fn dynamic_library_new(
|
||||||
static_data: OwnedPtr<StaticData>,
|
static_data: OwnedPtr<StaticData>,
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::dynamic_data::{Gen7MiscLibrary, MiscLibrary};
|
use crate::dynamic_data::{Gen7MiscLibrary, MiscLibrary};
|
||||||
use crate::ffi::IdentifiablePointer;
|
use crate::ffi::IdentifiablePointer;
|
||||||
|
|
||||||
|
/// Instantiates a new MiscLibrary.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn gen_7_misc_library_new() -> IdentifiablePointer<Box<dyn MiscLibrary>> {
|
extern "C" fn gen_7_misc_library_new() -> IdentifiablePointer<Box<dyn MiscLibrary>> {
|
||||||
let v: Box<dyn MiscLibrary> = Box::new(Gen7MiscLibrary::new());
|
let v: Box<dyn MiscLibrary> = Box::new(Gen7MiscLibrary::new());
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
|
/// The foreign function interfaces for the battle stat calculator
|
||||||
mod battle_stat_calculator;
|
mod battle_stat_calculator;
|
||||||
|
/// The foreign function interfaces for the damage library
|
||||||
mod damage_library;
|
mod damage_library;
|
||||||
|
/// The foreign function interfaces for the dynamic library
|
||||||
mod dynamic_library;
|
mod dynamic_library;
|
||||||
|
/// The foreign function interfaces for the misc library
|
||||||
mod misc_library;
|
mod misc_library;
|
||||||
|
/// The foreign function interfaces for the script resolver
|
||||||
mod script_resolver;
|
mod script_resolver;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::dynamic_data::{EmptyScriptResolver, ScriptResolver};
|
use crate::dynamic_data::{EmptyScriptResolver, ScriptResolver};
|
||||||
use crate::ffi::IdentifiablePointer;
|
use crate::ffi::IdentifiablePointer;
|
||||||
|
|
||||||
|
/// Instantiates a basic empty script resolver, that always returns None.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn empty_script_resolver_new() -> IdentifiablePointer<Box<dyn ScriptResolver>> {
|
extern "C" fn empty_script_resolver_new() -> IdentifiablePointer<Box<dyn ScriptResolver>> {
|
||||||
let v: Box<dyn ScriptResolver> = Box::new(EmptyScriptResolver {
|
let v: Box<dyn ScriptResolver> = Box::new(EmptyScriptResolver {
|
||||||
|
@ -11,12 +12,14 @@ extern "C" fn empty_script_resolver_new() -> IdentifiablePointer<Box<dyn ScriptR
|
||||||
IdentifiablePointer::new(ptr, id)
|
IdentifiablePointer::new(ptr, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Foreign function interfaces for the Webassembly script resolver.
|
||||||
#[cfg(feature = "wasm")]
|
#[cfg(feature = "wasm")]
|
||||||
mod web_assembly_script_resolver {
|
mod web_assembly_script_resolver {
|
||||||
use crate::dynamic_data::ScriptResolver;
|
use crate::dynamic_data::ScriptResolver;
|
||||||
use crate::ffi::{ExternPointer, IdentifiablePointer};
|
use crate::ffi::{ExternPointer, IdentifiablePointer};
|
||||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyScriptResolver;
|
use crate::script_implementations::wasm::script_resolver::WebAssemblyScriptResolver;
|
||||||
|
|
||||||
|
/// Instantiates a new WebAssemblyScriptResolver.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn webassembly_script_resolver_new() -> IdentifiablePointer<Box<dyn ScriptResolver>> {
|
extern "C" fn webassembly_script_resolver_new() -> IdentifiablePointer<Box<dyn ScriptResolver>> {
|
||||||
let v: Box<dyn ScriptResolver> = WebAssemblyScriptResolver::new();
|
let v: Box<dyn ScriptResolver> = WebAssemblyScriptResolver::new();
|
||||||
|
@ -25,17 +28,19 @@ mod web_assembly_script_resolver {
|
||||||
IdentifiablePointer::new(ptr, id)
|
IdentifiablePointer::new(ptr, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Load a compiled WASM module.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn webassembly_script_resolver_load_wasm_from_bytes(
|
extern "C" fn webassembly_script_resolver_load_wasm_from_bytes(
|
||||||
ptr: ExternPointer<Box<WebAssemblyScriptResolver>>,
|
mut ptr: ExternPointer<Box<WebAssemblyScriptResolver>>,
|
||||||
arr: *const u8,
|
arr: *const u8,
|
||||||
len: usize,
|
len: usize,
|
||||||
) {
|
) {
|
||||||
unsafe { ptr.as_mut().load_wasm_from_bytes(std::slice::from_raw_parts(arr, len)) }
|
unsafe { ptr.as_mut().load_wasm_from_bytes(std::slice::from_raw_parts(arr, len)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Tells the script resolver we're done loading wasm modules, and to finalize the resolver.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn webassembly_script_resolver_finalize(ptr: ExternPointer<Box<WebAssemblyScriptResolver>>) {
|
extern "C" fn webassembly_script_resolver_finalize(mut ptr: ExternPointer<Box<WebAssemblyScriptResolver>>) {
|
||||||
ptr.as_mut().finalize();
|
ptr.as_mut().finalize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,2 +1,4 @@
|
||||||
|
/// The foreign function interfaces for the dynamic data libraries
|
||||||
mod libraries;
|
mod libraries;
|
||||||
|
/// The foreign function interfaces for the dynamic data models
|
||||||
mod models;
|
mod models;
|
|
@ -1 +1,2 @@
|
||||||
|
/// The foreign function interface for a Pokemon.
|
||||||
mod pokemon;
|
mod pokemon;
|
||||||
|
|
|
@ -8,6 +8,7 @@ use std::ffi::{c_char, CStr, CString};
|
||||||
use std::ptr::drop_in_place;
|
use std::ptr::drop_in_place;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
/// Instantiates a new Pokemon.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_new(
|
extern "C" fn pokemon_new(
|
||||||
library: ExternPointer<Arc<DynamicLibrary>>,
|
library: ExternPointer<Arc<DynamicLibrary>>,
|
||||||
|
@ -39,34 +40,40 @@ extern "C" fn pokemon_new(
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Drops an Arc reference held by the FFI.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn pokemon_drop(ptr: OwnedPtr<Arc<Pokemon>>) {
|
unsafe extern "C" fn pokemon_drop(ptr: OwnedPtr<Arc<Pokemon>>) {
|
||||||
drop_in_place(ptr);
|
drop_in_place(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The library data of the Pokemon.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_library(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Arc<DynamicLibrary>> {
|
extern "C" fn pokemon_library(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Arc<DynamicLibrary>> {
|
||||||
ptr.as_ref().library().clone().into()
|
ptr.as_ref().library().clone().into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The species of the Pokemon.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_species(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Arc<Species>> {
|
extern "C" fn pokemon_species(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Arc<Species>> {
|
||||||
ptr.as_ref().species().clone().into()
|
ptr.as_ref().species().into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The form of the Pokemon.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_form(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Arc<Form>> {
|
extern "C" fn pokemon_form(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Arc<Form>> {
|
||||||
ptr.as_ref().form().clone().into()
|
ptr.as_ref().form().into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The species that should be displayed to the user. This handles stuff like the Illusion ability.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_display_species(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Arc<Species>> {
|
extern "C" fn pokemon_display_species(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Arc<Species>> {
|
||||||
ptr.as_ref().display_species().clone().into()
|
ptr.as_ref().display_species().into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The form that should be displayed to the user. This handles stuff like the Illusion ability.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_display_form(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Arc<Form>> {
|
extern "C" fn pokemon_display_form(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Arc<Form>> {
|
||||||
ptr.as_ref().display_form().clone().into()
|
ptr.as_ref().display_form().into()
|
||||||
}
|
}
|
||||||
|
|
||||||
ffi_arc_getter!(Pokemon, level, LevelInt);
|
ffi_arc_getter!(Pokemon, level, LevelInt);
|
||||||
|
@ -75,6 +82,7 @@ ffi_arc_getter!(Pokemon, unique_identifier, u32);
|
||||||
ffi_arc_getter!(Pokemon, gender, Gender);
|
ffi_arc_getter!(Pokemon, gender, Gender);
|
||||||
ffi_arc_getter!(Pokemon, coloring, u8);
|
ffi_arc_getter!(Pokemon, coloring, u8);
|
||||||
|
|
||||||
|
/// Gets the held item of a Pokemon
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_held_item(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Arc<Item>> {
|
extern "C" fn pokemon_held_item(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Arc<Item>> {
|
||||||
if let Some(v) = ptr.as_ref().held_item().read().as_ref() {
|
if let Some(v) = ptr.as_ref().held_item().read().as_ref() {
|
||||||
|
@ -84,44 +92,40 @@ extern "C" fn pokemon_held_item(ptr: ExternPointer<Arc<Pokemon>>) -> Identifiabl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Checks whether the Pokemon is holding a specific item.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_has_held_item(ptr: ExternPointer<Arc<Pokemon>>, name: *const c_char) -> u8 {
|
extern "C" fn pokemon_has_held_item(ptr: ExternPointer<Arc<Pokemon>>, name: *const c_char) -> u8 {
|
||||||
let name = unsafe { CStr::from_ptr(name) }.into();
|
let name = unsafe { CStr::from_ptr(name) }.into();
|
||||||
if ptr.as_ref().has_held_item(&name) {
|
u8::from(ptr.as_ref().has_held_item(&name))
|
||||||
1
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Changes the held item of the Pokemon. Returns the previously held item.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_set_held_item(
|
extern "C" fn pokemon_set_held_item(
|
||||||
ptr: ExternPointer<Arc<Pokemon>>,
|
ptr: ExternPointer<Arc<Pokemon>>,
|
||||||
item: ExternPointer<Arc<Item>>,
|
item: ExternPointer<Arc<Item>>,
|
||||||
) -> IdentifiablePointer<Arc<Item>> {
|
) -> IdentifiablePointer<Arc<Item>> {
|
||||||
if let Some(v) = ptr.as_ref().set_held_item(item.as_ref()) {
|
if let Some(v) = ptr.as_ref().set_held_item(item.as_ref()) {
|
||||||
v.clone().into()
|
v.into()
|
||||||
} else {
|
} else {
|
||||||
IdentifiablePointer::none()
|
IdentifiablePointer::none()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Removes the held item from the Pokemon. Returns the previously held item.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_remove_held_item(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Arc<Item>> {
|
extern "C" fn pokemon_remove_held_item(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Arc<Item>> {
|
||||||
if let Some(v) = ptr.as_ref().remove_held_item() {
|
if let Some(v) = ptr.as_ref().remove_held_item() {
|
||||||
v.clone().into()
|
v.into()
|
||||||
} else {
|
} else {
|
||||||
IdentifiablePointer::none()
|
IdentifiablePointer::none()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Makes the Pokemon uses its held item.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_consume_held_item(ptr: ExternPointer<Arc<Pokemon>>) -> u8 {
|
extern "C" fn pokemon_consume_held_item(ptr: ExternPointer<Arc<Pokemon>>) -> u8 {
|
||||||
if ptr.as_ref().consume_held_item() {
|
u8::from(ptr.as_ref().consume_held_item())
|
||||||
1
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ffi_arc_getter!(Pokemon, current_health, u32);
|
ffi_arc_getter!(Pokemon, current_health, u32);
|
||||||
|
@ -129,6 +133,7 @@ ffi_arc_getter!(Pokemon, max_health, u32);
|
||||||
ffi_arc_getter!(Pokemon, weight, f32);
|
ffi_arc_getter!(Pokemon, weight, f32);
|
||||||
ffi_arc_getter!(Pokemon, height, f32);
|
ffi_arc_getter!(Pokemon, height, f32);
|
||||||
|
|
||||||
|
/// An optional nickname of the Pokemon.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_nickname(ptr: ExternPointer<Arc<Pokemon>>) -> *mut c_char {
|
extern "C" fn pokemon_nickname(ptr: ExternPointer<Arc<Pokemon>>) -> *mut c_char {
|
||||||
let name = ptr.as_ref().nickname();
|
let name = ptr.as_ref().nickname();
|
||||||
|
@ -139,15 +144,13 @@ extern "C" fn pokemon_nickname(ptr: ExternPointer<Arc<Pokemon>>) -> *mut c_char
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Whether the actual ability on the form is a hidden ability.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_real_ability_is_hidden(ptr: ExternPointer<Arc<Pokemon>>) -> u8 {
|
extern "C" fn pokemon_real_ability_is_hidden(ptr: ExternPointer<Arc<Pokemon>>) -> u8 {
|
||||||
if ptr.as_ref().real_ability().hidden {
|
u8::from(ptr.as_ref().real_ability().hidden)
|
||||||
1
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The index of the actual ability on the form.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_real_ability_index(ptr: ExternPointer<Arc<Pokemon>>) -> u8 {
|
extern "C" fn pokemon_real_ability_index(ptr: ExternPointer<Arc<Pokemon>>) -> u8 {
|
||||||
ptr.as_ref().real_ability().index
|
ptr.as_ref().real_ability().index
|
||||||
|
@ -155,6 +158,8 @@ extern "C" fn pokemon_real_ability_index(ptr: ExternPointer<Arc<Pokemon>>) -> u8
|
||||||
|
|
||||||
ffi_vec_value_getters!(Pokemon, types, TypeIdentifier);
|
ffi_vec_value_getters!(Pokemon, types, TypeIdentifier);
|
||||||
|
|
||||||
|
/// Gets a learned move of the Pokemon. Index should generally be below [`MAX_MOVES`], you will get
|
||||||
|
/// a null pointer otherwise.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_learned_move_get(
|
extern "C" fn pokemon_learned_move_get(
|
||||||
ptr: ExternPointer<Arc<Pokemon>>,
|
ptr: ExternPointer<Arc<Pokemon>>,
|
||||||
|
@ -167,21 +172,25 @@ extern "C" fn pokemon_learned_move_get(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The stats of the Pokemon when disregarding any stat boosts.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_flat_stats(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<StatisticSet<u32>> {
|
extern "C" fn pokemon_flat_stats(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<StatisticSet<u32>> {
|
||||||
(ptr.as_ref().flat_stats() as *const StatisticSet<u32>).into()
|
(ptr.as_ref().flat_stats() as *const StatisticSet<u32>).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The stats of the Pokemon including the stat boosts.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_boosted_stats(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<StatisticSet<u32>> {
|
extern "C" fn pokemon_boosted_stats(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<StatisticSet<u32>> {
|
||||||
(ptr.as_ref().boosted_stats() as *const StatisticSet<u32>).into()
|
(ptr.as_ref().boosted_stats() as *const StatisticSet<u32>).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the stat boosts for a specific stat.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_get_stat_boost(ptr: ExternPointer<Arc<Pokemon>>, statistic: Statistic) -> i8 {
|
extern "C" fn pokemon_get_stat_boost(ptr: ExternPointer<Arc<Pokemon>>, statistic: Statistic) -> i8 {
|
||||||
ptr.as_ref().stat_boost(statistic)
|
ptr.as_ref().stat_boost(statistic)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Change a boosted stat by a certain amount.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_change_stat_boost(
|
extern "C" fn pokemon_change_stat_boost(
|
||||||
ptr: ExternPointer<Arc<Pokemon>>,
|
ptr: ExternPointer<Arc<Pokemon>>,
|
||||||
|
@ -189,35 +198,37 @@ extern "C" fn pokemon_change_stat_boost(
|
||||||
diff_amount: i8,
|
diff_amount: i8,
|
||||||
self_inflicted: u8,
|
self_inflicted: u8,
|
||||||
) -> u8 {
|
) -> u8 {
|
||||||
if ptr.as_ref().change_stat_boost(stat, diff_amount, self_inflicted == 1) {
|
u8::from(ptr.as_ref().change_stat_boost(stat, diff_amount, self_inflicted == 1))
|
||||||
1
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets a [individual value](https://bulbapedia.bulbagarden.net/wiki/Individual_values) of the Pokemon.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_get_individual_value(ptr: ExternPointer<Arc<Pokemon>>, stat: Statistic) -> u8 {
|
extern "C" fn pokemon_get_individual_value(ptr: ExternPointer<Arc<Pokemon>>, stat: Statistic) -> u8 {
|
||||||
ptr.as_ref().individual_values().get_stat(stat)
|
ptr.as_ref().individual_values().get_stat(stat)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Modifies a [individual value](https://bulbapedia.bulbagarden.net/wiki/Individual_values) of the Pokemon.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_set_individual_value(ptr: ExternPointer<Arc<Pokemon>>, stat: Statistic, value: u8) {
|
extern "C" fn pokemon_set_individual_value(ptr: ExternPointer<Arc<Pokemon>>, stat: Statistic, value: u8) {
|
||||||
ptr.as_ref().individual_values().set_stat(stat, value);
|
ptr.as_ref().individual_values().set_stat(stat, value);
|
||||||
ptr.as_ref().recalculate_flat_stats();
|
ptr.as_ref().recalculate_flat_stats();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets a [effort value](https://bulbapedia.bulbagarden.net/wiki/Effort_values) of the Pokemon.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_get_effort_value(ptr: ExternPointer<Arc<Pokemon>>, stat: Statistic) -> u8 {
|
extern "C" fn pokemon_get_effort_value(ptr: ExternPointer<Arc<Pokemon>>, stat: Statistic) -> u8 {
|
||||||
ptr.as_ref().effort_values().get_stat(stat)
|
ptr.as_ref().effort_values().get_stat(stat)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Modifies a [effort value](https://bulbapedia.bulbagarden.net/wiki/Effort_values) of the Pokemon.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_set_effort_value(ptr: ExternPointer<Arc<Pokemon>>, stat: Statistic, value: u8) {
|
extern "C" fn pokemon_set_effort_value(ptr: ExternPointer<Arc<Pokemon>>, stat: Statistic, value: u8) {
|
||||||
ptr.as_ref().effort_values().set_stat(stat, value);
|
ptr.as_ref().effort_values().set_stat(stat, value);
|
||||||
ptr.as_ref().recalculate_flat_stats();
|
ptr.as_ref().recalculate_flat_stats();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets the data for the battle the Pokemon is currently in. If the Pokemon is not in a battle, this
|
||||||
|
/// returns null.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_get_battle(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Battle> {
|
extern "C" fn pokemon_get_battle(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Battle> {
|
||||||
if let Some(v) = ptr.as_ref().get_battle() {
|
if let Some(v) = ptr.as_ref().get_battle() {
|
||||||
|
@ -227,54 +238,59 @@ extern "C" fn pokemon_get_battle(ptr: ExternPointer<Arc<Pokemon>>) -> Identifiab
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the index of the side of the battle the Pokemon is in. If the Pokemon
|
||||||
|
/// is not on the battlefield, this always returns 0.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_get_battle_side_index(ptr: ExternPointer<Arc<Pokemon>>) -> u8 {
|
extern "C" fn pokemon_get_battle_side_index(ptr: ExternPointer<Arc<Pokemon>>) -> u8 {
|
||||||
ptr.as_ref().get_battle_side_index().unwrap_or_default()
|
ptr.as_ref().get_battle_side_index().unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the index of the slot on the side of the battle the Pokemon is in. If the Pokemon
|
||||||
|
// is not on the battlefield, this always returns 0.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_get_battle_index(ptr: ExternPointer<Arc<Pokemon>>) -> u8 {
|
extern "C" fn pokemon_get_battle_index(ptr: ExternPointer<Arc<Pokemon>>) -> u8 {
|
||||||
ptr.as_ref().get_battle_index().unwrap_or_default()
|
ptr.as_ref().get_battle_index().unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns whether something overrides the ability.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_is_ability_overriden(ptr: ExternPointer<Arc<Pokemon>>) -> u8 {
|
extern "C" fn pokemon_is_ability_overriden(ptr: ExternPointer<Arc<Pokemon>>) -> u8 {
|
||||||
if ptr.as_ref().is_ability_overriden() {
|
u8::from(ptr.as_ref().is_ability_overriden())
|
||||||
1
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the currently active ability.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_active_ability(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Ability> {
|
extern "C" fn pokemon_active_ability(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Ability> {
|
||||||
(ptr.as_ref().active_ability() as *const Ability).into()
|
(ptr.as_ref().active_ability() as *const Ability).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Whether or not the Pokemon is allowed to gain experience.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_allowed_experience_gain(ptr: ExternPointer<Arc<Pokemon>>) -> u8 {
|
extern "C" fn pokemon_allowed_experience_gain(ptr: ExternPointer<Arc<Pokemon>>) -> u8 {
|
||||||
if ptr.as_ref().allowed_experience_gain() {
|
u8::from(ptr.as_ref().allowed_experience_gain())
|
||||||
1
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The [nature](https://bulbapedia.bulbagarden.net/wiki/Nature) of the Pokemon.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_nature(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Arc<Nature>> {
|
extern "C" fn pokemon_nature(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Arc<Nature>> {
|
||||||
ptr.as_ref().nature().clone().into()
|
ptr.as_ref().nature().clone().into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Calculates the flat stats on the Pokemon. This should be called when for example the base
|
||||||
|
/// stats, level, nature, IV, or EV changes. This has a side effect of recalculating the boosted
|
||||||
|
/// stats, as those depend on the flat stats.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_recalculate_flat_stats(ptr: ExternPointer<Arc<Pokemon>>) {
|
extern "C" fn pokemon_recalculate_flat_stats(ptr: ExternPointer<Arc<Pokemon>>) {
|
||||||
ptr.as_ref().recalculate_flat_stats()
|
ptr.as_ref().recalculate_flat_stats()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Calculates the boosted stats on the Pokemon. This should be called when a stat boost changes.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_recalculate_boosted_stats(ptr: ExternPointer<Arc<Pokemon>>) {
|
extern "C" fn pokemon_recalculate_boosted_stats(ptr: ExternPointer<Arc<Pokemon>>) {
|
||||||
ptr.as_ref().recalculate_boosted_stats()
|
ptr.as_ref().recalculate_boosted_stats()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Change the species of the Pokemon.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_change_species(
|
extern "C" fn pokemon_change_species(
|
||||||
ptr: ExternPointer<Arc<Pokemon>>,
|
ptr: ExternPointer<Arc<Pokemon>>,
|
||||||
|
@ -285,48 +301,44 @@ extern "C" fn pokemon_change_species(
|
||||||
.change_species(species.as_ref().clone(), form.as_ref().clone())
|
.change_species(species.as_ref().clone(), form.as_ref().clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Change the form of the Pokemon.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_change_form(ptr: ExternPointer<Arc<Pokemon>>, form: ExternPointer<Arc<Form>>) {
|
extern "C" fn pokemon_change_form(ptr: ExternPointer<Arc<Pokemon>>, form: ExternPointer<Arc<Form>>) {
|
||||||
ptr.as_ref().change_form(form.as_ref())
|
ptr.as_ref().change_form(form.as_ref())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Whether or not the Pokemon is useable in a battle.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_is_usable(ptr: ExternPointer<Arc<Pokemon>>) -> u8 {
|
extern "C" fn pokemon_is_usable(ptr: ExternPointer<Arc<Pokemon>>) -> u8 {
|
||||||
if ptr.as_ref().is_usable() {
|
u8::from(ptr.as_ref().is_usable())
|
||||||
1
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns whether the Pokemon is fainted.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_is_fainted(ptr: ExternPointer<Arc<Pokemon>>) -> u8 {
|
extern "C" fn pokemon_is_fainted(ptr: ExternPointer<Arc<Pokemon>>) -> u8 {
|
||||||
if ptr.as_ref().is_fainted() {
|
u8::from(ptr.as_ref().is_fainted())
|
||||||
1
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Whether or not the Pokemon is on the battlefield.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_is_on_battlefield(ptr: ExternPointer<Arc<Pokemon>>) -> u8 {
|
extern "C" fn pokemon_is_on_battlefield(ptr: ExternPointer<Arc<Pokemon>>) -> u8 {
|
||||||
if ptr.as_ref().is_on_battlefield() {
|
u8::from(ptr.as_ref().is_on_battlefield())
|
||||||
1
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Damages the Pokemon by a certain amount of damage, from a damage source.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_damage(ptr: ExternPointer<Arc<Pokemon>>, damage: u32, source: DamageSource) {
|
extern "C" fn pokemon_damage(ptr: ExternPointer<Arc<Pokemon>>, damage: u32, source: DamageSource) {
|
||||||
ptr.as_ref().damage(damage, source)
|
ptr.as_ref().damage(damage, source)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Heals the Pokemon by a specific amount. Unless allow_revive is set to true, this will not
|
||||||
|
/// heal if the Pokemon has 0 health. If the amount healed is 0, this will return false.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_heal(ptr: ExternPointer<Arc<Pokemon>>, amount: u32, allow_revive: u8) -> bool {
|
extern "C" fn pokemon_heal(ptr: ExternPointer<Arc<Pokemon>>, amount: u32, allow_revive: u8) -> bool {
|
||||||
ptr.as_ref().heal(amount, allow_revive == 1)
|
ptr.as_ref().heal(amount, allow_revive == 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Learn a move.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_learn_move(
|
extern "C" fn pokemon_learn_move(
|
||||||
ptr: ExternPointer<Arc<Pokemon>>,
|
ptr: ExternPointer<Arc<Pokemon>>,
|
||||||
|
@ -336,6 +348,7 @@ extern "C" fn pokemon_learn_move(
|
||||||
unsafe { ptr.as_ref().learn_move(&CStr::from_ptr(move_name).into(), learn_method) }
|
unsafe { ptr.as_ref().learn_move(&CStr::from_ptr(move_name).into(), learn_method) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Removes the current non-volatile status from the Pokemon.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_clear_status(ptr: ExternPointer<Arc<Pokemon>>) {
|
extern "C" fn pokemon_clear_status(ptr: ExternPointer<Arc<Pokemon>>) {
|
||||||
ptr.as_ref().clear_status()
|
ptr.as_ref().clear_status()
|
||||||
|
|
|
@ -1,22 +1,14 @@
|
||||||
|
/// The foreign function interfaces for the dynamic data
|
||||||
mod dynamic_data;
|
mod dynamic_data;
|
||||||
|
/// The foreign function interfaces for that static data
|
||||||
mod static_data;
|
mod static_data;
|
||||||
|
|
||||||
|
/// Helper type for clearer functions.
|
||||||
type OwnedPtr<T> = *mut T;
|
type OwnedPtr<T> = *mut T;
|
||||||
|
/// Helper type for clearer functions.
|
||||||
type BorrowedPtr<T> = *const T;
|
type BorrowedPtr<T> = *const T;
|
||||||
|
|
||||||
macro_rules! ffi_getter {
|
/// Generates a basic getter foreign function interface.
|
||||||
(
|
|
||||||
$type:ty, $func:ident, $returns: ty
|
|
||||||
) => {
|
|
||||||
paste::paste! {
|
|
||||||
#[no_mangle]
|
|
||||||
extern "C" fn [< $type:snake _ $func >](ptr: ExternPointer<$type>) -> $returns {
|
|
||||||
ptr.as_ref().$func()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! ffi_arc_getter {
|
macro_rules! ffi_arc_getter {
|
||||||
(
|
(
|
||||||
$type:ty, $func:ident, $returns: ty
|
$type:ty, $func:ident, $returns: ty
|
||||||
|
@ -30,6 +22,7 @@ macro_rules! ffi_arc_getter {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Generates a basic getter foreign function interface where the return type is a [`crate::StringKey`].
|
||||||
macro_rules! ffi_arc_stringkey_getter {
|
macro_rules! ffi_arc_stringkey_getter {
|
||||||
(
|
(
|
||||||
$type:ty, $func:ident
|
$type:ty, $func:ident
|
||||||
|
@ -43,6 +36,7 @@ macro_rules! ffi_arc_stringkey_getter {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Generates a foreign function interface for a vec. This generates a length function, and a getter.
|
||||||
macro_rules! ffi_vec_value_getters {
|
macro_rules! ffi_vec_value_getters {
|
||||||
(
|
(
|
||||||
$type:ty, $func:ident, $returns: ty
|
$type:ty, $func:ident, $returns: ty
|
||||||
|
@ -60,6 +54,8 @@ macro_rules! ffi_vec_value_getters {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Generates a foreign function interface for a vec of [`crate::StringKey`]. This generates a
|
||||||
|
/// length function, and a getter.
|
||||||
macro_rules! ffi_vec_stringkey_getters {
|
macro_rules! ffi_vec_stringkey_getters {
|
||||||
(
|
(
|
||||||
$type:ident, $func:ident
|
$type:ident, $func:ident
|
||||||
|
@ -80,57 +76,62 @@ macro_rules! ffi_vec_stringkey_getters {
|
||||||
use crate::{ValueIdentifiable, ValueIdentifier};
|
use crate::{ValueIdentifiable, ValueIdentifier};
|
||||||
pub(self) use ffi_arc_getter;
|
pub(self) use ffi_arc_getter;
|
||||||
pub(self) use ffi_arc_stringkey_getter;
|
pub(self) use ffi_arc_stringkey_getter;
|
||||||
pub(self) use ffi_getter;
|
|
||||||
pub(self) use ffi_vec_stringkey_getters;
|
pub(self) use ffi_vec_stringkey_getters;
|
||||||
pub(self) use ffi_vec_value_getters;
|
pub(self) use ffi_vec_value_getters;
|
||||||
|
use std::mem::transmute;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
/// Helper utility class to wrap a pointer for extern functions.
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub(self) struct ExternPointer<T: ?Sized> {
|
pub(self) struct ExternPointer<T: ?Sized> {
|
||||||
|
/// The wrapped pointer.
|
||||||
ptr: *mut T,
|
ptr: *mut T,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized> ExternPointer<T> {
|
impl<T: ?Sized> ExternPointer<T> {
|
||||||
|
/// Get the internal pointer as reference.
|
||||||
pub(self) fn as_ref(&self) -> &T {
|
pub(self) fn as_ref(&self) -> &T {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.ptr.as_ref().expect(&format!(
|
self.ptr
|
||||||
"Given pointer of type '{}' was null",
|
.as_ref()
|
||||||
std::any::type_name::<T>()
|
.unwrap_or_else(|| panic!("Given pointer of type '{}' was null", std::any::type_name::<T>()))
|
||||||
))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/// Get the internal pointer as mutable reference.
|
||||||
pub(self) fn as_mut(&self) -> &mut T {
|
pub(self) fn as_mut(&mut self) -> &mut T {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.ptr.as_mut().expect(&format!(
|
self.ptr
|
||||||
"Given pointer of type '{}' was null",
|
.as_mut()
|
||||||
std::any::type_name::<T>()
|
.unwrap_or_else(|| panic!("Given pointer of type '{}' was null", std::any::type_name::<T>()))
|
||||||
))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Helper utility class to give both the pointer and identifier to a FFI.
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub(self) struct IdentifiablePointer<T> {
|
pub(self) struct IdentifiablePointer<T> {
|
||||||
|
/// The wrapped pointer.
|
||||||
pub ptr: *const T,
|
pub ptr: *const T,
|
||||||
pub id: ValueIdentifier,
|
/// The identifier of the pointer.
|
||||||
|
pub id: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> IdentifiablePointer<T> {
|
impl<T> IdentifiablePointer<T> {
|
||||||
|
/// Creates a new IdentifiablePointer.
|
||||||
pub(self) fn new(ptr: *const T, id: ValueIdentifier) -> Self {
|
pub(self) fn new(ptr: *const T, id: ValueIdentifier) -> Self {
|
||||||
Self { ptr, id }
|
unsafe { Self { ptr, id: transmute(id) } }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Into<ExternPointer<T>> for *mut T {
|
impl<T> From<*mut T> for ExternPointer<T> {
|
||||||
fn into(self) -> ExternPointer<T> {
|
fn from(ptr: *mut T) -> Self {
|
||||||
ExternPointer { ptr: self }
|
ExternPointer { ptr }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ValueIdentifiable> From<Arc<T>> for IdentifiablePointer<Arc<T>> {
|
impl<T: ValueIdentifiable> From<Arc<T>> for IdentifiablePointer<Arc<T>> {
|
||||||
fn from(v: Arc<T>) -> Self {
|
fn from(v: Arc<T>) -> Self {
|
||||||
let id = v.value_identifier();
|
let id = unsafe { transmute(v.value_identifier()) };
|
||||||
Self {
|
Self {
|
||||||
ptr: Box::into_raw(Box::new(v)),
|
ptr: Box::into_raw(Box::new(v)),
|
||||||
id,
|
id,
|
||||||
|
@ -140,7 +141,7 @@ impl<T: ValueIdentifiable> From<Arc<T>> for IdentifiablePointer<Arc<T>> {
|
||||||
|
|
||||||
impl<T: ValueIdentifiable> From<Box<T>> for IdentifiablePointer<T> {
|
impl<T: ValueIdentifiable> From<Box<T>> for IdentifiablePointer<T> {
|
||||||
fn from(v: Box<T>) -> Self {
|
fn from(v: Box<T>) -> Self {
|
||||||
let id = v.value_identifier();
|
let id = unsafe { transmute(v.value_identifier()) };
|
||||||
Self {
|
Self {
|
||||||
ptr: Box::into_raw(v),
|
ptr: Box::into_raw(v),
|
||||||
id,
|
id,
|
||||||
|
@ -150,12 +151,13 @@ impl<T: ValueIdentifiable> From<Box<T>> for IdentifiablePointer<T> {
|
||||||
|
|
||||||
impl<T: ValueIdentifiable> From<*const T> for IdentifiablePointer<T> {
|
impl<T: ValueIdentifiable> From<*const T> for IdentifiablePointer<T> {
|
||||||
fn from(v: *const T) -> Self {
|
fn from(v: *const T) -> Self {
|
||||||
let id = unsafe { v.as_ref() }.unwrap().value_identifier();
|
let id = unsafe { transmute(v.as_ref().unwrap().value_identifier()) };
|
||||||
Self { ptr: v, id }
|
Self { ptr: v, id }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> IdentifiablePointer<T> {
|
impl<T> IdentifiablePointer<T> {
|
||||||
|
/// Returns an identifiable pointer with null as pointer, and 0 as identifier.
|
||||||
pub fn none() -> Self {
|
pub fn none() -> Self {
|
||||||
Self {
|
Self {
|
||||||
ptr: std::ptr::null(),
|
ptr: std::ptr::null(),
|
||||||
|
|
|
@ -5,6 +5,7 @@ use std::ffi::{c_char, CStr, CString};
|
||||||
use std::ptr::drop_in_place;
|
use std::ptr::drop_in_place;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
/// Instantiates a new ability.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn ability_new(
|
unsafe extern "C" fn ability_new(
|
||||||
name: *const c_char,
|
name: *const c_char,
|
||||||
|
@ -24,26 +25,31 @@ unsafe extern "C" fn ability_new(
|
||||||
Arc::new(Ability::new(&name, &effect, parameters_vec)).into()
|
Arc::new(Ability::new(&name, &effect, parameters_vec)).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Drops a reference counted ability.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn ability_drop(ptr: OwnedPtr<Arc<Ability>>) {
|
unsafe extern "C" fn ability_drop(ptr: OwnedPtr<Arc<Ability>>) {
|
||||||
drop_in_place(ptr)
|
drop_in_place(ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The name of the ability.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn ability_name(ptr: ExternPointer<Arc<Ability>>) -> OwnedPtr<c_char> {
|
unsafe extern "C" fn ability_name(ptr: ExternPointer<Arc<Ability>>) -> OwnedPtr<c_char> {
|
||||||
CString::new(ptr.as_ref().name().str()).unwrap().into_raw()
|
CString::new(ptr.as_ref().name().str()).unwrap().into_raw()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The name of the script effect of the ability.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn ability_effect(ptr: ExternPointer<Arc<Ability>>) -> OwnedPtr<c_char> {
|
unsafe extern "C" fn ability_effect(ptr: ExternPointer<Arc<Ability>>) -> OwnedPtr<c_char> {
|
||||||
CString::new(ptr.as_ref().effect().str()).unwrap().into_raw()
|
CString::new(ptr.as_ref().effect().str()).unwrap().into_raw()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The length of the parameters for the script effect of the ability.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn ability_parameter_length(ptr: ExternPointer<Arc<Ability>>) -> usize {
|
unsafe extern "C" fn ability_parameter_length(ptr: ExternPointer<Arc<Ability>>) -> usize {
|
||||||
ptr.as_ref().parameters().len()
|
ptr.as_ref().parameters().len()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets a parameter for the script effect of the ability.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn ability_parameter_get(
|
unsafe extern "C" fn ability_parameter_get(
|
||||||
ptr: ExternPointer<Arc<Ability>>,
|
ptr: ExternPointer<Arc<Ability>>,
|
||||||
|
|
|
@ -9,6 +9,7 @@ use std::ffi::{c_char, CStr, CString};
|
||||||
use std::ptr::drop_in_place;
|
use std::ptr::drop_in_place;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
/// Instantiates a new form.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn form_new(
|
unsafe extern "C" fn form_new(
|
||||||
name: *const c_char,
|
name: *const c_char,
|
||||||
|
@ -60,11 +61,13 @@ unsafe extern "C" fn form_new(
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Drops a reference count for a form.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn form_drop(ptr: OwnedPtr<Arc<Form>>) {
|
unsafe extern "C" fn form_drop(ptr: OwnedPtr<Arc<Form>>) {
|
||||||
drop_in_place(ptr)
|
drop_in_place(ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The name of the form.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn form_name(ptr: ExternPointer<Arc<Form>>) -> OwnedPtr<c_char> {
|
unsafe extern "C" fn form_name(ptr: ExternPointer<Arc<Form>>) -> OwnedPtr<c_char> {
|
||||||
let name = ptr.as_ref().name();
|
let name = ptr.as_ref().name();
|
||||||
|
@ -77,6 +80,7 @@ ffi_arc_getter!(Form, base_experience, u32);
|
||||||
|
|
||||||
ffi_vec_value_getters!(Form, types, TypeIdentifier);
|
ffi_vec_value_getters!(Form, types, TypeIdentifier);
|
||||||
|
|
||||||
|
/// The inherent values of a form of species that are used for the stats of a Pokemon.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn form_base_stats(ptr: ExternPointer<Arc<Form>>) -> IdentifiablePointer<StaticStatisticSet<u16>> {
|
unsafe extern "C" fn form_base_stats(ptr: ExternPointer<Arc<Form>>) -> IdentifiablePointer<StaticStatisticSet<u16>> {
|
||||||
(ptr.as_ref().base_stats() as *const StaticStatisticSet<u16>).into()
|
(ptr.as_ref().base_stats() as *const StaticStatisticSet<u16>).into()
|
||||||
|
@ -87,12 +91,9 @@ ffi_vec_stringkey_getters!(Form, hidden_abilities);
|
||||||
|
|
||||||
ffi_arc_getter!(Form, moves, BorrowedPtr<LearnableMoves>);
|
ffi_arc_getter!(Form, moves, BorrowedPtr<LearnableMoves>);
|
||||||
|
|
||||||
|
/// Check if the form has a specific flag set.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn form_has_flag(ptr: ExternPointer<Arc<Form>>, flag: *const c_char) -> u8 {
|
unsafe extern "C" fn form_has_flag(ptr: ExternPointer<Arc<Form>>, flag: *const c_char) -> u8 {
|
||||||
let flag = CStr::from_ptr(flag).into();
|
let flag = CStr::from_ptr(flag).into();
|
||||||
if ptr.as_ref().has_flag(&flag) {
|
u8::from(ptr.as_ref().has_flag(&flag))
|
||||||
1
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,22 +3,27 @@ use crate::ffi::{ExternPointer, OwnedPtr};
|
||||||
use crate::static_data::{GrowthRate, LookupGrowthRate};
|
use crate::static_data::{GrowthRate, LookupGrowthRate};
|
||||||
use std::ptr::drop_in_place;
|
use std::ptr::drop_in_place;
|
||||||
|
|
||||||
|
/// Instantiates a new lookup growth rate. The experience array should be the amount of experience
|
||||||
|
/// required per level, with the first element being the experience required for level 1 (generally 0).
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn growth_rate_lookup_new(array: *const u32, length: usize) -> OwnedPtr<Box<dyn GrowthRate>> {
|
unsafe extern "C" fn growth_rate_lookup_new(array: *const u32, length: usize) -> OwnedPtr<Box<dyn GrowthRate>> {
|
||||||
let array = std::slice::from_raw_parts(array, length);
|
let array = std::slice::from_raw_parts(array, length);
|
||||||
Box::into_raw(Box::new(Box::new(LookupGrowthRate::new(array.to_vec()))))
|
Box::into_raw(Box::new(Box::new(LookupGrowthRate::new(array.to_vec()))))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Drops the growth rate.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn growth_rate_lookup_drop(ptr: OwnedPtr<Box<dyn GrowthRate>>) {
|
unsafe extern "C" fn growth_rate_lookup_drop(ptr: OwnedPtr<Box<dyn GrowthRate>>) {
|
||||||
drop_in_place(ptr)
|
drop_in_place(ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Calculate the level something with this growth rate would have at a certain experience.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn growth_rate_calculate_level(ptr: ExternPointer<Box<dyn GrowthRate>>, experience: u32) -> LevelInt {
|
extern "C" fn growth_rate_calculate_level(ptr: ExternPointer<Box<dyn GrowthRate>>, experience: u32) -> LevelInt {
|
||||||
ptr.as_ref().calculate_level(experience)
|
ptr.as_ref().calculate_level(experience)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Calculate the experience something with this growth rate would have at a certain level.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn growth_rate_calculate_experience(ptr: ExternPointer<Box<dyn GrowthRate>>, level: LevelInt) -> u32 {
|
extern "C" fn growth_rate_calculate_experience(ptr: ExternPointer<Box<dyn GrowthRate>>, level: LevelInt) -> u32 {
|
||||||
ptr.as_ref().calculate_experience(level)
|
ptr.as_ref().calculate_experience(level)
|
||||||
|
|
|
@ -6,6 +6,7 @@ use std::ffi::{c_char, CStr, CString};
|
||||||
use std::ptr::drop_in_place;
|
use std::ptr::drop_in_place;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
/// Instantiates an item.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn item_new(
|
unsafe extern "C" fn item_new(
|
||||||
name: *const c_char,
|
name: *const c_char,
|
||||||
|
@ -24,11 +25,13 @@ unsafe extern "C" fn item_new(
|
||||||
Arc::new(Item::new(&name, category, battle_category, price, flags_set)).into()
|
Arc::new(Item::new(&name, category, battle_category, price, flags_set)).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Drops a reference counted item.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn item_drop(ptr: OwnedPtr<Arc<Item>>) {
|
unsafe extern "C" fn item_drop(ptr: OwnedPtr<Arc<Item>>) {
|
||||||
drop_in_place(ptr)
|
drop_in_place(ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The name of the item.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn item_name(ptr: ExternPointer<Arc<Item>>) -> OwnedPtr<c_char> {
|
unsafe extern "C" fn item_name(ptr: ExternPointer<Arc<Item>>) -> OwnedPtr<c_char> {
|
||||||
let name = ptr.as_ref().name();
|
let name = ptr.as_ref().name();
|
||||||
|
@ -39,12 +42,9 @@ ffi_arc_getter!(Item, category, ItemCategory);
|
||||||
ffi_arc_getter!(Item, battle_category, BattleItemCategory);
|
ffi_arc_getter!(Item, battle_category, BattleItemCategory);
|
||||||
ffi_arc_getter!(Item, price, i32);
|
ffi_arc_getter!(Item, price, i32);
|
||||||
|
|
||||||
|
/// Checks whether the item has a specific flag.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn item_has_flag(ptr: ExternPointer<Arc<Item>>, flag: *const c_char) -> u8 {
|
unsafe extern "C" fn item_has_flag(ptr: ExternPointer<Arc<Item>>, flag: *const c_char) -> u8 {
|
||||||
let flag = CStr::from_ptr(flag).into();
|
let flag = CStr::from_ptr(flag).into();
|
||||||
if ptr.as_ref().has_flag(&flag) {
|
u8::from(ptr.as_ref().has_flag(&flag))
|
||||||
1
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,19 +4,22 @@ use crate::static_data::LearnableMoves;
|
||||||
use std::ffi::{c_char, CStr};
|
use std::ffi::{c_char, CStr};
|
||||||
use std::ptr::drop_in_place;
|
use std::ptr::drop_in_place;
|
||||||
|
|
||||||
|
/// Instantiates a new Learnable Moves.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn learnable_moves_new() -> OwnedPtr<LearnableMoves> {
|
extern "C" fn learnable_moves_new() -> OwnedPtr<LearnableMoves> {
|
||||||
Box::into_raw(Box::new(LearnableMoves::new()))
|
Box::into_raw(Box::new(LearnableMoves::new()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// drops a learnablemoves struct.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn learnable_moves_drop(ptr: OwnedPtr<LearnableMoves>) {
|
unsafe extern "C" fn learnable_moves_drop(ptr: OwnedPtr<LearnableMoves>) {
|
||||||
drop_in_place(ptr)
|
drop_in_place(ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Adds a new level move the Pokemon can learn.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn learnable_moves_add_level_move(
|
unsafe extern "C" fn learnable_moves_add_level_move(
|
||||||
ptr: ExternPointer<LearnableMoves>,
|
mut ptr: ExternPointer<LearnableMoves>,
|
||||||
level: LevelInt,
|
level: LevelInt,
|
||||||
move_name: BorrowedPtr<c_char>,
|
move_name: BorrowedPtr<c_char>,
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -4,16 +4,19 @@ use crate::static_data::{GrowthRate, GrowthRateLibrary};
|
||||||
use std::ffi::{c_char, CStr};
|
use std::ffi::{c_char, CStr};
|
||||||
use std::ptr::drop_in_place;
|
use std::ptr::drop_in_place;
|
||||||
|
|
||||||
|
/// Instantiates a new growth rate library with a capacity
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn growth_rate_library_new(capacity: usize) -> IdentifiablePointer<GrowthRateLibrary> {
|
extern "C" fn growth_rate_library_new(capacity: usize) -> IdentifiablePointer<GrowthRateLibrary> {
|
||||||
Box::new(GrowthRateLibrary::new(capacity)).into()
|
Box::new(GrowthRateLibrary::new(capacity)).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Drops the growthrate library.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn growth_rate_library_drop(ptr: OwnedPtr<GrowthRateLibrary>) {
|
unsafe extern "C" fn growth_rate_library_drop(ptr: OwnedPtr<GrowthRateLibrary>) {
|
||||||
drop_in_place(ptr)
|
drop_in_place(ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Calculates the level for a given growth key name and a certain experience.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn growth_rate_library_calculate_level(
|
unsafe extern "C" fn growth_rate_library_calculate_level(
|
||||||
ptr: ExternPointer<GrowthRateLibrary>,
|
ptr: ExternPointer<GrowthRateLibrary>,
|
||||||
|
@ -24,6 +27,7 @@ unsafe extern "C" fn growth_rate_library_calculate_level(
|
||||||
.calculate_level(&CStr::from_ptr(growth_rate).into(), experience)
|
.calculate_level(&CStr::from_ptr(growth_rate).into(), experience)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Calculates the experience for a given growth key name and a certain level.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn growth_rate_library_calculate_experience(
|
unsafe extern "C" fn growth_rate_library_calculate_experience(
|
||||||
ptr: ExternPointer<GrowthRateLibrary>,
|
ptr: ExternPointer<GrowthRateLibrary>,
|
||||||
|
@ -34,9 +38,10 @@ unsafe extern "C" fn growth_rate_library_calculate_experience(
|
||||||
.calculate_experience(&CStr::from_ptr(growth_rate).into(), level)
|
.calculate_experience(&CStr::from_ptr(growth_rate).into(), level)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Adds a new growth rate with a name and value.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn growth_rate_library_add_growth_rate(
|
unsafe extern "C" fn growth_rate_library_add_growth_rate(
|
||||||
ptr: ExternPointer<GrowthRateLibrary>,
|
mut ptr: ExternPointer<GrowthRateLibrary>,
|
||||||
name: BorrowedPtr<c_char>,
|
name: BorrowedPtr<c_char>,
|
||||||
growth_rate: OwnedPtr<Box<dyn GrowthRate>>,
|
growth_rate: OwnedPtr<Box<dyn GrowthRate>>,
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -3,16 +3,19 @@ use crate::ffi::{ExternPointer, IdentifiablePointer, OwnedPtr};
|
||||||
use crate::static_data::LibrarySettings;
|
use crate::static_data::LibrarySettings;
|
||||||
use std::ptr::drop_in_place;
|
use std::ptr::drop_in_place;
|
||||||
|
|
||||||
|
/// Creates a new settings library.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn library_settings_new(max_level: LevelInt) -> IdentifiablePointer<LibrarySettings> {
|
extern "C" fn library_settings_new(max_level: LevelInt) -> IdentifiablePointer<LibrarySettings> {
|
||||||
Box::new(LibrarySettings::new(max_level)).into()
|
Box::new(LibrarySettings::new(max_level)).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Drop a library settings object.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn library_settings_drop(ptr: OwnedPtr<LibrarySettings>) {
|
unsafe extern "C" fn library_settings_drop(ptr: OwnedPtr<LibrarySettings>) {
|
||||||
drop_in_place(ptr)
|
drop_in_place(ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The highest level a Pokemon can be.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn library_settings_maximum_level(ptr: ExternPointer<LibrarySettings>) -> LevelInt {
|
extern "C" fn library_settings_maximum_level(ptr: ExternPointer<LibrarySettings>) -> LevelInt {
|
||||||
ptr.as_ref().maximum_level()
|
ptr.as_ref().maximum_level()
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
|
/// The foreign function interface for the growth rate library.
|
||||||
mod growth_rate_library;
|
mod growth_rate_library;
|
||||||
|
/// The foreign function interface for the library settings.
|
||||||
mod library_settings;
|
mod library_settings;
|
||||||
|
/// The foreign function interface for the nature library.
|
||||||
mod nature_library;
|
mod nature_library;
|
||||||
|
/// The foreign function interface for the static data.
|
||||||
mod static_data;
|
mod static_data;
|
||||||
|
/// The foreign function interface for the type library.
|
||||||
mod type_library;
|
mod type_library;
|
||||||
|
|
||||||
use crate::ffi::{BorrowedPtr, IdentifiablePointer, OwnedPtr};
|
use crate::ffi::{BorrowedPtr, IdentifiablePointer, OwnedPtr};
|
||||||
|
@ -10,6 +15,7 @@ use std::ffi::{c_char, CStr};
|
||||||
use std::ptr::drop_in_place;
|
use std::ptr::drop_in_place;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
/// Generates foreign function interfaces for a DataLibrary trait implementation.
|
||||||
macro_rules! library_interface {
|
macro_rules! library_interface {
|
||||||
($library_type:ty, $return_type:ty) => {
|
($library_type:ty, $return_type:ty) => {
|
||||||
paste::paste! {
|
paste::paste! {
|
||||||
|
|
|
@ -4,19 +4,22 @@ use std::ffi::{c_char, CStr, CString};
|
||||||
use std::ptr::drop_in_place;
|
use std::ptr::drop_in_place;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
/// Creates a new nature library with a given capacity.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn nature_library_new(capacity: usize) -> IdentifiablePointer<NatureLibrary> {
|
extern "C" fn nature_library_new(capacity: usize) -> IdentifiablePointer<NatureLibrary> {
|
||||||
Box::new(NatureLibrary::new(capacity)).into()
|
Box::new(NatureLibrary::new(capacity)).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Drop a nature library.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn nature_library_drop(ptr: OwnedPtr<NatureLibrary>) {
|
unsafe extern "C" fn nature_library_drop(ptr: OwnedPtr<NatureLibrary>) {
|
||||||
drop_in_place(ptr);
|
drop_in_place(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Adds a new nature with name to the library.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn nature_library_load_nature(
|
unsafe extern "C" fn nature_library_load_nature(
|
||||||
ptr: ExternPointer<NatureLibrary>,
|
mut ptr: ExternPointer<NatureLibrary>,
|
||||||
name: BorrowedPtr<c_char>,
|
name: BorrowedPtr<c_char>,
|
||||||
nature: OwnedPtr<Arc<Nature>>,
|
nature: OwnedPtr<Arc<Nature>>,
|
||||||
) {
|
) {
|
||||||
|
@ -24,6 +27,7 @@ unsafe extern "C" fn nature_library_load_nature(
|
||||||
.load_nature(CStr::from_ptr(name).into(), nature.as_ref().unwrap().clone())
|
.load_nature(CStr::from_ptr(name).into(), nature.as_ref().unwrap().clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets a nature by name.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn nature_library_get_nature(
|
unsafe extern "C" fn nature_library_get_nature(
|
||||||
ptr: ExternPointer<NatureLibrary>,
|
ptr: ExternPointer<NatureLibrary>,
|
||||||
|
@ -36,6 +40,7 @@ unsafe extern "C" fn nature_library_get_nature(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Finds a nature name by nature.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn nature_library_get_nature_name(
|
unsafe extern "C" fn nature_library_get_nature_name(
|
||||||
ptr: ExternPointer<NatureLibrary>,
|
ptr: ExternPointer<NatureLibrary>,
|
||||||
|
|
|
@ -5,54 +5,64 @@ use crate::static_data::{
|
||||||
};
|
};
|
||||||
use std::ptr::drop_in_place;
|
use std::ptr::drop_in_place;
|
||||||
|
|
||||||
|
/// Instantiates a new data collection.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn static_data_new(settings: OwnedPtr<LibrarySettings>) -> IdentifiablePointer<StaticData> {
|
unsafe extern "C" fn static_data_new(settings: OwnedPtr<LibrarySettings>) -> IdentifiablePointer<StaticData> {
|
||||||
Box::new(StaticData::new(*Box::from_raw(settings))).into()
|
Box::new(StaticData::new(*Box::from_raw(settings))).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Drop a static data.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn static_data_drop(ptr: OwnedPtr<StaticData>) {
|
unsafe extern "C" fn static_data_drop(ptr: OwnedPtr<StaticData>) {
|
||||||
drop_in_place(ptr)
|
drop_in_place(ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Several misc settings for the library.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn static_data_settings(data: ExternPointer<StaticData>) -> IdentifiablePointer<LibrarySettings> {
|
unsafe extern "C" fn static_data_settings(mut data: ExternPointer<StaticData>) -> IdentifiablePointer<LibrarySettings> {
|
||||||
(data.as_mut().settings() as *const LibrarySettings).into()
|
(data.as_mut().settings() as *const LibrarySettings).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// All data for Pokemon species.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn static_data_species(data: ExternPointer<StaticData>) -> IdentifiablePointer<SpeciesLibrary> {
|
unsafe extern "C" fn static_data_species(mut data: ExternPointer<StaticData>) -> IdentifiablePointer<SpeciesLibrary> {
|
||||||
(data.as_mut().species_mut() as *const SpeciesLibrary).into()
|
(data.as_mut().species_mut() as *const SpeciesLibrary).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// All data for the moves.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn static_data_moves(data: ExternPointer<StaticData>) -> IdentifiablePointer<MoveLibrary> {
|
unsafe extern "C" fn static_data_moves(mut data: ExternPointer<StaticData>) -> IdentifiablePointer<MoveLibrary> {
|
||||||
(data.as_mut().moves_mut() as *const MoveLibrary).into()
|
(data.as_mut().moves_mut() as *const MoveLibrary).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// All data for the items.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn static_data_items(data: ExternPointer<StaticData>) -> IdentifiablePointer<ItemLibrary> {
|
unsafe extern "C" fn static_data_items(mut data: ExternPointer<StaticData>) -> IdentifiablePointer<ItemLibrary> {
|
||||||
(data.as_mut().items_mut() as *const ItemLibrary).into()
|
(data.as_mut().items_mut() as *const ItemLibrary).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// All data for growth rates.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn static_data_growth_rates(
|
unsafe extern "C" fn static_data_growth_rates(
|
||||||
data: ExternPointer<StaticData>,
|
mut data: ExternPointer<StaticData>,
|
||||||
) -> IdentifiablePointer<GrowthRateLibrary> {
|
) -> IdentifiablePointer<GrowthRateLibrary> {
|
||||||
(data.as_mut().growth_rates_mut() as *const GrowthRateLibrary).into()
|
(data.as_mut().growth_rates_mut() as *const GrowthRateLibrary).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// All data related to types and type effectiveness.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn static_data_types(data: ExternPointer<StaticData>) -> IdentifiablePointer<TypeLibrary> {
|
unsafe extern "C" fn static_data_types(mut data: ExternPointer<StaticData>) -> IdentifiablePointer<TypeLibrary> {
|
||||||
(data.as_mut().types_mut() as *const TypeLibrary).into()
|
(data.as_mut().types_mut() as *const TypeLibrary).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// All data related to natures.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn static_data_natures(data: ExternPointer<StaticData>) -> IdentifiablePointer<NatureLibrary> {
|
unsafe extern "C" fn static_data_natures(mut data: ExternPointer<StaticData>) -> IdentifiablePointer<NatureLibrary> {
|
||||||
(data.as_mut().natures_mut() as *const NatureLibrary).into()
|
(data.as_mut().natures_mut() as *const NatureLibrary).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// All data related to abilities.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn static_data_abilities(data: ExternPointer<StaticData>) -> IdentifiablePointer<AbilityLibrary> {
|
unsafe extern "C" fn static_data_abilities(mut data: ExternPointer<StaticData>) -> IdentifiablePointer<AbilityLibrary> {
|
||||||
(data.as_mut().abilities_mut() as *const AbilityLibrary).into()
|
(data.as_mut().abilities_mut() as *const AbilityLibrary).into()
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,16 +3,19 @@ use crate::static_data::{TypeIdentifier, TypeLibrary};
|
||||||
use std::ffi::{c_char, CStr, CString};
|
use std::ffi::{c_char, CStr, CString};
|
||||||
use std::ptr::drop_in_place;
|
use std::ptr::drop_in_place;
|
||||||
|
|
||||||
|
/// Instantiates a new type library with a specific capacity.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn type_library_new(capacity: usize) -> IdentifiablePointer<TypeLibrary> {
|
extern "C" fn type_library_new(capacity: usize) -> IdentifiablePointer<TypeLibrary> {
|
||||||
Box::new(TypeLibrary::new(capacity)).into()
|
Box::new(TypeLibrary::new(capacity)).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Drops a type library.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn type_library_drop(ptr: OwnedPtr<TypeLibrary>) {
|
unsafe extern "C" fn type_library_drop(ptr: OwnedPtr<TypeLibrary>) {
|
||||||
drop_in_place(ptr);
|
drop_in_place(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets the type identifier for a type with a name.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn type_library_get_type_id(
|
unsafe extern "C" fn type_library_get_type_id(
|
||||||
ptr: ExternPointer<TypeLibrary>,
|
ptr: ExternPointer<TypeLibrary>,
|
||||||
|
@ -28,6 +31,7 @@ unsafe extern "C" fn type_library_get_type_id(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets the type name from the type identifier.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn type_library_get_type_name(
|
unsafe extern "C" fn type_library_get_type_name(
|
||||||
ptr: ExternPointer<TypeLibrary>,
|
ptr: ExternPointer<TypeLibrary>,
|
||||||
|
@ -43,6 +47,7 @@ unsafe extern "C" fn type_library_get_type_name(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets the effectiveness for a single attacking type against a single defending type.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn type_library_get_single_effectiveness(
|
extern "C" fn type_library_get_single_effectiveness(
|
||||||
ptr: ExternPointer<TypeLibrary>,
|
ptr: ExternPointer<TypeLibrary>,
|
||||||
|
@ -52,6 +57,9 @@ extern "C" fn type_library_get_single_effectiveness(
|
||||||
ptr.as_ref().get_single_effectiveness(attacking, defending)
|
ptr.as_ref().get_single_effectiveness(attacking, defending)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets the effectiveness for a single attacking type against an amount of defending types.
|
||||||
|
/// This is equivalent to running [`type_library_get_single_effectiveness`] on each defending type,
|
||||||
|
/// and multiplying the results with each other.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn type_library_get_effectiveness(
|
unsafe extern "C" fn type_library_get_effectiveness(
|
||||||
ptr: ExternPointer<TypeLibrary>,
|
ptr: ExternPointer<TypeLibrary>,
|
||||||
|
@ -63,17 +71,19 @@ unsafe extern "C" fn type_library_get_effectiveness(
|
||||||
ptr.as_ref().get_effectiveness(attacking, v)
|
ptr.as_ref().get_effectiveness(attacking, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Registers a new type in the library.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn type_library_register_type(
|
unsafe extern "C" fn type_library_register_type(
|
||||||
ptr: ExternPointer<TypeLibrary>,
|
mut ptr: ExternPointer<TypeLibrary>,
|
||||||
name: BorrowedPtr<c_char>,
|
name: BorrowedPtr<c_char>,
|
||||||
) -> TypeIdentifier {
|
) -> TypeIdentifier {
|
||||||
ptr.as_mut().register_type(&CStr::from_ptr(name).into())
|
ptr.as_mut().register_type(&CStr::from_ptr(name).into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the effectiveness for an attacking type against a defending type.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn type_library_set_effectiveness(
|
unsafe extern "C" fn type_library_set_effectiveness(
|
||||||
ptr: ExternPointer<TypeLibrary>,
|
mut ptr: ExternPointer<TypeLibrary>,
|
||||||
attacking: TypeIdentifier,
|
attacking: TypeIdentifier,
|
||||||
defending: TypeIdentifier,
|
defending: TypeIdentifier,
|
||||||
effectiveness: f32,
|
effectiveness: f32,
|
||||||
|
|
|
@ -4,43 +4,59 @@ use crate::StringKey;
|
||||||
use std::ffi::{c_char, CStr, CString};
|
use std::ffi::{c_char, CStr, CString};
|
||||||
use std::ptr::drop_in_place;
|
use std::ptr::drop_in_place;
|
||||||
|
|
||||||
|
/// The Foreign Function Interface for abilities
|
||||||
mod ability;
|
mod ability;
|
||||||
|
/// The Foreign Function Interface for forms
|
||||||
mod form;
|
mod form;
|
||||||
|
/// The Foreign Function Interface for growth rates
|
||||||
mod growth_rate;
|
mod growth_rate;
|
||||||
|
/// The Foreign Function Interface for items
|
||||||
mod item;
|
mod item;
|
||||||
|
/// The Foreign Function Interface for learnable moves
|
||||||
mod learnable_moves;
|
mod learnable_moves;
|
||||||
|
/// The Foreign Function Interface for libraries
|
||||||
mod libraries;
|
mod libraries;
|
||||||
|
/// The Foreign Function Interface for moves
|
||||||
mod move_data;
|
mod move_data;
|
||||||
|
/// The Foreign Function Interface for natures
|
||||||
mod nature;
|
mod nature;
|
||||||
|
/// The Foreign Function Interface for species
|
||||||
mod species;
|
mod species;
|
||||||
|
/// The Foreign Function Interface for sets of statistics
|
||||||
mod statistic_set;
|
mod statistic_set;
|
||||||
|
|
||||||
|
/// Instantiates an effect parameter with a boolean.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn effect_parameter_new_bool(value: u8) -> OwnedPtr<EffectParameter> {
|
extern "C" fn effect_parameter_new_bool(value: u8) -> OwnedPtr<EffectParameter> {
|
||||||
Box::into_raw(Box::new((value == 1).into()))
|
Box::into_raw(Box::new((value == 1).into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Instantiates an effect parameter with an integer.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn effect_parameter_new_int(value: i64) -> OwnedPtr<EffectParameter> {
|
extern "C" fn effect_parameter_new_int(value: i64) -> OwnedPtr<EffectParameter> {
|
||||||
Box::into_raw(Box::new(value.into()))
|
Box::into_raw(Box::new(value.into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Instantiates an effect parameter with a float.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn effect_parameter_new_float(value: f32) -> OwnedPtr<EffectParameter> {
|
extern "C" fn effect_parameter_new_float(value: f32) -> OwnedPtr<EffectParameter> {
|
||||||
Box::into_raw(Box::new(value.into()))
|
Box::into_raw(Box::new(value.into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Instantiates an effect parameter with a string.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn effect_parameter_new_string(value: *const c_char) -> OwnedPtr<EffectParameter> {
|
unsafe extern "C" fn effect_parameter_new_string(value: *const c_char) -> OwnedPtr<EffectParameter> {
|
||||||
let sk: StringKey = CStr::from_ptr(value).to_str().unwrap().into();
|
let sk: StringKey = CStr::from_ptr(value).to_str().unwrap().into();
|
||||||
Box::into_raw(Box::new(sk.into()))
|
Box::into_raw(Box::new(sk.into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Drop an effect parameter.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn effect_parameter_drop(ptr: OwnedPtr<EffectParameter>) {
|
unsafe extern "C" fn effect_parameter_drop(ptr: OwnedPtr<EffectParameter>) {
|
||||||
drop_in_place(ptr)
|
drop_in_place(ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the type of an effect parameter.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn effect_parameter_get_type(ptr: ExternPointer<EffectParameter>) -> u8 {
|
extern "C" fn effect_parameter_get_type(ptr: ExternPointer<EffectParameter>) -> u8 {
|
||||||
match ptr.as_ref() {
|
match ptr.as_ref() {
|
||||||
|
@ -51,15 +67,17 @@ extern "C" fn effect_parameter_get_type(ptr: ExternPointer<EffectParameter>) ->
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the boolean contained in the effect parameter, panics if the effect parameter is not a bool.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn effect_parameter_get_as_bool(ptr: ExternPointer<EffectParameter>) -> u8 {
|
extern "C" fn effect_parameter_get_as_bool(ptr: ExternPointer<EffectParameter>) -> u8 {
|
||||||
let p = ptr.as_ref();
|
let p = ptr.as_ref();
|
||||||
if let EffectParameter::Bool(_, b) = p {
|
if let EffectParameter::Bool(_, b) = p {
|
||||||
return if *b { 1 } else { 0 };
|
return u8::from(*b);
|
||||||
}
|
}
|
||||||
panic!("Unexpected effect parameter. Expected bool, was: {}", p);
|
panic!("Unexpected effect parameter. Expected bool, was: {}", p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the int contained in the effect parameter, panics if the effect parameter is not a int.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn effect_parameter_get_as_int(ptr: ExternPointer<EffectParameter>) -> i64 {
|
extern "C" fn effect_parameter_get_as_int(ptr: ExternPointer<EffectParameter>) -> i64 {
|
||||||
let p = ptr.as_ref();
|
let p = ptr.as_ref();
|
||||||
|
@ -69,6 +87,7 @@ extern "C" fn effect_parameter_get_as_int(ptr: ExternPointer<EffectParameter>) -
|
||||||
panic!("Unexpected effect parameter. Expected int, was: {}", p);
|
panic!("Unexpected effect parameter. Expected int, was: {}", p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the float contained in the effect parameter, panics if the effect parameter is not a float.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn effect_parameter_get_as_float(ptr: ExternPointer<EffectParameter>) -> f32 {
|
extern "C" fn effect_parameter_get_as_float(ptr: ExternPointer<EffectParameter>) -> f32 {
|
||||||
let p = ptr.as_ref();
|
let p = ptr.as_ref();
|
||||||
|
@ -78,6 +97,7 @@ extern "C" fn effect_parameter_get_as_float(ptr: ExternPointer<EffectParameter>)
|
||||||
panic!("Unexpected effect parameter. Expected float, was: {}", p);
|
panic!("Unexpected effect parameter. Expected float, was: {}", p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the string contained in the effect parameter, panics if the effect parameter is not a string.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn effect_parameter_get_as_string(ptr: ExternPointer<EffectParameter>) -> OwnedPtr<c_char> {
|
extern "C" fn effect_parameter_get_as_string(ptr: ExternPointer<EffectParameter>) -> OwnedPtr<c_char> {
|
||||||
let p = ptr.as_ref();
|
let p = ptr.as_ref();
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::ffi::{ffi_arc_getter, ffi_getter, BorrowedPtr, ExternPointer, IdentifiablePointer, OwnedPtr};
|
use crate::ffi::{ffi_arc_getter, BorrowedPtr, ExternPointer, IdentifiablePointer, OwnedPtr};
|
||||||
use crate::static_data::{EffectParameter, MoveCategory, MoveData, MoveTarget, SecondaryEffect, TypeIdentifier};
|
use crate::static_data::{EffectParameter, MoveCategory, MoveData, MoveTarget, SecondaryEffect, TypeIdentifier};
|
||||||
use crate::StringKey;
|
use crate::StringKey;
|
||||||
use hashbrown::HashSet;
|
use hashbrown::HashSet;
|
||||||
|
@ -6,6 +6,7 @@ use std::ffi::{c_char, CStr, CString};
|
||||||
use std::ptr::drop_in_place;
|
use std::ptr::drop_in_place;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
/// Instantiates a new move.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn move_data_new(
|
unsafe extern "C" fn move_data_new(
|
||||||
name: *const c_char,
|
name: *const c_char,
|
||||||
|
@ -46,11 +47,13 @@ unsafe extern "C" fn move_data_new(
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Drops a reference counted move.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn move_data_drop(ptr: OwnedPtr<Arc<MoveData>>) {
|
unsafe extern "C" fn move_data_drop(ptr: OwnedPtr<Arc<MoveData>>) {
|
||||||
drop_in_place(ptr)
|
drop_in_place(ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The name of the move.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn move_data_name(ptr: ExternPointer<Arc<MoveData>>) -> OwnedPtr<c_char> {
|
unsafe extern "C" fn move_data_name(ptr: ExternPointer<Arc<MoveData>>) -> OwnedPtr<c_char> {
|
||||||
let name = ptr.as_ref().name();
|
let name = ptr.as_ref().name();
|
||||||
|
@ -65,6 +68,7 @@ ffi_arc_getter!(MoveData, base_usages, u8);
|
||||||
ffi_arc_getter!(MoveData, target, MoveTarget);
|
ffi_arc_getter!(MoveData, target, MoveTarget);
|
||||||
ffi_arc_getter!(MoveData, priority, i8);
|
ffi_arc_getter!(MoveData, priority, i8);
|
||||||
|
|
||||||
|
/// The optional secondary effect the move has.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn move_data_secondary_effect(
|
unsafe extern "C" fn move_data_secondary_effect(
|
||||||
ptr: ExternPointer<Arc<MoveData>>,
|
ptr: ExternPointer<Arc<MoveData>>,
|
||||||
|
@ -77,16 +81,14 @@ unsafe extern "C" fn move_data_secondary_effect(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Arbitrary flags that can be applied to the move.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn move_data_has_flag(ptr: ExternPointer<Arc<MoveData>>, flag: *const c_char) -> u8 {
|
unsafe extern "C" fn move_data_has_flag(ptr: ExternPointer<Arc<MoveData>>, flag: *const c_char) -> u8 {
|
||||||
let flag = CStr::from_ptr(flag).into();
|
let flag = CStr::from_ptr(flag).into();
|
||||||
if ptr.as_ref().has_flag(&flag) {
|
u8::from(ptr.as_ref().has_flag(&flag))
|
||||||
1
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Instantiates a new Secondary Effect.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn secondary_effect_new(
|
unsafe extern "C" fn secondary_effect_new(
|
||||||
chance: f32,
|
chance: f32,
|
||||||
|
@ -108,23 +110,31 @@ unsafe extern "C" fn secondary_effect_new(
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Drop a secondary effect.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn secondary_effect_drop(ptr: OwnedPtr<SecondaryEffect>) {
|
unsafe extern "C" fn secondary_effect_drop(ptr: OwnedPtr<SecondaryEffect>) {
|
||||||
drop_in_place(ptr)
|
drop_in_place(ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
ffi_getter!(SecondaryEffect, chance, f32);
|
/// The chance the effect triggers.
|
||||||
|
#[no_mangle]
|
||||||
|
unsafe extern "C" fn secondary_effect_chance(ptr: ExternPointer<SecondaryEffect>) -> f32 {
|
||||||
|
ptr.as_ref().chance()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The name of the effect.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn secondary_effect_effect_name(ptr: ExternPointer<SecondaryEffect>) -> OwnedPtr<c_char> {
|
unsafe extern "C" fn secondary_effect_effect_name(ptr: ExternPointer<SecondaryEffect>) -> OwnedPtr<c_char> {
|
||||||
CString::new(ptr.as_ref().effect_name().str()).unwrap().into_raw()
|
CString::new(ptr.as_ref().effect_name().str()).unwrap().into_raw()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The length of parameters of the effect.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn secondary_effect_parameter_length(ptr: ExternPointer<SecondaryEffect>) -> usize {
|
unsafe extern "C" fn secondary_effect_parameter_length(ptr: ExternPointer<SecondaryEffect>) -> usize {
|
||||||
ptr.as_ref().parameters().len()
|
ptr.as_ref().parameters().len()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get a parameter of the effect.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn secondary_effect_parameter_get(
|
unsafe extern "C" fn secondary_effect_parameter_get(
|
||||||
ptr: ExternPointer<SecondaryEffect>,
|
ptr: ExternPointer<SecondaryEffect>,
|
||||||
|
|
|
@ -3,6 +3,7 @@ use crate::static_data::{Nature, Statistic};
|
||||||
use std::ptr::drop_in_place;
|
use std::ptr::drop_in_place;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
/// Instantiates a new statistic.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn nature_new(
|
extern "C" fn nature_new(
|
||||||
increase_stat: Statistic,
|
increase_stat: Statistic,
|
||||||
|
@ -13,21 +14,26 @@ extern "C" fn nature_new(
|
||||||
Nature::new(increase_stat, decrease_stat, increase_modifier, decrease_modifier).into()
|
Nature::new(increase_stat, decrease_stat, increase_modifier, decrease_modifier).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Reduce the reference count for a nature.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn nature_drop(ptr: OwnedPtr<Arc<Nature>>) {
|
unsafe extern "C" fn nature_drop(ptr: OwnedPtr<Arc<Nature>>) {
|
||||||
drop_in_place(ptr)
|
drop_in_place(ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The stat that should receive the increased modifier.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn nature_increased_stat(ptr: ExternPointer<Arc<Nature>>) -> Statistic {
|
extern "C" fn nature_increased_stat(ptr: ExternPointer<Arc<Nature>>) -> Statistic {
|
||||||
ptr.as_ref().increased_stat()
|
ptr.as_ref().increased_stat()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The stat that should receive the decreased modifier.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn nature_decreased_stat(ptr: ExternPointer<Arc<Nature>>) -> Statistic {
|
extern "C" fn nature_decreased_stat(ptr: ExternPointer<Arc<Nature>>) -> Statistic {
|
||||||
ptr.as_ref().decreased_stat()
|
ptr.as_ref().decreased_stat()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Calculates the modifier for a given stat. If it's the increased stat, returns the increased
|
||||||
|
/// modifier, if it's the decreased stat, returns the decreased modifier. Otherwise returns 1.0
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn nature_get_stat_modifier(ptr: ExternPointer<Arc<Nature>>, stat: Statistic) -> f32 {
|
extern "C" fn nature_get_stat_modifier(ptr: ExternPointer<Arc<Nature>>, stat: Statistic) -> f32 {
|
||||||
ptr.as_ref().get_stat_modifier(stat)
|
ptr.as_ref().get_stat_modifier(stat)
|
||||||
|
|
|
@ -6,6 +6,7 @@ use std::ffi::{c_char, CStr};
|
||||||
use std::ptr::drop_in_place;
|
use std::ptr::drop_in_place;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
/// Creates a new species.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn species_new(
|
unsafe extern "C" fn species_new(
|
||||||
id: u16,
|
id: u16,
|
||||||
|
@ -37,6 +38,7 @@ unsafe extern "C" fn species_new(
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Drop a reference to the species.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn species_drop(ptr: OwnedPtr<Arc<Species>>) {
|
unsafe extern "C" fn species_drop(ptr: OwnedPtr<Arc<Species>>) {
|
||||||
drop_in_place(ptr);
|
drop_in_place(ptr);
|
||||||
|
@ -48,9 +50,10 @@ ffi_arc_getter!(Species, gender_rate, f32);
|
||||||
ffi_arc_stringkey_getter!(Species, growth_rate);
|
ffi_arc_stringkey_getter!(Species, growth_rate);
|
||||||
ffi_arc_getter!(Species, capture_rate, u8);
|
ffi_arc_getter!(Species, capture_rate, u8);
|
||||||
|
|
||||||
|
/// Adds a new form to the species.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn species_add_form(
|
unsafe extern "C" fn species_add_form(
|
||||||
species: ExternPointer<Arc<Species>>,
|
mut species: ExternPointer<Arc<Species>>,
|
||||||
name: BorrowedPtr<c_char>,
|
name: BorrowedPtr<c_char>,
|
||||||
form: OwnedPtr<Arc<Form>>,
|
form: OwnedPtr<Arc<Form>>,
|
||||||
) {
|
) {
|
||||||
|
@ -58,6 +61,7 @@ unsafe extern "C" fn species_add_form(
|
||||||
species.as_mut().add_form(CStr::from_ptr(name).into(), form)
|
species.as_mut().add_form(CStr::from_ptr(name).into(), form)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets a form by name.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn species_get_form(
|
unsafe extern "C" fn species_get_form(
|
||||||
species: ExternPointer<Arc<Species>>,
|
species: ExternPointer<Arc<Species>>,
|
||||||
|
|
|
@ -2,6 +2,7 @@ use crate::ffi::{ExternPointer, IdentifiablePointer, OwnedPtr};
|
||||||
use crate::static_data::{StaticStatisticSet, Statistic, StatisticSet};
|
use crate::static_data::{StaticStatisticSet, Statistic, StatisticSet};
|
||||||
use std::ptr::drop_in_place;
|
use std::ptr::drop_in_place;
|
||||||
|
|
||||||
|
/// Basic foreign function interface for a statistic set.
|
||||||
macro_rules! statistic_set {
|
macro_rules! statistic_set {
|
||||||
($num_type:ident) => {
|
($num_type:ident) => {
|
||||||
paste::paste!{
|
paste::paste!{
|
||||||
|
@ -61,6 +62,7 @@ statistic_set!(i8);
|
||||||
statistic_set!(i16);
|
statistic_set!(i16);
|
||||||
statistic_set!(i32);
|
statistic_set!(i32);
|
||||||
|
|
||||||
|
/// Basic foreign function interface for a static statistic set.
|
||||||
macro_rules! static_statistic_set {
|
macro_rules! static_statistic_set {
|
||||||
($num_type:ident) => {
|
($num_type:ident) => {
|
||||||
paste::paste!{
|
paste::paste!{
|
||||||
|
|
|
@ -12,14 +12,14 @@ register! {
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
side: ExternRef<BattleSide>,
|
side: ExternRef<BattleSide>,
|
||||||
) -> u8 {
|
) -> u8 {
|
||||||
if side.value_func(&env).unwrap().has_fled_battle() { 1 } else { 0 }
|
u8::from(side.value_func(&env).unwrap().has_fled_battle())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battleside_is_defeated(
|
fn battleside_is_defeated(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
side: ExternRef<BattleSide>,
|
side: ExternRef<BattleSide>,
|
||||||
) -> u8 {
|
) -> u8 {
|
||||||
if side.value_func(&env).unwrap().is_defeated() { 1 } else { 0 }
|
u8::from(side.value_func(&env).unwrap().is_defeated())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battleside_get_side_index(
|
fn battleside_get_side_index(
|
||||||
|
@ -102,7 +102,7 @@ register! {
|
||||||
) -> u8 {
|
) -> u8 {
|
||||||
unsafe {
|
unsafe {
|
||||||
let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr));
|
let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr));
|
||||||
if side.value_func(&env).unwrap().has_volatile_script(&c_name.as_ref().into()) { 1 } else { 0 }
|
u8::from(side.value_func(&env).unwrap().has_volatile_script(&c_name.as_ref().into()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,10 +10,6 @@ register! {
|
||||||
battle_random: ExternRef<ChoiceQueue>,
|
battle_random: ExternRef<ChoiceQueue>,
|
||||||
pokemon: ExternRef<Pokemon>
|
pokemon: ExternRef<Pokemon>
|
||||||
) -> u8 {
|
) -> u8 {
|
||||||
if battle_random.value_func(&env).unwrap().move_pokemon_choice_next(pokemon.value_func(&env).unwrap()) {
|
u8::from(battle_random.value_func(&env).unwrap().move_pokemon_choice_next(pokemon.value_func(&env).unwrap()))
|
||||||
1
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ register! {
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
hit: ExternRef<HitData>,
|
hit: ExternRef<HitData>,
|
||||||
) -> u8 {
|
) -> u8 {
|
||||||
if hit.value_func(&env).unwrap().is_critical() { 1 } else { 0 }
|
u8::from(hit.value_func(&env).unwrap().is_critical())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hit_data_fail(
|
fn hit_data_fail(
|
||||||
|
|
|
@ -7,20 +7,26 @@ use wasmer::{FunctionEnv, FunctionEnvMut, Imports, StoreMut};
|
||||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||||
use crate::static_data::StaticData;
|
use crate::static_data::StaticData;
|
||||||
|
|
||||||
|
/// The battle registration
|
||||||
|
mod battle;
|
||||||
|
/// Battle random registration
|
||||||
mod battle_random;
|
mod battle_random;
|
||||||
/// Battle side registration
|
/// Battle side registration
|
||||||
mod battle_side;
|
mod battle_side;
|
||||||
|
/// Choice queue registration.
|
||||||
mod choice_queue;
|
mod choice_queue;
|
||||||
|
/// The executing move registration/
|
||||||
mod executing_move;
|
mod executing_move;
|
||||||
|
/// The hit data registration/
|
||||||
|
mod hit_data;
|
||||||
/// Learned move registration
|
/// Learned move registration
|
||||||
mod learned_move;
|
mod learned_move;
|
||||||
|
/// The party registration.
|
||||||
mod party;
|
mod party;
|
||||||
/// Pokemon registration
|
/// Pokemon registration
|
||||||
mod pokemon;
|
mod pokemon;
|
||||||
/// Turn choice registration
|
/// Turn choice registration
|
||||||
mod turn_choice;
|
mod turn_choice;
|
||||||
mod hit_data;
|
|
||||||
mod battle;
|
|
||||||
|
|
||||||
register! {
|
register! {
|
||||||
fn dynamic_library_get_static_data(
|
fn dynamic_library_get_static_data(
|
||||||
|
|
|
@ -7,7 +7,7 @@ use crate::script_implementations::wasm::script::WebAssemblyScript;
|
||||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||||
use crate::static_data::{ClampedStatisticSet, Species};
|
use crate::static_data::{ClampedStatisticSet, Species};
|
||||||
use crate::static_data::{Item, StatisticSet};
|
use crate::static_data::{Item, StatisticSet};
|
||||||
use crate::{ScriptCategory, StringKey};
|
use crate::ScriptCategory;
|
||||||
use std::ffi::{c_char, CStr};
|
use std::ffi::{c_char, CStr};
|
||||||
use wasmer::FunctionEnvMut;
|
use wasmer::FunctionEnvMut;
|
||||||
|
|
||||||
|
@ -134,11 +134,7 @@ register! {
|
||||||
self_inflicted: u8
|
self_inflicted: u8
|
||||||
) -> u8 {
|
) -> u8 {
|
||||||
unsafe{
|
unsafe{
|
||||||
if pokemon.value_func(&env).unwrap().change_stat_boost(transmute(stat), amount, self_inflicted == 1) {
|
u8::from(pokemon.value_func(&env).unwrap().change_stat_boost(transmute(stat), amount, self_inflicted == 1))
|
||||||
1
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,8 +190,7 @@ register! {
|
||||||
) -> u8 {
|
) -> u8 {
|
||||||
let name : *mut c_char = env.data().data().get_raw_pointer(name);
|
let name : *mut c_char = env.data().data().get_raw_pointer(name);
|
||||||
let name = unsafe { CStr::from_ptr(name) };
|
let name = unsafe { CStr::from_ptr(name) };
|
||||||
let key = StringKey::new(name.to_str().unwrap().into());
|
u8::from(pokemon.value_func(&env).unwrap().has_held_item(&name.into()))
|
||||||
if pokemon.value_func(&env).unwrap().has_held_item(&key) { 1 } else { 0 }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_heal(
|
fn pokemon_heal(
|
||||||
|
@ -204,7 +199,7 @@ register! {
|
||||||
amount: u32,
|
amount: u32,
|
||||||
allow_revive: u8
|
allow_revive: u8
|
||||||
) -> u8 {
|
) -> u8 {
|
||||||
if pokemon.value_func(&env).unwrap().heal(amount, allow_revive == 1) { 1 } else { 0 }
|
u8::from(pokemon.value_func(&env).unwrap().heal(amount, allow_revive == 1))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_clear_status(
|
fn pokemon_clear_status(
|
||||||
|
@ -261,7 +256,7 @@ register! {
|
||||||
) -> u8 {
|
) -> u8 {
|
||||||
unsafe {
|
unsafe {
|
||||||
let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr));
|
let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr));
|
||||||
if pokemon.value_func(&env).unwrap().has_volatile_script(&c_name.as_ref().into()) { 1 } else { 0 }
|
u8::from(pokemon.value_func(&env).unwrap().has_volatile_script(&c_name.as_ref().into()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -149,13 +149,7 @@ fn effect_parameter_get_type(env: FunctionEnvMut<WebAssemblyEnv>, parameter: Ext
|
||||||
fn effect_parameter_as_bool(env: FunctionEnvMut<WebAssemblyEnv>, parameter: ExternRef<EffectParameter>) -> u8 {
|
fn effect_parameter_as_bool(env: FunctionEnvMut<WebAssemblyEnv>, parameter: ExternRef<EffectParameter>) -> u8 {
|
||||||
let v = parameter.value_func(&env).unwrap();
|
let v = parameter.value_func(&env).unwrap();
|
||||||
match v {
|
match v {
|
||||||
EffectParameter::Bool(_, b) => {
|
EffectParameter::Bool(_, b) => u8::from(*b),
|
||||||
if *b {
|
|
||||||
1
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => panic!("Unexpected parameter type!"),
|
_ => panic!("Unexpected parameter type!"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ use crate::static_data::{
|
||||||
ItemLibrary, LibrarySettings, MoveLibrary, SpeciesLibrary, StaticData, StatisticSet, TypeLibrary,
|
ItemLibrary, LibrarySettings, MoveLibrary, SpeciesLibrary, StaticData, StatisticSet, TypeLibrary,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Item registration.
|
||||||
mod item;
|
mod item;
|
||||||
/// Moves data registration
|
/// Moves data registration
|
||||||
mod moves;
|
mod moves;
|
||||||
|
|
|
@ -56,17 +56,9 @@ fn move_data_get_priority(env: FunctionEnvMut<WebAssemblyEnv>, move_data: Extern
|
||||||
move_data.value_func(&env).unwrap().priority()
|
move_data.value_func(&env).unwrap().priority()
|
||||||
}
|
}
|
||||||
fn move_data_has_flag(env: FunctionEnvMut<WebAssemblyEnv>, move_data: ExternRef<MoveData>, flag: ExternRef<StringKey>) -> u8 {
|
fn move_data_has_flag(env: FunctionEnvMut<WebAssemblyEnv>, move_data: ExternRef<MoveData>, flag: ExternRef<StringKey>) -> u8 {
|
||||||
if move_data.value_func(&env).unwrap().has_flag(flag.value_func(&env).unwrap()) {
|
u8::from(move_data.value_func(&env).unwrap().has_flag(flag.value_func(&env).unwrap()))
|
||||||
1
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
fn move_data_has_flag_by_hash(env: FunctionEnvMut<WebAssemblyEnv>, move_data: ExternRef<MoveData>, flag_hash: u32) -> u8 {
|
fn move_data_has_flag_by_hash(env: FunctionEnvMut<WebAssemblyEnv>, move_data: ExternRef<MoveData>, flag_hash: u32) -> u8 {
|
||||||
if move_data.value_func(&env).unwrap().has_flag_by_hash(flag_hash) {
|
u8::from(move_data.value_func(&env).unwrap().has_flag_by_hash(flag_hash))
|
||||||
1
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,7 @@ impl WebAssemblyScript {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get a pointer inside the WASM memory.
|
||||||
pub(crate) fn get_wasm_pointer(&self) -> u32 {
|
pub(crate) fn get_wasm_pointer(&self) -> u32 {
|
||||||
self.self_ptr
|
self.self_ptr
|
||||||
}
|
}
|
||||||
|
@ -569,7 +570,7 @@ impl Script for WebAssemblyScript {
|
||||||
let env = &self.environment;
|
let env = &self.environment;
|
||||||
if let Some(func) = env.script_function_cache().prevent_stat_boost_change(env) {
|
if let Some(func) = env.script_function_cache().prevent_stat_boost_change(env) {
|
||||||
let ptr = env.allocate_temp(*prevent);
|
let ptr = env.allocate_temp(*prevent);
|
||||||
let self_inflicted = if self_inflicted { 1_u8 } else { 0_u8 };
|
let self_inflicted = u8::from(self_inflicted);
|
||||||
call_func!(
|
call_func!(
|
||||||
func,
|
func,
|
||||||
env,
|
env,
|
||||||
|
|
|
@ -173,6 +173,7 @@ script_function_cache! {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ScriptFunctionCache {
|
impl ScriptFunctionCache {
|
||||||
|
/// Get the name of a script.
|
||||||
pub(crate) fn script_get_name(&self, env: &Arc<WebAssemblyEnvironmentData>) -> Option<TypedFunction<u32, u32>> {
|
pub(crate) fn script_get_name(&self, env: &Arc<WebAssemblyEnvironmentData>) -> Option<TypedFunction<u32, u32>> {
|
||||||
{
|
{
|
||||||
let read_lock = self.script_get_name.read();
|
let read_lock = self.script_get_name.read();
|
||||||
|
@ -191,6 +192,7 @@ impl ScriptFunctionCache {
|
||||||
self.script_get_name.read().as_ref().cloned()
|
self.script_get_name.read().as_ref().cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Drop the memory of a CString inside the WASM memory.
|
||||||
pub(crate) fn dealloc_cstring(&self, env: &Arc<WebAssemblyEnvironmentData>) -> Option<TypedFunction<u32, ()>> {
|
pub(crate) fn dealloc_cstring(&self, env: &Arc<WebAssemblyEnvironmentData>) -> Option<TypedFunction<u32, ()>> {
|
||||||
{
|
{
|
||||||
let read_lock = self.dealloc_cstring.read();
|
let read_lock = self.dealloc_cstring.read();
|
||||||
|
|
|
@ -93,18 +93,15 @@ impl WebAssemblyScriptResolver {
|
||||||
self.modules.push(module);
|
self.modules.push(module);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initialise all the data we need.
|
/// Tells the script resolver we're done loading wasm modules, and to finalize the resolver.
|
||||||
pub fn finalize(&mut self) {
|
pub fn finalize(&mut self) {
|
||||||
let mut imports = Imports::new();
|
let mut imports = Imports::new();
|
||||||
//let mut exports = Exports::new();
|
|
||||||
|
|
||||||
let env = FunctionEnv::new(
|
let env = FunctionEnv::new(
|
||||||
&mut self.store_mut(),
|
&mut self.store_mut(),
|
||||||
WebAssemblyEnv::new(Arc::downgrade(&self.environment_data)),
|
WebAssemblyEnv::new(Arc::downgrade(&self.environment_data)),
|
||||||
);
|
);
|
||||||
register_webassembly_funcs(&mut imports, &mut self.store_mut(), &env);
|
register_webassembly_funcs(&mut imports, &mut self.store_mut(), &env);
|
||||||
//imports.register("env", exports);
|
|
||||||
|
|
||||||
for module in &self.modules {
|
for module in &self.modules {
|
||||||
for import in module.imports() {
|
for import in module.imports() {
|
||||||
if imports.get_export("env", import.name()).is_none() {
|
if imports.get_export("env", import.name()).is_none() {
|
||||||
|
|
|
@ -15,7 +15,8 @@ pub struct LookupGrowthRate {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LookupGrowthRate {
|
impl LookupGrowthRate {
|
||||||
/// Instantiates a new lookup growth rate.
|
/// Instantiates a new lookup growth rate. The experience vec should be the amount of experience
|
||||||
|
/// required per level, with the first element being the experience required for level 1 (generally 0).
|
||||||
pub fn new(experience: Vec<u32>) -> LookupGrowthRate {
|
pub fn new(experience: Vec<u32>) -> LookupGrowthRate {
|
||||||
LookupGrowthRate { experience }
|
LookupGrowthRate { experience }
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ pub mod tests {
|
||||||
pub fn build() -> AbilityLibrary {
|
pub fn build() -> AbilityLibrary {
|
||||||
let mut lib = AbilityLibrary::new(1);
|
let mut lib = AbilityLibrary::new(1);
|
||||||
lib.add(
|
lib.add(
|
||||||
&StringKey::new("test_ability".into()),
|
&StringKey::new("test_ability"),
|
||||||
Arc::new(Ability::new(&"test_ability".into(), &"test_ability".into(), Vec::new())),
|
Arc::new(Ability::new(&"test_ability".into(), &"test_ability".into(), Vec::new())),
|
||||||
);
|
);
|
||||||
// Drops borrow as mut
|
// Drops borrow as mut
|
||||||
|
|
|
@ -71,7 +71,7 @@ pub mod tests {
|
||||||
let m = build_move();
|
let m = build_move();
|
||||||
// Borrow as mut so we can insert
|
// Borrow as mut so we can insert
|
||||||
let w = &mut lib;
|
let w = &mut lib;
|
||||||
w.add(&StringKey::new("foo".into()), Arc::new(m));
|
w.add(&StringKey::new("foo"), Arc::new(m));
|
||||||
// Drops borrow as mut
|
// Drops borrow as mut
|
||||||
|
|
||||||
lib
|
lib
|
||||||
|
|
|
@ -49,27 +49,27 @@ pub enum EffectParameter {
|
||||||
String(ValueIdentifier, StringKey),
|
String(ValueIdentifier, StringKey),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<EffectParameter> for bool {
|
impl From<bool> for EffectParameter {
|
||||||
fn into(self) -> EffectParameter {
|
fn from(b: bool) -> Self {
|
||||||
EffectParameter::Bool(Default::default(), self)
|
EffectParameter::Bool(Default::default(), b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<EffectParameter> for i64 {
|
impl From<i64> for EffectParameter {
|
||||||
fn into(self) -> EffectParameter {
|
fn from(i: i64) -> Self {
|
||||||
EffectParameter::Int(Default::default(), self)
|
EffectParameter::Int(Default::default(), i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<EffectParameter> for f32 {
|
impl From<f32> for EffectParameter {
|
||||||
fn into(self) -> EffectParameter {
|
fn from(f: f32) -> Self {
|
||||||
EffectParameter::Float(Default::default(), self)
|
EffectParameter::Float(Default::default(), f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<EffectParameter> for StringKey {
|
impl From<StringKey> for EffectParameter {
|
||||||
fn into(self) -> EffectParameter {
|
fn from(s: StringKey) -> Self {
|
||||||
EffectParameter::String(Default::default(), self)
|
EffectParameter::String(Default::default(), s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,4 +10,5 @@ mod random;
|
||||||
/// The string_key module defines a custom string handling for reduced allocations and fast lookups
|
/// The string_key module defines a custom string handling for reduced allocations and fast lookups
|
||||||
/// and equality checks.
|
/// and equality checks.
|
||||||
mod string_key;
|
mod string_key;
|
||||||
|
/// Helper tool to keep track of moving memory for FFI.
|
||||||
mod value_identifier;
|
mod value_identifier;
|
||||||
|
|
|
@ -116,11 +116,12 @@ impl Display for StringKey {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<StringKey> for &CStr {
|
impl From<&CStr> for StringKey {
|
||||||
fn into(self) -> StringKey {
|
fn from(s: &CStr) -> Self {
|
||||||
StringKey::new(self.to_str().unwrap())
|
StringKey::new(s.to_str().unwrap())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a character to lowercased in a const safe way.
|
/// Converts a character to lowercased in a const safe way.
|
||||||
const fn to_lower(c: u8) -> u8 {
|
const fn to_lower(c: u8) -> u8 {
|
||||||
if c >= b'A' && c <= b'Z' {
|
if c >= b'A' && c <= b'Z' {
|
||||||
|
@ -170,7 +171,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn create_empty_stringkey() {
|
fn create_empty_stringkey() {
|
||||||
let sk = StringKey::new("".into());
|
let sk = StringKey::new("");
|
||||||
assert_eq!(sk.str(), "");
|
assert_eq!(sk.str(), "");
|
||||||
assert_eq!(sk.hash(), 0);
|
assert_eq!(sk.hash(), 0);
|
||||||
assert_eq!(sk.hash(), StringKey::get_hash(""));
|
assert_eq!(sk.hash(), StringKey::get_hash(""));
|
||||||
|
@ -178,7 +179,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn create_stringkey_foo() {
|
fn create_stringkey_foo() {
|
||||||
let sk = StringKey::new("foo".into());
|
let sk = StringKey::new("foo");
|
||||||
assert_eq!(sk.str(), "foo");
|
assert_eq!(sk.str(), "foo");
|
||||||
assert_eq!(sk.hash(), 2356372769);
|
assert_eq!(sk.hash(), 2356372769);
|
||||||
assert_eq!(sk.hash(), StringKey::get_hash("foo"));
|
assert_eq!(sk.hash(), StringKey::get_hash("foo"));
|
||||||
|
@ -187,7 +188,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn create_stringkey_bar() {
|
fn create_stringkey_bar() {
|
||||||
let sk = StringKey::new("bar".into());
|
let sk = StringKey::new("bar");
|
||||||
assert_eq!(sk.str(), "bar");
|
assert_eq!(sk.str(), "bar");
|
||||||
assert_eq!(sk.hash(), 1996459178);
|
assert_eq!(sk.hash(), 1996459178);
|
||||||
assert_eq!(sk.hash(), StringKey::get_hash("bar"));
|
assert_eq!(sk.hash(), StringKey::get_hash("bar"));
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||||
|
|
||||||
|
/// The current index for the value counter.
|
||||||
static CURRENT: AtomicUsize = AtomicUsize::new(1);
|
static CURRENT: AtomicUsize = AtomicUsize::new(1);
|
||||||
|
|
||||||
/// An extremely basic way to identify a piece of data.
|
/// An extremely basic way to identify a piece of data.
|
||||||
|
@ -9,9 +10,7 @@ pub struct ValueIdentifier(usize);
|
||||||
|
|
||||||
impl Default for ValueIdentifier {
|
impl Default for ValueIdentifier {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self(CURRENT.fetch_add(1, Ordering::SeqCst))
|
||||||
0: CURRENT.fetch_add(1, Ordering::SeqCst),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,15 +53,13 @@ pub fn load_types(path: &String, type_library: &mut TypeLibrary) {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let headers = reader.headers().unwrap();
|
let headers = reader.headers().unwrap();
|
||||||
for header in headers.iter().skip(1) {
|
for header in headers.iter().skip(1) {
|
||||||
type_library.register_type(&StringKey::new(header.into()));
|
type_library.register_type(&header.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
for record in reader.records() {
|
for record in reader.records() {
|
||||||
let record = record.unwrap();
|
let record = record.unwrap();
|
||||||
let offensive_type = record.get(0).unwrap();
|
let offensive_type = record.get(0).unwrap();
|
||||||
let offensive_type_id = type_library
|
let offensive_type_id = type_library.get_type_id(&offensive_type.into()).unwrap();
|
||||||
.get_type_id(&StringKey::new(offensive_type.into()))
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
for (i, v) in record.iter().skip(1).enumerate() {
|
for (i, v) in record.iter().skip(1).enumerate() {
|
||||||
let effectiveness = v.parse::<f32>().unwrap();
|
let effectiveness = v.parse::<f32>().unwrap();
|
||||||
|
@ -78,7 +76,7 @@ pub fn load_natures(path: &String, nature_library: &mut NatureLibrary) {
|
||||||
|
|
||||||
for record in reader.records() {
|
for record in reader.records() {
|
||||||
let record = record.unwrap();
|
let record = record.unwrap();
|
||||||
let nature_name = StringKey::new(record.get(0).unwrap().into());
|
let nature_name = record.get(0).unwrap().into();
|
||||||
let increased_statistic_str = record.get(1).unwrap();
|
let increased_statistic_str = record.get(1).unwrap();
|
||||||
let decreased_statistic_str = record.get(2).unwrap();
|
let decreased_statistic_str = record.get(2).unwrap();
|
||||||
if increased_statistic_str.is_empty() || decreased_statistic_str.is_empty() {
|
if increased_statistic_str.is_empty() || decreased_statistic_str.is_empty() {
|
||||||
|
@ -102,7 +100,7 @@ pub fn load_items(path: &String, lib: &mut ItemLibrary) {
|
||||||
let json_array = json.as_array().unwrap();
|
let json_array = json.as_array().unwrap();
|
||||||
|
|
||||||
for v in json_array {
|
for v in json_array {
|
||||||
let name = StringKey::new(v.get("name").unwrap().as_str().unwrap().into());
|
let name = v.get("name").unwrap().as_str().unwrap().into();
|
||||||
let category = serde_json::from_value(v.get("itemType").unwrap().clone()).unwrap();
|
let category = serde_json::from_value(v.get("itemType").unwrap().clone()).unwrap();
|
||||||
let mut battle_category = BattleItemCategory::None;
|
let mut battle_category = BattleItemCategory::None;
|
||||||
if let Some(c) = v.get("battleType") {
|
if let Some(c) = v.get("battleType") {
|
||||||
|
@ -113,7 +111,7 @@ pub fn load_items(path: &String, lib: &mut ItemLibrary) {
|
||||||
if let Some(f) = v.get("flags") {
|
if let Some(f) = v.get("flags") {
|
||||||
let a = f.as_array().unwrap();
|
let a = f.as_array().unwrap();
|
||||||
for flag in a {
|
for flag in a {
|
||||||
flags.insert(StringKey::new(flag.as_str().unwrap().into()));
|
flags.insert(flag.as_str().unwrap().into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,7 +152,7 @@ pub fn load_abilities(path: &String, ability_library: &mut AbilityLibrary) {
|
||||||
let name = StringKey::new(key);
|
let name = StringKey::new(key);
|
||||||
let mut effect = StringKey::empty();
|
let mut effect = StringKey::empty();
|
||||||
if let Some(e) = value.get("effect") {
|
if let Some(e) = value.get("effect") {
|
||||||
effect = StringKey::new(e.as_str().unwrap().into());
|
effect = e.as_str().unwrap().into();
|
||||||
}
|
}
|
||||||
let mut parameters = Vec::new();
|
let mut parameters = Vec::new();
|
||||||
if let Some(p) = value.get("parameters") {
|
if let Some(p) = value.get("parameters") {
|
||||||
|
@ -175,8 +173,8 @@ pub fn load_moves(path: &String, lib: &mut StaticData) {
|
||||||
let data = json.as_object().unwrap().get("data").unwrap().as_array().unwrap();
|
let data = json.as_object().unwrap().get("data").unwrap().as_array().unwrap();
|
||||||
for move_data in data {
|
for move_data in data {
|
||||||
let move_data = move_data.as_object().unwrap();
|
let move_data = move_data.as_object().unwrap();
|
||||||
let move_name = StringKey::new(move_data.get("name").unwrap().as_str().unwrap().into());
|
let move_name = move_data.get("name").unwrap().as_str().unwrap().into();
|
||||||
let move_type = StringKey::new(move_data.get("type").unwrap().as_str().unwrap().into());
|
let move_type = move_data.get("type").unwrap().as_str().unwrap().into();
|
||||||
let move_type_id = lib.types().get_type_id(&move_type).unwrap();
|
let move_type_id = lib.types().get_type_id(&move_type).unwrap();
|
||||||
let move_category = serde_json::from_value(move_data.get("category").unwrap().clone()).unwrap();
|
let move_category = serde_json::from_value(move_data.get("category").unwrap().clone()).unwrap();
|
||||||
let base_power = move_data.get("power").unwrap().as_i64().unwrap() as u8;
|
let base_power = move_data.get("power").unwrap().as_i64().unwrap() as u8;
|
||||||
|
@ -199,7 +197,7 @@ pub fn load_moves(path: &String, lib: &mut StaticData) {
|
||||||
|
|
||||||
Some(SecondaryEffect::new(
|
Some(SecondaryEffect::new(
|
||||||
chance,
|
chance,
|
||||||
StringKey::new(v.get("name").unwrap().as_str().unwrap().into()),
|
v.get("name").unwrap().as_str().unwrap().into(),
|
||||||
parameters,
|
parameters,
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
|
@ -210,7 +208,7 @@ pub fn load_moves(path: &String, lib: &mut StaticData) {
|
||||||
if let Some(f) = move_data.get("flags") {
|
if let Some(f) = move_data.get("flags") {
|
||||||
let f = f.as_array().unwrap();
|
let f = f.as_array().unwrap();
|
||||||
for flag in f {
|
for flag in f {
|
||||||
flags.insert(StringKey::new(flag.as_str().unwrap().into()));
|
flags.insert(flag.as_str().unwrap().into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,7 +244,7 @@ pub fn load_species(path: &String, library: &mut StaticData) {
|
||||||
let name = StringKey::new(key);
|
let name = StringKey::new(key);
|
||||||
let id = value.get("id").unwrap().as_i64().unwrap();
|
let id = value.get("id").unwrap().as_i64().unwrap();
|
||||||
let gender_rate = value.get("genderRatio").unwrap().as_f64().unwrap();
|
let gender_rate = value.get("genderRatio").unwrap().as_f64().unwrap();
|
||||||
let growth_rate_name = StringKey::new(value.get("growthRate").unwrap().as_str().unwrap().into());
|
let growth_rate_name = value.get("growthRate").unwrap().as_str().unwrap().into();
|
||||||
let _base_happiness = value.get("baseHappiness").unwrap().as_i64().unwrap();
|
let _base_happiness = value.get("baseHappiness").unwrap().as_i64().unwrap();
|
||||||
let catch_rate = value.get("catchRate").unwrap().as_i64().unwrap();
|
let catch_rate = value.get("catchRate").unwrap().as_i64().unwrap();
|
||||||
let _color = value.get("color").unwrap().as_str().unwrap();
|
let _color = value.get("color").unwrap().as_str().unwrap();
|
||||||
|
@ -289,13 +287,13 @@ fn load_wasm(path: &String, library: &mut WebAssemblyScriptResolver) {
|
||||||
fn parse_form(name: StringKey, value: &Value, library: &mut StaticData) -> Arc<Form> {
|
fn parse_form(name: StringKey, value: &Value, library: &mut StaticData) -> Arc<Form> {
|
||||||
let mut abilities = Vec::new();
|
let mut abilities = Vec::new();
|
||||||
for a in value.get("abilities").unwrap().as_array().unwrap() {
|
for a in value.get("abilities").unwrap().as_array().unwrap() {
|
||||||
abilities.push(StringKey::new(a.as_str().unwrap().into()));
|
abilities.push(a.as_str().unwrap().into());
|
||||||
}
|
}
|
||||||
let mut hidden_abilities = Vec::new();
|
let mut hidden_abilities = Vec::new();
|
||||||
for a in value.get("hiddenAbilities").unwrap().as_array().unwrap() {
|
for a in value.get("hiddenAbilities").unwrap().as_array().unwrap() {
|
||||||
hidden_abilities.push(StringKey::new(a.as_str().unwrap().into()));
|
hidden_abilities.push(a.as_str().unwrap().into());
|
||||||
}
|
}
|
||||||
let base_stats = parse_statistics(&value.get("baseStats").unwrap());
|
let base_stats = parse_statistics(value.get("baseStats").unwrap());
|
||||||
// TODO: ev reward
|
// TODO: ev reward
|
||||||
let height = value.get("height").unwrap().as_f64().unwrap();
|
let height = value.get("height").unwrap().as_f64().unwrap();
|
||||||
let weight = value.get("weight").unwrap().as_f64().unwrap();
|
let weight = value.get("weight").unwrap().as_f64().unwrap();
|
||||||
|
@ -306,15 +304,10 @@ fn parse_form(name: StringKey, value: &Value, library: &mut StaticData) -> Arc<F
|
||||||
.as_array()
|
.as_array()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|a| {
|
.map(|a| library.types().get_type_id(&a.as_str().unwrap().into()).unwrap())
|
||||||
library
|
|
||||||
.types()
|
|
||||||
.get_type_id(&StringKey::new(a.as_str().unwrap().into()))
|
|
||||||
.unwrap()
|
|
||||||
})
|
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let moves = parse_moves(&value.get("moves").unwrap(), library.moves());
|
let moves = parse_moves(value.get("moves").unwrap(), library.moves());
|
||||||
|
|
||||||
Arc::new(Form::new(
|
Arc::new(Form::new(
|
||||||
&name,
|
&name,
|
||||||
|
@ -379,7 +372,7 @@ fn parse_moves(value: &Value, move_library: &MoveLibrary) -> LearnableMoves {
|
||||||
|
|
||||||
let level_moves = value.get("levelMoves").unwrap().as_array().unwrap();
|
let level_moves = value.get("levelMoves").unwrap().as_array().unwrap();
|
||||||
for level_move in level_moves {
|
for level_move in level_moves {
|
||||||
let name = StringKey::new(level_move.get("name").unwrap().as_str().unwrap().into());
|
let name = level_move.get("name").unwrap().as_str().unwrap().into();
|
||||||
let level = level_move.get("level").unwrap().as_u64().unwrap() as LevelInt;
|
let level = level_move.get("level").unwrap().as_u64().unwrap() as LevelInt;
|
||||||
assert!(move_library.get(&name).is_some());
|
assert!(move_library.get(&name).is_some());
|
||||||
moves.add_level_move(level, &name);
|
moves.add_level_move(level, &name);
|
||||||
|
@ -401,7 +394,7 @@ fn parse_effect_parameter(value: &Value) -> EffectParameter {
|
||||||
n.as_i64().unwrap().into()
|
n.as_i64().unwrap().into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Value::String(s) => StringKey::new(s.as_str().into()).into(),
|
Value::String(s) => StringKey::new(s.as_str()).into(),
|
||||||
Value::Array(_) => {
|
Value::Array(_) => {
|
||||||
panic!("Unexpected type")
|
panic!("Unexpected type")
|
||||||
}
|
}
|
||||||
|
@ -421,8 +414,8 @@ fn test_type_library_loaded() {
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
lib.get_effectiveness(
|
lib.get_effectiveness(
|
||||||
lib.get_type_id(&StringKey::new("fire".into())).unwrap(),
|
lib.get_type_id(&"fire".into()).unwrap(),
|
||||||
&[lib.get_type_id(&StringKey::new("grass".into())).unwrap()],
|
&[lib.get_type_id(&"grass".into()).unwrap()],
|
||||||
),
|
),
|
||||||
2.0
|
2.0
|
||||||
);
|
);
|
||||||
|
|
|
@ -74,7 +74,7 @@ impl TestCase {
|
||||||
|
|
||||||
impl TestPokemon {
|
impl TestPokemon {
|
||||||
fn to_pokemon(&self, library: Arc<DynamicLibrary>) -> Pokemon {
|
fn to_pokemon(&self, library: Arc<DynamicLibrary>) -> Pokemon {
|
||||||
let mut builder = PokemonBuilder::new(library, StringKey::new(self.species.as_str().into()), self.level);
|
let mut builder = PokemonBuilder::new(library, self.species.as_str().into(), self.level);
|
||||||
for move_name in &self.moves {
|
for move_name in &self.moves {
|
||||||
builder = builder.learn_move(StringKey::new(move_name));
|
builder = builder.learn_move(StringKey::new(move_name));
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,7 +83,7 @@ fn validate_assurance() {
|
||||||
let executing_move = ExecutingMove::new(
|
let executing_move = ExecutingMove::new(
|
||||||
vec![],
|
vec![],
|
||||||
1,
|
1,
|
||||||
p1.clone(),
|
p1,
|
||||||
mv.clone(),
|
mv.clone(),
|
||||||
mv.move_data().clone(),
|
mv.move_data().clone(),
|
||||||
ScriptContainer::default(),
|
ScriptContainer::default(),
|
||||||
|
|
Loading…
Reference in New Issue