Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion autogen/lua_definitions/constants.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8223,7 +8223,9 @@ HOOK_ON_FIND_WATER_LEVEL = 63 --- @type LuaHookedEventType
HOOK_ON_FIND_POISON_GAS_LEVEL = 64 --- @type LuaHookedEventType
HOOK_ON_FIND_SURFACE_ON_RAY = 65 --- @type LuaHookedEventType
HOOK_ON_DYNOS_PACK_TOGGLED = 66 --- @type LuaHookedEventType
HOOK_MAX = 67 --- @type LuaHookedEventType
HOOK_BEFORE_PLAY_MODE_UPDATE = 67 --- @type LuaHookedEventType
HOOK_ON_PLAY_MODE_UPDATE = 68 --- @type LuaHookedEventType
HOOK_MAX = 69 --- @type LuaHookedEventType

--- @alias LuaHookedEventType
--- | `HOOK_UPDATE`
Expand Down Expand Up @@ -8293,6 +8295,8 @@ HOOK_MAX = 67 --- @type LuaHookedEventType
--- | `HOOK_ON_FIND_POISON_GAS_LEVEL`
--- | `HOOK_ON_FIND_SURFACE_ON_RAY`
--- | `HOOK_ON_DYNOS_PACK_TOGGLED`
--- | `HOOK_BEFORE_PLAY_MODE_UPDATE`
--- | `HOOK_ON_PLAY_MODE_UPDATE`
--- | `HOOK_MAX`

--- @type integer
Expand Down
4 changes: 3 additions & 1 deletion docs/lua/constants.md
Original file line number Diff line number Diff line change
Expand Up @@ -3547,7 +3547,9 @@
| HOOK_ON_FIND_POISON_GAS_LEVEL | 64 |
| HOOK_ON_FIND_SURFACE_ON_RAY | 65 |
| HOOK_ON_DYNOS_PACK_TOGGLED | 66 |
| HOOK_MAX | 67 |
| HOOK_BEFORE_PLAY_MODE_UPDATE | 67 |
| HOOK_ON_PLAY_MODE_UPDATE | 68 |
| HOOK_MAX | 69 |
- MAX_HOOKED_BEHAVIORS

[:arrow_up_small:](#)
Expand Down
4 changes: 3 additions & 1 deletion docs/lua/guides/hooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ The lua functions sent to `hook_event()` will be automatically called by SM64 wh
| HOOK_ON_GEO_PROCESS | Called when a GeoLayout is processed **Note:** You must set the `hookProcess` field of the graph node to a non-zero value | [GraphNode](../structs.md#GraphNode) graphNode, `integer` matStackIndex |
| HOOK_BEFORE_GEO_PROCESS | Called before a GeoLayout is processed **Note:** You must set the `hookProcess` field of the graph node to a non-zero value | [GraphNode](../structs.md#GraphNode) graphNode, `integer` matStackIndex |
| HOOK_ON_GEO_PROCESS_CHILDREN | Called when the children of a GeoLayout node is processed **Note:** You must set the `hookProcess` field of the parent graph node to a non-zero value | [GraphNode](../structs.md#GraphNode) graphNode, `integer` matStackIndex |
| HOOK_MARIO_OVERRIDE_GEOMETRY_INPUTS | Called before running Mario's geometry input logic, return `false` to not run it. | [MarioState](../structs.md) m |
| HOOK_MARIO_OVERRIDE_GEOMETRY_INPUTS | Called before running Mario's geometry input logic, return `false` to not run it. | [MarioState](../structs.md) m |
| HOOK_ON_INTERACTIONS | Called when the Mario interactions are processed | [MarioState](../structs.md#MarioState) mario |
| HOOK_ALLOW_FORCE_WATER_ACTION | Called when executing a non-water action while under the water's surface, or vice versa. Return `false` to prevent the player from being forced out of the action at the water's surface | [MarioState](../structs.md#MarioState) mario, `boolean` isInWaterAction |
| HOOK_BEFORE_WARP | Called before the local player warps. Return a table with `destLevel`, `destArea`, `destWarpNode`, to override the warp | `integer` destLevel, `integer` destArea, `integer` destWarpNode, `integer` arg |
Expand All @@ -158,6 +158,8 @@ The lua functions sent to `hook_event()` will be automatically called by SM64 wh
| HOOK_ON_FIND_POISON_GAS_LEVEL | Called after poison gas level detection completes. Return a number to override the gas level | `number` x, `number` z, `number` gasLevel |
| HOOK_ON_FIND_SURFACE_ON_RAY | Called after ray-surface intersection completes. Return `surface` to override the hit surface, or `surface, hitPos` to override both | `Vec3f` orig, `Vec3f` dir, [Surface](../structs.md#Surface) hitSurface, `Vec3f` hitPos |
| HOOK_ON_DYNOS_PACK_TOGGLED | Called after a DynOS pack is toggled | `string` dynosPackName, `boolean` enabled |
| HOOK_BEFORE_PLAY_MODE_UPDATE | Called before the play mode is ran. Return a number to override the play mode to be ran. | `number` playMode |
| HOOK_ON_PLAY_MODE_UPDATE | Called after the play mode is ran. Return a number to override the change level. | `number` playMode |

### Parameters

Expand Down
1 change: 1 addition & 0 deletions src/game/behaviors/bbh_tilting_trap.inc.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ void bhv_bbh_tilting_trap_platform_loop(void) {
u8 playersTouched = 0;
for (s32 i = 0; i < MAX_PLAYERS; i++) {
if (!is_player_active(&gMarioStates[i])) { continue; }
if (gMarioStates[i].marioObj == NULL) { continue; }
if (gMarioStates[i].marioObj->platform == o) {
x += gMarioStates[i].marioObj->oPosX;
y += gMarioStates[i].marioObj->oPosY;
Expand Down
1 change: 1 addition & 0 deletions src/game/behaviors/controllable_platform.inc.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ void controllable_platform_tilt_from_mario(void) {
f32 z = 0;

for (s32 i = 0; i < MAX_PLAYERS; i++) {
if (gMarioStates[i].marioObj == NULL) { continue; }
if (gMarioStates[i].marioObj->platform == o || gMarioStates[i].marioObj->platform == cur_obj_nearest_object_with_behavior(bhvControllablePlatformSub)) {
x += gMarioStates[i].pos[0];
z += gMarioStates[i].pos[2];
Expand Down
1 change: 1 addition & 0 deletions src/game/behaviors/dorrie.inc.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ void dorrie_act_raise_head(void) {

for (s32 i = 0; i < MAX_PLAYERS; i++) {
if (!is_player_active(&gMarioStates[i])) { continue; }
if (gMarioStates[i].marioObj == NULL) { continue; }
if (gMarioStates[i].marioObj->platform != o) { continue; }
s32 dist = dist_between_objects(o, gMarioStates[0].marioObj);
if (dist <= 780.0f) { continue; }
Expand Down
1 change: 1 addition & 0 deletions src/game/behaviors/floating_platform.inc.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ void floating_platform_act_0(void) {
u8 playersTouched = 0;
for (s32 i = 0; i < MAX_PLAYERS; i++) {
if (!is_player_active(&gMarioStates[i])) { continue; }
if (gMarioStates[i].marioObj == NULL) { continue; }
if (gMarioStates[i].marioObj->platform == o) {
x += gMarioStates[i].marioObj->oPosX;
z += gMarioStates[i].marioObj->oPosZ;
Expand Down
1 change: 1 addition & 0 deletions src/game/behaviors/platform_on_track.inc.c
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ static void platform_on_track_rock_ski_lift(void) {
struct Object* player = NULL;
for (s32 i = 0; i < MAX_PLAYERS; i++) {
if (!is_player_active(&gMarioStates[i])) { continue; }
if (gMarioStates[i].marioObj == NULL) { continue; }
if (gMarioStates[i].marioObj->platform != o) { continue; }
player = gMarioStates[i].marioObj;
break;
Expand Down
1 change: 1 addition & 0 deletions src/game/behaviors/seesaw_platform.inc.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ void bhv_seesaw_platform_update(void) {
u8 playersTouched = 0;
for (s32 i = 0; i < MAX_PLAYERS; i++) {
if (!is_player_active(&gMarioStates[i])) { continue; }
if (gMarioStates[i].marioObj == NULL) { continue; }
if (gMarioStates[i].marioObj->platform == o) {
x += gMarioStates[i].marioObj->oPosX;
y += gMarioStates[i].marioObj->oPosY;
Expand Down
3 changes: 2 additions & 1 deletion src/game/behaviors/tilting_inverted_pyramid.inc.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ void bhv_tilting_inverted_pyramid_loop(void) {
u8 playersTouched = 0;
for (s32 i = 0; i < MAX_PLAYERS; i++) {
if (!is_player_active(&gMarioStates[i])) { continue; }
if (gMarioStates[i].marioObj == NULL) { continue; }
if (gMarioStates[i].marioObj->platform != o) { continue; }
x += gMarioStates[i].marioObj->oPosX;
y += gMarioStates[i].marioObj->oPosY;
Expand Down Expand Up @@ -135,7 +136,7 @@ void bhv_tilting_inverted_pyramid_loop(void) {
o->oTiltingPyramidMarioOnPlatform = FALSE;
}

// Approach the normals by 0.01f towards the new goal, then create a transform matrix and orient the object.
// Approach the normals by 0.01f towards the new goal, then create a transform matrix and orient the object.
// Outside of the other conditionals since it needs to tilt regardless of whether Mario is on.
o->oTiltingPyramidNormalX = approach_by_increment(dx, o->oTiltingPyramidNormalX, 0.01f);
o->oTiltingPyramidNormalY = approach_by_increment(dy, o->oTiltingPyramidNormalY, 0.01f);
Expand Down
62 changes: 39 additions & 23 deletions src/game/level_update.c
Original file line number Diff line number Diff line change
Expand Up @@ -1503,6 +1503,44 @@ UNUSED static s32 play_mode_unused(void) {
return 0;
}

s32 update_current_play_mode() {
s32 changeLevel = 0;

s16 hookPlaymode = sCurrPlayMode;
if (smlua_call_event_hooks(HOOK_BEFORE_PLAY_MODE_UPDATE, sCurrPlayMode, &hookPlaymode)) {
sCurrPlayMode = hookPlaymode;
}

switch (sCurrPlayMode) {
case PLAY_MODE_NORMAL:
changeLevel = play_mode_normal();
break;
case PLAY_MODE_PAUSED:
if (!network_check_singleplayer_pause()) {
changeLevel = play_mode_normal();
}

if (sCurrPlayMode == PLAY_MODE_PAUSED) {
changeLevel = play_mode_paused();
}
break;
case PLAY_MODE_CHANGE_AREA:
changeLevel = play_mode_change_area();
break;
case PLAY_MODE_CHANGE_LEVEL:
changeLevel = play_mode_change_level();
break;
case PLAY_MODE_FRAME_ADVANCE:
changeLevel = play_mode_frame_advance();
break;
}
s32 hookChangeLevel = changeLevel;
if (smlua_call_event_hooks(HOOK_ON_PLAY_MODE_UPDATE, sCurrPlayMode, &hookChangeLevel)) {
changeLevel = hookChangeLevel;
}
return changeLevel;
}

void update_menu_level(void) {
// figure out level
s32 curLevel = 0;
Expand Down Expand Up @@ -1730,29 +1768,7 @@ s32 update_level(void) {
gCurrentArea->localAreaTimer++;
}

switch (sCurrPlayMode) {
case PLAY_MODE_NORMAL:
changeLevel = play_mode_normal();
break;
case PLAY_MODE_PAUSED:
if (!network_check_singleplayer_pause()) {
changeLevel = play_mode_normal();
}

if (sCurrPlayMode == PLAY_MODE_PAUSED) {
changeLevel = play_mode_paused();
}
break;
case PLAY_MODE_CHANGE_AREA:
changeLevel = play_mode_change_area();
break;
case PLAY_MODE_CHANGE_LEVEL:
changeLevel = play_mode_change_level();
break;
case PLAY_MODE_FRAME_ADVANCE:
changeLevel = play_mode_frame_advance();
break;
}
changeLevel = update_current_play_mode();

if (changeLevel) {
reset_volume();
Expand Down
4 changes: 3 additions & 1 deletion src/pc/lua/smlua_constants_autogen.c
Original file line number Diff line number Diff line change
Expand Up @@ -3557,7 +3557,9 @@ char gSmluaConstants[] = ""
"HOOK_ON_FIND_POISON_GAS_LEVEL=64\n"
"HOOK_ON_FIND_SURFACE_ON_RAY=65\n"
"HOOK_ON_DYNOS_PACK_TOGGLED=66\n"
"HOOK_MAX=67\n"
"HOOK_BEFORE_PLAY_MODE_UPDATE=67\n"
"HOOK_ON_PLAY_MODE_UPDATE=68\n"
"HOOK_MAX=69\n"
"MAX_HOOKED_BEHAVIORS=1024\n"
"HUD_DISPLAY_LIVES=0\n"
"HUD_DISPLAY_COINS=1\n"
Expand Down
2 changes: 2 additions & 0 deletions src/pc/lua/smlua_hook_events.inl
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,5 @@ SMLUA_EVENT_HOOK(HOOK_ON_FIND_WATER_LEVEL, _, f32 x, f32 z, f32 *waterLevel) //
SMLUA_EVENT_HOOK(HOOK_ON_FIND_POISON_GAS_LEVEL, _, f32 x, f32 z, f32 *gasLevel) // Manually defined hook
SMLUA_EVENT_HOOK(HOOK_ON_FIND_SURFACE_ON_RAY, _, Vec3f orig, Vec3f dir, struct Surface **hit_surface, Vec3f hit_pos) // Manually defined hook
SMLUA_EVENT_HOOK(HOOK_ON_DYNOS_PACK_TOGGLED, HOOK_RETURN_NEVER, const char *dynosPackName, bool enabled)
SMLUA_EVENT_HOOK(HOOK_BEFORE_PLAY_MODE_UPDATE, HOOK_RETURN_NEVER, s16 playmode, OUTPUT s16 *overridePlaymode)
SMLUA_EVENT_HOOK(HOOK_ON_PLAY_MODE_UPDATE, HOOK_RETURN_NEVER, s16 playmode, OUTPUT s32 *changeLevel)
64 changes: 64 additions & 0 deletions src/pc/lua/smlua_hook_events_autogen.inl
Original file line number Diff line number Diff line change
Expand Up @@ -1893,3 +1893,67 @@ bool smlua_call_event_hooks_HOOK_ON_DYNOS_PACK_TOGGLED(const char *dynosPackName
}
return hookResult;
}

bool smlua_call_event_hooks_HOOK_BEFORE_PLAY_MODE_UPDATE(s16 playmode, s16 *overridePlaymode) {
lua_State *L = gLuaState;
if (L == NULL) { return false; }
bool hookResult = false;

struct LuaHookedEvent *hook = &sHookedEvents[HOOK_BEFORE_PLAY_MODE_UPDATE];
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 playmode
lua_pushinteger(L, playmode);

// call the callback
if (0 != smlua_call_hook(L, 1, 1, 0, hook->mod[i], hook->modFile[i])) {
LOG_LUA("Failed to call the callback for hook %s - '%s/%s'", sLuaHookedEventTypeName[HOOK_BEFORE_PLAY_MODE_UPDATE], hook->mod[i]->relativePath, hook->modFile[i]->relativePath);
continue;
}
hookResult = true;

// return overridePlaymode
if (lua_type(L, -1) == LUA_TNUMBER) {
*overridePlaymode = smlua_to_integer(L, -1);
}

lua_settop(L, prevTop);
}
return hookResult;
}

bool smlua_call_event_hooks_HOOK_ON_PLAY_MODE_UPDATE(s16 playmode, s32 *changeLevel) {
lua_State *L = gLuaState;
if (L == NULL) { return false; }
bool hookResult = false;

struct LuaHookedEvent *hook = &sHookedEvents[HOOK_ON_PLAY_MODE_UPDATE];
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 playmode
lua_pushinteger(L, playmode);

// call the callback
if (0 != smlua_call_hook(L, 1, 1, 0, hook->mod[i], hook->modFile[i])) {
LOG_LUA("Failed to call the callback for hook %s - '%s/%s'", sLuaHookedEventTypeName[HOOK_ON_PLAY_MODE_UPDATE], hook->mod[i]->relativePath, hook->modFile[i]->relativePath);
continue;
}
hookResult = true;

// return changeLevel
if (lua_type(L, -1) == LUA_TNUMBER) {
*changeLevel = smlua_to_integer(L, -1);
}

lua_settop(L, prevTop);
}
return hookResult;
}
2 changes: 2 additions & 0 deletions src/pc/lua/smlua_hooks.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ enum LuaHookedEventType {
HOOK_ON_FIND_POISON_GAS_LEVEL,
HOOK_ON_FIND_SURFACE_ON_RAY,
HOOK_ON_DYNOS_PACK_TOGGLED,
HOOK_BEFORE_PLAY_MODE_UPDATE,
HOOK_ON_PLAY_MODE_UPDATE,
HOOK_MAX,
};

Expand Down