diff --git a/fighters/common/src/function_hooks/fighterspecializer/link.rs b/fighters/common/src/function_hooks/fighterspecializer/link.rs
new file mode 100644
index 0000000000..b43042be90
--- /dev/null
+++ b/fighters/common/src/function_hooks/fighterspecializer/link.rs
@@ -0,0 +1,6 @@
+ extern "C" {
+ #[link_name = "\u{1}_ZN3app23FighterSpecializer_Link29set_item_hold_anim_for_scriptERNS_7FighterE"]
+ pub fn set_item_hold_anim_for_script(
+ fighter: *mut smash::app::Fighter,
+ ) -> u64;
+ }
\ No newline at end of file
diff --git a/fighters/common/src/function_hooks/fighterspecializer/mod.rs b/fighters/common/src/function_hooks/fighterspecializer/mod.rs
index 67a56f60dd..325eca3f5e 100644
--- a/fighters/common/src/function_hooks/fighterspecializer/mod.rs
+++ b/fighters/common/src/function_hooks/fighterspecializer/mod.rs
@@ -2,6 +2,7 @@ use super::*;
mod brave;
mod jack;
+mod link;
mod pickel;
mod ptrainer;
diff --git a/fighters/falco/src/acmd/aerials.rs b/fighters/falco/src/acmd/aerials.rs
index 73cbd28e2e..9197097462 100644
--- a/fighters/falco/src/acmd/aerials.rs
+++ b/fighters/falco/src/acmd/aerials.rs
@@ -267,6 +267,7 @@ unsafe extern "C" fn effect_attackairhi(agent: &mut L2CAgentBase) {
}
}
+
unsafe extern "C" fn game_attackairlw(agent: &mut L2CAgentBase) {
let lua_state = agent.lua_state_agent;
let boma = agent.boma();
@@ -295,6 +296,7 @@ unsafe extern "C" fn game_attackairlw(agent: &mut L2CAgentBase) {
WorkModule::off_flag(boma, *FIGHTER_STATUS_ATTACK_AIR_FLAG_ENABLE_LANDING);
}
frame(lua_state, 44.0); // f52 (cancel frame)
+
}
pub fn install(agent: &mut Agent) {
@@ -316,6 +318,6 @@ pub fn install(agent: &mut Agent) {
agent.acmd("game_attackairhi", game_attackairhi, Priority::Low);
agent.acmd("effect_attackairhi", effect_attackairhi, Priority::Low);
-
+
agent.acmd("game_attackairlw", game_attackairlw, Priority::Low);
}
\ No newline at end of file
diff --git a/fighters/link/src/acmd/aerials.rs b/fighters/link/src/acmd/aerials.rs
index 9b554a67cc..f774372c89 100644
--- a/fighters/link/src/acmd/aerials.rs
+++ b/fighters/link/src/acmd/aerials.rs
@@ -18,9 +18,9 @@ unsafe extern "C" fn game_attackairn(agent: &mut L2CAgentBase) {
}
wait(lua_state, 3.0);
if is_excute(agent) {
- ATTACK(agent, 0, 0, Hash40::new("kneer"), 8.0, 361, 100, 0, 10, 4.0, -2.0, 0.0, 0.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_POS, false, 0, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_normal"), *ATTACK_SOUND_LEVEL_S, *COLLISION_SOUND_ATTR_KICK, *ATTACK_REGION_KICK);
- ATTACK(agent, 1, 0, Hash40::new("kneer"), 8.0, 361, 100, 0, 10, 4.0, 3.5, 0.0, 0.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_POS, false, 0, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_normal"), *ATTACK_SOUND_LEVEL_S, *COLLISION_SOUND_ATTR_KICK, *ATTACK_REGION_KICK);
- ATTACK(agent, 2, 0, Hash40::new("kneel"), 8.0, 361, 100, 0, 10, 3.5, 1.75, 0.0, 0.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_POS, false, 0, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_normal"), *ATTACK_SOUND_LEVEL_S, *COLLISION_SOUND_ATTR_KICK, *ATTACK_REGION_KICK);
+ ATTACK(agent, 0, 0, Hash40::new("kneer"), 7.0, 361, 100, 0, 10, 4.0, -2.0, 0.0, 0.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_POS, false, 0, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_normal"), *ATTACK_SOUND_LEVEL_S, *COLLISION_SOUND_ATTR_KICK, *ATTACK_REGION_KICK);
+ ATTACK(agent, 1, 0, Hash40::new("kneer"), 7.0, 361, 100, 0, 10, 4.0, 3.5, 0.0, 0.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_POS, false, 0, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_normal"), *ATTACK_SOUND_LEVEL_S, *COLLISION_SOUND_ATTR_KICK, *ATTACK_REGION_KICK);
+ ATTACK(agent, 2, 0, Hash40::new("kneel"), 7.0, 361, 100, 0, 10, 3.5, 1.75, 0.0, 0.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_POS, false, 0, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_normal"), *ATTACK_SOUND_LEVEL_S, *COLLISION_SOUND_ATTR_KICK, *ATTACK_REGION_KICK);
}
frame(lua_state, 28.0);
if is_excute(agent) {
@@ -47,7 +47,7 @@ unsafe extern "C" fn game_attackairf(agent: &mut L2CAgentBase) {
frame(lua_state, 13.0);
FT_MOTION_RATE(agent, 1.0);
if is_excute(agent) {
- ATTACK(agent, 0, 0, Hash40::new("armr"), 12.0, 361, 103, 0, 30, 2.5, 0.0, 0.0, 0.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_OFF, *ATTACK_LR_CHECK_POS, false, 0, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_cutup"), *ATTACK_SOUND_LEVEL_M, *COLLISION_SOUND_ATTR_CUTUP, *ATTACK_REGION_SWORD);
+ ATTACK(agent, 0, 0, Hash40::new("armr"), 11.0, 50, 110, 0, 30, 2.5, 0.0, 0.0, 0.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_OFF, *ATTACK_LR_CHECK_POS, false, 0, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_cutup"), *ATTACK_SOUND_LEVEL_M, *COLLISION_SOUND_ATTR_CUTUP, *ATTACK_REGION_SWORD);
ATTACK(agent, 1, 0, Hash40::new("sword2"), 14.0, 361, 100, 0, 30, 3.5, 0.0, 0.0, 0.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_POS, false, 0, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_cutup"), *ATTACK_SOUND_LEVEL_L, *COLLISION_SOUND_ATTR_CUTUP, *ATTACK_REGION_SWORD);
ATTACK(agent, 2, 0, Hash40::new("sword2"), 14.0, 361, 100, 0, 30, 3.5, 4.25, 0.0, 0.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_POS, false, 0, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_cutup"), *ATTACK_SOUND_LEVEL_L, *COLLISION_SOUND_ATTR_CUTUP, *ATTACK_REGION_SWORD);
ATTACK(agent, 3, 0, Hash40::new("sword2"), 14.0, 361, 100, 0, 30, 3.5, 8.5, 0.0, 0.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_OFF, *ATTACK_LR_CHECK_POS, false, 0, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_cutup"), *ATTACK_SOUND_LEVEL_L, *COLLISION_SOUND_ATTR_CUTUP, *ATTACK_REGION_SWORD);
@@ -131,11 +131,11 @@ unsafe extern "C" fn game_attackairb(agent: &mut L2CAgentBase) {
frame(lua_state, 6.0);
FT_MOTION_RATE_RANGE(agent, 6.0, 14.0, 10.0);
if is_excute(agent) {
- ATTACK(agent, 0, 0, Hash40::new("hip"), 5.0, 70, 100, 40, 0, 4.8, 0.0, 0.0, 0.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_POS, true, 0, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_G, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_normal"), *ATTACK_SOUND_LEVEL_S, *COLLISION_SOUND_ATTR_KICK, *ATTACK_REGION_KICK);
+ ATTACK(agent, 0, 0, Hash40::new("hip"), 5.0, 70, 118, 40, 0, 4.8, 0.0, 0.0, 0.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_POS, true, 0, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_G, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_normal"), *ATTACK_SOUND_LEVEL_S, *COLLISION_SOUND_ATTR_KICK, *ATTACK_REGION_KICK);
ATTACK(agent, 1, 0, Hash40::new("hip"), 5.0, 365, 100, 40, 0, 4.8, 0.0, 0.0, 0.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_POS, true, 0, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_A, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_normal"), *ATTACK_SOUND_LEVEL_S, *COLLISION_SOUND_ATTR_KICK, *ATTACK_REGION_KICK);
- ATTACK(agent, 2, 0, Hash40::new("kneer"), 5.0, 70, 100, 40, 0, 4.3, -0.5, 0.0, 0.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_B, true, 0, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_G, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_normal"), *ATTACK_SOUND_LEVEL_S, *COLLISION_SOUND_ATTR_KICK, *ATTACK_REGION_KICK);
+ ATTACK(agent, 2, 0, Hash40::new("kneer"), 5.0, 70, 118, 40, 0, 4.3, -0.5, 0.0, 0.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_B, true, 0, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_G, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_normal"), *ATTACK_SOUND_LEVEL_S, *COLLISION_SOUND_ATTR_KICK, *ATTACK_REGION_KICK);
ATTACK(agent, 3, 0, Hash40::new("kneer"), 5.0, 365, 100, 40, 0, 4.3, -0.5, 0.0, 0.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_B, true, 0, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_A, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_normal"), *ATTACK_SOUND_LEVEL_S, *COLLISION_SOUND_ATTR_KICK, *ATTACK_REGION_KICK);
- ATTACK(agent, 4, 0, Hash40::new("kneer"), 5.0, 70, 100, 40, 0, 4.3, 5.0, 0.0, 0.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_B, true, 0, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_G, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_normal"), *ATTACK_SOUND_LEVEL_S, *COLLISION_SOUND_ATTR_KICK, *ATTACK_REGION_KICK);
+ ATTACK(agent, 4, 0, Hash40::new("kneer"), 5.0, 70, 118, 40, 0, 4.3, 5.0, 0.0, 0.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_B, true, 0, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_G, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_normal"), *ATTACK_SOUND_LEVEL_S, *COLLISION_SOUND_ATTR_KICK, *ATTACK_REGION_KICK);
ATTACK(agent, 5, 0, Hash40::new("kneer"), 5.0, 365, 100, 40, 0, 4.3, 5.0, 0.0, 0.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_B, true, 0, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_A, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_normal"), *ATTACK_SOUND_LEVEL_S, *COLLISION_SOUND_ATTR_KICK, *ATTACK_REGION_KICK);
}
wait(lua_state, 3.0);
@@ -177,11 +177,11 @@ unsafe extern "C" fn game_attackairhi(agent: &mut L2CAgentBase) {
frame(lua_state, 11.0);
if is_excute(agent) {
WorkModule::on_flag(boma, *FIGHTER_STATUS_ATTACK_AIR_FLAG_ENABLE_LANDING);
- ATTACK(agent, 0, 0, Hash40::new("sword2"), 14.0, 85, 98, 0, 25, 3.5, 8.5, 0.0, 0.0, Some(-4.0), Some(0.0), Some(0.0), 1.0, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_POS, false, 0, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_sting"), *ATTACK_SOUND_LEVEL_L, *COLLISION_SOUND_ATTR_CUTUP, *ATTACK_REGION_SWORD);
+ ATTACK(agent, 0, 0, Hash40::new("sword2"), 14.0, 80, 98, 0, 25, 3.5, 8.5, 0.0, 0.0, Some(-4.0), Some(0.0), Some(0.0), 1.0, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_POS, false, 0, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_sting"), *ATTACK_SOUND_LEVEL_L, *COLLISION_SOUND_ATTR_CUTUP, *ATTACK_REGION_SWORD);
}
frame(lua_state, 14.0);
if is_excute(agent) {
- ATTACK(agent, 0, 0, Hash40::new("sword2"), 12.0, 85, 91, 0, 22, 3.0, 8.5, 0.0, 0.0, Some(-4.0), Some(0.0), Some(0.0), 1.0, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_POS, false, 0, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_cutup"), *ATTACK_SOUND_LEVEL_L, *COLLISION_SOUND_ATTR_CUTUP, *ATTACK_REGION_SWORD);
+ ATTACK(agent, 0, 0, Hash40::new("sword2"), 12.0, 80, 91, 0, 22, 3.0, 8.5, 0.0, 0.0, Some(-4.0), Some(0.0), Some(0.0), 1.0, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_POS, false, 0, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_cutup"), *ATTACK_SOUND_LEVEL_L, *COLLISION_SOUND_ATTR_CUTUP, *ATTACK_REGION_SWORD);
}
frame(lua_state, 41.0);
if is_excute(agent) {
diff --git a/fighters/link/src/acmd/ground.rs b/fighters/link/src/acmd/ground.rs
index 16997bc547..e5d8c1335e 100644
--- a/fighters/link/src/acmd/ground.rs
+++ b/fighters/link/src/acmd/ground.rs
@@ -137,8 +137,7 @@ unsafe extern "C" fn game_attackdash(agent: &mut L2CAgentBase) {
frame(lua_state, 7.0);
sv_kinetic_energy!(set_speed_mul, agent, FIGHTER_KINETIC_ENERGY_ID_MOTION, 0.93);
if is_excute(agent) {
- WorkModule::on_flag(boma, *FIGHTER_LINK_INSTANCE_WORK_ID_FLAG_WAIT_SHIELD);
- ATTACK(agent, 0, 0, Hash40::new("top"), 12.0, 70, 93, 0, 40, 3.5, 0.0, 4.0, 6.0, Some(0.0), Some(10.0), Some(6.0), 1.0, 1.0, *ATTACK_SETOFF_KIND_OFF, *ATTACK_LR_CHECK_F, false, 3, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_normal"), *ATTACK_SOUND_LEVEL_L, *COLLISION_SOUND_ATTR_KICK, *ATTACK_REGION_OBJECT);
+ ATTACK(agent, 0, 0, Hash40::new("top"), 12.0, 75, 93, 0, 40, 3.5, 0.0, 4.0, 6.0, Some(0.0), Some(10.0), Some(6.0), 1.0, 1.0, *ATTACK_SETOFF_KIND_OFF, *ATTACK_LR_CHECK_F, false, 3, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_normal"), *ATTACK_SOUND_LEVEL_L, *COLLISION_SOUND_ATTR_KICK, *ATTACK_REGION_OBJECT);
}
frame(lua_state, 9.0);
sv_kinetic_energy!(set_speed_mul, agent, FIGHTER_KINETIC_ENERGY_ID_MOTION, 1.0);
@@ -146,9 +145,13 @@ unsafe extern "C" fn game_attackdash(agent: &mut L2CAgentBase) {
if is_excute(agent) {
ATTACK(agent, 0, 0, Hash40::new("top"), 9.0, 62, 55, 0, 45, 5.5, 0.0, 8.5, 4.0, Some(0.0), Some(8.5), Some(4.75), 1.0, 1.0, *ATTACK_SETOFF_KIND_OFF, *ATTACK_LR_CHECK_F, false, 3, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_normal"), *ATTACK_SOUND_LEVEL_M, *COLLISION_SOUND_ATTR_PUNCH, *ATTACK_REGION_OBJECT);
}
+ frame(lua_state, 11.0);
+ if is_excute(agent) {
+ shield!(agent, *MA_MSC_CMD_REFLECTOR, *COLLISION_KIND_REFLECTOR, 0, hash40("top"), 5.5, 0.0, 8.5, 4.0, 0.0, 8.5, 4.75, 1.55, 0.8, 999, false, 0.8, *FIGHTER_REFLECTOR_GROUP_HOMERUNBAT);
+ }
frame(lua_state, 15.0);
if is_excute(agent) {
- WorkModule::off_flag(boma, *FIGHTER_LINK_INSTANCE_WORK_ID_FLAG_WAIT_SHIELD);
+ shield!(agent, *MA_MSC_CMD_SHIELD_OFF, *COLLISION_KIND_REFLECTOR, 0, *FIGHTER_REFLECTOR_GROUP_HOMERUNBAT);
AttackModule::clear_all(boma);
}
frame(lua_state, 28.0);
diff --git a/fighters/link/src/acmd/smashes.rs b/fighters/link/src/acmd/smashes.rs
index 60090008d1..b1e07629b6 100644
--- a/fighters/link/src/acmd/smashes.rs
+++ b/fighters/link/src/acmd/smashes.rs
@@ -349,40 +349,44 @@ unsafe extern "C" fn game_attacklw4(agent: &mut L2CAgentBase) {
if is_excute(agent) {
WorkModule::on_flag(boma, *FIGHTER_STATUS_ATTACK_FLAG_START_SMASH_HOLD);
}
+ frame(lua_state, 6.0);
+ FT_MOTION_RATE_RANGE(agent, 6.0, 8.0, 7.0);
+ frame(lua_state, 8.0);
+ FT_MOTION_RATE(agent, 1.0);
frame(lua_state, 9.0);
if is_excute(agent) {
- ATTACK(agent, 0, 0, Hash40::new("armr"), 13.0, 75, 95, 0, 30, 2.5, 0.0, 0.0, 0.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_POS, false, 5, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_cutup"), *ATTACK_SOUND_LEVEL_M, *COLLISION_SOUND_ATTR_CUTUP, *ATTACK_REGION_SWORD);
- ATTACK(agent, 1, 0, Hash40::new("sword2"), 16.0, 75, 95, 0, 30, 3.5, 0.0, 0.0, 0.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_POS, false, 5, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_cutup"), *ATTACK_SOUND_LEVEL_L, *COLLISION_SOUND_ATTR_CUTUP, *ATTACK_REGION_SWORD);
- ATTACK(agent, 2, 0, Hash40::new("sword2"), 16.0, 75, 95, 0, 30, 3.5, 4.25, 0.0, 0.0, None, None, None, 1.1, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_POS, false, 5, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_cutup"), *ATTACK_SOUND_LEVEL_L, *COLLISION_SOUND_ATTR_CUTUP, *ATTACK_REGION_SWORD);
- ATTACK(agent, 3, 0, Hash40::new("sword2"), 16.0, 75, 95, 0, 30, 3.5, 8.5, 0.0, 0.0, None, None, None, 1.1, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_POS, false, 5, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_cutup"), *ATTACK_SOUND_LEVEL_L, *COLLISION_SOUND_ATTR_CUTUP, *ATTACK_REGION_SWORD);
- ATTACK(agent, 4, 0, Hash40::new("kneel"), 13.0, 75, 95, 0, 30, 2.7, 0.5, 0.0, -0.9, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_POS, false, 5, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_cutup"), *ATTACK_SOUND_LEVEL_M, *COLLISION_SOUND_ATTR_CUTUP, *ATTACK_REGION_SWORD);
+ ATTACK(agent, 0, 0, Hash40::new("armr"), 13.0, 80, 110, 0, 35, 2.5, 0.0, 0.0, 0.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_POS, false, 5, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_cutup"), *ATTACK_SOUND_LEVEL_M, *COLLISION_SOUND_ATTR_CUTUP, *ATTACK_REGION_SWORD);
+ ATTACK(agent, 1, 0, Hash40::new("sword2"), 16.0, 80, 96, 0, 35, 3.5, 0.0, 0.0, 0.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_POS, false, 5, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_cutup"), *ATTACK_SOUND_LEVEL_L, *COLLISION_SOUND_ATTR_CUTUP, *ATTACK_REGION_SWORD);
+ ATTACK(agent, 2, 0, Hash40::new("sword2"), 16.0, 80, 96, 0, 35, 3.5, 4.25, 0.0, 0.0, None, None, None, 1.1, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_POS, false, 5, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_cutup"), *ATTACK_SOUND_LEVEL_L, *COLLISION_SOUND_ATTR_CUTUP, *ATTACK_REGION_SWORD);
+ ATTACK(agent, 3, 0, Hash40::new("sword2"), 16.0, 80, 96, 0, 35, 3.5, 8.5, 0.0, 0.0, None, None, None, 1.1, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_POS, false, 5, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_cutup"), *ATTACK_SOUND_LEVEL_L, *COLLISION_SOUND_ATTR_CUTUP, *ATTACK_REGION_SWORD);
+ ATTACK(agent, 4, 0, Hash40::new("kneel"), 13.0, 80, 110, 0, 35, 2.7, 0.5, 0.0, -0.9, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_POS, false, 5, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_cutup"), *ATTACK_SOUND_LEVEL_M, *COLLISION_SOUND_ATTR_CUTUP, *ATTACK_REGION_SWORD);
AttackModule::set_attack_height_all(boma, app::AttackHeight(*ATTACK_HEIGHT_LOW), false);
}
wait(lua_state, 2.0);
if is_excute(agent) {
AttackModule::clear_all(boma);
}
+ frame(lua_state, 15.0);
+ FT_MOTION_RATE_RANGE(agent, 15.0, 19.0, 7.0);
+ frame(lua_state, 20.0);
+ FT_MOTION_RATE(agent, 1.0);
frame(lua_state, 21.0);
if is_excute(agent) {
- ATTACK(agent, 0, 0, Hash40::new("armr"), 10.0, 75, 98, 0, 20, 2.5, 0.0, 0.0, 0.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_POS, false, 5, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_cutup"), *ATTACK_SOUND_LEVEL_M, *COLLISION_SOUND_ATTR_CUTUP, *ATTACK_REGION_SWORD);
- ATTACK(agent, 1, 0, Hash40::new("sword2"), 14.0, 86, 72, 0, 40, 3.5, 0.0, 0.0, 0.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_POS, false, 5, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_cutup"), *ATTACK_SOUND_LEVEL_M, *COLLISION_SOUND_ATTR_CUTUP, *ATTACK_REGION_SWORD);
- ATTACK(agent, 2, 0, Hash40::new("sword2"), 14.0, 86, 72, 0, 40, 3.5, 4.25, 0.0, 0.0, None, None, None, 1.1, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_POS, false, 5, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_cutup"), *ATTACK_SOUND_LEVEL_L, *COLLISION_SOUND_ATTR_CUTUP, *ATTACK_REGION_SWORD);
- ATTACK(agent, 3, 0, Hash40::new("sword2"), 14.0, 86, 72, 0, 40, 3.5, 8.5, 0.0, 0.0, None, None, None, 1.1, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_POS, false, 5, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_cutup"), *ATTACK_SOUND_LEVEL_L, *COLLISION_SOUND_ATTR_CUTUP, *ATTACK_REGION_SWORD);
- ATTACK(agent, 4, 0, Hash40::new("kneer"), 10.0, 75, 98, 0, 20, 2.7, 1.5, 0.0, -0.7, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_POS, false, 5, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_cutup"), *ATTACK_SOUND_LEVEL_M, *COLLISION_SOUND_ATTR_CUTUP, *ATTACK_REGION_SWORD);
+ ATTACK(agent, 0, 0, Hash40::new("armr"), 14.0, 80, 107, 0, 35, 2.5, 0.0, 0.0, 0.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_POS, false, 5, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_cutup"), *ATTACK_SOUND_LEVEL_M, *COLLISION_SOUND_ATTR_CUTUP, *ATTACK_REGION_SWORD);
+ ATTACK(agent, 1, 0, Hash40::new("sword2"), 17.0, 80, 97, 0, 35, 3.5, 0.0, 0.0, 0.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_POS, false, 5, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_cutup"), *ATTACK_SOUND_LEVEL_L, *COLLISION_SOUND_ATTR_CUTUP, *ATTACK_REGION_SWORD);
+ ATTACK(agent, 2, 0, Hash40::new("sword2"), 17.0, 80, 97, 0, 35, 3.5, 4.25, 0.0, 0.0, None, None, None, 1.1, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_POS, false, 5, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_cutup"), *ATTACK_SOUND_LEVEL_L, *COLLISION_SOUND_ATTR_CUTUP, *ATTACK_REGION_SWORD);
+ ATTACK(agent, 3, 0, Hash40::new("sword2"), 17.0, 80, 97, 0, 35, 3.5, 8.5, 0.0, 0.0, None, None, None, 1.1, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_POS, false, 5, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_cutup"), *ATTACK_SOUND_LEVEL_L, *COLLISION_SOUND_ATTR_CUTUP, *ATTACK_REGION_SWORD);
+ ATTACK(agent, 4, 0, Hash40::new("kneer"), 14.0, 80, 107, 0, 35, 2.7, 1.5, 0.0, -0.7, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_POS, false, 5, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_cutup"), *ATTACK_SOUND_LEVEL_M, *COLLISION_SOUND_ATTR_CUTUP, *ATTACK_REGION_SWORD);
AttackModule::set_attack_height_all(boma, app::AttackHeight(*ATTACK_HEIGHT_LOW), false);
}
frame(lua_state, 23.0);
if is_excute(agent) {
AttackModule::clear_all(boma);
}
- frame(lua_state, 31.0);
+ frame(lua_state, 36.0);
if is_excute(agent) {
VarModule::on_flag(agent.battle_object, vars::link::status::ENABLE_SPECIAL_LW_CANCEL);
}
- frame(lua_state, 32.0);
- FT_MOTION_RATE_RANGE(agent, 32.0, 56.0, 12.0);
- frame(lua_state, 56.0);
- FT_MOTION_RATE(agent, 1.0);
}
unsafe extern "C" fn effect_attacklw4(agent: &mut L2CAgentBase) {
diff --git a/fighters/link/src/acmd/specials.rs b/fighters/link/src/acmd/specials.rs
index ad3bdd1af5..5e5b721a6b 100644
--- a/fighters/link/src/acmd/specials.rs
+++ b/fighters/link/src/acmd/specials.rs
@@ -1,16 +1,114 @@
use super::*;
+unsafe extern "C" fn game_specials1(agent: &mut L2CAgentBase) {
+ let lua_state = agent.lua_state_agent;
+ let boma = agent.boma();
+ frame(lua_state, 1.0);
+ FT_MOTION_RATE_RANGE(agent, 1.0, 5.0, 2.0);
+ frame(lua_state, 5.0);
+ FT_MOTION_RATE(agent, 1.0);
+ if is_excute(agent) {
+ ArticleModule::generate_article(boma, *FIGHTER_LINK_GENERATE_ARTICLE_BOOMERANG, false, 0);
+ }
+ frame(lua_state, 27.0);
+ if is_excute(agent) {
+ ArticleModule::shoot(boma, *FIGHTER_LINK_GENERATE_ARTICLE_BOOMERANG, app::ArticleOperationTarget(*ARTICLE_OPE_TARGET_ALL), false);
+ }
+}
+
+unsafe extern "C" fn sound_specials1(agent: &mut L2CAgentBase) {
+ let lua_state = agent.lua_state_agent;
+ let boma = agent.boma();
+ frame(lua_state, 3.0);
+ if is_excute(agent) {
+ PLAY_SE(agent, Hash40::new("vc_link_attack03"));
+ }
+ frame(lua_state, 25.0);
+ if is_excute(agent) {
+ PLAY_SE(agent, Hash40::new("se_link_special_s01"));
+ }
+}
+
+unsafe extern "C" fn game_specialairs1(agent: &mut L2CAgentBase) {
+ let lua_state = agent.lua_state_agent;
+ let boma = agent.boma();
+ frame(lua_state, 1.0);
+ FT_MOTION_RATE_RANGE(agent, 1.0, 5.0, 2.0);
+ frame(lua_state, 5.0);
+ FT_MOTION_RATE(agent, 1.0);
+ if is_excute(agent) {
+ ArticleModule::generate_article(boma, *FIGHTER_LINK_GENERATE_ARTICLE_BOOMERANG, false, 0);
+ }
+ frame(lua_state, 27.0);
+ if is_excute(agent) {
+ ArticleModule::shoot(boma, *FIGHTER_LINK_GENERATE_ARTICLE_BOOMERANG, app::ArticleOperationTarget(*ARTICLE_OPE_TARGET_ALL), false);
+ }
+}
+
+unsafe extern "C" fn sound_specialairs1(agent: &mut L2CAgentBase) {
+ let lua_state = agent.lua_state_agent;
+ let boma = agent.boma();
+ frame(lua_state, 3.0);
+ if is_excute(agent) {
+ PLAY_SE(agent, Hash40::new("vc_link_attack03"));
+ }
+ frame(lua_state, 25.0);
+ if is_excute(agent) {
+ PLAY_SE(agent, Hash40::new("se_link_special_s01"));
+ }
+}
+
+// Hand hitbox when Boomerang is used while out
+unsafe extern "C" fn game_specials1blank(agent: &mut L2CAgentBase) {
+ let lua_state = agent.lua_state_agent;
+ let boma = agent.boma();
+ if is_excute(agent) {
+ }
+ frame(lua_state, 1.0);
+ FT_MOTION_RATE_RANGE(agent, 1.0, 5.0, 2.0);
+ frame(lua_state, 5.0);
+ FT_MOTION_RATE(agent, 1.0);
+ frame(lua_state, 26.0);
+ if is_excute(agent) {
+ ATTACK(agent, 0, 0, Hash40::new("armr"), 4.0, 45, 100, 0, 16, 2.5, 2.0, 0.0, 0.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_POS, true, 0, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_normal"), *ATTACK_SOUND_LEVEL_M, *COLLISION_SOUND_ATTR_PUNCH, *ATTACK_REGION_KICK);
+ }
+ frame(lua_state, 28.0);
+ if is_excute(agent) {
+ AttackModule::clear_all(boma);
+ }
+}
+
+// Hand hitbox when Boomerang is used while out
+unsafe extern "C" fn game_specialairs1blank(agent: &mut L2CAgentBase) {
+ let lua_state = agent.lua_state_agent;
+ let boma = agent.boma();
+ if is_excute(agent) {
+ }
+ frame(lua_state, 1.0);
+ FT_MOTION_RATE_RANGE(agent, 1.0, 5.0, 2.0);
+ frame(lua_state, 5.0);
+ FT_MOTION_RATE(agent, 1.0);
+ frame(lua_state, 26.0);
+ if is_excute(agent) {
+ ATTACK(agent, 0, 0, Hash40::new("armr"), 4.0, 45, 100, 0, 16, 2.5, 2.0, 0.0, 0.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_POS, true, 0, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_normal"), *ATTACK_SOUND_LEVEL_M, *COLLISION_SOUND_ATTR_PUNCH, *ATTACK_REGION_KICK);
+ }
+ frame(lua_state, 28.0);
+ if is_excute(agent) {
+ AttackModule::clear_all(boma);
+ }
+}
+
unsafe extern "C" fn game_specialhi(agent: &mut L2CAgentBase) {
let lua_state = agent.lua_state_agent;
let boma = agent.boma();
frame(lua_state, 1.0);
- FT_MOTION_RATE_RANGE(agent, 1.0, 2.5, 7.0);
+ FT_MOTION_RATE_RANGE(agent, 1.0, 2.5, 5.0);
frame(lua_state, 2.5);
FT_MOTION_RATE_RANGE(agent, 2.5, 4.0, 1.0);
frame(lua_state, 4.0);
FT_MOTION_RATE(agent, 1.0);
if is_excute(agent) {
- ATTACK(agent, 0, 0, Hash40::new("top"), 16.0, 40, 82, 0, 49, 4.0, 0.0, 9.0, 4.0, Some(0.0), Some(9.0), Some(17.0), 1.0, 1.0, *ATTACK_SETOFF_KIND_OFF, *ATTACK_LR_CHECK_POS, false, 10, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_cutup"), *ATTACK_SOUND_LEVEL_L, *COLLISION_SOUND_ATTR_CUTUP, *ATTACK_REGION_SWORD);
+ ATTACK(agent, 0, 0, Hash40::new("top"), 16.0, 40, 82, 0, 49, 4.0, 0.0, 9.0, 4.0, Some(0.0), Some(9.0), Some(17.0), 1.3, 0.7, *ATTACK_SETOFF_KIND_OFF, *ATTACK_LR_CHECK_POS, false, 10, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_cutup"), *ATTACK_SOUND_LEVEL_L, *COLLISION_SOUND_ATTR_CUTUP, *ATTACK_REGION_SWORD);
}
wait(lua_state, 3.0);
if is_excute(agent) {
@@ -326,6 +424,14 @@ unsafe extern "C" fn effect_specialairhi(agent: &mut L2CAgentBase) {
}
pub fn install(agent: &mut Agent) {
+ agent.acmd("game_specials1", game_specials1, Priority::Low);
+ agent.acmd("sound_specials1", sound_specials1, Priority::Low);
+ agent.acmd("game_specialairs1", game_specialairs1, Priority::Low);
+ agent.acmd("sound_specialairs1", sound_specialairs1, Priority::Low);
+
+ agent.acmd("game_specials1blank", game_specials1blank, Priority::Low);
+ agent.acmd("game_specialairs1blank", game_specialairs1blank, Priority::Low);
+
agent.acmd("game_specialhi", game_specialhi, Priority::Low);
agent.acmd("effect_specialhi", effect_specialhi, Priority::Low);
agent.acmd("game_specialairhi", game_specialairhi, Priority::Low);
diff --git a/fighters/link/src/acmd/throws.rs b/fighters/link/src/acmd/throws.rs
index e151189248..c2492f7ce0 100644
--- a/fighters/link/src/acmd/throws.rs
+++ b/fighters/link/src/acmd/throws.rs
@@ -187,7 +187,6 @@ unsafe extern "C" fn game_throwlw(agent: &mut L2CAgentBase) {
CHECK_FINISH_CAMERA(agent, -2, 0);
}
frame(lua_state, 24.0);
- FT_MOTION_RATE_RANGE(agent, 24.0, 48.0, 22.0);
if is_excute(agent) {
let target = WorkModule::get_int64(boma, *FIGHTER_STATUS_THROW_WORK_INT_TARGET_OBJECT);
let target_group = WorkModule::get_int64(boma, *FIGHTER_STATUS_THROW_WORK_INT_TARGET_HIT_GROUP);
@@ -195,12 +194,10 @@ unsafe extern "C" fn game_throwlw(agent: &mut L2CAgentBase) {
ATK_HIT_ABS(agent, *FIGHTER_ATTACK_ABSOLUTE_KIND_THROW, Hash40::new("throw"), target, target_group, target_no);
AttackModule::clear_all(boma);
}
- frame(lua_state, 35.0);
+ frame(lua_state, 28.0);
if is_excute(agent) {
VarModule::on_flag(agent.battle_object, vars::link::status::ENABLE_SPECIAL_LW_CANCEL);
}
- frame(lua_state, 48.0);
- FT_MOTION_RATE(agent, 1.0);
}
pub fn install(agent: &mut Agent) {
diff --git a/fighters/link/src/acmd/tilts.rs b/fighters/link/src/acmd/tilts.rs
index bc51146d07..387a3f4c38 100644
--- a/fighters/link/src/acmd/tilts.rs
+++ b/fighters/link/src/acmd/tilts.rs
@@ -100,19 +100,15 @@ unsafe extern "C" fn game_attackhi3(agent: &mut L2CAgentBase) {
let boma = agent.boma();
frame(lua_state, 8.0);
if is_excute(agent) {
- ATTACK(agent, 0, 0, Hash40::new("armr"), 9.0, 70, 122, 0, 30, 2.5, 0.0, 0.0, 0.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_OFF, *ATTACK_LR_CHECK_POS, false, 0, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_cutup"), *ATTACK_SOUND_LEVEL_M, *COLLISION_SOUND_ATTR_CUTUP, *ATTACK_REGION_SWORD);
- ATTACK(agent, 1, 0, Hash40::new("sword2"), 9.0, 70, 122, 0, 30, 3.5, 0.0, 0.0, -2.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_OFF, *ATTACK_LR_CHECK_POS, false, 0, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_cutup"), *ATTACK_SOUND_LEVEL_M, *COLLISION_SOUND_ATTR_CUTUP, *ATTACK_REGION_SWORD);
- ATTACK(agent, 2, 0, Hash40::new("sword2"), 9.0, 70, 122, 0, 30, 3.5, 4.25, 0.0, -2.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_POS, false, 0, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_cutup"), *ATTACK_SOUND_LEVEL_M, *COLLISION_SOUND_ATTR_CUTUP, *ATTACK_REGION_SWORD);
+ ATTACK(agent, 0, 0, Hash40::new("armr"), 9.0, 70, 120, 0, 27, 2.5, 0.0, 0.0, 0.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_OFF, *ATTACK_LR_CHECK_POS, false, 0, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_cutup"), *ATTACK_SOUND_LEVEL_M, *COLLISION_SOUND_ATTR_CUTUP, *ATTACK_REGION_SWORD);
+ ATTACK(agent, 1, 0, Hash40::new("sword2"), 9.0, 70, 120, 0, 27, 3.5, 0.0, 0.0, -2.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_OFF, *ATTACK_LR_CHECK_POS, false, 0, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_cutup"), *ATTACK_SOUND_LEVEL_M, *COLLISION_SOUND_ATTR_CUTUP, *ATTACK_REGION_SWORD);
+ ATTACK(agent, 2, 0, Hash40::new("sword2"), 9.0, 70, 120, 0, 27, 3.5, 4.25, 0.0, -2.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_POS, false, 0, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_cutup"), *ATTACK_SOUND_LEVEL_M, *COLLISION_SOUND_ATTR_CUTUP, *ATTACK_REGION_SWORD);
ATTACK(agent, 3, 0, Hash40::new("sword2"), 10.0, 85, 115, 0, 30, 3.5, 8.5, 0.0, -2.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_POS, false, 0, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_cutup"), *ATTACK_SOUND_LEVEL_L, *COLLISION_SOUND_ATTR_CUTUP, *ATTACK_REGION_SWORD);
}
frame(lua_state, 14.0);
if is_excute(agent) {
AttackModule::clear_all(boma);
}
- frame(lua_state, 23.0);
- if is_excute(agent) {
- VarModule::on_flag(agent.battle_object, vars::link::status::ENABLE_SPECIAL_LW_CANCEL);
- }
}
unsafe extern "C" fn effect_attackhi3(agent: &mut L2CAgentBase) {
@@ -127,7 +123,7 @@ unsafe extern "C" fn effect_attackhi3(agent: &mut L2CAgentBase) {
if is_excute(agent) {
FOOT_EFFECT(agent, Hash40::new("sys_run_smoke"), Hash40::new("top"), -3, 0, -1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, false);
}
- frame(lua_state, 12.0);
+ frame(lua_state, 13.0);
if is_excute(agent) {
AFTER_IMAGE_OFF(agent, 5);
EFFECT_OFF_KIND(agent, Hash40::new("link_sword"), false, false);
@@ -142,16 +138,20 @@ unsafe extern "C" fn game_attacklw3(agent: &mut L2CAgentBase) {
frame(lua_state, 13.0);
FT_MOTION_RATE(agent, 1.0);
if is_excute(agent) {
- ATTACK(agent, 0, 0, Hash40::new("armr"), 10.0, 64, 101, 0, 25, 2.5, 0.0, 0.0, 0.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_OFF, *ATTACK_LR_CHECK_F, false, 0, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_cutup"), *ATTACK_SOUND_LEVEL_M, *COLLISION_SOUND_ATTR_CUTUP, *ATTACK_REGION_SWORD);
+ ATTACK(agent, 0, 0, Hash40::new("armr"), 10.0, 71, 94, 0, 25, 2.5, 0.0, 0.0, 0.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_OFF, *ATTACK_LR_CHECK_F, false, 0, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_cutup"), *ATTACK_SOUND_LEVEL_M, *COLLISION_SOUND_ATTR_CUTUP, *ATTACK_REGION_SWORD);
ATTACK(agent, 1, 0, Hash40::new("sword2"), 11.0, 82, 91, 0, 45, 3.5, 0.0, 0.0, 0.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_OFF, *ATTACK_LR_CHECK_F, false, 0, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_G, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_cutup"), *ATTACK_SOUND_LEVEL_L, *COLLISION_SOUND_ATTR_CUTUP, *ATTACK_REGION_SWORD);
ATTACK(agent, 3, 0, Hash40::new("sword2"), 11.0, 82, 91, 0, 45, 3.5, 4.25, 0.0, 0.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_OFF, *ATTACK_LR_CHECK_F, false, 0, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_cutup"), *ATTACK_SOUND_LEVEL_L, *COLLISION_SOUND_ATTR_CUTUP, *ATTACK_REGION_SWORD);
- ATTACK(agent, 4, 0, Hash40::new("sword2"), 12.0, 82, 91, 0, 50, 3.5, 8.5, 0.0, 0.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_OFF, *ATTACK_LR_CHECK_F, false, 0, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_cutup"), *ATTACK_SOUND_LEVEL_L, *COLLISION_SOUND_ATTR_CUTUP, *ATTACK_REGION_SWORD);
+ ATTACK(agent, 4, 0, Hash40::new("sword2"), 12.0, 92, 91, 0, 50, 3.5, 8.5, 0.0, 0.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_OFF, *ATTACK_LR_CHECK_F, false, 0, 0.0, 0, false, false, false, false, true, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_cutup"), *ATTACK_SOUND_LEVEL_L, *COLLISION_SOUND_ATTR_CUTUP, *ATTACK_REGION_SWORD);
AttackModule::set_attack_height_all(boma, app::AttackHeight(*ATTACK_HEIGHT_LOW), false);
}
frame(lua_state, 16.0);
if is_excute(agent) {
AttackModule::clear_all(boma);
}
+ frame(lua_state, 21.0);
+ if is_excute(agent) {
+ VarModule::on_flag(agent.battle_object, vars::link::status::ENABLE_SPECIAL_LW_CANCEL);
+ }
}
unsafe extern "C" fn effect_attacklw3(agent: &mut L2CAgentBase) {
@@ -168,10 +168,6 @@ unsafe extern "C" fn effect_attacklw3(agent: &mut L2CAgentBase) {
AFTER_IMAGE_OFF(agent, 4);
EFFECT_OFF_KIND(agent, Hash40::new("link_sword"), false, false);
}
- frame(lua_state, 21.0);
- if is_excute(agent) {
- VarModule::on_flag(agent.battle_object, vars::link::status::ENABLE_SPECIAL_LW_CANCEL);
- }
}
unsafe extern "C" fn expression_attacklw3(agent: &mut L2CAgentBase) {
diff --git a/fighters/link/src/boomerang/acmd.rs b/fighters/link/src/boomerang/acmd.rs
index e5177c8701..f3becfecd5 100644
--- a/fighters/link/src/boomerang/acmd.rs
+++ b/fighters/link/src/boomerang/acmd.rs
@@ -4,16 +4,20 @@ unsafe extern "C" fn game_fly(agent: &mut L2CAgentBase) {
let lua_state = agent.lua_state_agent;
let boma = agent.boma();
if is_excute(agent) {
- ATTACK(agent, 0, 0, Hash40::new("top"), 10.0, 80, 29, 0, 91, 4.0, 0.0, 0.0, 0.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_SPEED, false, 0, 0.0, 0, true, false, false, false, false, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_normal"), *ATTACK_SOUND_LEVEL_L, *COLLISION_SOUND_ATTR_KICK, *ATTACK_REGION_OBJECT);
+ ATTACK(agent, 0, 0, Hash40::new("top"), 11.0, 78, 40, 0, 64, 4.0, 0.0, 0.0, 0.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_SPEED, false, 0, 0.0, 0, true, false, false, false, false, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_normal"), *ATTACK_SOUND_LEVEL_L, *COLLISION_SOUND_ATTR_KICK, *ATTACK_REGION_OBJECT);
AttackModule::enable_safe_pos(boma);
}
- frame(lua_state, 10.0);
+ frame(lua_state, 5.0);
if is_excute(agent) {
- ATTACK(agent, 0, 0, Hash40::new("top"), 8.0, 80, 37, 0, 74, 3.6, 0.0, 0.0, 0.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_SPEED, false, 0, 0.0, 0, true, false, false, false, false, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_normal"), *ATTACK_SOUND_LEVEL_M, *COLLISION_SOUND_ATTR_KICK, *ATTACK_REGION_OBJECT);
+ VarModule::on_flag(agent.battle_object, vars::link::status::ENABLE_SPECIAL_LW_CANCEL);
+ }
+ frame(lua_state, 8.0);
+ if is_excute(agent) {
+ ATTACK(agent, 0, 0, Hash40::new("top"), 8.0, 78, 46, 0, 57, 3.6, 0.0, 0.0, 0.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_SPEED, false, 0, 0.0, 0, true, false, false, false, false, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_normal"), *ATTACK_SOUND_LEVEL_M, *COLLISION_SOUND_ATTR_KICK, *ATTACK_REGION_OBJECT);
}
frame(lua_state, 23.0);
if is_excute(agent) {
- ATTACK(agent, 0, 0, Hash40::new("top"), 6.0, 80, 44, 0, 55, 3.6, 0.0, 0.0, 0.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_SPEED, false, 0, 0.0, 0, true, false, false, false, false, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_normal"), *ATTACK_SOUND_LEVEL_M, *COLLISION_SOUND_ATTR_KICK, *ATTACK_REGION_OBJECT);
+ ATTACK(agent, 0, 0, Hash40::new("top"), 6.0, 70, 44, 0, 55, 3.6, 0.0, 0.0, 0.0, None, None, None, 1.0, 1.0, *ATTACK_SETOFF_KIND_ON, *ATTACK_LR_CHECK_SPEED, false, 0, 0.0, 0, true, false, false, false, false, *COLLISION_SITUATION_MASK_GA, *COLLISION_CATEGORY_MASK_ALL, *COLLISION_PART_MASK_ALL, false, Hash40::new("collision_attr_normal"), *ATTACK_SOUND_LEVEL_M, *COLLISION_SOUND_ATTR_KICK, *ATTACK_REGION_OBJECT);
}
}
diff --git a/fighters/link/src/status/special_lw.rs b/fighters/link/src/status/special_lw.rs
index ad03eac111..50ee11b0a1 100644
--- a/fighters/link/src/status/special_lw.rs
+++ b/fighters/link/src/status/special_lw.rs
@@ -1,5 +1,123 @@
use super::*;
+unsafe extern "C" fn item_throw_status_main(agent: &mut L2CFighterCommon) -> L2CValue {
+ //is down-special input
+ let is_special_lw_input;
+ let stick_x = ControlModule::get_stick_x(agent.module_accessor);
+ let stick_y = ControlModule::get_stick_y(agent.module_accessor);
+ let special_stick_x = WorkModule::get_param_float(agent.module_accessor, hash40("common"), hash40("special_stick_x"));
+ let special_stick_y = WorkModule::get_param_float(agent.module_accessor, hash40("common"), hash40("special_stick_y"));
+ let squat_stick_y = WorkModule::get_param_float(agent.module_accessor, hash40("common"), hash40("squat_stick_y"));
+ let special_button = ControlModule::check_button_trigger(agent.module_accessor, *CONTROL_PAD_BUTTON_SPECIAL);
+ let special_s = agent.global_table[CMD_CAT1].get_i32() & (*FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_S) != 0;
+ let special_lw = agent.global_table[CMD_CAT1].get_i32() & (*FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_LW) != 0;
+ let item_throw = agent.global_table[CMD_CAT3].get_i32() & (*FIGHTER_PAD_CMD_CAT3_FLAG_ITEM_LIGHT_THROW_ALL|*FIGHTER_PAD_CMD_CAT3_FLAG_ITEM_LIGHT_THROW_AIR_ALL) != 0;
+ let is_squat = agent.global_table[STATUS_KIND].get_i32() == *FIGHTER_STATUS_KIND_SQUAT_WAIT;
+ if (
+ !special_s
+ && special_lw
+ ) || (
+ special_button
+ && is_squat
+ && stick_y <= squat_stick_y
+ ) || (
+ special_button
+ && !is_squat
+ && stick_x.abs() <= special_stick_x
+ && stick_y <= special_stick_y*-1.0
+ ) {
+ is_special_lw_input = true;
+ }else {
+ is_special_lw_input = false;
+ }
+ smashline::original_status(Main, agent, *FIGHTER_STATUS_KIND_ITEM_THROW)(agent);
+ //special-lw disabled & has bomb
+ let bomb_id = WorkModule::get_int(agent.module_accessor, *FIGHTER_LINK_INSTANCE_WORK_ID_INT_BOMB_OBJECT_ID);
+ if !WorkModule::is_enable_transition_term(agent.module_accessor, *FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_SPECIAL_LW)
+ && ItemModule::get_have_item_id(agent.module_accessor, 0) == bomb_id as u64
+ && is_special_lw_input || !item_throw {
+ if MotionModule::motion_kind(agent.module_accessor) == hash40("item_light_throw_f")
+ || MotionModule::motion_kind(agent.module_accessor) == hash40("item_light_throw_air_f") {
+ if agent.is_situation(*SITUATION_KIND_GROUND) {
+ MotionModule::change_motion(agent.module_accessor, Hash40::new("special_lw_throw"), 0.0, 1.0, false, 0.0, false, false);
+ WorkModule::set_int64(agent.module_accessor, hash40("special_lw_throw") as i64, *FIGHTER_STATUS_ITEM_THROW_WORK_INT_MOTION_KIND);
+ WorkModule::set_int64(agent.module_accessor, hash40("special_air_lw_throw") as i64, *FIGHTER_STATUS_ITEM_THROW_WORK_INT_MOTION_KIND_OPPOSITE);
+ }else {
+ MotionModule::change_motion(agent.module_accessor, Hash40::new("special_air_lw_throw"), 0.0, 1.0, false, 0.0, false, false);
+ WorkModule::set_int64(agent.module_accessor, hash40("special_air_lw_throw") as i64, *FIGHTER_STATUS_ITEM_THROW_WORK_INT_MOTION_KIND);
+ WorkModule::set_int64(agent.module_accessor, hash40("special_lw_throw") as i64, *FIGHTER_STATUS_ITEM_THROW_WORK_INT_MOTION_KIND_OPPOSITE);
+ }
+ MotionModule::remove_motion_partial(agent.module_accessor, *FIGHTER_MOTION_PART_SET_KIND_HAVE_ITEM, false);
+ }
+ }
+ 0.into()
+}
+
+unsafe extern "C" fn item_throw_status_end(agent: &mut L2CFighterCommon) -> L2CValue {
+ smashline::original_status(End, agent, *FIGHTER_STATUS_KIND_ITEM_THROW)(agent);
+ if ItemModule::is_have_item(agent.module_accessor, 0) {
+ let bomb_id = WorkModule::get_int(agent.module_accessor, *FIGHTER_LINK_INSTANCE_WORK_ID_INT_BOMB_OBJECT_ID);
+ if ItemModule::get_have_item_id(agent.module_accessor, 0) == bomb_id as u64 {
+ }
+ }
+ 0.into()
+}
+
+unsafe extern "C" fn special_lw_throw_game(agent: &mut L2CAgentBase) {
+ FT_MOTION_RATE(agent, 0.4);
+ frame(agent.lua_state_agent, 27.0);
+ if is_excute(agent) {
+ let lr = PostureModule::lr(agent.module_accessor);
+ let item_id = ItemModule::get_have_item_id(agent.module_accessor,0) as u32;
+ let item_boma = sv_battle_object::module_accessor(item_id);
+ agent.clear_lua_stack();
+ lua_args!(agent, 12, 2, *ITEM_FIGHTER_VAR_FLOAT_ITEM_THROW_ANGLE, *ITEM_FIGHTER_VAR_FLOAT_ITEM_THROW_SPEED, *ITEM_FIGHTER_VAR_FLOAT_ITEM_THROW_POWER);
+ smash::app::sv_animcmd::THROW_ITEM_OFFSET(agent.lua_state_agent);
+ KineticModule::add_speed(item_boma, &Vector3f{x:1.85*lr, y:0.1, z:0.0});
+ }
+ frame(agent.lua_state_agent, 32.0);
+ if is_excute(agent) {
+ FT_MOTION_RATE(agent, 1.0);
+}}
+
+unsafe extern "C" fn special_lw_throw_exp(agent: &mut L2CAgentBase) {
+ if is_excute(agent) {
+ slope!(agent, *MA_MSC_CMD_SLOPE_SLOPE, *SLOPE_STATUS_LR);
+ VisibilityModule::set_int64(agent.module_accessor, hash40("shield") as i64, hash40("shield_back") as i64);
+ }
+ frame(agent.lua_state_agent, 5.0);
+ if is_excute(agent) {
+ VisibilityModule::set_int64(agent.module_accessor, hash40("sword") as i64, hash40("sword_back") as i64);
+ }
+ frame(agent.lua_state_agent, 47.0);
+ if is_excute(agent) {
+ VisibilityModule::set_int64(agent.module_accessor, hash40("sword") as i64, hash40("sword_normal") as i64);
+ }
+ frame(agent.lua_state_agent, 52.0);
+ if is_excute(agent) {
+ VisibilityModule::set_int64(agent.module_accessor, hash40("shield") as i64, hash40("shield_normal") as i64);
+ }
+}
+
+unsafe extern "C" fn special_lw_blast_exp(agent: &mut L2CAgentBase) {
+ if is_excute(agent) {
+ ItemModule::set_have_item_visibility(agent.module_accessor, false, 0);
+ slope!(agent, *MA_MSC_CMD_SLOPE_SLOPE, *SLOPE_STATUS_LR);
+ VisibilityModule::set_int64(agent.module_accessor, hash40("shield") as i64, hash40("shield_back") as i64);
+ }
+ frame(agent.lua_state_agent, 9.0);
+ if is_excute(agent) {
+ ControlModule::set_rumble(agent.module_accessor, Hash40::new("rbkind_nohits"), 5, false, *BATTLE_OBJECT_ID_INVALID as u32);
+ }
+ frame(agent.lua_state_agent, 34.0);
+ if is_excute(agent) {
+ //fixing shield visibility not switching when grabbing an item
+ if !ItemModule::is_have_item(agent.module_accessor, 0) {
+ VisibilityModule::set_int64(agent.module_accessor, hash40("shield") as i64, hash40("shield_normal") as i64);
+ }
+ }
+}
+
unsafe extern "C" fn special_lw_pre(fighter: &mut L2CFighterCommon) -> L2CValue {
let ret = smashline::original_status(Pre, fighter, *FIGHTER_STATUS_KIND_SPECIAL_LW)(fighter);
FighterStatusModuleImpl::set_fighter_status_data(
@@ -48,6 +166,17 @@ unsafe extern "C" fn special_lw_blast_pre(fighter: &mut L2CFighterCommon) -> L2C
}
pub fn install(agent: &mut Agent) {
+ agent.status(Main, *FIGHTER_STATUS_KIND_ITEM_THROW, item_throw_status_main);
+ agent.status(End, *FIGHTER_STATUS_KIND_ITEM_THROW, item_throw_status_end);
+
+ agent.game_acmd("game_speciallwthrow", special_lw_throw_game, Priority::High);
+ agent.game_acmd("game_specialairlwthrow", special_lw_throw_game, Priority::High);
+ agent.expression_acmd("expression_speciallwthrow", special_lw_throw_exp, Priority::High);
+ agent.expression_acmd("expression_specialairlwthrow", special_lw_throw_exp, Priority::High);
+
+ agent.expression_acmd("expression_speciallwblast", special_lw_blast_exp, Priority::High);
+ agent.expression_acmd("expression_specialairlwblast", special_lw_blast_exp, Priority::High);
+
agent.status(Pre, *FIGHTER_STATUS_KIND_SPECIAL_LW, special_lw_pre);
agent.status(Pre, *FIGHTER_LINK_STATUS_KIND_SPECIAL_LW_BLAST, special_lw_blast_pre);
}
\ No newline at end of file
diff --git a/romfs/source/fighter/common/param/fighter_param.prcxml b/romfs/source/fighter/common/param/fighter_param.prcxml
index 68ec584fa2..7ae63056aa 100644
--- a/romfs/source/fighter/common/param/fighter_param.prcxml
+++ b/romfs/source/fighter/common/param/fighter_param.prcxml
@@ -99,7 +99,7 @@
8
10
7
- 14
+ 13
18
4
1
diff --git a/romfs/source/fighter/link/motion/body/motion_patch.yaml b/romfs/source/fighter/link/motion/body/motion_patch.yaml
index f4b2613cc4..b000448116 100644
--- a/romfs/source/fighter/link/motion/body/motion_patch.yaml
+++ b/romfs/source/fighter/link/motion/body/motion_patch.yaml
@@ -79,7 +79,7 @@ guard_off:
cancel_frame: 12
throw_f:
extra:
- cancel_frame: 35
+ cancel_frame: 30
throw_b:
extra:
cancel_frame: 33
@@ -101,6 +101,21 @@ attack_13:
attack_lw3:
extra:
cancel_frame: 33
+special_s1:
+ extra:
+ cancel_frame: 44
+special_s1_blank:
+ extra:
+ cancel_frame: 44
+special_air_s1_blank:
+ extra:
+ cancel_frame: 44
+special_s2:
+ extra:
+ cancel_frame: 1
+special_airs2:
+ extra:
+ cancel_frame: 1
special_hi:
extra:
cancel_frame: 80
@@ -112,10 +127,68 @@ attack_hi4:
cancel_frame: 72
attack_lw4:
extra:
- cancel_frame: 53
+ cancel_frame: 48
special_lw:
extra:
cancel_frame: 40
+special_lw_throw:
+ game_script: game_speciallwthrow
+ flags:
+ turn: false
+ loop: false
+ move: true
+ fix_trans: false
+ fix_rot: false
+ fix_scale: false
+ unk_40: false
+ unk_80: true
+ unk_100: false
+ unk_200: false
+ unk_400: false
+ unk_800: false
+ unk_1000: false
+ unk_2000: false
+ blend_frames: 0
+ animations:
+ - name: d03speciallwthrow.nuanmb
+ scripts:
+ - expression_speciallwthrow
+ - sound_speciallwthrow
+ - effect_speciallwthrow
+ extra:
+ intangible_start_frame: 0
+ intangible_end_frame: 0
+ cancel_frame: 41
+ freeze_during_hitstop: false
+special_air_lw_throw:
+ game_script: game_specialairlwthrow
+ flags:
+ turn: false
+ loop: false
+ move: true
+ fix_trans: false
+ fix_rot: false
+ fix_scale: false
+ unk_40: false
+ unk_80: true
+ unk_100: false
+ unk_200: false
+ unk_400: false
+ unk_800: false
+ unk_1000: false
+ unk_2000: false
+ blend_frames: 0
+ animations:
+ - name: d03specialairlwthrow.nuanmb
+ scripts:
+ - expression_specialairlwthrow
+ - sound_specialairlwthrow
+ - effect_specialairlwthrow
+ extra:
+ intangible_start_frame: 0
+ intangible_end_frame: 0
+ cancel_frame: 41
+ freeze_during_hitstop: false
attack_hi3:
extra:
cancel_frame: 33
@@ -124,7 +197,7 @@ appeal_hi_l:
cancel_frame: 90
attack_dash:
extra:
- cancel_frame: 42
+ cancel_frame: 40
attack_s3_s:
extra:
cancel_frame: 39