Adds assist and assurance, fixes

This commit is contained in:
2022-09-09 20:09:56 +02:00
parent 05430c5e84
commit 365bdc8aec
57 changed files with 533 additions and 95 deletions

0
gen_7_scripts/Cargo.toml Normal file → Executable file
View File

1
gen_7_scripts/src/lib.rs Normal file → Executable file
View File

@@ -14,6 +14,7 @@ use pkmn_lib_interface::set_load_script_fn;
pub mod registered_scripts;
pub mod moves;
pub mod util_scripts;
pub(crate) mod utils;
#[no_mangle]
#[cfg(not(test))]

16
gen_7_scripts/src/moves/acrobatics.rs Normal file → Executable file
View File

@@ -1,20 +1,16 @@
use crate::script;
use core::any::Any;
use pkmn_lib_interface::app_interface::{ExecutingMove, Pokemon};
use pkmn_lib_interface::handling::{Script, ScriptCapabilities};
pub struct Acrobatics {}
impl Acrobatics {
pub const fn get_const_name() -> &'static str {
"acrobatics"
}
}
script!(Acrobatics, "acrobatics");
impl Script for Acrobatics {
fn new() -> Self {
Self {}
}
fn get_name() -> &'static str {
fn get_name(&self) -> &'static str {
Self::get_const_name()
}
@@ -37,4 +33,8 @@ impl Script for Acrobatics {
}
}
}
fn as_any(&self) -> &dyn Any {
self
}
}

7
gen_7_scripts/src/moves/acupressure.rs Normal file → Executable file
View File

@@ -1,3 +1,4 @@
use core::any::Any;
use core::mem::transmute;
use pkmn_lib_interface::app_interface::{ExecutingMove, Pokemon, Statistic};
use pkmn_lib_interface::handling::{Script, ScriptCapabilities};
@@ -15,7 +16,7 @@ impl Script for Acupressure {
Self {}
}
fn get_name() -> &'static str {
fn get_name(&self) -> &'static str {
Self::get_const_name()
}
@@ -32,4 +33,8 @@ impl Script for Acupressure {
unsafe { transmute(target.battle().unwrap().random().get_between(1, 6) as u8) };
target.change_stat_boost(rand_stat, 2, false);
}
fn as_any(&self) -> &dyn Any {
self
}
}

7
gen_7_scripts/src/moves/after_you.rs Normal file → Executable file
View File

@@ -1,3 +1,4 @@
use core::any::Any;
use pkmn_lib_interface::app_interface::{ExecutingMove, Pokemon};
use pkmn_lib_interface::handling::{Script, ScriptCapabilities};
@@ -14,7 +15,7 @@ impl Script for AfterYou {
Self {}
}
fn get_name() -> &'static str {
fn get_name(&self) -> &'static str {
Self::get_const_name()
}
@@ -32,4 +33,8 @@ impl Script for AfterYou {
mv.get_hit_data(&target, hit).fail()
}
}
fn as_any(&self) -> &dyn Any {
self
}
}

View File

@@ -0,0 +1,66 @@
use crate::script;
use alloc::vec::Vec;
use core::any::Any;
use pkmn_lib_interface::app_interface::{MoveData, Party, Pokemon, StringKey, TurnChoice};
use pkmn_lib_interface::handling::{Script, ScriptCapabilities};
script!(Assist, "assist");
impl Assist {
fn get_party_moves(party: &Party, user: &Pokemon) -> Vec<MoveData> {
let mut possible_moves = Vec::new();
// Iterate over every mon in the party
for mon_index in 0..party.length() {
let mon = party.get_pokemon(mon_index);
if let Some(mon) = mon {
// Ignore moves from the user
if mon == *user {
continue;
}
// Iterate over all moves. We make the assumption of 4 moves.
for move_index in 0..4 {
let mv = mon.get_learned_move(move_index);
if let Some(mv) = mv {
// Make sure we can copy the move, otherwise add it as possible move.
if crate::utils::copyable_moves::can_copy_move(&mv.move_data()) {
possible_moves.push(mv.move_data())
}
}
}
}
}
possible_moves
}
}
impl Script for Assist {
fn new() -> Self {
Self {}
}
fn get_name(&self) -> &'static str {
Self::get_const_name()
}
fn get_capabilities(&self) -> &[ScriptCapabilities] {
&[ScriptCapabilities::ChangeMove]
}
fn change_move(&self, choice: TurnChoice, move_name: &mut StringKey) {
let user = choice.user();
let battle = user.battle().unwrap();
let party = battle.find_party_for_pokemon(&user).unwrap().party();
let possible_moves = Self::get_party_moves(&party, &user);
if possible_moves.len() == 0 {
choice.fail();
return;
}
let random = battle.random().get_max(possible_moves.len() as i32);
*move_name = possible_moves[random as usize].name();
}
fn as_any(&self) -> &dyn Any {
self
}
}

View File

@@ -0,0 +1,109 @@
use crate::script;
use alloc::boxed::Box;
use core::any::Any;
use core::sync::atomic::{AtomicBool, Ordering};
use pkmn_lib_interface::app_interface::{
BattleSide, DamageSource, ExecutingMove, Pokemon, TurnChoice,
};
use pkmn_lib_interface::handling::{Script, ScriptCapabilities};
script!(Assurance, "assurance");
impl Script for Assurance {
fn new() -> Self {
Self {}
}
fn get_name(&self) -> &'static str {
Self::get_const_name()
}
fn get_capabilities(&self) -> &[ScriptCapabilities] {
&[
ScriptCapabilities::OnBeforeTurn,
ScriptCapabilities::ChangeBasePower,
]
}
fn on_before_turn(&self, choice: TurnChoice) {
if let TurnChoice::Move(data) = &choice {
let side: BattleSide = choice
.user()
.battle()
.unwrap()
.sides()
.get(data.target_side() as u32)
.unwrap();
side.add_volatile(Box::new(AssuranceData {
for_position: data.target_index(),
has_hit: AtomicBool::new(false),
}));
}
}
fn change_base_power(
&self,
_move: ExecutingMove,
target: Pokemon,
_hit: u8,
base_power: &mut u8,
) {
if let Some(s) = target
.battle_side()
.get_volatile::<AssuranceData>(AssuranceData::get_const_name())
{
if s.has_hit.load(Ordering::Relaxed) {
*base_power *= 2;
}
}
}
fn as_any(&self) -> &dyn Any {
self
}
}
script!(
AssuranceData,
"assurance_data",
for_position: u8,
has_hit: AtomicBool
);
impl Script for AssuranceData {
fn new() -> Self {
Self {
for_position: 0,
has_hit: AtomicBool::new(false),
}
}
fn get_name(&self) -> &'static str {
Self::get_const_name()
}
fn get_capabilities(&self) -> &[ScriptCapabilities] {
&[ScriptCapabilities::OnEndTurn, ScriptCapabilities::OnDamage]
}
fn on_end_turn(&self) {
let side: BattleSide = self.get_owner().unwrap();
side.remove_volatile(self);
}
fn on_damage(
&self,
pokemon: Pokemon,
_source: DamageSource,
_old_health: u32,
_new_health: u32,
) {
if pokemon.battle_side_index() == self.for_position {
self.has_hit.store(true, Ordering::Relaxed);
}
}
fn as_any(&self) -> &dyn Any {
self
}
}

2
gen_7_scripts/src/moves/mod.rs Normal file → Executable file
View File

@@ -2,3 +2,5 @@ pub mod acrobatics;
pub mod acupressure;
pub mod after_you;
pub mod multi_hit_move;
pub mod assist;
pub mod assurance;

7
gen_7_scripts/src/moves/multi_hit_move.rs Normal file → Executable file
View File

@@ -1,3 +1,4 @@
use core::any::Any;
use pkmn_lib_interface::app_interface::TurnChoice;
use pkmn_lib_interface::handling::{Script, ScriptCapabilities};
@@ -14,7 +15,7 @@ impl Script for MultiHitMove {
Self {}
}
fn get_name() -> &'static str {
fn get_name(&self) -> &'static str {
Self::get_const_name()
}
@@ -34,4 +35,8 @@ impl Script for MultiHitMove {
_ => *number_of_hits,
}
}
fn as_any(&self) -> &dyn Any {
self
}
}

2
gen_7_scripts/src/registered_scripts.rs Normal file → Executable file
View File

@@ -29,6 +29,8 @@ pub fn get_script(category: ScriptCategory, name: &StringKey) -> Option<Box<dyn
acrobatics::Acrobatics,
acupressure::Acupressure,
after_you::AfterYou,
assist::Assist,
assurance::Assurance,
multi_hit_move::MultiHitMove,
);
}

7
gen_7_scripts/src/util_scripts/force_effect_trigger.rs Normal file → Executable file
View File

@@ -1,3 +1,4 @@
use core::any::Any;
use pkmn_lib_interface::app_interface::{ExecutingMove, Pokemon};
use pkmn_lib_interface::handling::{Script, ScriptCapabilities};
@@ -14,7 +15,7 @@ impl Script for ForceEffectTriggerScript {
Self {}
}
fn get_name() -> &'static str {
fn get_name(&self) -> &'static str {
Self::get_const_name()
}
@@ -32,4 +33,8 @@ impl Script for ForceEffectTriggerScript {
// Set to 50_000% chance.
*chance = 50_000.0;
}
fn as_any(&self) -> &dyn Any {
self
}
}

0
gen_7_scripts/src/util_scripts/mod.rs Normal file → Executable file
View File

View File

@@ -0,0 +1,74 @@
use pkmn_lib_interface::app_interface::{get_hash, MoveData};
macro_rules! non_copyable {
(
$mv:ident,
$($move_name:literal),+
) => {
match $mv.name().hash() {
0
$(
| const { get_hash($move_name) }
)* => false,
_ => true
}
};
}
pub fn can_copy_move(mv: &MoveData) -> bool {
// A list of all moves that cannot be copied. This expands to a match statement, so is fast on
// runtime.
non_copyable!(
mv,
"assist",
"baneful_bunker",
"beak_blast",
"belch",
"bestow",
"bounce",
"celebrate",
"chatter",
"circle_throw",
"copycat",
"counter",
"covet",
"destiny_bond",
"detect",
"dig",
"dive",
"dragon_tail",
"endure",
"feint",
"fly",
"focus_punch",
"follow_me",
"helping_hand",
"hold_hands",
"kings_shield",
"mat_block",
"me_first",
"metronome",
"mimic",
"mirror_coat",
"mirror_move",
"nature_power",
"phantom_force",
"protect",
"rage_powder",
"roar",
"shadow_force",
"shell_trap",
"sketch",
"sky_drop",
"sleep_talk",
"snatch",
"spiky_shield",
"spotlight",
"struggle",
"switcheroo",
"thief",
"transform",
"trick",
"whirlwind"
)
}

25
gen_7_scripts/src/utils/mod.rs Executable file
View File

@@ -0,0 +1,25 @@
pub mod copyable_moves;
#[macro_export]
macro_rules! script{
(
$name: ident,
$id: literal
$(
,
$field_name:ident : $field_type:ty
)*
) => {
pub struct $name {
$(
$field_name: $field_type,
)*
}
impl $name {
pub const fn get_const_name() -> &'static str {
$id
}
}
}
}