1
0
Fork 0
mirror of https://github.com/jugeeya/UltimateTrainingModpack.git synced 2025-02-17 14:40:31 +00:00

Bugfix: PT savestates (#292)

* Prevent PT from respawning twice during save_state loads

* Save fighter_kind in state

* Fix bug where save states might not be loaded immediately if ptrainer status was wait

* Avoid endless loop with PT if loading a save state which was set without PT

* Move is_dead to common::mod.rs
This commit is contained in:
asimon-1 2021-12-23 20:46:17 -08:00 committed by GitHub
parent b52112bb12
commit f9522d2699
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 49 additions and 6 deletions

View file

@ -142,3 +142,24 @@ pub fn is_in_shieldstun(module_accessor: &mut app::BattleObjectModuleAccessor) -
pub fn get_random_int(max: i32) -> i32 {
unsafe { app::sv_math::rand(hash40("fighter"), max) }
}
pub unsafe fn is_dead(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool {
let fighter_kind = app::utility::get_kind(module_accessor);
let fighter_is_ptrainer = [
*FIGHTER_KIND_PZENIGAME,
*FIGHTER_KIND_PFUSHIGISOU,
*FIGHTER_KIND_PLIZARDON,
]
.contains(&fighter_kind);
let status_kind = StatusModule::status_kind(module_accessor) as i32;
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
// And the previous status is FIGHTER_STATUS_NONE
if fighter_is_ptrainer {
[*FIGHTER_STATUS_KIND_DEAD, *FIGHTER_STATUS_KIND_STANDBY].contains(&status_kind)
|| (status_kind == FIGHTER_STATUS_KIND_WAIT
&& prev_status_kind == FIGHTER_STATUS_KIND_NONE)
} else {
[*FIGHTER_STATUS_KIND_DEAD, *FIGHTER_STATUS_KIND_STANDBY].contains(&status_kind)
}
}

View file

@ -1,8 +1,8 @@
use crate::common::consts::FighterId;
use crate::common::consts::OnOff;
use crate::common::consts::SaveStateMirroring;
use crate::common::get_random_int;
use crate::common::MENU;
use crate::common::{get_random_int, is_dead};
use crate::training::reset;
use smash::app::{self, lua_bind::*};
use smash::hash40;
@ -24,6 +24,7 @@ struct SavedState {
lr: f32,
situation_kind: i32,
state: SaveState,
fighter_kind: i32,
}
macro_rules! default_save_state {
@ -35,6 +36,7 @@ macro_rules! default_save_state {
lr: 1.0,
situation_kind: 0,
state: NoAction,
fighter_kind: -1,
}
};
}
@ -108,14 +110,22 @@ pub unsafe fn save_states(module_accessor: &mut app::BattleObjectModuleAccessor)
}
let status = StatusModule::status_kind(module_accessor) as i32;
let save_state = if WorkModule::get_int(module_accessor, *FIGHTER_INSTANCE_WORK_ID_INT_ENTRY_ID)
== FighterId::CPU as i32
{
let is_cpu = WorkModule::get_int(module_accessor, *FIGHTER_INSTANCE_WORK_ID_INT_ENTRY_ID)
== FighterId::CPU as i32;
let save_state = if is_cpu {
&mut SAVE_STATE_CPU
} else {
&mut SAVE_STATE_PLAYER
};
let fighter_kind = app::utility::get_kind(module_accessor);
let fighter_is_ptrainer = [
*FIGHTER_KIND_PZENIGAME,
*FIGHTER_KIND_PFUSHIGISOU,
*FIGHTER_KIND_PLIZARDON,
]
.contains(&fighter_kind);
// Grab + Dpad up: reset state
if ControlModule::check_button_on(module_accessor, *CONTROL_PAD_BUTTON_CATCH)
&& ControlModule::check_button_trigger(module_accessor, *CONTROL_PAD_BUTTON_APPEAL_HI)
@ -133,8 +143,14 @@ pub unsafe fn save_states(module_accessor: &mut app::BattleObjectModuleAccessor)
if save_state.state == KillPlayer {
SoundModule::stop_all_sound(module_accessor);
if status == FIGHTER_STATUS_KIND_REBIRTH {
save_state.state = PosMove;
} else if status != FIGHTER_STATUS_KIND_DEAD && status != FIGHTER_STATUS_KIND_STANDBY {
if !(fighter_is_ptrainer
&& 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) {
// Try moving off-screen so we don't see effects.
let pos = Vector3f {
x: -300.0,
@ -232,6 +248,12 @@ pub unsafe fn save_states(module_accessor: &mut app::BattleObjectModuleAccessor)
save_state.lr = PostureModule::lr(module_accessor);
save_state.percent = DamageModule::damage(module_accessor, 0);
save_state.situation_kind = StatusModule::situation_kind(module_accessor);
if fighter_is_ptrainer {
// Only store the fighter_kind for pokemon trainer
save_state.fighter_kind = app::utility::get_kind(module_accessor);
} else {
save_state.fighter_kind = -1;
}
let zeros = Vector3f {
x: 0.0,