Add function to get random nature, add shiny rate to library settings
continuous-integration/drone/push Build is passing Details

This commit is contained in:
Deukhoofd 2023-04-14 10:36:38 +02:00
parent d7b3c0cd8d
commit 3058739ea0
Signed by: Deukhoofd
GPG Key ID: F63E044490819F6F
7 changed files with 61 additions and 12 deletions

View File

@ -5,8 +5,8 @@ use std::ptr::drop_in_place;
/// 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]
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));
extern "C" fn gen_7_damage_library_new(has_randomness: u8) -> IdentifiablePointer<Box<dyn DamageLibrary>> {
let v: Box<dyn DamageLibrary> = Box::new(Gen7DamageLibrary::new(has_randomness == 1));
let id = v.value_identifier();
let ptr = Box::into_raw(Box::new(v));
IdentifiablePointer::new(ptr, id)

View File

@ -4,9 +4,16 @@ use crate::static_data::{LibrarySettings, LibrarySettingsImpl};
use std::ptr::drop_in_place;
/// Creates a new settings library.
/// - `maximum_level` is the highest level a Pokemon can be.
/// - `shiny_rate` is the chance of a Pokemon being shiny, as the denominator of a fraction, where
/// the nominator is 1. For example, if this is 1000, then the chance of a Pokemon being shiny is
/// 1/1000.
#[no_mangle]
extern "C" fn library_settings_new(max_level: LevelInt) -> IdentifiablePointer<Box<dyn LibrarySettings>> {
let b: Box<dyn LibrarySettings> = Box::new(LibrarySettingsImpl::new(max_level));
extern "C" fn library_settings_new(
max_level: LevelInt,
shiny_rate: u32,
) -> IdentifiablePointer<Box<dyn LibrarySettings>> {
let b: Box<dyn LibrarySettings> = Box::new(LibrarySettingsImpl::new(max_level, shiny_rate));
b.into()
}
@ -21,3 +28,10 @@ unsafe extern "C" fn library_settings_drop(ptr: OwnedPtr<Box<dyn LibrarySettings
extern "C" fn library_settings_maximum_level(ptr: ExternPointer<Box<dyn LibrarySettings>>) -> LevelInt {
ptr.as_ref().maximum_level()
}
/// The chance of a Pokemon being shiny, as the denominator of a fraction, where the nominator
/// is 1. For example, if this is 1000, then the chance of a Pokemon being shiny is 1/1000.
#[no_mangle]
extern "C" fn library_settings_shiny_rate(ptr: ExternPointer<Box<dyn LibrarySettings>>) -> u32 {
ptr.as_ref().shiny_rate()
}

View File

@ -1,5 +1,6 @@
use crate::ffi::{BorrowedPtr, ExternPointer, IdentifiablePointer, OwnedPtr};
use crate::static_data::{Nature, NatureLibrary, NatureLibraryImpl};
use crate::Random;
use std::ffi::{c_char, CStr, CString};
use std::ptr::drop_in_place;
use std::sync::Arc;
@ -41,6 +42,16 @@ unsafe extern "C" fn nature_library_get_nature(
}
}
/// Gets a random nature.
#[no_mangle]
unsafe extern "C" fn nature_library_get_random_nature(
ptr: ExternPointer<Box<dyn NatureLibrary>>,
seed: u64,
) -> IdentifiablePointer<Arc<dyn Nature>> {
let mut rand = Random::new(seed as u128);
ptr.as_ref().get_random_nature(&mut rand).into()
}
/// Finds a nature name by nature.
#[no_mangle]
unsafe extern "C" fn nature_library_get_nature_name(

View File

@ -6,6 +6,10 @@ use std::fmt::Debug;
pub trait LibrarySettings: Debug + ValueIdentifiable {
/// The highest level a Pokemon can be.
fn maximum_level(&self) -> LevelInt;
/// The chance of a Pokemon being shiny, as the denominator of a fraction, where the nominator
/// is 1. For example, if this is 1000, then the chance of a Pokemon being shiny is 1/1000.
fn shiny_rate(&self) -> u32;
}
/// This library holds several misc settings for the library.
@ -15,23 +19,35 @@ pub struct LibrarySettingsImpl {
identifier: ValueIdentifier,
/// The highest level a Pokemon can be.
maximum_level: LevelInt,
/// The chance of a Pokemon being shiny, as the denominator of a fraction, where the nominator
/// is 1. For example, if this is 1000, then the chance of a Pokemon being shiny is 1/1000.
shiny_rate: u32,
}
impl LibrarySettingsImpl {
/// Creates a new settings library.
pub fn new(maximum_level: LevelInt) -> Self {
/// - `maximum_level` is the highest level a Pokemon can be.
/// - `shiny_rate` is the chance of a Pokemon being shiny, as the denominator of a fraction, where
/// the nominator is 1. For example, if this is 1000, then the chance of a Pokemon being shiny is
/// 1/1000.
pub fn new(maximum_level: LevelInt, shiny_rate: u32) -> Self {
assert!(shiny_rate >= 1);
assert!(maximum_level >= 1);
Self {
identifier: Default::default(),
maximum_level,
shiny_rate,
}
}
}
impl LibrarySettings for LibrarySettingsImpl {
/// The highest level a Pokemon can be.
fn maximum_level(&self) -> LevelInt {
self.maximum_level
}
fn shiny_rate(&self) -> u32 {
self.shiny_rate
}
}
impl ValueIdentifiable for LibrarySettingsImpl {

View File

@ -1,6 +1,6 @@
use crate::static_data::Nature;
use crate::{StringKey, ValueIdentifiable, ValueIdentifier};
use hashbrown::HashMap;
use crate::{Random, StringKey, ValueIdentifiable, ValueIdentifier};
use indexmap::IndexMap;
use std::fmt::Debug;
use std::sync::Arc;
@ -10,6 +10,8 @@ pub trait NatureLibrary: Debug + ValueIdentifiable {
fn load_nature(&mut self, name: StringKey, nature: Arc<dyn Nature>);
/// Gets a nature by name.
fn get_nature(&self, key: &StringKey) -> Option<Arc<dyn Nature>>;
/// Gets a random nature.
fn get_random_nature(&self, rand: &mut Random) -> Arc<dyn Nature>;
/// Finds a nature name by nature.
fn get_nature_name(&self, nature: &Arc<dyn Nature>) -> StringKey;
}
@ -20,7 +22,7 @@ pub struct NatureLibraryImpl {
/// A unique identifier so we know what value this is.
identifier: ValueIdentifier,
/// The underlying data structure.
map: HashMap<StringKey, Arc<dyn Nature>>,
map: IndexMap<StringKey, Arc<dyn Nature>>,
}
impl NatureLibraryImpl {
@ -28,7 +30,7 @@ impl NatureLibraryImpl {
pub fn new(capacity: usize) -> Self {
Self {
identifier: Default::default(),
map: HashMap::with_capacity(capacity),
map: IndexMap::with_capacity(capacity),
}
}
}
@ -44,6 +46,11 @@ impl NatureLibrary for NatureLibraryImpl {
self.map.get(key).cloned()
}
fn get_random_nature(&self, rand: &mut Random) -> Arc<dyn Nature> {
let i = rand.get_between(0, self.map.len() as i32);
return self.map.get_index(i as usize).unwrap().1.clone();
}
/// Finds a nature name by nature.
fn get_nature_name(&self, nature: &Arc<dyn Nature>) -> StringKey {
for kv in &self.map {
@ -87,6 +94,7 @@ pub mod tests {
fn load_nature(&mut self, name: StringKey, nature: Arc<dyn Nature>);
fn get_nature(&self, key: &StringKey) -> Option<Arc<dyn Nature>>;
fn get_nature_name(&self, nature: &Arc<dyn Nature>) -> StringKey;
fn get_random_nature(&self, rand: &mut Random) -> Arc<dyn Nature>;
}
impl ValueIdentifiable for NatureLibrary {
fn value_identifier(&self) -> ValueIdentifier{

View File

@ -199,7 +199,7 @@ pub mod test {
pub fn build() -> StaticDataImpl {
StaticDataImpl {
identifier: Default::default(),
settings: Box::new(LibrarySettingsImpl::new(100)),
settings: Box::new(LibrarySettingsImpl::new(100, 100)),
species: crate::static_data::libraries::species_library::tests::build(),
moves: crate::static_data::libraries::move_library::tests::build(),
items: crate::static_data::libraries::item_library::tests::build(),

View File

@ -65,7 +65,7 @@ pub fn load_library() -> LoadResult {
let species_load_time = t2 - t1;
let data = StaticDataImpl::new(
Box::new(LibrarySettingsImpl::new(100)),
Box::new(LibrarySettingsImpl::new(100, 100)),
species,
moves,
items,