Adds ability to get the current time of day
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
c75541720b
commit
0c6a0cadfe
|
@ -156,7 +156,7 @@ pub mod test {
|
|||
static_data: Arc::new(crate::static_data::libraries::static_data::test::build()),
|
||||
stat_calculator: Arc::new(Gen7BattleStatCalculator::new()),
|
||||
damage_calculator: Arc::new(Gen7DamageLibrary::new(false)),
|
||||
misc_library: Arc::new(Gen7MiscLibrary::new()),
|
||||
misc_library: Arc::new(Gen7MiscLibrary::default()),
|
||||
script_resolver: Arc::new(EmptyScriptResolver {}),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use std::fmt::Debug;
|
||||
use chrono::Timelike;
|
||||
use std::fmt::{Debug, Formatter};
|
||||
use std::sync::Arc;
|
||||
|
||||
use hashbrown::HashSet;
|
||||
|
@ -6,7 +7,7 @@ use hashbrown::HashSet;
|
|||
use crate::dynamic_data::choices::{MoveChoice, TurnChoice};
|
||||
use crate::dynamic_data::Pokemon;
|
||||
use crate::dynamic_data::{LearnedMove, MoveLearnMethod};
|
||||
use crate::static_data::{MoveCategory, MoveData, MoveDataImpl, MoveTarget, SecondaryEffectImpl};
|
||||
use crate::static_data::{MoveCategory, MoveData, MoveDataImpl, MoveTarget, SecondaryEffectImpl, TimeOfDay};
|
||||
use crate::StringKey;
|
||||
|
||||
/// The misc library holds several misc functions required for the battle to run.
|
||||
|
@ -16,19 +17,24 @@ pub trait MiscLibrary: Debug {
|
|||
/// Returns the move we need to use if we can't use another move. Typically Struggle.
|
||||
fn replacement_move(&self, user: &Pokemon, target_side: u8, target_index: u8) -> TurnChoice;
|
||||
// TODO: can evolve from level up?
|
||||
// TODO: get time
|
||||
/// Gets the current time of day for the battle.
|
||||
fn time_of_day(&self) -> TimeOfDay;
|
||||
}
|
||||
|
||||
/// A function pointer to get the time of day.
|
||||
type GetTimeOfDayFn = Box<dyn Fn() -> TimeOfDay>;
|
||||
|
||||
/// A gen 7 implementation for the MiscLibrary.
|
||||
#[derive(Debug)]
|
||||
pub struct Gen7MiscLibrary {
|
||||
/// The learned move data for struggle.
|
||||
struggle_learned_move: Arc<LearnedMove>,
|
||||
/// The function to get the time of day.
|
||||
get_time_fn: GetTimeOfDayFn,
|
||||
}
|
||||
|
||||
impl Gen7MiscLibrary {
|
||||
/// Instantiates a new MiscLibrary.
|
||||
pub fn new() -> Self {
|
||||
pub fn new(get_time_fn: GetTimeOfDayFn) -> Self {
|
||||
let struggle_data: Arc<dyn MoveData> = Arc::new(MoveDataImpl::new(
|
||||
&StringKey::new("struggle"),
|
||||
0.into(),
|
||||
|
@ -46,13 +52,28 @@ impl Gen7MiscLibrary {
|
|||
HashSet::new(),
|
||||
));
|
||||
let struggle_learned_move = Arc::new(LearnedMove::new(struggle_data, MoveLearnMethod::Unknown));
|
||||
Self { struggle_learned_move }
|
||||
Self {
|
||||
struggle_learned_move,
|
||||
get_time_fn,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Gen7MiscLibrary {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
Self::new(Box::new(|| {
|
||||
let time = chrono::Local::now().time();
|
||||
let hour = time.hour();
|
||||
// Following the values for Pokemon Sun.
|
||||
match hour {
|
||||
0..=5 => TimeOfDay::Night,
|
||||
6..=9 => TimeOfDay::Morning,
|
||||
10..=16 => TimeOfDay::Day,
|
||||
17 => TimeOfDay::Evening,
|
||||
18..=23 => TimeOfDay::Night,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -70,4 +91,14 @@ impl MiscLibrary for Gen7MiscLibrary {
|
|||
target_index,
|
||||
))
|
||||
}
|
||||
|
||||
fn time_of_day(&self) -> TimeOfDay {
|
||||
(self.get_time_fn)()
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for Gen7MiscLibrary {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_str("Gen7MiscLibrary")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,46 @@
|
|||
use crate::dynamic_data::{Gen7MiscLibrary, MiscLibrary};
|
||||
use crate::ffi::ffi_handle::FFIHandle;
|
||||
use crate::static_data::TimeOfDay;
|
||||
use std::sync::Arc;
|
||||
|
||||
/// Instantiates a new MiscLibrary.
|
||||
#[no_mangle]
|
||||
extern "C" fn gen_7_misc_library_new() -> FFIHandle<Arc<dyn MiscLibrary>> {
|
||||
let v: Arc<dyn MiscLibrary> = Arc::new(Gen7MiscLibrary::new());
|
||||
extern "C" fn gen_7_misc_library_new(get_time_of_day_fn: FFIGetTimeOfDayFn) -> FFIHandle<Arc<dyn MiscLibrary>> {
|
||||
let v: Arc<dyn MiscLibrary> = Arc::new(Gen7MiscLibrary::new(Box::new(get_time_of_day_fn)));
|
||||
FFIHandle::get_handle(v.into())
|
||||
}
|
||||
|
||||
/// Wrapper class for easier use of an external function pointer.
|
||||
#[repr(C)]
|
||||
pub(super) struct FFIGetTimeOfDayFn {
|
||||
/// The actual C function to be called. Note that we pass the batch id as a pair of u64s. This
|
||||
/// is because u128 does not have a stable ABI yet.
|
||||
f: extern "C" fn() -> u8,
|
||||
}
|
||||
|
||||
impl FFIGetTimeOfDayFn {
|
||||
/// Calls the actual wrapped function in the correct format.
|
||||
fn call_self(&self) -> TimeOfDay {
|
||||
unsafe { std::mem::transmute((self.f)()) }
|
||||
}
|
||||
}
|
||||
|
||||
impl FnMut<()> for FFIGetTimeOfDayFn {
|
||||
extern "rust-call" fn call_mut(&mut self, _: ()) -> Self::Output {
|
||||
self.call_self()
|
||||
}
|
||||
}
|
||||
|
||||
impl FnOnce<()> for FFIGetTimeOfDayFn {
|
||||
type Output = TimeOfDay;
|
||||
|
||||
extern "rust-call" fn call_once(self, _: ()) -> Self::Output {
|
||||
self.call_self()
|
||||
}
|
||||
}
|
||||
|
||||
impl Fn<()> for FFIGetTimeOfDayFn {
|
||||
extern "rust-call" fn call(&self, _: ()) -> Self::Output {
|
||||
self.call_self()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
use crate::dynamic_data::{DynamicLibrary, ScriptOwnerData};
|
||||
use crate::dynamic_data::{DynamicLibrary, MiscLibrary, ScriptOwnerData};
|
||||
use crate::script_implementations::wasm::export_registry::register;
|
||||
use crate::script_implementations::wasm::export_registry::wasm_result::{try_wasm, wasm_ok, WasmResult};
|
||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||
use wasmer::{FunctionEnv, FunctionEnvMut, Imports, StoreMut};
|
||||
|
||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||
use crate::static_data::StaticData;
|
||||
use crate::static_data::{StaticData, TimeOfDay};
|
||||
|
||||
/// The battle registration
|
||||
mod battle;
|
||||
|
@ -38,6 +38,27 @@ register! {
|
|||
wasm_ok(ExternRef::<dyn StaticData>::func_new(&env, static_data.into()))
|
||||
}
|
||||
|
||||
fn dynamic_library_get_misc_library(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
dynamic_lib: ExternRef<dyn DynamicLibrary>,
|
||||
) -> WasmResult<ExternRef<dyn MiscLibrary>> {
|
||||
let dynamic_lib = try_wasm!(dynamic_lib.value_func_arc(&env), env);
|
||||
let misc_library = dynamic_lib.misc_library();
|
||||
wasm_ok(ExternRef::<dyn MiscLibrary>::func_new(&env, misc_library.into()))
|
||||
}
|
||||
|
||||
fn misc_library_get_time_of_day(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
dynamic_lib: ExternRef<dyn MiscLibrary>,
|
||||
) -> WasmResult<u8> {
|
||||
let misc_library = try_wasm!(dynamic_lib.value_func_arc(&env), env);
|
||||
unsafe{
|
||||
let time_of_day = misc_library.time_of_day();
|
||||
wasm_ok(std::mem::transmute::<TimeOfDay, u8>(time_of_day))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn script_get_owner(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
script: u32,
|
||||
|
|
|
@ -40,6 +40,7 @@ pub(crate) enum WasmObject {
|
|||
|
||||
// Dynamic data libraries
|
||||
DynamicLibrary(Weak<dyn crate::dynamic_data::DynamicLibrary>),
|
||||
MiscLibrary(Weak<dyn crate::dynamic_data::MiscLibrary>),
|
||||
|
||||
// Battle data
|
||||
Battle(WeakBattleReference),
|
||||
|
@ -88,6 +89,7 @@ impl PartialEq for WasmObject {
|
|||
(WasmObject::PokemonParty(s1), WasmObject::PokemonParty(s2)) => Weak::ptr_eq(s1, s2),
|
||||
(WasmObject::LearnedMove(s1), WasmObject::LearnedMove(s2)) => Weak::ptr_eq(s1, s2),
|
||||
(WasmObject::DynamicLibrary(s1), WasmObject::DynamicLibrary(s2)) => Weak::ptr_eq(s1, s2),
|
||||
(WasmObject::MiscLibrary(s1), WasmObject::MiscLibrary(s2)) => Weak::ptr_eq(s1, s2),
|
||||
(WasmObject::Battle(s1), WasmObject::Battle(s2)) => WeakBattleReference::eq(s1, s2),
|
||||
(WasmObject::ChoiceQueue(s1), WasmObject::ChoiceQueue(s2)) => Weak::ptr_eq(s1, s2),
|
||||
(WasmObject::BattleRandom(s1), WasmObject::BattleRandom(s2)) => Weak::ptr_eq(s1, s2),
|
||||
|
@ -131,6 +133,7 @@ impl Hash for WasmObject {
|
|||
WasmObject::PokemonParty(m) => m.as_ptr().hash(state),
|
||||
WasmObject::LearnedMove(m) => m.as_ptr().hash(state),
|
||||
WasmObject::DynamicLibrary(m) => m.as_ptr().hash(state),
|
||||
WasmObject::MiscLibrary(m) => m.as_ptr().hash(state),
|
||||
WasmObject::Battle(m) => m.as_ptr().hash(state),
|
||||
WasmObject::ChoiceQueue(m) => m.as_ptr().hash(state),
|
||||
WasmObject::BattleRandom(m) => m.as_ptr().hash(state),
|
||||
|
@ -394,6 +397,14 @@ impl From<&Arc<dyn crate::dynamic_data::DynamicLibrary>> for WasmObject {
|
|||
|
||||
impl_from_wasm_obj!(DynamicLibrary, Arc<dyn crate::dynamic_data::DynamicLibrary>);
|
||||
|
||||
impl From<&Arc<dyn crate::dynamic_data::MiscLibrary>> for WasmObject {
|
||||
fn from(value: &Arc<dyn crate::dynamic_data::MiscLibrary>) -> Self {
|
||||
Self::MiscLibrary(Arc::downgrade(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl_from_wasm_obj!(MiscLibrary, Arc<dyn crate::dynamic_data::MiscLibrary>);
|
||||
|
||||
impl From<&Arc<crate::dynamic_data::BattleRandom>> for WasmObject {
|
||||
fn from(value: &Arc<crate::dynamic_data::BattleRandom>) -> Self {
|
||||
Self::BattleRandom(Arc::downgrade(value))
|
||||
|
|
|
@ -168,17 +168,6 @@ impl<T> Default for VecExternRef<T> {
|
|||
}
|
||||
}
|
||||
|
||||
// impl<T: 'static> VecExternRef<T> {
|
||||
// /// Instantiates a new VecExternRef for a given slice.
|
||||
// pub fn new(env: &WebAssemblyEnvironmentData, value: &Vec<T>) -> Self {
|
||||
// Self {
|
||||
// index: env.get_extern_vec_ref_index(value),
|
||||
// size: value.len() as u32,
|
||||
// _phantom: Default::default(),
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
unsafe impl<T> FromToNativeWasmType for VecExternRef<T> {
|
||||
type Native = i64;
|
||||
|
||||
|
|
|
@ -15,6 +15,9 @@ pub use species_data::*;
|
|||
pub use statistic_set::*;
|
||||
#[doc(inline)]
|
||||
pub use statistics::*;
|
||||
#[doc(inline)]
|
||||
pub use time_of_day::*;
|
||||
|
||||
use std::fmt::{Display, Formatter};
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -50,6 +53,8 @@ mod species_data;
|
|||
mod statistic_set;
|
||||
/// Statistics are numerical values on Pokemon that are used in battle.
|
||||
mod statistics;
|
||||
/// Time of day defines the time of day for a battle.
|
||||
mod time_of_day;
|
||||
|
||||
/// A parameter for an effect. This is basically a simple way to dynamically store multiple different
|
||||
/// primitives on data.
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
/// The time of day. These values are the 4 different groups of time of day in Pokemon games since
|
||||
/// gen 5. The exact times these correspond to differ between games.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
#[repr(u8)]
|
||||
pub enum TimeOfDay {
|
||||
/// The morning.
|
||||
Morning = 0,
|
||||
/// The day.
|
||||
Day = 1,
|
||||
/// The evening.
|
||||
Evening = 2,
|
||||
/// The night.
|
||||
Night = 3,
|
||||
}
|
|
@ -20,7 +20,7 @@ use pkmn_lib::static_data::{
|
|||
GrowthRateLibrary, GrowthRateLibraryImpl, ItemImpl, ItemLibrary, ItemLibraryImpl, LearnableMoves,
|
||||
LearnableMovesImpl, LibrarySettingsImpl, LookupGrowthRate, MoveDataImpl, MoveLibrary, MoveLibraryImpl, NatureImpl,
|
||||
NatureLibrary, NatureLibraryImpl, SecondaryEffect, SecondaryEffectImpl, SpeciesImpl, SpeciesLibrary,
|
||||
SpeciesLibraryImpl, StaticDataImpl, StaticStatisticSet, Statistic, TypeLibrary, TypeLibraryImpl,
|
||||
SpeciesLibraryImpl, StaticDataImpl, StaticStatisticSet, Statistic, TimeOfDay, TypeLibrary, TypeLibraryImpl,
|
||||
};
|
||||
use pkmn_lib::StringKey;
|
||||
|
||||
|
@ -84,7 +84,7 @@ pub fn load_library() -> LoadResult {
|
|||
Arc::new(data),
|
||||
Arc::new(Gen7BattleStatCalculator::new()),
|
||||
Arc::new(Gen7DamageLibrary::new(false)),
|
||||
Arc::new(Gen7MiscLibrary::new()),
|
||||
Arc::new(Gen7MiscLibrary::new(Box::new(|| TimeOfDay::Day))),
|
||||
script_resolver,
|
||||
));
|
||||
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue