Skip to content

Instantly share code, notes, and snippets.

@jam1garner
Created June 21, 2020 02:53
Show Gist options
  • Save jam1garner/fe346f0117b3bb7b18ab82ef5c739cab to your computer and use it in GitHub Desktop.
Save jam1garner/fe346f0117b3bb7b18ab82ef5c739cab to your computer and use it in GitHub Desktop.
#![feature(proc_macro_hygiene)]
use skyline::nro::{self, NroInfo};
use smash::app::{self, lua_bind::*, sv_system, sv_animcmd};
use smash::hash40;
use smash::lib::{lua_const::*, L2CValue, L2CAgent};
use smash::lua2cpp::L2CFighterCommon;
pub fn get_category(boma: &mut app::BattleObjectModuleAccessor) -> i32{
return (boma.info >> 28) as u8 as i32;
}
extern "C"{
#[link_name = "\u{1}_ZN3app7utility8get_kindEPKNS_26BattleObjectModuleAccessorE"]
pub fn get_kind(module_accessor: &mut app::BattleObjectModuleAccessor) -> i32;
}
macro_rules! acmd {
(
$l2c_state:expr,
{
$(
$func_name:ident(
$(
$args:expr
),*
$(,)?
);
)*
}
) => {
let l2c_agent = &mut L2CAgent::new($l2c_state);
let lua_state = $l2c_state;
$(
l2c_agent.clear_lua_stack();
$(
l2c_agent.push_lua_stack(&mut ($args).into());
)*
sv_animcmd::$func_name(lua_state);
)*
};
}
pub unsafe fn per_frame_updater(fighter: &mut L2CFighterCommon) {
let boma = sv_system::battle_object_module_accessor(fighter.lua_state_agent);
let lua_state = fighter.lua_state_agent;
if get_category(boma) == *BATTLE_OBJECT_CATEGORY_FIGHTER && get_kind(boma) == *FIGHTER_KIND_MARIO { //check for the current battle object being a fighter, and being mario
if MotionModule::motion_kind(boma) == hash40("attack_air_f") { //check for forward aerial
//sv_animcmd::frame(lua_state, 16.0); //might need some extra pushing/popping of lua stack...?? idk
if MotionModule::frame(boma) as i32 == 16 /*sv_animcmd::is_excute(lua_state)*/ { //check for frame 16
//if this hitbox connects, it will end up hitting multiple times because it's not using is_excute. This is because this function runs once per frame,
//which also includes hitlag, in which mario will stay on frame 16 since hitlag pauses animations.
//is_excute checks to make sure the code only runs once, and would eliminate this issue
println!("fair");
AttackModule::clear_all(boma); //clear previous hitboxes
acmd!(lua_state, {
ATTACK(
0, 0, hash40("arml"), 19.0, 361, 80, 0, 30, 113.0, 3.2, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0,
ATTACK_SETOFF_KIND_ON, ATTACK_LR_CHECK_F, ATTACK_LR_CHECK_F, ATTACK_LR_CHECK_F,
ATTACK_LR_CHECK_F, ATTACK_LR_CHECK_F, false, false, false, false, true,
COLLISION_SITUATION_MASK_GA, COLLISION_CATEGORY_MASK_ALL, COLLISION_PART_MASK_ALL,
false, hash40("collision_attr_fire"), ATTACK_SOUND_LEVEL_M, COLLISION_SOUND_ATTR_PUNCH,
ATTACK_REGION_PUNCH
);
});
}
}
}
}
/*#[skyline::hook(replace = smash::lib::L2CAgent::clear_lua_stack)]
pub unsafe fn clear_lua_stack_hook(l2c_agent: &mut L2CAgent) -> u64 {
l2c_agent.sv_set_function_hash(std::mem::transmute())
}*/
#[skyline::hook(replace = smash::lua2cpp::L2CFighterCommon_sys_line_system_control_fighter)] //runs once per frame, per fighter
pub unsafe fn sys_line_system_control_fighter_hook(fighter: &mut L2CFighterCommon) -> L2CValue {
per_frame_updater(fighter);
original!()(fighter)
}
fn nro_main(nro: &NroInfo) {
match nro.name {
"common" => {
skyline::install_hook!(sys_line_system_control_fighter_hook);
}
_ => (),
}
}
#[skyline::main(name = "ACMD_Test")]
pub fn main() {
nro::add_hook(nro_main).unwrap();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment