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:
parent
b52112bb12
commit
f9522d2699
2 changed files with 49 additions and 6 deletions
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue