diff --git a/data/dynos_mgr_actor.cpp b/data/dynos_mgr_actor.cpp index d80adb44f..aa9056fb0 100644 --- a/data/dynos_mgr_actor.cpp +++ b/data/dynos_mgr_actor.cpp @@ -204,7 +204,7 @@ void DynOS_Actor_Override(struct Object* obj, void** aSharedChild) { if (it == _ValidActors.end()) { return; } // Check if the behavior uses a character specific model - if (obj && (obj->behavior == smlua_override_behavior(bhvMario) || + if (obj && (obj->behavior == bhvMario || obj->behavior == smlua_override_behavior(bhvNormalCap) || obj->behavior == smlua_override_behavior(bhvWingCap) || obj->behavior == smlua_override_behavior(bhvMetalCap) || diff --git a/src/game/behavior_actions.c b/src/game/behavior_actions.c index e6c358df8..1c8303a52 100644 --- a/src/game/behavior_actions.c +++ b/src/game/behavior_actions.c @@ -168,7 +168,7 @@ Gfx *geo_move_mario_part_from_parent(s32 run, UNUSED struct GraphNode *node, Mat if (run == TRUE) { sp1C = (struct Object *) gCurGraphNodeObject; - if (sp1C->behavior == smlua_override_behavior(bhvMario) && sp1C->prevObj != NULL) { + if (sp1C->behavior == bhvMario && sp1C->prevObj != NULL) { create_transformation_from_matrices(sp20, mtx, *gCurGraphNodeCamera->matrixPtr); obj_update_pos_from_parent_transformation(sp20, sp1C->prevObj); obj_set_gfx_pos_from_pos(sp1C->prevObj); diff --git a/src/game/behaviors/flame_mario.inc.c b/src/game/behaviors/flame_mario.inc.c index cbfa5c215..63f82c015 100644 --- a/src/game/behaviors/flame_mario.inc.c +++ b/src/game/behaviors/flame_mario.inc.c @@ -32,7 +32,7 @@ void bhv_black_smoke_mario_loop(void) { } void bhv_flame_mario_loop(void) { - if (o->parentObj == NULL || o->parentObj->behavior != smlua_override_behavior(bhvMario)) { + if (o->parentObj == NULL || o->parentObj->behavior != bhvMario) { obj_mark_for_deletion(o); return; } diff --git a/src/game/behaviors/water_mist_particle.inc.c b/src/game/behaviors/water_mist_particle.inc.c index f47a22bf2..9780ade70 100644 --- a/src/game/behaviors/water_mist_particle.inc.c +++ b/src/game/behaviors/water_mist_particle.inc.c @@ -3,7 +3,7 @@ void bhv_water_mist_spawn_loop(void) { clear_particle_flags(0x20000); - if (o->parentObj == NULL || o->parentObj->behavior != smlua_override_behavior(bhvMario)) { + if (o->parentObj == NULL || o->parentObj->behavior != bhvMario) { obj_mark_for_deletion(o); return; } @@ -11,7 +11,7 @@ void bhv_water_mist_spawn_loop(void) { } void bhv_water_mist_loop(void) { - if (o->parentObj == NULL || o->parentObj->behavior != smlua_override_behavior(bhvMario)) { + if (o->parentObj == NULL || o->parentObj->behavior != bhvMario) { obj_mark_for_deletion(o); return; } diff --git a/src/game/behaviors/water_splashes_and_waves.inc.c b/src/game/behaviors/water_splashes_and_waves.inc.c index b5c52ac15..c555306a0 100644 --- a/src/game/behaviors/water_splashes_and_waves.inc.c +++ b/src/game/behaviors/water_splashes_and_waves.inc.c @@ -93,7 +93,7 @@ void bhv_water_droplet_loop(void) { } void bhv_idle_water_wave_loop(void) { - if (o->parentObj == NULL || o->parentObj->behavior != smlua_override_behavior(bhvMario)) { + if (o->parentObj == NULL || o->parentObj->behavior != bhvMario) { obj_mark_for_deletion(o); return; } diff --git a/src/game/mario.c b/src/game/mario.c index 8858ae372..7d0b3e69c 100644 --- a/src/game/mario.c +++ b/src/game/mario.c @@ -2404,11 +2404,10 @@ void mario_update_wall(struct MarioState* m, struct WallCollisionData* wcd) { struct MarioState *get_mario_state_from_object(struct Object *o) { if (!o) { return NULL; } - for (s32 i = 0; i != MAX_PLAYERS; ++i) { - struct MarioState *m = &gMarioStates[i]; - if (m->marioObj == o) { - return m; - } + if (o->behavior != bhvMario) { return NULL; } + s32 stateIndex = o->oBehParams - 1; + if (stateIndex >= 0 && stateIndex < MAX_PLAYERS) { + return &gMarioStates[stateIndex]; } return NULL; } diff --git a/src/game/mario_misc.c b/src/game/mario_misc.c index 8e4e62f26..02644b79b 100644 --- a/src/game/mario_misc.c +++ b/src/game/mario_misc.c @@ -359,7 +359,7 @@ s8 geo_get_processing_mario_index(void) { return index; } - if (gCurGraphNodeProcessingObject->behavior != smlua_override_behavior(bhvMario)) { + if (gCurGraphNodeProcessingObject->behavior != bhvMario) { return -1; } diff --git a/src/game/object_list_processor.c b/src/game/object_list_processor.c index ec0534d05..e6f8c0adf 100644 --- a/src/game/object_list_processor.c +++ b/src/game/object_list_processor.c @@ -558,7 +558,7 @@ void spawn_objects_from_info(UNUSED s32 unused, struct SpawnInfo *spawnInfo) { object->respawnInfo = &spawnInfo->behaviorArg; // found a player - if (spawnInfo->behaviorArg & ((u32)1 << 31) && object->behavior == smlua_override_behavior(bhvMario)) { + if (spawnInfo->behaviorArg & ((u32)1 << 31) && object->behavior == bhvMario) { u16 playerIndex = (spawnInfo->behaviorArg & ~(1 << 31)); object->oBehParams = playerIndex + 1; gMarioObjects[playerIndex] = object; diff --git a/src/game/rendering_graph_node.c b/src/game/rendering_graph_node.c index e4699d835..a97fbfffc 100644 --- a/src/game/rendering_graph_node.c +++ b/src/game/rendering_graph_node.c @@ -18,6 +18,7 @@ #include "game/first_person_cam.h" #include "course_table.h" #include "skybox.h" +#include "mario.h" /** * This file contains the code that processes the scene graph for rendering. @@ -1227,12 +1228,8 @@ static void geo_sanitize_object_gfx(void) { } static struct MarioBodyState *get_mario_body_state_from_mario_object(struct Object *marioObj) { - for (s32 i = 0; i < MAX_PLAYERS; ++i) { - struct MarioState *m = &gMarioStates[i]; - if (m->marioObj == marioObj) { - return m->marioBodyState; - } - } + struct MarioState *m = get_mario_state_from_object(marioObj); + if (m) { return m->marioBodyState; } return NULL; } @@ -1262,13 +1259,7 @@ static void geo_process_object(struct Object *node) { } if (node->header.gfx.node.flags & GRAPH_RENDER_PLAYER) { - gCurGraphNodeMarioState = NULL; - for (s32 i = 0; i < MAX_PLAYERS; i++) { - if (gMarioStates[i].marioObj == node) { - gCurGraphNodeMarioState = &gMarioStates[i]; - break; - } - } + gCurGraphNodeMarioState = get_mario_state_from_object(node); if (gCurGraphNodeMarioState != NULL) { gCurGraphNodeMarioState->minimumBoneY = 9999; } @@ -1390,9 +1381,11 @@ static void geo_process_object(struct Object *node) { gMatStackPrevFixed[gMatStackIndex] = mtxPrev; if (node->header.gfx.sharedChild != NULL) { - gCurMarioBodyState = get_mario_body_state_from_mario_object(node); - if (gCurMarioBodyState) { - gCurMarioBodyState->currAnimPart = MARIO_ANIM_PART_NONE; + if (node->header.gfx.node.flags & GRAPH_RENDER_PLAYER) { + gCurMarioBodyState = get_mario_body_state_from_mario_object(node); + if (gCurMarioBodyState) { + gCurMarioBodyState->currAnimPart = MARIO_ANIM_PART_NONE; + } } gCurGraphNodeObject = (struct GraphNodeObject *) node; node->header.gfx.sharedChild->parent = &node->header.gfx.node; diff --git a/src/game/spawn_object.c b/src/game/spawn_object.c index c0e6f40a3..d0e4c65ca 100644 --- a/src/game/spawn_object.c +++ b/src/game/spawn_object.c @@ -220,7 +220,7 @@ void unload_object(struct Object *obj) { obj->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE; // Clear Mario object pointers - if (obj->behavior == smlua_override_behavior(bhvMario)) { + if (obj->behavior == bhvMario) { u8 playerIndex = obj->oBehParams - 1; if (playerIndex < MAX_PLAYERS) { gMarioObjects[playerIndex] = NULL; diff --git a/src/pc/lua/smlua_hooks.c b/src/pc/lua/smlua_hooks.c index e0cf01b9b..2c7ed2329 100644 --- a/src/pc/lua/smlua_hooks.c +++ b/src/pc/lua/smlua_hooks.c @@ -452,6 +452,12 @@ int smlua_hook_custom_bhv(BehaviorScript *bhvScript, const char *bhvName) { } u32 originalBehaviorId = get_id_from_behavior(bhvScript); + + if (originalBehaviorId == id_bhvMario) { + LOG_LUA_LINE("Cannot hook Mario's behavior. Use HOOK_MARIO_UPDATE and HOOK_BEFORE_MARIO_UPDATE."); + return 0; + } + u8 newBehavior = originalBehaviorId >= id_bhv_max_count; struct LuaHookedBehavior *hooked = &sHookedBehaviors[sHookedBehaviorsCount]; @@ -507,6 +513,11 @@ int smlua_hook_behavior(lua_State* L) { return 0; } + if (overrideBehaviorId == id_bhvMario) { + LOG_LUA_LINE("Hook behavior: cannot hook Mario's behavior. Use HOOK_MARIO_UPDATE and HOOK_BEFORE_MARIO_UPDATE."); + return 0; + } + lua_Integer objectList = smlua_to_integer(L, 2); if (objectList <= 0 || objectList >= NUM_OBJ_LISTS || !gSmLuaConvertSuccess) { LOG_LUA_LINE("Hook behavior: tried use invalid object list: %lld, %u", objectList, gSmLuaConvertSuccess); diff --git a/src/pc/network/network_player.c b/src/pc/network/network_player.c index 7b5294b5a..5e1661bbb 100644 --- a/src/pc/network/network_player.c +++ b/src/pc/network/network_player.c @@ -59,7 +59,7 @@ void network_player_update_model(u8 localIndex) { if (index >= CT_MAX) { index = 0; } m->character = &gCharacters[index]; - if (m->marioObj == NULL || m->marioObj->behavior != smlua_override_behavior(bhvMario)) { return; } + if (m->marioObj == NULL || m->marioObj->behavior != bhvMario) { return; } obj_set_model(m->marioObj, m->character->modelId); } diff --git a/src/pc/network/packets/packet_spawn_star.c b/src/pc/network/packets/packet_spawn_star.c index 057bbd849..f22fbf436 100644 --- a/src/pc/network/packets/packet_spawn_star.c +++ b/src/pc/network/packets/packet_spawn_star.c @@ -75,7 +75,7 @@ void network_receive_spawn_star(struct Packet* p) { void network_send_spawn_star_nle(struct Object* o, u32 params) { if (!o) { return; } u8 globalIndex = UNKNOWN_GLOBAL_INDEX; - if (o->behavior == smlua_override_behavior(bhvMario)) { + if (o->behavior == bhvMario) { u8 localIndex = o->oBehParams - 1; if (localIndex < MAX_PLAYERS) { globalIndex = gNetworkPlayers[localIndex].globalIndex; } }