2022-06-16 15:59:33 +00:00
|
|
|
use crate::dynamic_data::choices::{MoveChoice, SwitchChoice, TurnChoice};
|
|
|
|
use crate::dynamic_data::models::battle::Battle;
|
|
|
|
use crate::dynamic_data::models::executing_move::ExecutingMove;
|
|
|
|
use crate::dynamic_data::models::learned_move::{LearnedMove, MoveLearnMethod};
|
|
|
|
use crate::dynamic_data::models::pokemon::Pokemon;
|
|
|
|
use crate::dynamic_data::script_handling::ScriptSource;
|
|
|
|
use crate::static_data::{MoveCategory, MoveData, MoveTarget, SecondaryEffect};
|
|
|
|
use crate::{script_hook, StringKey};
|
|
|
|
use hashbrown::HashSet;
|
|
|
|
use parking_lot::RwLock;
|
|
|
|
use std::fmt::{Debug, Formatter};
|
|
|
|
use std::sync::Arc;
|
|
|
|
|
|
|
|
pub trait MiscLibrary<'library> {
|
|
|
|
fn is_critical(
|
|
|
|
&self,
|
|
|
|
battle: &Battle,
|
|
|
|
executing_move: &ExecutingMove,
|
|
|
|
target: &Arc<RwLock<Pokemon>>,
|
|
|
|
hit_number: u8,
|
|
|
|
) -> bool;
|
|
|
|
fn can_flee(&self, choice: &SwitchChoice) -> bool;
|
|
|
|
fn replacement_move<'func>(
|
|
|
|
&'func self,
|
|
|
|
user: &Arc<RwLock<Pokemon<'func, 'library>>>,
|
|
|
|
target_side: u8,
|
|
|
|
target_index: u8,
|
|
|
|
) -> TurnChoice<'func, 'library>;
|
|
|
|
// TODO: can evolve from level up?
|
|
|
|
// TODO: get time
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'library> Debug for dyn MiscLibrary<'library> {
|
|
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
|
|
f.write_str("MiscLibrary")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct Gen7MiscLibrary<'library> {
|
|
|
|
struggle_data: *const MoveData,
|
2022-06-18 12:17:29 +00:00
|
|
|
struggle_learned_move: Arc<LearnedMove<'library>>,
|
2022-06-16 15:59:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<'library> Gen7MiscLibrary<'library> {
|
|
|
|
pub fn new() -> Self {
|
|
|
|
let struggle_data = Box::new(MoveData::new(
|
|
|
|
&StringKey::new("struggle"),
|
|
|
|
0,
|
|
|
|
MoveCategory::Physical,
|
|
|
|
50,
|
|
|
|
255,
|
2022-06-18 12:17:29 +00:00
|
|
|
255,
|
2022-06-16 15:59:33 +00:00
|
|
|
MoveTarget::Any,
|
|
|
|
0,
|
|
|
|
SecondaryEffect::new(-1.0, StringKey::new("struggle"), vec![]),
|
|
|
|
HashSet::new(),
|
|
|
|
));
|
|
|
|
let struggle_ptr = Box::into_raw(struggle_data);
|
2022-06-18 12:17:29 +00:00
|
|
|
let struggle_learned_move = Arc::new(LearnedMove::new(unsafe { &*struggle_ptr }, MoveLearnMethod::Unknown));
|
2022-06-16 15:59:33 +00:00
|
|
|
Self {
|
|
|
|
struggle_data: struggle_ptr,
|
|
|
|
struggle_learned_move,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'library> Drop for Gen7MiscLibrary<'library> {
|
|
|
|
fn drop(&mut self) {
|
|
|
|
unsafe {
|
|
|
|
Box::from_raw(self.struggle_data as *mut MoveData);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'library> MiscLibrary<'library> for Gen7MiscLibrary<'library> {
|
|
|
|
fn is_critical(
|
|
|
|
&self,
|
|
|
|
battle: &Battle,
|
|
|
|
executing_move: &ExecutingMove,
|
|
|
|
target: &Arc<RwLock<Pokemon>>,
|
|
|
|
hit_number: u8,
|
|
|
|
) -> bool {
|
|
|
|
if executing_move.use_move().category() == MoveCategory::Status {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
let mut crit_stage = 0;
|
|
|
|
script_hook!(
|
|
|
|
change_critical_stage,
|
|
|
|
executing_move,
|
|
|
|
executing_move,
|
|
|
|
target,
|
|
|
|
hit_number,
|
|
|
|
&mut crit_stage
|
|
|
|
);
|
|
|
|
// Crit stage is an unsigned byte, so we only care about values of 0 or higher.
|
|
|
|
// For a critical stage of 3+ we always return true.
|
|
|
|
match crit_stage {
|
|
|
|
0 => battle.random().get_max(24) == 0,
|
|
|
|
1 => battle.random().get_max(8) == 0,
|
|
|
|
2 => battle.random().get_max(2) == 0,
|
|
|
|
_ => true,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn can_flee(&self, _choice: &SwitchChoice) -> bool {
|
|
|
|
todo!()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn replacement_move<'func>(
|
|
|
|
&'func self,
|
|
|
|
user: &Arc<RwLock<Pokemon<'func, 'library>>>,
|
|
|
|
target_side: u8,
|
|
|
|
target_index: u8,
|
|
|
|
) -> TurnChoice<'func, 'library> {
|
|
|
|
TurnChoice::Move(MoveChoice::new(
|
|
|
|
user.clone(),
|
|
|
|
self.struggle_learned_move.clone(),
|
|
|
|
target_side,
|
|
|
|
target_index,
|
|
|
|
))
|
|
|
|
}
|
|
|
|
}
|