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()),
|
static_data: Arc::new(crate::static_data::libraries::static_data::test::build()),
|
||||||
stat_calculator: Arc::new(Gen7BattleStatCalculator::new()),
|
stat_calculator: Arc::new(Gen7BattleStatCalculator::new()),
|
||||||
damage_calculator: Arc::new(Gen7DamageLibrary::new(false)),
|
damage_calculator: Arc::new(Gen7DamageLibrary::new(false)),
|
||||||
misc_library: Arc::new(Gen7MiscLibrary::new()),
|
misc_library: Arc::new(Gen7MiscLibrary::default()),
|
||||||
script_resolver: Arc::new(EmptyScriptResolver {}),
|
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 std::sync::Arc;
|
||||||
|
|
||||||
use hashbrown::HashSet;
|
use hashbrown::HashSet;
|
||||||
|
@ -6,7 +7,7 @@ use hashbrown::HashSet;
|
||||||
use crate::dynamic_data::choices::{MoveChoice, TurnChoice};
|
use crate::dynamic_data::choices::{MoveChoice, TurnChoice};
|
||||||
use crate::dynamic_data::Pokemon;
|
use crate::dynamic_data::Pokemon;
|
||||||
use crate::dynamic_data::{LearnedMove, MoveLearnMethod};
|
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;
|
use crate::StringKey;
|
||||||
|
|
||||||
/// The misc library holds several misc functions required for the battle to run.
|
/// 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.
|
/// 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;
|
fn replacement_move(&self, user: &Pokemon, target_side: u8, target_index: u8) -> TurnChoice;
|
||||||
// TODO: can evolve from level up?
|
// 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.
|
/// A gen 7 implementation for the MiscLibrary.
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Gen7MiscLibrary {
|
pub struct Gen7MiscLibrary {
|
||||||
/// The learned move data for struggle.
|
/// The learned move data for struggle.
|
||||||
struggle_learned_move: Arc<LearnedMove>,
|
struggle_learned_move: Arc<LearnedMove>,
|
||||||
|
/// The function to get the time of day.
|
||||||
|
get_time_fn: GetTimeOfDayFn,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Gen7MiscLibrary {
|
impl Gen7MiscLibrary {
|
||||||
/// Instantiates a new MiscLibrary.
|
/// 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(
|
let struggle_data: Arc<dyn MoveData> = Arc::new(MoveDataImpl::new(
|
||||||
&StringKey::new("struggle"),
|
&StringKey::new("struggle"),
|
||||||
0.into(),
|
0.into(),
|
||||||
|
@ -46,13 +52,28 @@ impl Gen7MiscLibrary {
|
||||||
HashSet::new(),
|
HashSet::new(),
|
||||||
));
|
));
|
||||||
let struggle_learned_move = Arc::new(LearnedMove::new(struggle_data, MoveLearnMethod::Unknown));
|
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 {
|
impl Default for Gen7MiscLibrary {
|
||||||
fn default() -> Self {
|
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,
|
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::dynamic_data::{Gen7MiscLibrary, MiscLibrary};
|
||||||
use crate::ffi::ffi_handle::FFIHandle;
|
use crate::ffi::ffi_handle::FFIHandle;
|
||||||
|
use crate::static_data::TimeOfDay;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
/// Instantiates a new MiscLibrary.
|
/// Instantiates a new MiscLibrary.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn gen_7_misc_library_new() -> FFIHandle<Arc<dyn MiscLibrary>> {
|
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());
|
let v: Arc<dyn MiscLibrary> = Arc::new(Gen7MiscLibrary::new(Box::new(get_time_of_day_fn)));
|
||||||
FFIHandle::get_handle(v.into())
|
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::register;
|
||||||
use crate::script_implementations::wasm::export_registry::wasm_result::{try_wasm, wasm_ok, WasmResult};
|
use crate::script_implementations::wasm::export_registry::wasm_result::{try_wasm, wasm_ok, WasmResult};
|
||||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||||
use wasmer::{FunctionEnv, FunctionEnvMut, Imports, StoreMut};
|
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, TimeOfDay};
|
||||||
|
|
||||||
/// The battle registration
|
/// The battle registration
|
||||||
mod battle;
|
mod battle;
|
||||||
|
@ -38,6 +38,27 @@ register! {
|
||||||
wasm_ok(ExternRef::<dyn StaticData>::func_new(&env, static_data.into()))
|
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(
|
fn script_get_owner(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
script: u32,
|
script: u32,
|
||||||
|
|
|
@ -40,6 +40,7 @@ pub(crate) enum WasmObject {
|
||||||
|
|
||||||
// Dynamic data libraries
|
// Dynamic data libraries
|
||||||
DynamicLibrary(Weak<dyn crate::dynamic_data::DynamicLibrary>),
|
DynamicLibrary(Weak<dyn crate::dynamic_data::DynamicLibrary>),
|
||||||
|
MiscLibrary(Weak<dyn crate::dynamic_data::MiscLibrary>),
|
||||||
|
|
||||||
// Battle data
|
// Battle data
|
||||||
Battle(WeakBattleReference),
|
Battle(WeakBattleReference),
|
||||||
|
@ -88,6 +89,7 @@ impl PartialEq for WasmObject {
|
||||||
(WasmObject::PokemonParty(s1), WasmObject::PokemonParty(s2)) => Weak::ptr_eq(s1, s2),
|
(WasmObject::PokemonParty(s1), WasmObject::PokemonParty(s2)) => Weak::ptr_eq(s1, s2),
|
||||||
(WasmObject::LearnedMove(s1), WasmObject::LearnedMove(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::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::Battle(s1), WasmObject::Battle(s2)) => WeakBattleReference::eq(s1, s2),
|
||||||
(WasmObject::ChoiceQueue(s1), WasmObject::ChoiceQueue(s2)) => Weak::ptr_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),
|
(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::PokemonParty(m) => m.as_ptr().hash(state),
|
||||||
WasmObject::LearnedMove(m) => m.as_ptr().hash(state),
|
WasmObject::LearnedMove(m) => m.as_ptr().hash(state),
|
||||||
WasmObject::DynamicLibrary(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::Battle(m) => m.as_ptr().hash(state),
|
||||||
WasmObject::ChoiceQueue(m) => m.as_ptr().hash(state),
|
WasmObject::ChoiceQueue(m) => m.as_ptr().hash(state),
|
||||||
WasmObject::BattleRandom(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_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 {
|
impl From<&Arc<crate::dynamic_data::BattleRandom>> for WasmObject {
|
||||||
fn from(value: &Arc<crate::dynamic_data::BattleRandom>) -> Self {
|
fn from(value: &Arc<crate::dynamic_data::BattleRandom>) -> Self {
|
||||||
Self::BattleRandom(Arc::downgrade(value))
|
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> {
|
unsafe impl<T> FromToNativeWasmType for VecExternRef<T> {
|
||||||
type Native = i64;
|
type Native = i64;
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,9 @@ pub use species_data::*;
|
||||||
pub use statistic_set::*;
|
pub use statistic_set::*;
|
||||||
#[doc(inline)]
|
#[doc(inline)]
|
||||||
pub use statistics::*;
|
pub use statistics::*;
|
||||||
|
#[doc(inline)]
|
||||||
|
pub use time_of_day::*;
|
||||||
|
|
||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -50,6 +53,8 @@ mod species_data;
|
||||||
mod statistic_set;
|
mod statistic_set;
|
||||||
/// Statistics are numerical values on Pokemon that are used in battle.
|
/// Statistics are numerical values on Pokemon that are used in battle.
|
||||||
mod statistics;
|
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
|
/// A parameter for an effect. This is basically a simple way to dynamically store multiple different
|
||||||
/// primitives on data.
|
/// 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,
|
GrowthRateLibrary, GrowthRateLibraryImpl, ItemImpl, ItemLibrary, ItemLibraryImpl, LearnableMoves,
|
||||||
LearnableMovesImpl, LibrarySettingsImpl, LookupGrowthRate, MoveDataImpl, MoveLibrary, MoveLibraryImpl, NatureImpl,
|
LearnableMovesImpl, LibrarySettingsImpl, LookupGrowthRate, MoveDataImpl, MoveLibrary, MoveLibraryImpl, NatureImpl,
|
||||||
NatureLibrary, NatureLibraryImpl, SecondaryEffect, SecondaryEffectImpl, SpeciesImpl, SpeciesLibrary,
|
NatureLibrary, NatureLibraryImpl, SecondaryEffect, SecondaryEffectImpl, SpeciesImpl, SpeciesLibrary,
|
||||||
SpeciesLibraryImpl, StaticDataImpl, StaticStatisticSet, Statistic, TypeLibrary, TypeLibraryImpl,
|
SpeciesLibraryImpl, StaticDataImpl, StaticStatisticSet, Statistic, TimeOfDay, TypeLibrary, TypeLibraryImpl,
|
||||||
};
|
};
|
||||||
use pkmn_lib::StringKey;
|
use pkmn_lib::StringKey;
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ pub fn load_library() -> LoadResult {
|
||||||
Arc::new(data),
|
Arc::new(data),
|
||||||
Arc::new(Gen7BattleStatCalculator::new()),
|
Arc::new(Gen7BattleStatCalculator::new()),
|
||||||
Arc::new(Gen7DamageLibrary::new(false)),
|
Arc::new(Gen7DamageLibrary::new(false)),
|
||||||
Arc::new(Gen7MiscLibrary::new()),
|
Arc::new(Gen7MiscLibrary::new(Box::new(|| TimeOfDay::Day))),
|
||||||
script_resolver,
|
script_resolver,
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
Binary file not shown.
Loading…
Reference in New Issue