mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-11-25 13:35:12 +00:00
Fix issues Extended Moveset mod (+ extras) (#146)
* Allow Lua action hooks to specify custom functions for more behavior ...like gravity, and update all current mods to match. Spin jump and wall slide from the Extended Moveset mod now have gravity code basically matching the original mod. Currently, any place you'd want to use one of these new action hooks still requires an O(n) check through all action hook per call. This should probably be changed. * Fix some remaining issues with Extended Moveset Lua port - Remove divergent spin jump code - Remove divergent roll code - Remap roll button to Y - Reimplement dive slide to make dive hop work like the original - Allow spin from double jump, backflip, side flip * Fix more issues with Extended Moveset Lua port - Reimplement all users of update_walking_speed to incorporate the Tight Controls edits and modified speed caps - Fix instances of angle arithmetic to wrap properly across the mod * Don't chop off group bits of custom action flags; assign missing groups in mods This fixes the Extended Moveset's underwater actions. Chopping off those bits was making the game consider the underwater actions to be a part of the Stationary group, which caused `check_common_stationary_cancels`, which upwarps Mario to the surface. * Tweak roll sliding angle tendency Rolling will now gradually (but fairly quckly) try to tend Mario's facing angle down the slope. This is cleaner than my old method that tries to flip Mario's angle (wrongly) when he begins moving downward, having that logic coexist with the logic for normal sliding actions that can also tend Mario to face backward down the slope. Just looks ugly now by comparison. * Disallow spin jump on slides in Extended Moveset port This matches the original mod * Extended Moveset: Crazy Box Bounce check * Extended Moveset: Fix hugging the wall when spin jumping after wall kick * Extended Moveset: Fix ledge drop snapping up to ground Just reimplement `act_air_hit_wall` ourselves. * Extended Moveset: Add Kaze's walking speed fix * smlua_hooks.c: Restore option to use old API for hook_mario_action The intent is to allow mods outside of this repo to continue working. Co-authored-by: djoslin0 <djoslin0@users.noreply.github.com>
This commit is contained in:
parent
5e5ef35118
commit
d87dd73db1
18 changed files with 574 additions and 149 deletions
|
@ -71,9 +71,9 @@ function hook_event(hookEventType, func)
|
|||
end
|
||||
|
||||
--- @param actionId integer
|
||||
--- @param func fun(m:MarioState):integer
|
||||
--- @param funcOrFuncTable fun(m:MarioState):integer | table(fun(m:MarioState):integer)
|
||||
--- @param interactionType InteractionFlag
|
||||
function hook_mario_action(actionId, func, interactionType)
|
||||
function hook_mario_action(actionId, funcOrFuncTable, interactionType)
|
||||
-- ...
|
||||
end
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
- [enum SeqId](#enum-SeqId)
|
||||
- [sm64.h](#sm64h)
|
||||
- [smlua_hooks.h](#smlua_hooksh)
|
||||
- [enum LuaActionHookType](#enum-LuaActionHookType)
|
||||
- [enum LuaHookedEventType](#enum-LuaHookedEventType)
|
||||
- [smlua_misc_utils.h](#smlua_misc_utilsh)
|
||||
- [enum HudDisplayFlags](#enum-HudDisplayFlags)
|
||||
|
@ -2766,6 +2767,13 @@
|
|||
|
||||
## [smlua_hooks.h](#smlua_hooks.h)
|
||||
|
||||
### [enum LuaActionHookType](#LuaActionHookType)
|
||||
| Identifier | Value |
|
||||
| :--------- | :---- |
|
||||
| ACTION_HOOK_EVERY_FRAME | 0 |
|
||||
| ACTION_HOOK_GRAVITY | 1 |
|
||||
| ACTION_HOOK_MAX | 2 |
|
||||
|
||||
### [enum LuaHookedEventType](#LuaHookedEventType)
|
||||
| Identifier | Value |
|
||||
| :--------- | :---- |
|
||||
|
|
|
@ -141,9 +141,16 @@ hook_event(HOOK_MARIO_UPDATE, mario_update)
|
|||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| action_id | `integer` |
|
||||
| func | `Lua Function` ([MarioState](structs.md#MarioState) m) |
|
||||
| func | Table with entries for [Action Hook Types](#action-hook-types) of `Lua Function` ([MarioState](structs.md#MarioState) m) |
|
||||
| interaction_type | [enum InteractionFlag](constants.md#enum-InteractionFlag) <optional> |
|
||||
|
||||
#### [Action Hook Types](#action-hook-types)
|
||||
|
||||
| Type | Description | Returns |
|
||||
| :--- | :---------- | :------ |
|
||||
| every_frame | Main action code, called once per frame | `true` if action cancelled, else `false` |
|
||||
| gravity | Called inside `apply_gravity` when in action | Unused |
|
||||
|
||||
### Lua Example
|
||||
|
||||
```lua
|
||||
|
@ -183,12 +190,17 @@ function act_wall_slide(m)
|
|||
return set_mario_action(m, ACT_FREEFALL, 0)
|
||||
end
|
||||
|
||||
-- gravity
|
||||
m.vel.y = m.vel.y + 2
|
||||
|
||||
return 0
|
||||
end
|
||||
|
||||
function act_wall_slide_gravity(m)
|
||||
m.vel.y = m.vel.y - 2
|
||||
|
||||
if m.vel.y < -15 then
|
||||
m.vel.y = -15
|
||||
end
|
||||
end
|
||||
|
||||
function mario_on_set_action(m)
|
||||
-- wall slide
|
||||
if m.action == ACT_SOFT_BONK then
|
||||
|
@ -198,7 +210,7 @@ function mario_on_set_action(m)
|
|||
end
|
||||
|
||||
hook_event(HOOK_ON_SET_MARIO_ACTION, mario_on_set_action)
|
||||
hook_mario_action(ACT_WALL_SLIDE, act_wall_slide)
|
||||
hook_mario_action(ACT_WALL_SLIDE, { every_frame = act_wall_slide, gravity = act_wall_slide_gravity } )
|
||||
```
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
|
|
@ -36,8 +36,8 @@ end
|
|||
-- luigi --
|
||||
-----------
|
||||
|
||||
ACT_SPIN_POUND_LAND = allocate_mario_action(ACT_FLAG_STATIONARY | ACT_FLAG_ATTACKING)
|
||||
ACT_SPIN_POUND = allocate_mario_action(ACT_FLAG_AIR | ACT_FLAG_ATTACKING)
|
||||
ACT_SPIN_POUND_LAND = allocate_mario_action(ACT_GROUP_STATIONARY | ACT_FLAG_STATIONARY | ACT_FLAG_ATTACKING)
|
||||
ACT_SPIN_POUND = allocate_mario_action(ACT_GROUP_AIRBORNE | ACT_FLAG_AIR | ACT_FLAG_ATTACKING)
|
||||
|
||||
function act_spin_pound(m)
|
||||
local e = gStateExtras[m.playerIndex]
|
||||
|
@ -360,7 +360,7 @@ gEventTable[CT_TOAD] = {
|
|||
-- waluigi --
|
||||
-------------
|
||||
|
||||
ACT_WALL_SLIDE = allocate_mario_action(ACT_FLAG_AIR | ACT_FLAG_MOVING | ACT_FLAG_ALLOW_VERTICAL_WIND_ACTION)
|
||||
ACT_WALL_SLIDE = allocate_mario_action(ACT_GROUP_AIRBORNE | ACT_FLAG_AIR | ACT_FLAG_MOVING | ACT_FLAG_ALLOW_VERTICAL_WIND_ACTION)
|
||||
|
||||
function act_wall_slide(m)
|
||||
if (m.input & INPUT_A_PRESSED) ~= 0 then
|
||||
|
@ -482,10 +482,10 @@ gEventTable[CT_WALUIGI] = {
|
|||
-- wario --
|
||||
-----------
|
||||
|
||||
ACT_WARIO_DASH = allocate_mario_action(ACT_FLAG_MOVING | ACT_FLAG_ATTACKING)
|
||||
ACT_WARIO_AIR_DASH = allocate_mario_action(ACT_FLAG_AIR | ACT_FLAG_ATTACKING)
|
||||
ACT_CORKSCREW_CONK = allocate_mario_action(ACT_FLAG_AIR | ACT_FLAG_ATTACKING | ACT_FLAG_ALLOW_VERTICAL_WIND_ACTION)
|
||||
ACT_WARIO_SPINNING_OBJ = allocate_mario_action(ACT_FLAG_STATIONARY)
|
||||
ACT_WARIO_DASH = allocate_mario_action(ACT_GROUP_MOVING | ACT_FLAG_MOVING | ACT_FLAG_ATTACKING)
|
||||
ACT_WARIO_AIR_DASH = allocate_mario_action(ACT_GROUP_AIRBORNE | ACT_FLAG_AIR | ACT_FLAG_ATTACKING)
|
||||
ACT_CORKSCREW_CONK = allocate_mario_action(ACT_GROUP_AIRBORNE | ACT_FLAG_AIR | ACT_FLAG_ATTACKING | ACT_FLAG_ALLOW_VERTICAL_WIND_ACTION)
|
||||
ACT_WARIO_SPINNING_OBJ = allocate_mario_action(ACT_GROUP_OBJECT | ACT_FLAG_STATIONARY)
|
||||
|
||||
function act_corkscrew_conk(m)
|
||||
local e = gStateExtras[m.playerIndex]
|
||||
|
@ -1009,10 +1009,10 @@ hook_event(HOOK_MARIO_UPDATE, mario_update)
|
|||
hook_event(HOOK_ON_SET_MARIO_ACTION, mario_on_set_action)
|
||||
hook_event(HOOK_BEFORE_PHYS_STEP, mario_before_phys_step)
|
||||
|
||||
hook_mario_action(ACT_WALL_SLIDE, act_wall_slide)
|
||||
hook_mario_action(ACT_SPIN_POUND, act_spin_pound, INT_GROUND_POUND_OR_TWIRL)
|
||||
hook_mario_action(ACT_SPIN_POUND_LAND, act_spin_pound_land, INT_GROUND_POUND_OR_TWIRL)
|
||||
hook_mario_action(ACT_WARIO_DASH, act_wario_dash, INT_PUNCH)
|
||||
hook_mario_action(ACT_WARIO_AIR_DASH, act_wario_air_dash, INT_PUNCH)
|
||||
hook_mario_action(ACT_CORKSCREW_CONK, act_corkscrew_conk, INT_FAST_ATTACK_OR_SHELL)
|
||||
hook_mario_action(ACT_WARIO_SPINNING_OBJ, act_wario_spinning_obj)
|
||||
hook_mario_action(ACT_WALL_SLIDE, { every_frame = act_wall_slide })
|
||||
hook_mario_action(ACT_SPIN_POUND, { every_frame = act_spin_pound }, INT_GROUND_POUND_OR_TWIRL)
|
||||
hook_mario_action(ACT_SPIN_POUND_LAND, { every_frame = act_spin_pound_land }, INT_GROUND_POUND_OR_TWIRL)
|
||||
hook_mario_action(ACT_WARIO_DASH, { every_frame = act_wario_dash }, INT_PUNCH)
|
||||
hook_mario_action(ACT_WARIO_AIR_DASH, { every_frame = act_wario_air_dash }, INT_PUNCH)
|
||||
hook_mario_action(ACT_CORKSCREW_CONK, { every_frame = act_corkscrew_conk }, INT_FAST_ATTACK_OR_SHELL)
|
||||
hook_mario_action(ACT_WARIO_SPINNING_OBJ, { every_frame = act_wario_spinning_obj })
|
||||
|
|
|
@ -6,18 +6,18 @@
|
|||
-- initialize actions --
|
||||
------------------------
|
||||
|
||||
ACT_SPIN_POUND_LAND = allocate_mario_action(ACT_FLAG_STATIONARY | ACT_FLAG_ATTACKING)
|
||||
ACT_ROLL = allocate_mario_action(ACT_FLAG_MOVING | ACT_FLAG_BUTT_OR_STOMACH_SLIDE)
|
||||
ACT_GROUND_POUND_JUMP = allocate_mario_action(ACT_FLAG_AIR | ACT_FLAG_ALLOW_VERTICAL_WIND_ACTION)
|
||||
ACT_SPIN_JUMP = allocate_mario_action(ACT_FLAG_AIR | ACT_FLAG_ALLOW_VERTICAL_WIND_ACTION)
|
||||
ACT_SPIN_POUND = allocate_mario_action(ACT_FLAG_AIR | ACT_FLAG_ATTACKING)
|
||||
ACT_LEDGE_PARKOUR = allocate_mario_action(ACT_FLAG_AIR)
|
||||
ACT_ROLL_AIR = allocate_mario_action(ACT_FLAG_AIR | ACT_FLAG_ALLOW_VERTICAL_WIND_ACTION)
|
||||
ACT_WALL_SLIDE = allocate_mario_action(ACT_FLAG_AIR | ACT_FLAG_MOVING | ACT_FLAG_ALLOW_VERTICAL_WIND_ACTION)
|
||||
ACT_WATER_GROUND_POUND = allocate_mario_action(ACT_FLAG_MOVING | ACT_FLAG_SWIMMING | ACT_FLAG_SWIMMING_OR_FLYING | ACT_FLAG_WATER_OR_TEXT | ACT_FLAG_ATTACKING)
|
||||
ACT_WATER_GROUND_POUND_LAND = allocate_mario_action(ACT_FLAG_STATIONARY | ACT_FLAG_SWIMMING | ACT_FLAG_SWIMMING_OR_FLYING | ACT_FLAG_WATER_OR_TEXT)
|
||||
ACT_WATER_GROUND_POUND_STROKE = allocate_mario_action(ACT_FLAG_MOVING | ACT_FLAG_SWIMMING | ACT_FLAG_SWIMMING_OR_FLYING | ACT_FLAG_WATER_OR_TEXT)
|
||||
ACT_WATER_GROUND_POUND_JUMP = allocate_mario_action(ACT_FLAG_MOVING | ACT_FLAG_SWIMMING | ACT_FLAG_SWIMMING_OR_FLYING | ACT_FLAG_WATER_OR_TEXT)
|
||||
ACT_SPIN_POUND_LAND = allocate_mario_action(ACT_GROUP_STATIONARY | ACT_FLAG_STATIONARY | ACT_FLAG_ATTACKING)
|
||||
ACT_ROLL = allocate_mario_action(ACT_GROUP_MOVING | ACT_FLAG_MOVING | ACT_FLAG_BUTT_OR_STOMACH_SLIDE)
|
||||
ACT_GROUND_POUND_JUMP = allocate_mario_action(ACT_GROUP_AIRBORNE | ACT_FLAG_AIR | ACT_FLAG_ALLOW_VERTICAL_WIND_ACTION)
|
||||
ACT_SPIN_JUMP = allocate_mario_action(ACT_GROUP_AIRBORNE | ACT_FLAG_AIR | ACT_FLAG_ALLOW_VERTICAL_WIND_ACTION)
|
||||
ACT_SPIN_POUND = allocate_mario_action(ACT_GROUP_AIRBORNE | ACT_FLAG_AIR | ACT_FLAG_ATTACKING)
|
||||
ACT_LEDGE_PARKOUR = allocate_mario_action(ACT_GROUP_AIRBORNE | ACT_FLAG_AIR)
|
||||
ACT_ROLL_AIR = allocate_mario_action(ACT_GROUP_AIRBORNE | ACT_FLAG_AIR | ACT_FLAG_ALLOW_VERTICAL_WIND_ACTION)
|
||||
ACT_WALL_SLIDE = allocate_mario_action(ACT_GROUP_AIRBORNE | ACT_FLAG_AIR | ACT_FLAG_MOVING | ACT_FLAG_ALLOW_VERTICAL_WIND_ACTION)
|
||||
ACT_WATER_GROUND_POUND = allocate_mario_action(ACT_GROUP_SUBMERGED | ACT_FLAG_MOVING | ACT_FLAG_SWIMMING | ACT_FLAG_SWIMMING_OR_FLYING | ACT_FLAG_WATER_OR_TEXT | ACT_FLAG_ATTACKING)
|
||||
ACT_WATER_GROUND_POUND_LAND = allocate_mario_action(ACT_GROUP_SUBMERGED | ACT_FLAG_STATIONARY | ACT_FLAG_SWIMMING | ACT_FLAG_SWIMMING_OR_FLYING | ACT_FLAG_WATER_OR_TEXT)
|
||||
ACT_WATER_GROUND_POUND_STROKE = allocate_mario_action(ACT_GROUP_SUBMERGED | ACT_FLAG_MOVING | ACT_FLAG_SWIMMING | ACT_FLAG_SWIMMING_OR_FLYING | ACT_FLAG_WATER_OR_TEXT)
|
||||
ACT_WATER_GROUND_POUND_JUMP = allocate_mario_action(ACT_GROUP_SUBMERGED | ACT_FLAG_MOVING | ACT_FLAG_SWIMMING | ACT_FLAG_SWIMMING_OR_FLYING | ACT_FLAG_WATER_OR_TEXT)
|
||||
|
||||
-----------------------------
|
||||
-- initialize extra fields --
|
||||
|
@ -57,6 +57,10 @@ for i=0,(MAX_PLAYERS-1) do
|
|||
e.savedWallSlide = false
|
||||
end
|
||||
|
||||
function limit_angle(a)
|
||||
return (a + 0x8000) % 0x10000 - 0x8000
|
||||
end
|
||||
|
||||
----------
|
||||
-- roll --
|
||||
----------
|
||||
|
@ -74,27 +78,19 @@ function update_roll_sliding_angle(m, accel, lossFactor)
|
|||
|
||||
m.slideYaw = atan2s(m.slideVelZ, m.slideVelX)
|
||||
|
||||
local facingDYaw = m.faceAngle.y - m.slideYaw
|
||||
local facingDYaw = limit_angle(m.faceAngle.y - m.slideYaw)
|
||||
local newFacingDYaw = facingDYaw
|
||||
|
||||
if newFacingDYaw > 0 and newFacingDYaw <= 0x4000 then
|
||||
newFacingDYaw = newFacingDYaw - 0x200
|
||||
if newFacingDYaw > 0 and newFacingDYaw <= 0x8000 then
|
||||
newFacingDYaw = newFacingDYaw - 0x800
|
||||
if newFacingDYaw < 0 then newFacingDYaw = 0 end
|
||||
|
||||
elseif newFacingDYaw >= -0x4000 and newFacingDYaw < 0 then
|
||||
newFacingDYaw = newFacingDYaw + 0x200
|
||||
elseif newFacingDYaw >= -0x8000 and newFacingDYaw < 0 then
|
||||
newFacingDYaw = newFacingDYaw + 0x800
|
||||
if newFacingDYaw > 0 then newFacingDYaw = 0 end
|
||||
|
||||
elseif newFacingDYaw > 0x4000 and newFacingDYaw < 0x8000 then
|
||||
newFacingDYaw = newFacingDYaw + 0x200
|
||||
if newFacingDYaw > 0x8000 then newFacingDYaw = 0x8000 end
|
||||
|
||||
elseif newFacingDYaw > -0x8000 and newFacingDYaw < -0x4000 then
|
||||
newFacingDYaw = newFacingDYaw - 0x200
|
||||
if newFacingDYaw < -0x8000 then newFacingDYaw = -0x8000 end
|
||||
end
|
||||
|
||||
m.faceAngle.y = m.slideYaw + newFacingDYaw
|
||||
m.faceAngle.y = limit_angle(m.slideYaw + newFacingDYaw)
|
||||
|
||||
m.vel.x = m.slideVelX
|
||||
m.vel.y = 0.0
|
||||
|
@ -109,15 +105,6 @@ function update_roll_sliding_angle(m, accel, lossFactor)
|
|||
m.slideVelX = m.slideVelX * 100.0 / m.forwardVel
|
||||
m.slideVelZ = m.slideVelZ * 100.0 / m.forwardVel
|
||||
end
|
||||
|
||||
if newFacingDYaw < -0x4000 or newFacingDYaw > 0x4000 then
|
||||
m.forwardVel = m.forwardVel * -1.0
|
||||
m.faceAngle.y = m.faceAngle.y + 0x4000
|
||||
end
|
||||
|
||||
-- HACK: instead of approaching slideYaw, just set faceAngle to it
|
||||
-- this is different than the original Extended Movement... just couldn't figure out the bug
|
||||
m.faceAngle.y = m.slideYaw
|
||||
end
|
||||
|
||||
function update_roll_sliding(m, stopSpeed)
|
||||
|
@ -196,7 +183,7 @@ function act_roll(m)
|
|||
return set_jumping_action(m, ACT_LONG_JUMP, 0)
|
||||
end
|
||||
|
||||
if (m.controller.buttonPressed & U_JPAD) ~= 0 and m.actionTimer > 0 then
|
||||
if (m.controller.buttonPressed & X_BUTTON) ~= 0 and m.actionTimer > 0 then
|
||||
m.vel.y = 19.0
|
||||
play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, 0)
|
||||
|
||||
|
@ -305,7 +292,7 @@ function update_roll(m)
|
|||
end
|
||||
|
||||
if m.action == ACT_CROUCHING then
|
||||
if (m.controller.buttonPressed & U_JPAD) ~= 0 then
|
||||
if (m.controller.buttonPressed & X_BUTTON) ~= 0 then
|
||||
m.vel.y = 19.0
|
||||
mario_set_forward_vel(m, 32.0)
|
||||
play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, 0)
|
||||
|
@ -317,7 +304,7 @@ function update_roll(m)
|
|||
end
|
||||
|
||||
if m.action == ACT_CROUCH_SLIDE then
|
||||
if (m.controller.buttonPressed & U_JPAD) ~= 0 then
|
||||
if (m.controller.buttonPressed & X_BUTTON) ~= 0 then
|
||||
m.vel.y = 19.0
|
||||
mario_set_forward_vel(m, math.max(32, m.forwardVel))
|
||||
play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, 0)
|
||||
|
@ -329,7 +316,7 @@ function update_roll(m)
|
|||
end
|
||||
|
||||
if m.action == ACT_GROUND_POUND_LAND then
|
||||
if (m.controller.buttonPressed & U_JPAD) ~= 0 then
|
||||
if (m.controller.buttonPressed & X_BUTTON) ~= 0 then
|
||||
mario_set_forward_vel(m, 60)
|
||||
|
||||
play_sound(SOUND_ACTION_SPIN, m.marioObj.header.gfx.cameraToObject)
|
||||
|
@ -358,7 +345,7 @@ function mario_update_spin_input(m)
|
|||
local signedOverflow = 0
|
||||
|
||||
if rawAngle < e.stickLastAngle then
|
||||
if (e.stickLastAngle - rawAngle) > 0x8000 then
|
||||
if e.stickLastAngle - rawAngle > 0x8000 then
|
||||
signedOverflow = 1
|
||||
end
|
||||
if signedOverflow ~= 0 then
|
||||
|
@ -367,7 +354,7 @@ function mario_update_spin_input(m)
|
|||
newDirection = -1
|
||||
end
|
||||
elseif rawAngle > e.stickLastAngle then
|
||||
if (rawAngle - e.stickLastAngle) > 0x8000 then
|
||||
if rawAngle - e.stickLastAngle > 0x8000 then
|
||||
signedOverflow = 1
|
||||
end
|
||||
if signedOverflow ~= 0 then
|
||||
|
@ -455,7 +442,7 @@ function act_spin_jump(m)
|
|||
if (m.input & INPUT_NONZERO_ANALOG) ~= 0 then
|
||||
m.faceAngle.y = m.intendedYaw
|
||||
else
|
||||
m.faceAngle.y = e.rotAngle
|
||||
m.faceAngle.y = limit_angle(e.rotAngle)
|
||||
end
|
||||
|
||||
return set_mario_action(m, ACT_SPIN_POUND, m.actionState)
|
||||
|
@ -466,21 +453,17 @@ function act_spin_jump(m)
|
|||
common_air_action_step(m, ACT_DOUBLE_JUMP_LAND, MARIO_ANIM_TWIRL,
|
||||
AIR_STEP_CHECK_HANG)
|
||||
|
||||
if (e.savedWallSlide == false) or (m.pos.y <= e.savedWallSlideHeight) then
|
||||
-- set facing direction
|
||||
-- not part of original Extended Moveset
|
||||
local yawDiff = m.faceAngle.y - m.intendedYaw
|
||||
e.rotAngle = e.rotAngle + yawDiff
|
||||
m.faceAngle.y = m.intendedYaw
|
||||
end
|
||||
|
||||
e.rotAngle = e.rotAngle + 0x2867
|
||||
if (e.rotAngle > 0x10000) then e.rotAngle = e.rotAngle - 0x10000 end
|
||||
if (e.rotAngle < -0x10000) then e.rotAngle = e.rotAngle + 0x10000 end
|
||||
m.marioObj.header.gfx.angle.y = m.marioObj.header.gfx.angle.y + (e.rotAngle * spinDirFactor)
|
||||
m.marioObj.header.gfx.angle.y = limit_angle(m.marioObj.header.gfx.angle.y + (e.rotAngle * spinDirFactor))
|
||||
|
||||
-- gravity
|
||||
m.vel.y = m.vel.y + 2
|
||||
m.actionTimer = m.actionTimer + 1
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function act_spin_jump_gravity(m)
|
||||
if (m.flags & MARIO_WING_CAP) ~= 0 and m.vel.y < 0.0 and (m.input & INPUT_A_DOWN) ~= 0 then
|
||||
m.marioBodyState.wingFlutter = 1
|
||||
m.vel.y = m.vel.y - 0.7
|
||||
|
@ -494,17 +477,15 @@ function act_spin_jump(m)
|
|||
if m.vel.y > 0 then
|
||||
m.vel.y = m.vel.y - 4
|
||||
else
|
||||
m.vel.y = m.vel.y + 1.4
|
||||
m.vel.y = m.vel.y - 1.4
|
||||
end
|
||||
|
||||
if m.vel.y < -75.0 then
|
||||
m.vel.y = -75.5
|
||||
m.vel.y = -75.0
|
||||
end
|
||||
end
|
||||
|
||||
m.actionTimer = m.actionTimer + 1
|
||||
|
||||
return false
|
||||
return 0
|
||||
end
|
||||
|
||||
function act_spin_pound(m)
|
||||
|
@ -552,13 +533,13 @@ function act_spin_pound(m)
|
|||
-- set facing direction
|
||||
-- not part of original Extended Moveset
|
||||
local yawDiff = m.faceAngle.y - m.intendedYaw
|
||||
e.rotAngle = e.rotAngle + yawDiff
|
||||
e.rotAngle = limit_angle(e.rotAngle + yawDiff)
|
||||
m.faceAngle.y = m.intendedYaw
|
||||
|
||||
e.rotAngle = e.rotAngle + 0x3053
|
||||
if e.rotAngle > 0x10000 then e.rotAngle = e.rotAngle - 0x10000 end
|
||||
if e.rotAngle < -0x10000 then e.rotAngle = e.rotAngle + 0x10000 end
|
||||
m.marioObj.header.gfx.angle.y = m.marioObj.header.gfx.angle.y + e.rotAngle * spinDirFactor
|
||||
m.marioObj.header.gfx.angle.y = limit_angle(m.marioObj.header.gfx.angle.y + e.rotAngle * spinDirFactor)
|
||||
|
||||
m.actionTimer = m.actionTimer + 1
|
||||
|
||||
|
@ -586,7 +567,7 @@ function act_spin_pound_land(m)
|
|||
return set_jumping_action(m, ACT_GROUND_POUND_JUMP, 0)
|
||||
end
|
||||
|
||||
if (m.controller.buttonPressed & U_JPAD) ~= 0 then
|
||||
if (m.controller.buttonPressed & X_BUTTON) ~= 0 then
|
||||
mario_set_forward_vel(m, 60)
|
||||
|
||||
play_sound(SOUND_ACTION_SPIN, m.marioObj.header.gfx.cameraToObject)
|
||||
|
@ -623,7 +604,7 @@ function act_wall_slide(m)
|
|||
|
||||
if (m.input & INPUT_A_PRESSED) ~= 0 then
|
||||
m.vel.y = 52.0
|
||||
-- m.faceAngle.y = m.faceAngle.y + 0x8000
|
||||
-- m.faceAngle.y = limit_angle(m.faceAngle.y + 0x8000)
|
||||
return set_mario_action(m, ACT_WALL_KICK_AIR, 0)
|
||||
end
|
||||
|
||||
|
@ -648,12 +629,50 @@ function act_wall_slide(m)
|
|||
return set_mario_action(m, ACT_FREEFALL, 0)
|
||||
end
|
||||
|
||||
-- gravity
|
||||
m.vel.y = m.vel.y + 2
|
||||
|
||||
return 0
|
||||
end
|
||||
|
||||
function act_wall_slide_gravity(m)
|
||||
m.vel.y = m.vel.y - 2
|
||||
|
||||
if m.vel.y < -15 then
|
||||
m.vel.y = -15
|
||||
end
|
||||
end
|
||||
|
||||
function act_air_hit_wall(m)
|
||||
if m.heldObj ~= 0 then
|
||||
mario_drop_held_object(m)
|
||||
end
|
||||
|
||||
m.actionTimer = m.actionTimer + 1
|
||||
if m.actionTimer <= 1 and (m.input & INPUT_A_PRESSED) ~= 0 then
|
||||
m.vel.y = 52.0
|
||||
m.faceAngle.y = limit_angle(m.faceAngle.y + 0x8000)
|
||||
return set_mario_action(m, ACT_WALL_KICK_AIR, 0)
|
||||
elseif m.forwardVel >= 38.0 then
|
||||
m.wallKickTimer = 5
|
||||
if m.vel.y > 0.0 then
|
||||
m.vel.y = 0.0
|
||||
end
|
||||
|
||||
m.particleFlags = m.particleFlags | PARTICLE_VERTICAL_STAR
|
||||
return set_mario_action(m, ACT_BACKWARD_AIR_KB, 0)
|
||||
else
|
||||
m.faceAngle.y = limit_angle(m.faceAngle.y + 0x8000)
|
||||
return set_mario_action(m, ACT_WALL_SLIDE, 0)
|
||||
end
|
||||
|
||||
--! Missing return statement (in original C code). The returned value is the result of the call
|
||||
-- to set_mario_animation. In practice, this value is nonzero.
|
||||
-- This results in this action "cancelling" into itself. It is supposed to
|
||||
-- execute three times, each on a separate frame, but instead it executes
|
||||
-- three times on the same frame.
|
||||
-- This results in firsties only being possible for a single frame, instead
|
||||
-- of three.
|
||||
return set_mario_animation(m, MARIO_ANIM_START_WALLKICK)
|
||||
end
|
||||
|
||||
------------------------
|
||||
-- water ground pound --
|
||||
------------------------
|
||||
|
@ -875,7 +894,7 @@ function act_water_ground_pound_jump(m)
|
|||
set_swimming_at_surface_particles(m, PARTICLE_WAVE_TRAIL)
|
||||
|
||||
e.rotAngle = e.rotAngle + (0x10000*1.0 - e.rotAngle) / 5.0
|
||||
m.marioObj.header.gfx.angle.y = m.marioObj.header.gfx.angle.y - e.rotAngle
|
||||
m.marioObj.header.gfx.angle.y = limit_angle(m.marioObj.header.gfx.angle.y - e.rotAngle)
|
||||
|
||||
return 0
|
||||
end
|
||||
|
@ -965,6 +984,338 @@ function act_ground_pound_jump(m)
|
|||
return 0
|
||||
end
|
||||
|
||||
-------------------------------------
|
||||
-- dive slide patched for dive hop --
|
||||
-------------------------------------
|
||||
|
||||
function act_dive_slide(m)
|
||||
if (m.input & INPUT_ABOVE_SLIDE) == 0 and (m.input & INPUT_A_PRESSED) ~= 0 then
|
||||
queue_rumble_data_mario(m, 5, 80)
|
||||
if m.forwardVel > 0 then
|
||||
return set_mario_action(m, ACT_FORWARD_ROLLOUT, 0)
|
||||
else
|
||||
return set_mario_action(m, ACT_BACKWARD_ROLLOUT, 0)
|
||||
end
|
||||
end
|
||||
|
||||
if (m.input & INPUT_ABOVE_SLIDE) == 0 then
|
||||
if (m.input & INPUT_B_PRESSED) ~= 0 then
|
||||
-- dive hop
|
||||
m.vel.y = 21.0
|
||||
return set_mario_action(m, ACT_DIVE, 1)
|
||||
end
|
||||
end
|
||||
|
||||
play_mario_landing_sound_once(m, SOUND_ACTION_TERRAIN_BODY_HIT_GROUND)
|
||||
|
||||
--! If the dive slide ends on the same frame that we pick up on object,
|
||||
-- Mario will not be in the dive slide action for the call to
|
||||
-- mario_check_object_grab, and so will end up in the regular picking action,
|
||||
-- rather than the picking up after dive action.
|
||||
|
||||
if update_sliding(m, 8.0) ~= 0 and is_anim_at_end(m) ~= 0 then
|
||||
mario_set_forward_vel(m, 0.0)
|
||||
set_mario_action(m, ACT_STOMACH_SLIDE_STOP, 0)
|
||||
end
|
||||
|
||||
if mario_check_object_grab(m) ~= 0 then
|
||||
mario_grab_used_object(m)
|
||||
if m.heldObj ~= 0 then
|
||||
m.marioBodyState.grabPos = GRAB_POS_LIGHT_OBJ
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
common_slide_action(m, ACT_STOMACH_SLIDE_STOP, ACT_FREEFALL, MARIO_ANIM_DIVE)
|
||||
return false
|
||||
end
|
||||
|
||||
-------------------------------------------------------
|
||||
-- Patched actions using update_walking_speed action --
|
||||
-- for Tight Controls and modfied speed caps --
|
||||
-------------------------------------------------------
|
||||
|
||||
function update_walking_speed_extended(m)
|
||||
local maxTargetSpeed = 0
|
||||
local targetSpeed = 0
|
||||
local firmSpeedCap = 0
|
||||
local hardSpeedCap = 105.0
|
||||
|
||||
if m.prevAction == ACT_ROLL then
|
||||
firmSpeedCap = 60.0
|
||||
else
|
||||
firmSpeedCap = 48.0
|
||||
end
|
||||
|
||||
if m.floor ~= 0 and m.floor.type == SURFACE_SLOW then
|
||||
maxTargetSpeed = 24.0
|
||||
else
|
||||
maxTargetSpeed = 32.0
|
||||
end
|
||||
|
||||
if m.intendedMag < maxTargetSpeed then
|
||||
targetSpeed = m.intendedMag
|
||||
else
|
||||
targetSpeed = maxTargetSpeed
|
||||
end
|
||||
|
||||
if m.quicksandDepth > 10.0 then
|
||||
targetSpeed = targetSpeed * (6.25 / m.quicksandDepth)
|
||||
end
|
||||
|
||||
if m.forwardVel <= 8.0 then
|
||||
m.forwardVel = math.min(m.intendedMag, 8.0) -- Same fix as Melee dashback (by Kaze)
|
||||
end
|
||||
|
||||
-- instead of a hard walk speed cap, going over this new firm speed cap makes you slow down to it twice as fast
|
||||
local decayFactor = 0
|
||||
if m.forwardVel > firmSpeedCap then
|
||||
decayFactor = 2.0
|
||||
else
|
||||
decayFactor = 1.0
|
||||
end
|
||||
|
||||
if m.forwardVel <= 0.0 then
|
||||
m.forwardVel = m.forwardVel + 1.1
|
||||
elseif m.forwardVel <= targetSpeed then
|
||||
m.forwardVel = m.forwardVel + (1.1 - m.forwardVel / 43.0)
|
||||
elseif m.floor ~= 0 and m.floor.normal.y >= 0.95 then
|
||||
m.forwardVel = m.forwardVel - decayFactor
|
||||
else
|
||||
-- reintroduce the old hardcap for the weird slopes where you kind of just maintain your speed
|
||||
if (m.forwardVel > firmSpeedCap) then
|
||||
m.forwardVel = firmSpeedCap;
|
||||
end
|
||||
end
|
||||
|
||||
if m.forwardVel > hardSpeedCap then
|
||||
m.forwardVel = hardSpeedCap
|
||||
end
|
||||
|
||||
if analog_stick_held_back(m) ~= 0 then
|
||||
m.faceAngle.y = m.intendedYaw;
|
||||
|
||||
if m.forwardVel < 0 then
|
||||
mario_set_forward_vel(m, -m.forwardVel);
|
||||
end
|
||||
else
|
||||
m.faceAngle.y = m.intendedYaw - approach_s32(limit_angle(m.intendedYaw - m.faceAngle.y), 0, 0xC00, 0xC00);
|
||||
end
|
||||
|
||||
apply_slope_accel(m)
|
||||
end
|
||||
|
||||
function act_walking(m)
|
||||
local startPos = m.pos
|
||||
local startYaw = m.faceAngle.y
|
||||
|
||||
mario_drop_held_object(m)
|
||||
|
||||
if should_begin_sliding(m) ~= 0 then
|
||||
return set_mario_action(m, ACT_BEGIN_SLIDING, 0)
|
||||
end
|
||||
|
||||
if (m.input & INPUT_FIRST_PERSON) ~= 0 then
|
||||
return begin_braking_action(m)
|
||||
end
|
||||
|
||||
if (m.input & INPUT_A_PRESSED) ~= 0 then
|
||||
return set_jump_from_landing(m)
|
||||
end
|
||||
|
||||
if check_ground_dive_or_punch(m) ~= 0 then
|
||||
return true
|
||||
end
|
||||
|
||||
if (m.input & INPUT_ZERO_MOVEMENT) ~= 0 then
|
||||
return begin_braking_action(m)
|
||||
end
|
||||
|
||||
if analog_stick_held_back(m) ~= 0 and m.forwardVel >= 12.0 then
|
||||
return set_mario_action(m, ACT_TURNING_AROUND, 0)
|
||||
end
|
||||
|
||||
if (m.input & INPUT_Z_PRESSED) ~= 0 then
|
||||
return set_mario_action(m, ACT_CROUCH_SLIDE, 0)
|
||||
end
|
||||
|
||||
m.actionState = 0
|
||||
|
||||
vec3f_copy(startPos, m.pos)
|
||||
update_walking_speed_extended(m)
|
||||
|
||||
local stepResult = perform_ground_step(m)
|
||||
if stepResult == GROUND_STEP_LEFT_GROUND then
|
||||
set_mario_action(m, ACT_FREEFALL, 0)
|
||||
set_mario_animation(m, MARIO_ANIM_GENERAL_FALL)
|
||||
elseif stepResult == GROUND_STEP_NONE then
|
||||
anim_and_audio_for_walk(m)
|
||||
if (m.intendedMag - m.forwardVel > 16.0) then
|
||||
m.particleFlags = m.particleFlags | PARTICLE_DUST
|
||||
end
|
||||
elseif stepResult == GROUND_STEP_HIT_WALL then
|
||||
push_or_sidle_wall(m, startPos)
|
||||
m.actionTimer = 0
|
||||
end
|
||||
|
||||
check_ledge_climb_down(m)
|
||||
tilt_body_walking(m, startYaw)
|
||||
return false
|
||||
end
|
||||
|
||||
function act_hold_walking(m)
|
||||
if m.heldObj.behavior == bhvJumpingBox then
|
||||
return set_mario_action(m, ACT_CRAZY_BOX_BOUNCE, 0)
|
||||
end
|
||||
|
||||
if (m.marioObj.oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) ~= 0 then
|
||||
return drop_and_set_mario_action(m, ACT_WALKING, 0)
|
||||
end
|
||||
|
||||
if should_begin_sliding(m) ~= 0 then
|
||||
return set_mario_action(m, ACT_HOLD_BEGIN_SLIDING, 0)
|
||||
end
|
||||
|
||||
if (m.input & INPUT_B_PRESSED) ~= 0 then
|
||||
return set_mario_action(m, ACT_THROWING, 0)
|
||||
end
|
||||
|
||||
if (m.input & INPUT_A_PRESSED) ~= 0 then
|
||||
return set_jumping_action(m, ACT_HOLD_JUMP, 0)
|
||||
end
|
||||
|
||||
if (m.input & INPUT_ZERO_MOVEMENT) ~= 0 then
|
||||
return set_mario_action(m, ACT_HOLD_DECELERATING, 0)
|
||||
end
|
||||
|
||||
if (m.input & INPUT_Z_PRESSED) ~= 0 then
|
||||
return drop_and_set_mario_action(m, ACT_CROUCH_SLIDE, 0)
|
||||
end
|
||||
|
||||
m.intendedMag = m.intendedMag * 0.4
|
||||
|
||||
update_walking_speed_extended(m)
|
||||
|
||||
local stepResult = perform_ground_step(m)
|
||||
if stepResult == GROUND_STEP_LEFT_GROUND then
|
||||
set_mario_action(m, ACT_HOLD_FREEFALL, 0)
|
||||
elseif stepResult == GROUND_STEP_HIT_WALL then
|
||||
if m.forwardVel > 16.0 then
|
||||
mario_set_forward_vel(m, 16.0)
|
||||
end
|
||||
end
|
||||
|
||||
anim_and_audio_for_hold_walk(m)
|
||||
|
||||
if 0.4 * m.intendedMag - m.forwardVel > 10.0 then
|
||||
m.particleFlags = m.particleFlags | PARTICLE_DUST
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function act_hold_heavy_walking(m)
|
||||
if (m.input & INPUT_B_PRESSED) ~= 0 then
|
||||
return set_mario_action(m, ACT_HEAVY_THROW, 0)
|
||||
end
|
||||
|
||||
if should_begin_sliding(m) ~= 0 then
|
||||
return drop_and_set_mario_action(m, ACT_BEGIN_SLIDING, 0)
|
||||
end
|
||||
|
||||
if (m.input & INPUT_ZERO_MOVEMENT) ~= 0 then
|
||||
return set_mario_action(m, ACT_HOLD_HEAVY_IDLE, 0)
|
||||
end
|
||||
|
||||
m.intendedMag = m.intendedMag * 0.1
|
||||
|
||||
update_walking_speed_extended(m)
|
||||
|
||||
local stepResult = perform_ground_step(m)
|
||||
if stepResult == GROUND_STEP_LEFT_GROUND then
|
||||
drop_and_set_mario_action(m, ACT_FREEFALL, 0)
|
||||
elseif stepResult == GROUND_STEP_HIT_WALL then
|
||||
if (m.forwardVel > 10.0) then
|
||||
mario_set_forward_vel(m, 10.0)
|
||||
end
|
||||
end
|
||||
|
||||
anim_and_audio_for_heavy_walk(m)
|
||||
return false
|
||||
end
|
||||
|
||||
function act_finish_turning_around(m)
|
||||
if (m.input & INPUT_ABOVE_SLIDE) ~= 0 then
|
||||
return set_mario_action(m, ACT_BEGIN_SLIDING, 0)
|
||||
end
|
||||
|
||||
if (m.input & INPUT_A_PRESSED) ~= 0 then
|
||||
return set_jumping_action(m, ACT_SIDE_FLIP, 0)
|
||||
end
|
||||
|
||||
update_walking_speed_extended(m)
|
||||
set_mario_animation(m, MARIO_ANIM_TURNING_PART2)
|
||||
|
||||
if perform_ground_step(m) == GROUND_STEP_LEFT_GROUND then
|
||||
set_mario_action(m, ACT_FREEFALL, 0)
|
||||
end
|
||||
|
||||
if is_anim_at_end(m) ~= 0 then
|
||||
set_mario_action(m, ACT_WALKING, 0)
|
||||
end
|
||||
|
||||
m.marioObj.header.gfx.angle.y = limit_angle(m.marioObj.header.gfx.angle.y + 0x8000)
|
||||
return false
|
||||
end
|
||||
|
||||
function act_crawling(m)
|
||||
if should_begin_sliding(m) ~= 0 then
|
||||
return set_mario_action(m, ACT_BEGIN_SLIDING, 0)
|
||||
end
|
||||
|
||||
if (m.input & INPUT_FIRST_PERSON) ~= 0 then
|
||||
return set_mario_action(m, ACT_STOP_CRAWLING, 0)
|
||||
end
|
||||
|
||||
if (m.input & INPUT_A_PRESSED) ~= 0 then
|
||||
return set_jumping_action(m, ACT_JUMP, 0)
|
||||
end
|
||||
|
||||
if check_ground_dive_or_punch(m) ~= 0 then
|
||||
return true
|
||||
end
|
||||
|
||||
if (m.input & INPUT_ZERO_MOVEMENT) ~= 0 then
|
||||
return set_mario_action(m, ACT_STOP_CRAWLING, 0)
|
||||
end
|
||||
|
||||
if (m.input & INPUT_Z_DOWN) == 0 then
|
||||
return set_mario_action(m, ACT_STOP_CRAWLING, 0)
|
||||
end
|
||||
|
||||
m.intendedMag = m.intendedMag * 0.1
|
||||
|
||||
update_walking_speed_extended(m)
|
||||
|
||||
local stepResult = perform_ground_step(m)
|
||||
if stepResult == GROUND_STEP_LEFT_GROUND then
|
||||
set_mario_action(m, ACT_FREEFALL, 0)
|
||||
elseif stepResult == GROUND_STEP_HIT_WALL then
|
||||
if m.forwardVel > 10.0 then
|
||||
mario_set_forward_vel(m, 10.0)
|
||||
end
|
||||
--! Possibly unintended missing break
|
||||
align_with_floor(m)
|
||||
elseif stepResult == GROUND_STEP_NONE then
|
||||
align_with_floor(m)
|
||||
end
|
||||
|
||||
local val04 = (m.intendedMag * 2.0 * 0x10000)
|
||||
set_mario_anim_with_accel(m, MARIO_ANIM_CRAWLING, val04)
|
||||
play_step_sound(m, 26, 79)
|
||||
return false
|
||||
end
|
||||
|
||||
---------------------------------------------------------
|
||||
|
||||
function mario_on_set_action(m)
|
||||
|
@ -974,30 +1325,26 @@ function mario_on_set_action(m)
|
|||
e.savedWallSlide = false
|
||||
end
|
||||
|
||||
if e.spinInput ~= 0 then
|
||||
if m.action == ACT_JUMP or m.action == ACT_DOUBLE_JUMP or m.action == ACT_TRIPLE_JUMP or m.action == ACT_SPECIAL_TRIPLE_JUMP or m.action == ACT_SIDE_FLIP or m.action == ACT_BACKFLIP or m.action == ACT_WALL_KICK_AIR then
|
||||
if e.spinInput ~= 0 and (m.input & INPUT_ABOVE_SLIDE) == 0 then
|
||||
if m.action == ACT_JUMP or
|
||||
m.action == ACT_DOUBLE_JUMP or
|
||||
m.action == ACT_TRIPLE_JUMP or
|
||||
m.action == ACT_SPECIAL_TRIPLE_JUMP or
|
||||
m.action == ACT_SIDE_FLIP or
|
||||
m.action == ACT_BACKFLIP then
|
||||
set_mario_action(m, ACT_SPIN_JUMP, 1)
|
||||
m.vel.y = 65.0
|
||||
m.faceAngle.y = m.intendedYaw
|
||||
end
|
||||
end
|
||||
|
||||
if m.action == ACT_GROUND_POUND_JUMP then
|
||||
m.vel.y = 65.0
|
||||
elseif m.action == ACT_SOFT_BONK then
|
||||
m.faceAngle.y = m.faceAngle.y + 0x8000
|
||||
m.pos.x = e.lastPos.x
|
||||
m.pos.y = e.lastPos.y
|
||||
m.pos.z = e.lastPos.z
|
||||
set_mario_action(m, ACT_WALL_SLIDE, 0)
|
||||
m.vel.x = 0
|
||||
m.vel.y = 0
|
||||
m.vel.z = 0
|
||||
elseif m.action == ACT_WATER_PLUNGE and m.prevAction == ACT_GROUND_POUND then
|
||||
if m.action == ACT_WATER_PLUNGE and m.prevAction == ACT_GROUND_POUND then
|
||||
return set_mario_action(m, ACT_WATER_GROUND_POUND, 1)
|
||||
elseif m.action == ACT_WALL_SLIDE then
|
||||
m.vel.y = 0.0
|
||||
elseif m.action == ACT_GROUND_POUND and m.prevAction == ACT_SIDE_FLIP then
|
||||
-- correct animation
|
||||
m.marioObj.header.gfx.angle.y = m.marioObj.header.gfx.angle.y - 0x8000
|
||||
m.marioObj.header.gfx.angle.y = limit_angle(m.marioObj.header.gfx.angle.y - 0x8000)
|
||||
elseif m.action == ACT_LEDGE_GRAB then
|
||||
e.rotAngle = m.forwardVel
|
||||
end
|
||||
|
@ -1034,15 +1381,6 @@ function mario_update(m)
|
|||
mario_update_spin_input(m)
|
||||
update_roll(m)
|
||||
|
||||
-- dive hop
|
||||
if (m.input & INPUT_B_PRESSED) ~= 0 and (m.input & INPUT_ABOVE_SLIDE) == 0 then
|
||||
if m.action == ACT_FORWARD_ROLLOUT and m.prevAction == ACT_DIVE_SLIDE then
|
||||
m.vel.y = 21.0
|
||||
return set_mario_action(m, ACT_DIVE, 1)
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
-- dive out of ACT_GROUND_POUND
|
||||
if m.action == ACT_GROUND_POUND and (m.input & INPUT_B_PRESSED) ~= 0 then
|
||||
mario_set_forward_vel(m, 10.0)
|
||||
|
@ -1051,7 +1389,11 @@ function mario_update(m)
|
|||
end
|
||||
|
||||
-- spin
|
||||
if (m.action == ACT_JUMP or m.action == ACT_WALL_KICK_AIR) and e.spinInput ~= 0 then
|
||||
if (m.action == ACT_JUMP or
|
||||
m.action == ACT_WALL_KICK_AIR or
|
||||
m.action == ACT_DOUBLE_JUMP or
|
||||
m.action == ACT_BACKFLIP or
|
||||
m.action == ACT_SIDE_FLIP) and e.spinInput ~= 0 then
|
||||
set_mario_action(m, ACT_SPIN_JUMP, 1)
|
||||
e.spinInput = 0
|
||||
end
|
||||
|
@ -1076,7 +1418,7 @@ function mario_update(m)
|
|||
-- maintain spinning from water ground pound jump anim
|
||||
if m.action == ACT_WATER_JUMP and m.prevAction == ACT_WATER_GROUND_POUND_JUMP then
|
||||
e.rotAngle = e.rotAngle + (0x10000*1.0 - e.rotAngle) / 5.0
|
||||
m.marioObj.header.gfx.angle.y = m.marioObj.header.gfx.angle.y - e.rotAngle
|
||||
m.marioObj.header.gfx.angle.y = limit_angle(m.marioObj.header.gfx.angle.y - e.rotAngle)
|
||||
end
|
||||
|
||||
-- edge parkour
|
||||
|
@ -1106,15 +1448,22 @@ hook_event(HOOK_BEFORE_MARIO_UPDATE, before_mario_update)
|
|||
hook_event(HOOK_MARIO_UPDATE, mario_update)
|
||||
hook_event(HOOK_ON_SET_MARIO_ACTION, mario_on_set_action)
|
||||
|
||||
hook_mario_action(ACT_ROLL, act_roll)
|
||||
hook_mario_action(ACT_ROLL_AIR, act_roll_air)
|
||||
hook_mario_action(ACT_SPIN_JUMP, act_spin_jump)
|
||||
hook_mario_action(ACT_SPIN_POUND, act_spin_pound)
|
||||
hook_mario_action(ACT_SPIN_POUND_LAND, act_spin_pound_land)
|
||||
hook_mario_action(ACT_GROUND_POUND_JUMP, act_ground_pound_jump)
|
||||
hook_mario_action(ACT_WALL_SLIDE, act_wall_slide)
|
||||
hook_mario_action(ACT_WATER_GROUND_POUND, act_water_ground_pound)
|
||||
hook_mario_action(ACT_WATER_GROUND_POUND_LAND, act_water_ground_pound_land)
|
||||
hook_mario_action(ACT_WATER_GROUND_POUND_STROKE, act_water_ground_pound_stroke)
|
||||
hook_mario_action(ACT_WATER_GROUND_POUND_JUMP, act_water_ground_pound_jump)
|
||||
hook_mario_action(ACT_LEDGE_PARKOUR, act_ledge_parkour)
|
||||
hook_mario_action(ACT_ROLL, { every_frame = act_roll })
|
||||
hook_mario_action(ACT_ROLL_AIR, { every_frame = act_roll_air })
|
||||
hook_mario_action(ACT_SPIN_JUMP, { every_frame = act_spin_jump, gravity = act_spin_jump_gravity })
|
||||
hook_mario_action(ACT_SPIN_POUND, { every_frame = act_spin_pound })
|
||||
hook_mario_action(ACT_SPIN_POUND_LAND, { every_frame = act_spin_pound_land })
|
||||
hook_mario_action(ACT_GROUND_POUND_JUMP, { every_frame = act_ground_pound_jump })
|
||||
hook_mario_action(ACT_WALL_SLIDE, { every_frame = act_wall_slide, gravity = act_wall_slide_gravity })
|
||||
hook_mario_action(ACT_WATER_GROUND_POUND, { every_frame = act_water_ground_pound })
|
||||
hook_mario_action(ACT_WATER_GROUND_POUND_LAND, { every_frame = act_water_ground_pound_land })
|
||||
hook_mario_action(ACT_WATER_GROUND_POUND_STROKE, { every_frame = act_water_ground_pound_stroke })
|
||||
hook_mario_action(ACT_WATER_GROUND_POUND_JUMP, { every_frame = act_water_ground_pound_jump })
|
||||
hook_mario_action(ACT_LEDGE_PARKOUR, { every_frame = act_ledge_parkour })
|
||||
hook_mario_action(ACT_DIVE_SLIDE, { every_frame = act_dive_slide })
|
||||
hook_mario_action(ACT_WALKING, { every_frame = act_walking })
|
||||
hook_mario_action(ACT_HOLD_WALKING, { every_frame = act_hold_walking })
|
||||
hook_mario_action(ACT_HOLD_HEAVY_WALKING, { every_frame = act_hold_heavy_walking })
|
||||
hook_mario_action(ACT_FINISH_TURNING_AROUND, { every_frame = act_finish_turning_around })
|
||||
hook_mario_action(ACT_CRAWLING, { every_frame = act_crawling })
|
||||
hook_mario_action(ACT_AIR_HIT_WALL, { every_frame = act_air_hit_wall })
|
||||
|
|
|
@ -273,6 +273,6 @@ function act_race_shell_air(m)
|
|||
return 0
|
||||
end
|
||||
|
||||
hook_mario_action(ACT_RIDING_SHELL_GROUND, act_race_shell_ground)
|
||||
hook_mario_action(ACT_RIDING_SHELL_JUMP, act_race_shell_air)
|
||||
hook_mario_action(ACT_RIDING_SHELL_FALL, act_race_shell_air)
|
||||
hook_mario_action(ACT_RIDING_SHELL_GROUND, { every_frame = act_race_shell_ground })
|
||||
hook_mario_action(ACT_RIDING_SHELL_JUMP, { every_frame = act_race_shell_air })
|
||||
hook_mario_action(ACT_RIDING_SHELL_FALL, { every_frame = act_race_shell_air })
|
||||
|
|
|
@ -2200,7 +2200,7 @@ s32 mario_execute_airborne_action(struct MarioState *m) {
|
|||
|
||||
play_far_fall_sound(m);
|
||||
|
||||
if (!smlua_call_action_hook(m, (s32*)&cancel)) {
|
||||
if (!smlua_call_action_hook(ACTION_HOOK_EVERY_FRAME, m, (s32*)&cancel)) {
|
||||
/* clang-format off */
|
||||
switch (m->action) {
|
||||
case ACT_JUMP: cancel = act_jump(m); break;
|
||||
|
|
|
@ -1072,7 +1072,7 @@ s32 mario_execute_automatic_action(struct MarioState *m) {
|
|||
|
||||
m->quicksandDepth = 0.0f;
|
||||
|
||||
if (!smlua_call_action_hook(m, &cancel)) {
|
||||
if (!smlua_call_action_hook(ACTION_HOOK_EVERY_FRAME, m, &cancel)) {
|
||||
/* clang-format off */
|
||||
switch (m->action) {
|
||||
case ACT_HOLDING_POLE: cancel = act_holding_pole(m); break;
|
||||
|
|
|
@ -2974,7 +2974,7 @@ s32 mario_execute_cutscene_action(struct MarioState *m) {
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
if (!smlua_call_action_hook(m, &cancel)) {
|
||||
if (!smlua_call_action_hook(ACTION_HOOK_EVERY_FRAME, m, &cancel)) {
|
||||
/* clang-format off */
|
||||
switch (m->action) {
|
||||
case ACT_DISAPPEARED: cancel = act_disappeared(m); break;
|
||||
|
|
|
@ -2002,7 +2002,7 @@ s32 mario_execute_moving_action(struct MarioState *m) {
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
if (!smlua_call_action_hook(m, &cancel)) {
|
||||
if (!smlua_call_action_hook(ACTION_HOOK_EVERY_FRAME, m, &cancel)) {
|
||||
/* clang-format off */
|
||||
switch (m->action) {
|
||||
case ACT_WALKING: cancel = act_walking(m); break;
|
||||
|
|
|
@ -493,7 +493,7 @@ s32 mario_execute_object_action(struct MarioState *m) {
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
if (!smlua_call_action_hook(m, &cancel)) {
|
||||
if (!smlua_call_action_hook(ACTION_HOOK_EVERY_FRAME, m, &cancel)) {
|
||||
/* clang-format off */
|
||||
switch (m->action) {
|
||||
case ACT_PUNCHING: cancel = act_punching(m); break;
|
||||
|
|
|
@ -1130,7 +1130,7 @@ s32 mario_execute_stationary_action(struct MarioState *m) {
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
if (!smlua_call_action_hook(m, &cancel)) {
|
||||
if (!smlua_call_action_hook(ACTION_HOOK_EVERY_FRAME, m, &cancel)) {
|
||||
/* clang-format off */
|
||||
switch (m->action) {
|
||||
case ACT_IDLE: cancel = act_idle(m); break;
|
||||
|
|
|
@ -1593,7 +1593,7 @@ s32 mario_execute_submerged_action(struct MarioState *m) {
|
|||
m->marioBodyState->headAngle[1] = 0;
|
||||
m->marioBodyState->headAngle[2] = 0;
|
||||
|
||||
if (!smlua_call_action_hook(m, &cancel)) {
|
||||
if (!smlua_call_action_hook(ACTION_HOOK_EVERY_FRAME, m, &cancel)) {
|
||||
/* clang-format off */
|
||||
switch (m->action) {
|
||||
case ACT_WATER_IDLE: cancel = act_water_idle(m); break;
|
||||
|
|
|
@ -594,6 +594,8 @@ u32 should_strengthen_gravity_for_jump_ascent(struct MarioState *m) {
|
|||
}
|
||||
|
||||
void apply_gravity(struct MarioState *m) {
|
||||
s32 result;
|
||||
|
||||
if (m->action == ACT_TWIRLING && m->vel[1] < 0.0f) {
|
||||
apply_twirl_gravity(m);
|
||||
} else if (m->action == ACT_SHOT_FROM_CANNON) {
|
||||
|
@ -624,6 +626,8 @@ void apply_gravity(struct MarioState *m) {
|
|||
if (m->vel[1] < -16.0f) {
|
||||
m->vel[1] = -16.0f;
|
||||
}
|
||||
} else if (smlua_call_action_hook(ACTION_HOOK_GRAVITY, m, &result)) {
|
||||
|
||||
} else if ((m->flags & MARIO_WING_CAP) && m->vel[1] < 0.0f && (m->input & INPUT_A_DOWN)) {
|
||||
m->marioBodyState->wingFlutter = TRUE;
|
||||
|
||||
|
|
|
@ -2819,8 +2819,10 @@ char gSmluaConstants[] = ""
|
|||
"HOOK_ON_OBJECT_RENDER = 20\n"
|
||||
"HOOK_ON_DEATH = 21\n"
|
||||
"HOOK_ON_PACKET_RECEIVE = 22\n"
|
||||
"HOOK_USE_ACT_SELECT = 23\n"
|
||||
"HOOK_MAX = 24\n"
|
||||
"HOOK_MAX = 23\n"
|
||||
"ACTION_HOOK_EVERY_FRAME = 0\n"
|
||||
"ACTION_HOOK_GRAVITY = 1\n"
|
||||
"ACTION_HOOK_MAX = 2\n"
|
||||
"HUD_DISPLAY_LIVES = 0\n"
|
||||
"HUD_DISPLAY_COINS = 1\n"
|
||||
"HUD_DISPLAY_STARS = 2\n"
|
||||
|
|
|
@ -533,7 +533,7 @@ void smlua_call_event_hooks_use_act_select(enum LuaHookedEventType hookType, int
|
|||
struct LuaHookedMarioAction {
|
||||
u32 action;
|
||||
u32 interactionType;
|
||||
int reference;
|
||||
int actionHookRefs[ACTION_HOOK_MAX];
|
||||
struct Mod* mod;
|
||||
};
|
||||
|
||||
|
@ -565,11 +565,11 @@ int smlua_hook_mario_action(lua_State* L) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
lua_pushvalue(L, 2);
|
||||
int ref = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
int secondParamType = lua_type(L, 2);
|
||||
bool oldApi = secondParamType == LUA_TFUNCTION;
|
||||
|
||||
if (ref == -1) {
|
||||
LOG_LUA_LINE("Hook Action: %lld tried to hook undefined function", action);
|
||||
if (!oldApi && secondParamType != LUA_TTABLE) {
|
||||
LOG_LUA_LINE("smlua_hook_mario_action received improper type '%d'", lua_type(L, 2));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -583,9 +583,45 @@ int smlua_hook_mario_action(lua_State* L) {
|
|||
}
|
||||
|
||||
struct LuaHookedMarioAction* hooked = &sHookedMarioActions[sHookedMarioActionsCount];
|
||||
|
||||
// Support calling the function with just one function corresponding to the "every frame" hook instead of a full
|
||||
// table with all hooks
|
||||
if (oldApi) {
|
||||
for (int i = 0; i < ACTION_HOOK_MAX; i++) {
|
||||
hooked->actionHookRefs[i] = LUA_NOREF;
|
||||
}
|
||||
|
||||
lua_pushvalue(L, 2);
|
||||
int ref = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
|
||||
if (ref == -1) {
|
||||
LOG_LUA_LINE("Hook Action: %lld tried to hook undefined function", action);
|
||||
return 0;
|
||||
}
|
||||
|
||||
hooked->actionHookRefs[ACTION_HOOK_EVERY_FRAME] = ref;
|
||||
}
|
||||
else {
|
||||
for (int i = 0; i < ACTION_HOOK_MAX; i++) {
|
||||
lua_pushstring(L, LuaActionHookTypeArgName[i]);
|
||||
|
||||
if (lua_gettable(L, 2) == LUA_TNIL) {
|
||||
hooked->actionHookRefs[i] = LUA_NOREF;
|
||||
} else {
|
||||
int ref = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
|
||||
if (ref == -1) {
|
||||
LOG_LUA_LINE("Hook Action: %lld tried to hook undefined function", action);
|
||||
return 0;
|
||||
}
|
||||
|
||||
hooked->actionHookRefs[i] = ref;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hooked->action = action;
|
||||
hooked->interactionType = interactionType;
|
||||
hooked->reference = ref;
|
||||
hooked->mod = gLuaActiveMod;
|
||||
if (!gSmLuaConvertSuccess) { return 0; }
|
||||
|
||||
|
@ -593,14 +629,16 @@ int smlua_hook_mario_action(lua_State* L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
bool smlua_call_action_hook(struct MarioState* m, s32* returnValue) {
|
||||
bool smlua_call_action_hook(enum LuaActionHookType hookType, struct MarioState* m, s32* returnValue) {
|
||||
lua_State* L = gLuaState;
|
||||
if (L == NULL) { return false; }
|
||||
|
||||
//TODO GAG: Set up things such that O(n) check isn't performed on every action hook? Maybe in MarioState?
|
||||
for (int i = 0; i < sHookedMarioActionsCount; i++) {
|
||||
struct LuaHookedMarioAction* hook = &sHookedMarioActions[i];
|
||||
if (hook->action == m->action) {
|
||||
if (hook->action == m->action && hook->actionHookRefs[hookType] != LUA_NOREF) {
|
||||
// push the callback onto the stack
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, hook->reference);
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, hook->actionHookRefs[hookType]);
|
||||
|
||||
// push mario state
|
||||
lua_getglobal(L, "gMarioStates");
|
||||
|
@ -1084,7 +1122,7 @@ void smlua_clear_hooks(void) {
|
|||
struct LuaHookedMarioAction* hooked = &sHookedMarioActions[i];
|
||||
hooked->action = 0;
|
||||
hooked->mod = NULL;
|
||||
hooked->reference = 0;
|
||||
memset(hooked->actionHookRefs, 0, sizeof(hooked->actionHookRefs));
|
||||
}
|
||||
sHookedMarioActionsCount = 0;
|
||||
|
||||
|
|
|
@ -66,6 +66,18 @@ static const char* LuaHookedEventTypeName[] = {
|
|||
"HOOK_MAX"
|
||||
};
|
||||
|
||||
enum LuaActionHookType {
|
||||
ACTION_HOOK_EVERY_FRAME,
|
||||
ACTION_HOOK_GRAVITY,
|
||||
ACTION_HOOK_MAX,
|
||||
};
|
||||
|
||||
static const char* LuaActionHookTypeArgName[] = {
|
||||
"every_frame",
|
||||
"gravity",
|
||||
"max (dummy)",
|
||||
};
|
||||
|
||||
extern u32 gLuaMarioActionIndex;
|
||||
|
||||
int smlua_hook_custom_bhv(BehaviorScript *bhvScript, const char *bhvName);
|
||||
|
@ -92,7 +104,7 @@ bool smlua_is_behavior_hooked(const BehaviorScript *behavior);
|
|||
bool smlua_call_behavior_hook(const BehaviorScript** behavior, struct Object* object, bool before);
|
||||
|
||||
int smlua_call_hook(lua_State* L, int nargs, int nresults, int errfunc, struct Mod* activeMod);
|
||||
bool smlua_call_action_hook(struct MarioState* m, s32* returnValue);
|
||||
bool smlua_call_action_hook(enum LuaActionHookType hookType, struct MarioState* m, s32* returnValue);
|
||||
u32 smlua_get_action_interaction_type(struct MarioState* m);
|
||||
|
||||
bool smlua_call_chat_command_hook(char* command);
|
||||
|
|
|
@ -273,7 +273,7 @@ bool is_game_paused(void) {
|
|||
///
|
||||
|
||||
u32 allocate_mario_action(u32 actFlags) {
|
||||
actFlags = actFlags & (~((u32)0xFF));
|
||||
actFlags = actFlags & (~((u32)0x3F));
|
||||
return actFlags | ACT_FLAG_CUSTOM_ACTION | gLuaMarioActionIndex++;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue