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
This commit is contained in:
MysterD 2022-01-24 19:19:19 -08:00
parent 47a129573f
commit 2e79f860e6
12 changed files with 318 additions and 22 deletions

View file

@ -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]

View file

@ -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)

View file

@ -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);

View file

@ -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)

View file

@ -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)

View file

@ -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;
}

View file

@ -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);

View file

@ -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) {

View file

@ -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++) {

View file

@ -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"

View file

@ -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);

View file

@ -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,
};