From 05f4c42f81f00e9d6cc1bd2fe9e3e6c88aea72d0 Mon Sep 17 00:00:00 2001 From: Isaac0-dev <62234577+Isaac0-dev@users.noreply.github.com> Date: Thu, 1 Jun 2023 14:10:06 +1000 Subject: [PATCH 1/2] add cancels to HOOK_BEFORE_PHYS_STEP allowing for custom step systems (#400) * add cancels to HOOK_BEFORE_PHYS_STEP allowing for custom step systems * give lua mods access to stepArg and nextPos from hanging and air step; fix a crash when m.floor is null --- autogen/lua_definitions/constants.lua | 12 +++++ docs/lua/constants.md | 4 ++ docs/lua/guides/hooks.md | 2 +- include/sm64.h | 5 ++ src/game/mario.c | 10 ++-- src/game/mario_actions_automatic.c | 5 +- src/game/mario_actions_submerged.c | 15 +++--- src/game/mario_step.c | 6 ++- src/pc/lua/smlua_constants_autogen.c | 4 ++ src/pc/lua/smlua_hooks.c | 77 ++++++++++++++++++++++++++- src/pc/lua/smlua_hooks.h | 2 + 11 files changed, 124 insertions(+), 18 deletions(-) diff --git a/autogen/lua_definitions/constants.lua b/autogen/lua_definitions/constants.lua index 15db1032b..81f0ac59b 100644 --- a/autogen/lua_definitions/constants.lua +++ b/autogen/lua_definitions/constants.lua @@ -8126,6 +8126,18 @@ PARTICLE_WATER_SPLASH = (1 << 6) --- @type integer PARTICLE_WAVE_TRAIL = (1 << 10) +--- @type integer +STEP_TYPE_AIR = 2 + +--- @type integer +STEP_TYPE_GROUND = 1 + +--- @type integer +STEP_TYPE_HANG = 4 + +--- @type integer +STEP_TYPE_WATER = 3 + --- @type integer VALID_BUTTONS = (A_BUTTON | B_BUTTON | Z_TRIG | START_BUTTON | U_JPAD | D_JPAD | L_JPAD | R_JPAD | L_TRIG | R_TRIG | X_BUTTON | Y_BUTTON | U_CBUTTONS | D_CBUTTONS | L_CBUTTONS | R_CBUTTONS ) diff --git a/docs/lua/constants.md b/docs/lua/constants.md index 3600db432..4df4e9802 100644 --- a/docs/lua/constants.md +++ b/docs/lua/constants.md @@ -2894,6 +2894,10 @@ - PARTICLE_VERTICAL_STAR - PARTICLE_WATER_SPLASH - PARTICLE_WAVE_TRAIL +- STEP_TYPE_AIR +- STEP_TYPE_GROUND +- STEP_TYPE_HANG +- STEP_TYPE_WATER - VALID_BUTTONS - WATER_STEP_CANCELLED - WATER_STEP_HIT_CEILING diff --git a/docs/lua/guides/hooks.md b/docs/lua/guides/hooks.md index af584645a..7f8eca33a 100644 --- a/docs/lua/guides/hooks.md +++ b/docs/lua/guides/hooks.md @@ -91,7 +91,7 @@ The lua functions sent to `hook_event()` will be automatically called by SM64 wh | HOOK_MARIO_UPDATE | Called once per player per frame at the end of a mario update | [MarioState](structs.md#MarioState) mario | | HOOK_BEFORE_MARIO_UPDATE | Called once per player per frame at the beginning of a mario update | [MarioState](structs.md#MarioState) mario | | HOOK_ON_SET_MARIO_ACTION | Called every time a player's current action is changed | [MarioState](structs.md#MarioState) mario | -| HOOK_BEFORE_PHYS_STEP | Called once per player per frame before physics code is run | [MarioState](structs.md#MarioState) mario | +| HOOK_BEFORE_PHYS_STEP | Called once per player per frame before physics code is run, return an integer to cancel it with your own step result | [MarioState](structs.md#MarioState) mario, `integer` stepType | | HOOK_ALLOW_PVP_ATTACK | Called when one player attacks another, return `true` to allow the attack | [MarioState](structs.md#MarioState) attacker, [MarioState](structs.md#MarioState) victim | | HOOK_ON_PVP_ATTACK | Called when one player attacks another | [MarioState](structs.md#MarioState) attacker, [MarioState](structs.md#MarioState) victim | | HOOK_ON_PLAYER_CONNECTED | Called when a player connects | [MarioState](structs.md#MarioState) connector | diff --git a/include/sm64.h b/include/sm64.h index ea0348964..02e1490f0 100644 --- a/include/sm64.h +++ b/include/sm64.h @@ -88,6 +88,11 @@ #define WATER_STEP_CANCELLED 3 #define WATER_STEP_HIT_WALL 4 +#define STEP_TYPE_GROUND 1 +#define STEP_TYPE_AIR 2 +#define STEP_TYPE_WATER 3 +#define STEP_TYPE_HANG 4 + #define PARTICLE_DUST /* 0x00000001 */ (1 << 0) #define PARTICLE_VERTICAL_STAR /* 0x00000002 */ (1 << 1) #define PARTICLE_2 /* 0x00000004 */ (1 << 2) diff --git a/src/game/mario.c b/src/game/mario.c index d896664d7..1a09b8b12 100644 --- a/src/game/mario.c +++ b/src/game/mario.c @@ -631,7 +631,7 @@ struct Surface *resolve_and_return_wall_collisions(Vec3f pos, f32 offset, f32 ra if (find_wall_collisions(&collisionData)) { wall = collisionData.walls[collisionData.numWalls - 1]; } - + // I'm not sure if this code is actually ever used or not. pos[0] = collisionData.x; pos[1] = collisionData.y; @@ -1143,7 +1143,7 @@ u32 set_mario_action(struct MarioState *m, u32 action, u32 actionArg) { u32 returnValue = 0; smlua_call_event_hooks_mario_action_params_ret_int(HOOK_BEFORE_SET_MARIO_ACTION, m, action, &returnValue); if (returnValue == 1) { return TRUE; } else if (returnValue) { action = returnValue; } - + switch (action & ACT_GROUP_MASK) { case ACT_GROUP_MOVING: action = set_mario_action_moving(m, action, actionArg); @@ -2187,14 +2187,14 @@ s32 execute_mario_action(UNUSED struct Object *o) { // Both of the wind handling portions play wind audio only in // non-Japanese releases. extern bool gDjuiInMainMenu; - if (gMarioState->floor->type == SURFACE_HORIZONTAL_WIND && !gDjuiInMainMenu) { + if (gMarioState->floor && gMarioState->floor->type == SURFACE_HORIZONTAL_WIND && !gDjuiInMainMenu) { spawn_wind_particles(0, (gMarioState->floor->force << 8)); #ifndef VERSION_JP play_sound(SOUND_ENV_WIND2, gMarioState->marioObj->header.gfx.cameraToObject); #endif } - if (gMarioState->floor->type == SURFACE_VERTICAL_WIND) { + if (gMarioState->floor && gMarioState->floor->type == SURFACE_VERTICAL_WIND) { spawn_wind_particles(1, 0); #ifndef VERSION_JP play_sound(SOUND_ENV_WIND2, gMarioState->marioObj->header.gfx.cameraToObject); @@ -2240,7 +2240,7 @@ void init_single_mario(struct MarioState* m) { m->invincTimer = 0; m->visibleToEnemies = TRUE; - + if (m->cap & (SAVE_FLAG_CAP_ON_GROUND | SAVE_FLAG_CAP_ON_KLEPTO | SAVE_FLAG_CAP_ON_UKIKI | SAVE_FLAG_CAP_ON_MR_BLIZZARD)) { m->flags = 0; } else { diff --git a/src/game/mario_actions_automatic.c b/src/game/mario_actions_automatic.c index 8f884b917..b571a03f5 100644 --- a/src/game/mario_actions_automatic.c +++ b/src/game/mario_actions_automatic.c @@ -69,7 +69,7 @@ void play_climbing_sounds(struct MarioState *m, s32 b) { s32 set_pole_position(struct MarioState *m, f32 offsetY) { if (!m) { return 0; } if (m->usedObj == NULL) { m->usedObj = cur_obj_find_nearest_pole(); } - + // This is here so if somehow a pole despawns while you are on it. // You will just drop from it. if (m->usedObj == NULL) { @@ -340,7 +340,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); + s32 returnValue = 0; + if (smlua_call_event_hooks_mario_param_and_int_ret_int(HOOK_BEFORE_PHYS_STEP, m, STEP_TYPE_HANG, &returnValue)) return returnValue; if (gServerSettings.enableCheats && gCheats.superSpeed && m->playerIndex == 0) { m->vel[0] *= SUPER_SPEED_MULTIPLIER; diff --git a/src/game/mario_actions_submerged.c b/src/game/mario_actions_submerged.c index e7dd1df4f..e14390c2d 100644 --- a/src/game/mario_actions_submerged.c +++ b/src/game/mario_actions_submerged.c @@ -26,9 +26,9 @@ #define MIN_SWIM_STRENGTH 160 #define MIN_SWIM_SPEED 16.0f -static s16 sWasAtSurface[MAX_PLAYERS] = { FALSE, FALSE, FALSE, FALSE, - FALSE, FALSE, FALSE, FALSE, - FALSE, FALSE, FALSE, FALSE, +static s16 sWasAtSurface[MAX_PLAYERS] = { FALSE, FALSE, FALSE, FALSE, + FALSE, FALSE, FALSE, FALSE, + FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }; static s16 sSwimStrength[MAX_PLAYERS] = { MIN_SWIM_STRENGTH, MIN_SWIM_STRENGTH, MIN_SWIM_STRENGTH, MIN_SWIM_STRENGTH, MIN_SWIM_STRENGTH, MIN_SWIM_STRENGTH, MIN_SWIM_STRENGTH, MIN_SWIM_STRENGTH, @@ -192,7 +192,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); + s32 returnValue = 0; + if (smlua_call_event_hooks_mario_param_and_int_ret_int(HOOK_BEFORE_PHYS_STEP, m, STEP_TYPE_WATER, &returnValue)) return (u32) returnValue; if (gServerSettings.enableCheats && gCheats.superSpeed && m->playerIndex == 0) { m->vel[0] *= SUPER_SPEED_MULTIPLIER; @@ -552,7 +553,7 @@ static s32 check_water_jump(struct MarioState *m) { static s32 act_breaststroke(struct MarioState *m) { if (!m) { return 0; } u16 pIndex = m->playerIndex; - + if (m->actionArg == 0) { sSwimStrength[pIndex] = MIN_SWIM_STRENGTH; } @@ -613,7 +614,7 @@ static s32 act_breaststroke(struct MarioState *m) { static s32 act_swimming_end(struct MarioState *m) { if (!m) { return 0; } u16 pIndex = m->playerIndex; - + if (m->flags & MARIO_METAL_CAP) { return set_mario_action(m, ACT_METAL_WATER_FALLING, 1); } @@ -653,7 +654,7 @@ static s32 act_swimming_end(struct MarioState *m) { static s32 act_flutter_kick(struct MarioState *m) { if (!m) { return 0; } u16 pIndex = m->playerIndex; - + if (m->flags & MARIO_METAL_CAP) { return set_mario_action(m, ACT_METAL_WATER_FALLING, 1); } diff --git a/src/game/mario_step.c b/src/game/mario_step.c index f3aff044d..9daa54b57 100644 --- a/src/game/mario_step.c +++ b/src/game/mario_step.c @@ -350,7 +350,8 @@ s32 perform_ground_step(struct MarioState *m) { u32 stepResult; Vec3f intendedPos; - smlua_call_event_hooks_mario_param(HOOK_BEFORE_PHYS_STEP, m); + s32 returnValue = 0; + if (smlua_call_event_hooks_mario_param_and_int_ret_int(HOOK_BEFORE_PHYS_STEP, m, STEP_TYPE_GROUND, &returnValue)) return returnValue; if (gServerSettings.enableCheats && gCheats.superSpeed && m->playerIndex == 0 && m->action != ACT_BUBBLED) { m->vel[0] *= SUPER_SPEED_MULTIPLIER; @@ -708,7 +709,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); + s32 returnValue = 0; + if (smlua_call_event_hooks_mario_param_and_int_and_int_ret_int(HOOK_BEFORE_PHYS_STEP, m, STEP_TYPE_AIR, stepArg, &returnValue)) return returnValue; if (gServerSettings.enableCheats && gCheats.superSpeed && m->playerIndex == 0 && m->action != ACT_BUBBLED) { m->vel[0] *= SUPER_SPEED_MULTIPLIER; diff --git a/src/pc/lua/smlua_constants_autogen.c b/src/pc/lua/smlua_constants_autogen.c index 0cbd54207..bd1e6de3a 100644 --- a/src/pc/lua/smlua_constants_autogen.c +++ b/src/pc/lua/smlua_constants_autogen.c @@ -2582,6 +2582,10 @@ char gSmluaConstants[] = "" "WATER_STEP_HIT_CEILING = 2\n" "WATER_STEP_CANCELLED = 3\n" "WATER_STEP_HIT_WALL = 4\n" +"STEP_TYPE_GROUND = 1\n" +"STEP_TYPE_AIR = 2\n" +"STEP_TYPE_WATER = 3\n" +"STEP_TYPE_HANG = 4\n" "PARTICLE_DUST = (1 << 0)\n" "PARTICLE_VERTICAL_STAR = (1 << 1)\n" "PARTICLE_2 = (1 << 2)\n" diff --git a/src/pc/lua/smlua_hooks.c b/src/pc/lua/smlua_hooks.c index a039fba4c..a253a0790 100644 --- a/src/pc/lua/smlua_hooks.c +++ b/src/pc/lua/smlua_hooks.c @@ -677,7 +677,7 @@ bool smlua_call_event_hooks_mario_character_sound_param_ret_int(enum LuaHookedEv lua_pushinteger(L, m->playerIndex); lua_gettable(L, -2); lua_remove(L, -2); - + // push character sound lua_pushinteger(L, characterSound); @@ -765,6 +765,81 @@ void smlua_call_event_hooks_mario_param_and_int_ret_bool(enum LuaHookedEventType } } +bool smlua_call_event_hooks_mario_param_and_int_ret_int(enum LuaHookedEventType hookType, struct MarioState* m, s32 param, s32* returnValue) { + lua_State* L = gLuaState; + if (L == NULL) { return false; } + struct LuaHookedEvent* hook = &sHookedEvents[hookType]; + for (int i = 0; i < hook->count; i++) { + s32 prevTop = lua_gettop(L); + + // push the callback onto the stack + lua_rawgeti(L, LUA_REGISTRYINDEX, hook->reference[i]); + + // push mario state + lua_getglobal(L, "gMarioStates"); + lua_pushinteger(L, m->playerIndex); + lua_gettable(L, -2); + lua_remove(L, -2); + + // push param + lua_pushinteger(L, param); + + // call the callback + if (0 != smlua_call_hook(L, 2, 1, 0, hook->mod[i])) { + LOG_LUA("Failed to call the callback: %u", hookType); + continue; + } + + // output the return value + if (lua_type(L, -1) == LUA_TNUMBER) { + *returnValue = smlua_to_integer(L, -1); + lua_settop(L, prevTop); + return true; + } + lua_settop(L, prevTop); + } + return false; +} + +bool smlua_call_event_hooks_mario_param_and_int_and_int_ret_int(enum LuaHookedEventType hookType, struct MarioState* m, s32 param, u32 args, s32* returnValue) { + lua_State* L = gLuaState; + if (L == NULL) { return false; } + struct LuaHookedEvent* hook = &sHookedEvents[hookType]; + for (int i = 0; i < hook->count; i++) { + s32 prevTop = lua_gettop(L); + + // push the callback onto the stack + lua_rawgeti(L, LUA_REGISTRYINDEX, hook->reference[i]); + + // push mario state + lua_getglobal(L, "gMarioStates"); + lua_pushinteger(L, m->playerIndex); + lua_gettable(L, -2); + lua_remove(L, -2); + + // push param + lua_pushinteger(L, param); + + // push args + lua_pushinteger(L, args); + + // call the callback + if (0 != smlua_call_hook(L, 3, 1, 0, hook->mod[i])) { + LOG_LUA("Failed to call the callback: %u", hookType); + continue; + } + + // output the return value + if (lua_type(L, -1) == LUA_TNUMBER) { + *returnValue = smlua_to_integer(L, -1); + lua_settop(L, prevTop); + return true; + } + lua_settop(L, prevTop); + } + return false; +} + //////////////////// // hooked actions // //////////////////// diff --git a/src/pc/lua/smlua_hooks.h b/src/pc/lua/smlua_hooks.h index a0696a682..f44f9af25 100644 --- a/src/pc/lua/smlua_hooks.h +++ b/src/pc/lua/smlua_hooks.h @@ -122,6 +122,8 @@ void smlua_call_event_hooks_on_chat_message(enum LuaHookedEventType hookType, st bool smlua_call_event_hooks_mario_character_sound_param_ret_int(enum LuaHookedEventType hookType, struct MarioState* m, enum CharacterSound characterSound, s32* returnValue); void smlua_call_event_hooks_mario_action_params_ret_int(enum LuaHookedEventType hookType, struct MarioState *m, u32 action, u32* returnValue); void smlua_call_event_hooks_mario_param_and_int_ret_bool(enum LuaHookedEventType hookType, struct MarioState* m, s32 param, bool* returnValue); +bool smlua_call_event_hooks_mario_param_and_int_ret_int(enum LuaHookedEventType hookType, struct MarioState* m, s32 param, s32* returnValue); +bool smlua_call_event_hooks_mario_param_and_int_and_int_ret_int(enum LuaHookedEventType hookType, struct MarioState* m, s32 param, u32 args, s32* returnValue); enum BehaviorId smlua_get_original_behavior_id(const BehaviorScript* behavior); const BehaviorScript* smlua_override_behavior(const BehaviorScript* behavior); From fc195495c8cd731a611d3be6d5db2a4dcf0c2b71 Mon Sep 17 00:00:00 2001 From: Motoo Chhotoo Chintoo <72434298+motoo-tobbler@users.noreply.github.com> Date: Thu, 1 Jun 2023 13:19:43 +0530 Subject: [PATCH 2/2] Added a shell-script for MacOS systems. (#403) This commit adds a shell-script to the root folder. The script serves the purpose of downloading and compiling the source code of libjuice library, and copying it to the appropriate location. This script is only intended for MacOS. --- mac-intel-essential.sh | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 mac-intel-essential.sh diff --git a/mac-intel-essential.sh b/mac-intel-essential.sh new file mode 100644 index 000000000..0965bc670 --- /dev/null +++ b/mac-intel-essential.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +#Download +echo Downloading: libjuice +dl_ver=1.2.2 +curl -L https://github.com/paullouisageneau/libjuice/archive/refs/tags/v"$dl_ver".tar.gz -o libjuice.tar.gz +tar -xf libjuice.tar.gz + +#Compilation +echo ' +Compiling: libjuice' +cd libjuice-"$dl_ver" +cmake -B build && cd build +make -j2 + +#Copy to lib/coopnet/mac/libjuice.dylib +echo " +Copying: libjuice to 'lib/coopnet/mac'" +cp libjuice."$dl_ver".dylib ../../lib/coopnet/mac/libjuice."$dl_ver".dylib + +echo Done