1
0
Fork 0
mirror of https://github.com/jugeeya/UltimateTrainingModpack.git synced 2024-11-28 04:44:06 +00:00

Pokemon Trainer: Save State Fix (#387)

* Initial; stay same pokemon, but still go through ball throw animation

* Remove PTrainer ball throw animation

* Merge with master

* Needed import

* Format Rust code using rustfmt

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This commit is contained in:
jugeeya 2022-10-06 13:49:03 -07:00 committed by GitHub
parent d25583cda2
commit 7bbae26f35
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 68 additions and 29 deletions

View file

@ -9,7 +9,7 @@ crate-type = ["cdylib"]
[dependencies] [dependencies]
skyline = { git = "https://github.com/ultimate-research/skyline-rs.git" } skyline = { git = "https://github.com/ultimate-research/skyline-rs.git" }
skyline_smash = { git = "https://github.com/ultimate-research/skyline-smash.git", branch = "no-cache" } skyline_smash = { git = "https://github.com/ultimate-research/skyline-smash.git", branch = "no-cache" }
skyline-web = { git = "https://github.com/skyline-rs/skyline-web.git" } skyline-web = { git = "https://github.com/skyline-rs/skyline-web.git" }
bitflags = "1.2.1" bitflags = "1.2.1"
parking_lot = { version = "0.12.0", features = ["nightly"] } parking_lot = { version = "0.12.0", features = ["nightly"] }

View file

@ -118,19 +118,21 @@ pub fn is_in_shieldstun(module_accessor: &mut app::BattleObjectModuleAccessor) -
&& status_kind == FIGHTER_STATUS_KIND_GUARD_OFF) && status_kind == FIGHTER_STATUS_KIND_GUARD_OFF)
} }
pub unsafe fn is_dead(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool { pub unsafe fn is_ptrainer(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool {
let fighter_kind = app::utility::get_kind(module_accessor); [
let fighter_is_ptrainer = [
*FIGHTER_KIND_PZENIGAME, *FIGHTER_KIND_PZENIGAME,
*FIGHTER_KIND_PFUSHIGISOU, *FIGHTER_KIND_PFUSHIGISOU,
*FIGHTER_KIND_PLIZARDON, *FIGHTER_KIND_PLIZARDON,
] ]
.contains(&fighter_kind); .contains(&app::utility::get_kind(module_accessor))
}
pub unsafe fn is_dead(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool {
let status_kind = StatusModule::status_kind(module_accessor) as i32; let status_kind = StatusModule::status_kind(module_accessor) as i32;
let prev_status_kind = StatusModule::prev_status_kind(module_accessor, 0); let prev_status_kind = StatusModule::prev_status_kind(module_accessor, 0);
// Pokemon trainer enters FIGHTER_STATUS_KIND_WAIT for one frame during their respawn animation // Pokemon trainer enters FIGHTER_STATUS_KIND_WAIT for one frame during their respawn animation
// And the previous status is FIGHTER_STATUS_NONE // And the previous status is FIGHTER_STATUS_NONE
if fighter_is_ptrainer { if is_ptrainer(module_accessor) {
[*FIGHTER_STATUS_KIND_DEAD, *FIGHTER_STATUS_KIND_STANDBY].contains(&status_kind) [*FIGHTER_STATUS_KIND_DEAD, *FIGHTER_STATUS_KIND_STANDBY].contains(&status_kind)
|| (status_kind == FIGHTER_STATUS_KIND_WAIT || (status_kind == FIGHTER_STATUS_KIND_WAIT
&& prev_status_kind == FIGHTER_STATUS_KIND_NONE) && prev_status_kind == FIGHTER_STATUS_KIND_NONE)

View file

@ -76,7 +76,7 @@ macro_rules! default_save_state {
}; };
} }
use crate::ITEM_MANAGER_ADDR; use crate::{get_module_accessor, is_ptrainer, ITEM_MANAGER_ADDR};
use SaveState::*; use SaveState::*;
static mut SAVE_STATE_PLAYER: SavedState = default_save_state!(); static mut SAVE_STATE_PLAYER: SavedState = default_save_state!();
@ -124,6 +124,9 @@ pub unsafe fn get_param_int(
if param_hash == hash40("rebirth_move_frame") { if param_hash == hash40("rebirth_move_frame") {
return Some(0); return Some(0);
} }
if param_hash == hash40("rebirth_move_frame_trainer") {
return Some(0);
}
if param_hash == hash40("rebirth_wait_frame") { if param_hash == hash40("rebirth_wait_frame") {
return Some(0); return Some(0);
} }
@ -134,6 +137,11 @@ pub unsafe fn get_param_int(
return Some(0); return Some(0);
} }
} }
if param_type == hash40("param_mball") {
if param_hash == hash40("change_fly_frame") {
return Some(0);
}
}
None None
} }
@ -159,6 +167,40 @@ fn set_damage(module_accessor: &mut app::BattleObjectModuleAccessor, damage: f32
} }
} }
unsafe fn get_ptrainer_module_accessor(
module_accessor: &mut app::BattleObjectModuleAccessor,
) -> &mut app::BattleObjectModuleAccessor {
let ptrainer_object_id =
LinkModule::get_parent_object_id(module_accessor, *FIGHTER_POKEMON_LINK_NO_PTRAINER);
&mut *app::sv_battle_object::module_accessor(ptrainer_object_id as u32)
}
unsafe fn on_ptrainer_death(module_accessor: &mut app::BattleObjectModuleAccessor) {
if !is_ptrainer(module_accessor) {
return;
}
WorkModule::off_flag(
get_ptrainer_module_accessor(module_accessor),
*WEAPON_PTRAINER_PTRAINER_INSTANCE_WORK_ID_FLAG_ENABLE_CHANGE_POKEMON,
);
let ptrainer_module_accessor = get_ptrainer_module_accessor(module_accessor);
MotionModule::set_rate(ptrainer_module_accessor, 1000.0);
if ArticleModule::is_exist(
ptrainer_module_accessor,
*WEAPON_PTRAINER_PTRAINER_GENERATE_ARTICLE_MBALL,
) {
let ptrainer_masterball: u64 = ArticleModule::get_article(
ptrainer_module_accessor,
*WEAPON_PTRAINER_PTRAINER_GENERATE_ARTICLE_MBALL,
);
let ptrainer_masterball_id =
Article::get_battle_object_id(ptrainer_masterball as *mut app::Article);
let ptrainer_masterball_module_accessor =
&mut *app::sv_battle_object::module_accessor(ptrainer_masterball_id as u32);
MotionModule::set_rate(ptrainer_masterball_module_accessor, 1000.0);
}
}
pub unsafe fn save_states(module_accessor: &mut app::BattleObjectModuleAccessor) { pub unsafe fn save_states(module_accessor: &mut app::BattleObjectModuleAccessor) {
if MENU.save_state_enable == OnOff::Off { if MENU.save_state_enable == OnOff::Off {
return; return;
@ -174,14 +216,9 @@ pub unsafe fn save_states(module_accessor: &mut app::BattleObjectModuleAccessor)
}; };
let fighter_kind = app::utility::get_kind(module_accessor); let fighter_kind = app::utility::get_kind(module_accessor);
let fighter_is_ptrainer = [ let fighter_is_ptrainer = is_ptrainer(module_accessor);
*FIGHTER_KIND_PZENIGAME,
*FIGHTER_KIND_PFUSHIGISOU,
*FIGHTER_KIND_PLIZARDON,
]
.contains(&fighter_kind);
let fighter_is_popo = fighter_kind == *FIGHTER_KIND_POPO; // For making sure Popo doesn't steal Nana's PosMove let fighter_is_popo = fighter_kind == *FIGHTER_KIND_POPO; // For making sure Popo doesn't steal Nana's PosMove
let fighter_is_nana = fighter_kind == *FIGHTER_KIND_NANA; // Don't want Nana to reopen savestates etc. let fighter_is_nana = fighter_kind == *FIGHTER_KIND_NANA; // Don't want Nana to reopen save states etc.
let fighter_is_buffable = [ let fighter_is_buffable = [
*FIGHTER_KIND_BRAVE, *FIGHTER_KIND_BRAVE,
*FIGHTER_KIND_CLOUD, *FIGHTER_KIND_CLOUD,
@ -193,14 +230,13 @@ pub unsafe fn save_states(module_accessor: &mut app::BattleObjectModuleAccessor)
.contains(&fighter_kind); .contains(&fighter_kind);
// Grab + Dpad up: reset state // Grab + Dpad up: reset state
if (MENU.save_state_autoload == OnOff::On let autoload_reset = MENU.save_state_autoload == OnOff::On
&& !fighter_is_ptrainer
&& save_state.state == NoAction && save_state.state == NoAction
&& is_dead(module_accessor)) && is_dead(module_accessor);
|| (ControlModule::check_button_on(module_accessor, *CONTROL_PAD_BUTTON_CATCH) let triggered_reset =
&& ControlModule::check_button_trigger(module_accessor, *CONTROL_PAD_BUTTON_APPEAL_HI)) ControlModule::check_button_on(module_accessor, *CONTROL_PAD_BUTTON_CATCH)
&& !fighter_is_nana && ControlModule::check_button_trigger(module_accessor, *CONTROL_PAD_BUTTON_APPEAL_HI);
{ if (autoload_reset || triggered_reset) && !fighter_is_nana {
if save_state.state == NoAction { if save_state.state == NoAction {
SAVE_STATE_PLAYER.state = KillPlayer; SAVE_STATE_PLAYER.state = KillPlayer;
SAVE_STATE_CPU.state = KillPlayer; SAVE_STATE_CPU.state = KillPlayer;
@ -211,15 +247,10 @@ pub unsafe fn save_states(module_accessor: &mut app::BattleObjectModuleAccessor)
// move to camera bounds // move to camera bounds
if save_state.state == KillPlayer { if save_state.state == KillPlayer {
on_ptrainer_death(module_accessor);
SoundModule::stop_all_sound(module_accessor); SoundModule::stop_all_sound(module_accessor);
if status == FIGHTER_STATUS_KIND_REBIRTH { if status == FIGHTER_STATUS_KIND_REBIRTH {
if !(fighter_is_ptrainer save_state.state = PosMove;
&& save_state.fighter_kind > 0
&& fighter_kind != save_state.fighter_kind)
{
// For ptrainer, don't move on unless we're cycled back to the right pokemon
save_state.state = PosMove;
}
} else if !is_dead(module_accessor) && !fighter_is_nana { } else if !is_dead(module_accessor) && !fighter_is_nana {
// Don't kill Nana again, since she already gets killed by the game from Popo's death // Don't kill Nana again, since she already gets killed by the game from Popo's death
// Try moving off-screen so we don't see effects. // Try moving off-screen so we don't see effects.
@ -236,7 +267,7 @@ pub unsafe fn save_states(module_accessor: &mut app::BattleObjectModuleAccessor)
if item != 0 { if item != 0 {
let item = item as *mut Item; let item = item as *mut Item;
let item_battle_object_id = let item_battle_object_id =
smash::app::lua_bind::Item::get_battle_object_id(item) as u32; app::lua_bind::Item::get_battle_object_id(item) as u32;
ItemManager::remove_item_from_id(item_mgr, item_battle_object_id); ItemManager::remove_item_from_id(item_mgr, item_battle_object_id);
} }
}); });
@ -358,6 +389,12 @@ pub unsafe fn save_states(module_accessor: &mut app::BattleObjectModuleAccessor)
true, true,
); );
} }
if fighter_is_ptrainer {
WorkModule::on_flag(
get_ptrainer_module_accessor(module_accessor),
*WEAPON_PTRAINER_PTRAINER_INSTANCE_WORK_ID_FLAG_ENABLE_CHANGE_POKEMON,
);
}
} }
// if the fighter is Popo, change the state to one where only Nana can move // if the fighter is Popo, change the state to one where only Nana can move