From 2e79f860e6eddf051d420c4bd1fbc8028c3607b3 Mon Sep 17 00:00:00 2001 From: MysterD Date: Mon, 24 Jan 2022 19:19:19 -0800 Subject: [PATCH] More lua improvements Added hooks: ON_SET_MARIO_ACTION, BEFORE_PHYS_STEP Working on Luigi's character abilities Autogen lua functions for surface_collision.h --- autogen/convert_header.py | 1 + autogen/lua_constants/constants.lua | 4 +- autogen/lua_functions/surface_collision.h | 9 + mods/character-abilities.lua | 95 ++++++++++- mods/extended-moveset.lua | 16 +- src/game/mario.c | 3 + src/game/mario_actions_automatic.c | 2 + src/game/mario_actions_submerged.c | 2 + src/game/mario_step.c | 5 + src/pc/lua/smlua_constants_autogen.c | 4 +- src/pc/lua/smlua_functions_autogen.c | 197 ++++++++++++++++++++++ src/pc/lua/smlua_hooks.h | 2 + 12 files changed, 318 insertions(+), 22 deletions(-) create mode 100644 autogen/lua_functions/surface_collision.h diff --git a/autogen/convert_header.py b/autogen/convert_header.py index a3e9964a9..767476fdb 100644 --- a/autogen/convert_header.py +++ b/autogen/convert_header.py @@ -23,6 +23,7 @@ template = """/* THIS FILE IS AUTOGENERATED */ #include "audio/external.h" #include "object_fields.h" #include "engine/math_util.h" +#include "engine/surface_collision.h" $[FUNCTIONS] diff --git a/autogen/lua_constants/constants.lua b/autogen/lua_constants/constants.lua index 7774617fa..d51086baf 100644 --- a/autogen/lua_constants/constants.lua +++ b/autogen/lua_constants/constants.lua @@ -5,7 +5,9 @@ HOOK_UPDATE = 0 HOOK_MARIO_UPDATE = 1 HOOK_BEFORE_MARIO_UPDATE = 2 -HOOK_MAX = 3 +HOOK_ON_SET_MARIO_ACTION = 3 +HOOK_BEFORE_PHYS_STEP = 4 +HOOK_MAX = 5 _CObject = { __index = function (t,k) diff --git a/autogen/lua_functions/surface_collision.h b/autogen/lua_functions/surface_collision.h new file mode 100644 index 000000000..fc1ba4721 --- /dev/null +++ b/autogen/lua_functions/surface_collision.h @@ -0,0 +1,9 @@ +s32 f32_find_wall_collision(f32 *xPtr, f32 *yPtr, f32 *zPtr, f32 offsetY, f32 radius); +s32 find_wall_collisions(struct WallCollisionData *colData); +f32 find_ceil(f32 posX, f32 posY, f32 posZ, struct Surface **pceil); +f32 find_floor_height_and_data(f32 xPos, f32 yPos, f32 zPos, struct FloorGeometry **floorGeo); +f32 find_floor_height(f32 x, f32 y, f32 z); +f32 find_floor(f32 xPos, f32 yPos, f32 zPos, struct Surface **pfloor); +f32 find_water_level(f32 x, f32 z); +f32 find_poison_gas_level(f32 x, f32 z); +void find_surface_on_ray(Vec3f orig, Vec3f dir, struct Surface **hit_surface, Vec3f hit_pos); diff --git a/mods/character-abilities.lua b/mods/character-abilities.lua index 0857df088..ebb590347 100644 --- a/mods/character-abilities.lua +++ b/mods/character-abilities.lua @@ -1,27 +1,97 @@ +-- TODO: + +-- Luigi: runs on water +-- Luigi: tune swim and holding item speeds +-- Luigi: low friction +-- Luigi: BUG - can't jump off tree normally + +-- Mario: wall kick slide all the way down wall + + gMarioStateExtras = {} for i=0,(MAX_PLAYERS-1) do gMarioStateExtras[i] = {} local m = gMarioStates[i] local e = gMarioStateExtras[i] - e.actionLastFrame = m.action + e.lastAction = m.action + e.animFrame = 0 + e.scuttle = 0 end ----------- -- luigi -- ----------- -function luigi_action_on_change(m) +function luigi_before_phys_step(m) + local e = gMarioStateExtras[m.playerIndex] + + local hScale = 1.0 + local vScale = 1.0 + + -- faster swimming + if (m.action & ACT_FLAG_SWIMMING) ~= 0 then + hScale = hScale * 1.25 + end + + -- slower holding item + if m.heldObj ~= nil then + m.vel.y = m.vel.y - 2.0 + hScale = hScale * 0.9 + if (m.action & ACT_FLAG_AIR) ~= 0 then + hScale = hScale * 0.9 + end + end + m.forwardVel = m.forwardVel * 0.99 + + m.vel.x = m.vel.x * hScale + m.vel.y = m.vel.y * vScale + m.vel.z = m.vel.z * hScale +end + +function luigi_on_set_action(m) local e = gMarioStateExtras[m.playerIndex] -- extra height to the backflip if m.action == ACT_BACKFLIP then - m.vel.y = m.vel.y + 25 + m.vel.y = m.vel.y + 18 + + -- nerf wall kicks + elseif m.action == ACT_WALL_KICK_AIR and m.prevAction ~= ACT_HOLDING_POLE and m.prevAction ~= ACT_CLIMBING_POLE then + if m.vel.y > 15 then m.vel.y = 15 end + return + + -- turn dive into kick when holding jump + elseif m.action == ACT_DIVE and (m.controller.buttonDown & A_BUTTON) ~= 0 and e.scuttle > 0 then + return set_mario_action(m, ACT_JUMP_KICK, 0) + + -- extra height on jumps + elseif 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_STEEP_JUMP or m.action == ACT_SIDE_FLIP or m.action == ACT_RIDING_SHELL_JUMP then + m.vel.y = m.vel.y + 6 + end + + e.lastAction = action end function luigi_update(m) local e = gMarioStateExtras[m.playerIndex] + + -- air scuttle + e.scuttle = 0 + if m.action == ACT_JUMP or m.action == ACT_DOUBLE_JUMP then + if (m.controller.buttonDown & A_BUTTON) ~= 0 and m.vel.y < -5 then + m.vel.y = m.vel.y + 2.5 + set_mario_animation(m, MARIO_ANIM_RUNNING_UNUSED) + set_anim_to_frame(m, e.animFrame) + e.animFrame = e.animFrame + 10 + if e.animFrame >= m.marioObj.header.gfx.animInfo.curAnim.loopEnd then + e.animFrame = e.animFrame - m.marioObj.header.gfx.animInfo.curAnim.loopEnd + end + e.scuttle = 1 + end + end + -- backflip turns into twirl if m.action == ACT_BACKFLIP and m.marioObj.header.gfx.animInfo.animFrame > 18 then m.angleVel.y = 0x1800 @@ -32,6 +102,17 @@ end ---------- -- main -- ---------- +function mario_before_phys_step(m) + -- if luigi then + luigi_before_phys_step(m) + -- end +end + +function mario_on_set_action(m) + -- if luigi then + luigi_on_set_action(m) + -- end +end function mario_action_on_change(m) -- if luigi then @@ -45,12 +126,6 @@ function mario_update(m) -- if luigi then luigi_update(m) -- end - - -- action change event - if e.actionLastFrame ~= m.action then - mario_action_on_change(m) - end - e.actionLastFrame = m.action end ----------- @@ -58,3 +133,5 @@ end ----------- 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) diff --git a/mods/extended-moveset.lua b/mods/extended-moveset.lua index c80825d0b..be7586bb9 100644 --- a/mods/extended-moveset.lua +++ b/mods/extended-moveset.lua @@ -35,7 +35,6 @@ for i=0,(MAX_PLAYERS-1) do e.spinDirection = 0 e.spinBufferTimer = 0 e.spinInput = 0 - e.actionLastFrame = m.action e.lastIntendedMag = 0 e.lastPos = {} e.lastPos.x = m.pos.x @@ -953,7 +952,7 @@ end --------------------------------------------------------- -function mario_action_on_change(m) +function mario_on_set_action(m) local e = gMarioStateExtras[m.playerIndex] 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_SIDE_FLIP or m.action == ACT_BACKFLIP or m.action == ACT_WALL_KICK_AIR then @@ -974,9 +973,9 @@ function mario_action_on_change(m) m.vel.x = 0 m.vel.y = 0 m.vel.z = 0 - elseif m.action == ACT_WATER_PLUNGE and e.actionLastFrame == ACT_GROUND_POUND then + elseif 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_GROUND_POUND and e.actionLastFrame == ACT_SIDE_FLIP then + 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 elseif m.action == ACT_LEDGE_GRAB then @@ -1032,7 +1031,7 @@ function mario_update(m) end -- spin - if e.actionLastFrame == m.action and (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) and e.spinInput ~= 0 then set_mario_action(m, ACT_SPIN_JUMP, 1) e.spinInput = 0 end @@ -1071,12 +1070,6 @@ function mario_update(m) end end - -- action change event - if e.actionLastFrame ~= m.action then - mario_action_on_change(m) - end - e.actionLastFrame = m.action - -- save last pos e.lastPos.x = m.pos.x e.lastPos.y = m.pos.y @@ -1091,6 +1084,7 @@ end 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) diff --git a/src/game/mario.c b/src/game/mario.c index 18c86d6b7..15ef088e2 100644 --- a/src/game/mario.c +++ b/src/game/mario.c @@ -40,6 +40,7 @@ #include "pc/configfile.h" #include "pc/cheats.h" #include "pc/network/network.h" +#include "pc/lua/smlua.h" #include "pc/logfile.h" #ifdef BETTERCAMERA #include "bettercamera.h" @@ -1070,6 +1071,8 @@ u32 set_mario_action(struct MarioState *m, u32 action, u32 actionArg) { m->actionState = 0; m->actionTimer = 0; + smlua_call_event_hooks_mario_param(HOOK_ON_SET_MARIO_ACTION, m); + return TRUE; } diff --git a/src/game/mario_actions_automatic.c b/src/game/mario_actions_automatic.c index f5df09cb6..fa90135e9 100644 --- a/src/game/mario_actions_automatic.c +++ b/src/game/mario_actions_automatic.c @@ -321,6 +321,8 @@ s32 perform_hanging_step(struct MarioState *m, Vec3f nextPos) { f32 floorHeight; f32 ceilOffset; + smlua_call_event_hooks_mario_param(HOOK_BEFORE_PHYS_STEP, m); + m->wall = resolve_and_return_wall_collisions(nextPos, 50.0f, 50.0f); floorHeight = find_floor(nextPos[0], nextPos[1], nextPos[2], &floor); ceilHeight = vec3f_find_ceil(nextPos, floorHeight, &ceil); diff --git a/src/game/mario_actions_submerged.c b/src/game/mario_actions_submerged.c index d2c3ee22c..0b9d540b6 100644 --- a/src/game/mario_actions_submerged.c +++ b/src/game/mario_actions_submerged.c @@ -174,6 +174,8 @@ u32 perform_water_step(struct MarioState *m) { Vec3f step; struct Object *marioObj = m->marioObj; + smlua_call_event_hooks_mario_param(HOOK_BEFORE_PHYS_STEP, m); + vec3f_copy(step, m->vel); if (m->action & ACT_FLAG_SWIMMING) { diff --git a/src/game/mario_step.c b/src/game/mario_step.c index 326378908..24f417f0d 100644 --- a/src/game/mario_step.c +++ b/src/game/mario_step.c @@ -8,6 +8,7 @@ #include "game_init.h" #include "interaction.h" #include "mario_step.h" +#include "pc/lua/smlua.h" static s16 sMovingSandSpeeds[] = { 12, 8, 4, 0 }; @@ -325,6 +326,8 @@ s32 perform_ground_step(struct MarioState *m) { u32 stepResult; Vec3f intendedPos; + smlua_call_event_hooks_mario_param(HOOK_BEFORE_PHYS_STEP, m); + for (i = 0; i < 4; i++) { intendedPos[0] = m->pos[0] + m->floor->normal.y * (m->vel[0] / 4.0f); intendedPos[2] = m->pos[2] + m->floor->normal.y * (m->vel[2] / 4.0f); @@ -614,6 +617,8 @@ s32 perform_air_step(struct MarioState *m, u32 stepArg) { s32 quarterStepResult; s32 stepResult = AIR_STEP_NONE; + smlua_call_event_hooks_mario_param(HOOK_BEFORE_PHYS_STEP, m); + m->wall = NULL; for (i = 0; i < 4; i++) { diff --git a/src/pc/lua/smlua_constants_autogen.c b/src/pc/lua/smlua_constants_autogen.c index a1c856c84..193ecb041 100644 --- a/src/pc/lua/smlua_constants_autogen.c +++ b/src/pc/lua/smlua_constants_autogen.c @@ -1,7 +1,9 @@ char gSmluaConstants[] = "HOOK_UPDATE = 0\n" "HOOK_MARIO_UPDATE = 1\n" "HOOK_BEFORE_MARIO_UPDATE = 2\n" -"HOOK_MAX = 3\n" +"HOOK_ON_SET_MARIO_ACTION = 3\n" +"HOOK_BEFORE_PHYS_STEP = 4\n" +"HOOK_MAX = 5\n" "_CObject = {\n" " __index = function (t,k)\n" " return _get_field(t['_lot'], t['_pointer'], k);\n" diff --git a/src/pc/lua/smlua_functions_autogen.c b/src/pc/lua/smlua_functions_autogen.c index ec9313f9c..1a886e73f 100644 --- a/src/pc/lua/smlua_functions_autogen.c +++ b/src/pc/lua/smlua_functions_autogen.c @@ -11,6 +11,7 @@ #include "audio/external.h" #include "object_fields.h" #include "engine/math_util.h" +#include "engine/surface_collision.h" ////////////// // camera.h // @@ -2907,6 +2908,191 @@ int smlua_func_set_vel_from_pitch_and_yaw(lua_State* L) { return 1; } + ///////////////////////// + // surface_collision.h // +///////////////////////// + +/* +int smlua_func_f32_find_wall_collision(lua_State* L) { + if(!smlua_functions_valid_param_count(L, 5)) { return 0; } + + f32 * xPtr <--- UNIMPLEMENTED + if (!gSmLuaConvertSuccess) { return 0; } + f32 * yPtr <--- UNIMPLEMENTED + if (!gSmLuaConvertSuccess) { return 0; } + f32 * zPtr <--- UNIMPLEMENTED + if (!gSmLuaConvertSuccess) { return 0; } + f32 offsetY = smlua_to_number(L, 4); + if (!gSmLuaConvertSuccess) { return 0; } + f32 radius = smlua_to_number(L, 5); + if (!gSmLuaConvertSuccess) { return 0; } + + lua_pushinteger(L, f32_find_wall_collision(xPtr, yPtr, zPtr, offsetY, radius)); + + return 1; +} +*/ + +/* +int smlua_func_find_wall_collisions(lua_State* L) { + if(!smlua_functions_valid_param_count(L, 1)) { return 0; } + + struct WallCollisionData* colData <--- UNIMPLEMENTED + if (!gSmLuaConvertSuccess) { return 0; } + + lua_pushinteger(L, find_wall_collisions(colData)); + + return 1; +} +*/ + +/* +int smlua_func_find_ceil(lua_State* L) { + if(!smlua_functions_valid_param_count(L, 4)) { return 0; } + + f32 posX = smlua_to_number(L, 1); + if (!gSmLuaConvertSuccess) { return 0; } + f32 posY = smlua_to_number(L, 2); + if (!gSmLuaConvertSuccess) { return 0; } + f32 posZ = smlua_to_number(L, 3); + if (!gSmLuaConvertSuccess) { return 0; } + struct Surface** pceil <--- UNIMPLEMENTED + if (!gSmLuaConvertSuccess) { return 0; } + + lua_pushnumber(L, find_ceil(posX, posY, posZ, pceil)); + + return 1; +} +*/ + +/* +int smlua_func_find_floor_height_and_data(lua_State* L) { + if(!smlua_functions_valid_param_count(L, 4)) { return 0; } + + f32 xPos = smlua_to_number(L, 1); + if (!gSmLuaConvertSuccess) { return 0; } + f32 yPos = smlua_to_number(L, 2); + if (!gSmLuaConvertSuccess) { return 0; } + f32 zPos = smlua_to_number(L, 3); + if (!gSmLuaConvertSuccess) { return 0; } + struct FloorGeometry** floorGeo <--- UNIMPLEMENTED + if (!gSmLuaConvertSuccess) { return 0; } + + lua_pushnumber(L, find_floor_height_and_data(xPos, yPos, zPos, floorGeo)); + + return 1; +} +*/ + +int smlua_func_find_floor_height(lua_State* L) { + if(!smlua_functions_valid_param_count(L, 3)) { return 0; } + + f32 x = smlua_to_number(L, 1); + if (!gSmLuaConvertSuccess) { return 0; } + f32 y = smlua_to_number(L, 2); + if (!gSmLuaConvertSuccess) { return 0; } + f32 z = smlua_to_number(L, 3); + if (!gSmLuaConvertSuccess) { return 0; } + + lua_pushnumber(L, find_floor_height(x, y, z)); + + return 1; +} + +/* +int smlua_func_find_floor(lua_State* L) { + if(!smlua_functions_valid_param_count(L, 4)) { return 0; } + + f32 xPos = smlua_to_number(L, 1); + if (!gSmLuaConvertSuccess) { return 0; } + f32 yPos = smlua_to_number(L, 2); + if (!gSmLuaConvertSuccess) { return 0; } + f32 zPos = smlua_to_number(L, 3); + if (!gSmLuaConvertSuccess) { return 0; } + struct Surface** pfloor <--- UNIMPLEMENTED + if (!gSmLuaConvertSuccess) { return 0; } + + lua_pushnumber(L, find_floor(xPos, yPos, zPos, pfloor)); + + return 1; +} +*/ + +int smlua_func_find_water_level(lua_State* L) { + if(!smlua_functions_valid_param_count(L, 2)) { return 0; } + + f32 x = smlua_to_number(L, 1); + if (!gSmLuaConvertSuccess) { return 0; } + f32 z = smlua_to_number(L, 2); + if (!gSmLuaConvertSuccess) { return 0; } + + lua_pushnumber(L, find_water_level(x, z)); + + return 1; +} + +int smlua_func_find_poison_gas_level(lua_State* L) { + if(!smlua_functions_valid_param_count(L, 2)) { return 0; } + + f32 x = smlua_to_number(L, 1); + if (!gSmLuaConvertSuccess) { return 0; } + f32 z = smlua_to_number(L, 2); + if (!gSmLuaConvertSuccess) { return 0; } + + lua_pushnumber(L, find_poison_gas_level(x, z)); + + return 1; +} + +/* +int smlua_func_find_surface_on_ray(lua_State* L) { + if(!smlua_functions_valid_param_count(L, 4)) { return 0; } + + + f32* orig = smlua_get_vec3f_from_buffer(); + orig[0] = smlua_get_number_field(1, "x"); + if (!gSmLuaConvertSuccess) { return 0; } + orig[1] = smlua_get_number_field(1, "y"); + if (!gSmLuaConvertSuccess) { return 0; } + orig[2] = smlua_get_number_field(1, "z"); + if (!gSmLuaConvertSuccess) { return 0; } + + f32* dir = smlua_get_vec3f_from_buffer(); + dir[0] = smlua_get_number_field(2, "x"); + if (!gSmLuaConvertSuccess) { return 0; } + dir[1] = smlua_get_number_field(2, "y"); + if (!gSmLuaConvertSuccess) { return 0; } + dir[2] = smlua_get_number_field(2, "z"); + if (!gSmLuaConvertSuccess) { return 0; } + struct Surface** hit_surface <--- UNIMPLEMENTED + if (!gSmLuaConvertSuccess) { return 0; } + + f32* hit_pos = smlua_get_vec3f_from_buffer(); + hit_pos[0] = smlua_get_number_field(4, "x"); + if (!gSmLuaConvertSuccess) { return 0; } + hit_pos[1] = smlua_get_number_field(4, "y"); + if (!gSmLuaConvertSuccess) { return 0; } + hit_pos[2] = smlua_get_number_field(4, "z"); + if (!gSmLuaConvertSuccess) { return 0; } + + find_surface_on_ray(orig, dir, hit_surface, hit_pos); + + smlua_push_number_field(1, "x", orig[0]); + smlua_push_number_field(1, "y", orig[1]); + smlua_push_number_field(1, "z", orig[2]); + + smlua_push_number_field(2, "x", dir[0]); + smlua_push_number_field(2, "y", dir[1]); + smlua_push_number_field(2, "z", dir[2]); + + smlua_push_number_field(4, "x", hit_pos[0]); + smlua_push_number_field(4, "y", hit_pos[1]); + smlua_push_number_field(4, "z", hit_pos[2]); + + return 1; +} +*/ + /////////////// // thread6.c // /////////////// @@ -3199,6 +3385,17 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "perform_air_step", smlua_func_perform_air_step); smlua_bind_function(L, "set_vel_from_pitch_and_yaw", smlua_func_set_vel_from_pitch_and_yaw); + // surface_collision.h + //smlua_bind_function(L, "f32_find_wall_collision", smlua_func_f32_find_wall_collision); <--- UNIMPLEMENTED + //smlua_bind_function(L, "find_wall_collisions", smlua_func_find_wall_collisions); <--- UNIMPLEMENTED + //smlua_bind_function(L, "find_ceil", smlua_func_find_ceil); <--- UNIMPLEMENTED + //smlua_bind_function(L, "find_floor_height_and_data", smlua_func_find_floor_height_and_data); <--- UNIMPLEMENTED + smlua_bind_function(L, "find_floor_height", smlua_func_find_floor_height); + //smlua_bind_function(L, "find_floor", smlua_func_find_floor); <--- UNIMPLEMENTED + smlua_bind_function(L, "find_water_level", smlua_func_find_water_level); + smlua_bind_function(L, "find_poison_gas_level", smlua_func_find_poison_gas_level); + //smlua_bind_function(L, "find_surface_on_ray", smlua_func_find_surface_on_ray); <--- UNIMPLEMENTED + // thread6.c smlua_bind_function(L, "queue_rumble_data", smlua_func_queue_rumble_data); smlua_bind_function(L, "queue_rumble_data_object", smlua_func_queue_rumble_data_object); diff --git a/src/pc/lua/smlua_hooks.h b/src/pc/lua/smlua_hooks.h index 464757058..06f56c5db 100644 --- a/src/pc/lua/smlua_hooks.h +++ b/src/pc/lua/smlua_hooks.h @@ -7,6 +7,8 @@ enum LuaHookedEventType { HOOK_UPDATE, HOOK_MARIO_UPDATE, HOOK_BEFORE_MARIO_UPDATE, + HOOK_ON_SET_MARIO_ACTION, + HOOK_BEFORE_PHYS_STEP, HOOK_MAX, };