From d37ba32989386a60afe0709ccdb9c528895401be Mon Sep 17 00:00:00 2001 From: PeachyPeach <72323920+PeachyPeachSM64@users.noreply.github.com> Date: Sat, 5 Mar 2022 23:39:55 +0100 Subject: [PATCH 1/2] Added obj_has_behavior_id and obj_has_model_extended functions; break bhvBreakableBoxSmall objects without a wall collision by setting some flags in oInteractStatus (#12) * Added obj_has_behavior_id and obj_has_model_extended functions; break bhvBreakableBoxSmall objects without a wall collision by setting some flags in oInteractStatus --- docs/lua/functions.md | 44 ++++++++++++++++++++ src/game/behaviors/breakable_box_small.inc.c | 4 +- src/pc/lua/smlua_functions_autogen.c | 28 +++++++++++++ src/pc/lua/smlua_obj_utils.c | 10 +++++ src/pc/lua/smlua_obj_utils.h | 2 + 5 files changed, 87 insertions(+), 1 deletion(-) diff --git a/docs/lua/functions.md b/docs/lua/functions.md index 5a9cc8d7..68628397 100644 --- a/docs/lua/functions.md +++ b/docs/lua/functions.md @@ -631,6 +631,8 @@ - [obj_get_next_with_same_behavior_id](#obj_get_next_with_same_behavior_id) - [obj_get_next_with_same_behavior_id_and_field_f32](#obj_get_next_with_same_behavior_id_and_field_f32) - [obj_get_next_with_same_behavior_id_and_field_s32](#obj_get_next_with_same_behavior_id_and_field_s32) + - [obj_has_behavior_id](#obj_has_behavior_id) + - [obj_has_model_extended](#obj_has_model_extended) - [obj_set_model_extended](#obj_set_model_extended) - [spawn_sync_object](#spawn_sync_object) @@ -11593,6 +11595,48 @@ The `reliable` field will ensure that the packet arrives, but should be used spa
+## [obj_has_behavior_id](#obj_has_behavior_id) + +### Lua Example +`local integerValue = obj_has_behavior_id(o, behaviorId)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | +| behaviorId | [enum BehaviorId](constants.md#enum-BehaviorId) | + +### Returns +- `integer` + +### C Prototype +`s32 obj_has_behavior_id(struct Object *o, enum BehaviorId behaviorId);` + +[:arrow_up_small:](#) + +
+ +## [obj_has_model_extended](#obj_has_model_extended) + +### Lua Example +`local integerValue = obj_has_model_extended(o, modelId)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | +| modelId | [enum ModelExtendedId](constants.md#enum-ModelExtendedId) | + +### Returns +- `integer` + +### C Prototype +`s32 obj_has_model_extended(struct Object *o, enum ModelExtendedId modelId);` + +[:arrow_up_small:](#) + +
+ ## [obj_set_model_extended](#obj_set_model_extended) ### Lua Example diff --git a/src/game/behaviors/breakable_box_small.inc.c b/src/game/behaviors/breakable_box_small.inc.c index bcdab9c9..cf4923fd 100644 --- a/src/game/behaviors/breakable_box_small.inc.c +++ b/src/game/behaviors/breakable_box_small.inc.c @@ -47,7 +47,9 @@ void small_breakable_box_act_move(void) { } } - if (sp1E & 2) { + // Set these flags to break the small box without a wall collision + s32 breakStatus = ATTACK_KICK_OR_TRIP | INT_STATUS_INTERACTED | INT_STATUS_WAS_ATTACKED | INT_STATUS_STOP_RIDING; + if ((sp1E & 2) || (o->oInteractStatus & breakStatus) == breakStatus) { spawn_mist_particles(); spawn_triangle_break_particles(20, 138, 0.7f, 3); obj_spawn_yellow_coins(o, 3); diff --git a/src/pc/lua/smlua_functions_autogen.c b/src/pc/lua/smlua_functions_autogen.c index bb9a0b7d..276c4b26 100644 --- a/src/pc/lua/smlua_functions_autogen.c +++ b/src/pc/lua/smlua_functions_autogen.c @@ -7397,6 +7397,32 @@ int smlua_func_obj_get_next_with_same_behavior_id_and_field_s32(lua_State* L) { return 1; } +int smlua_func_obj_has_behavior_id(lua_State* L) { + if(!smlua_functions_valid_param_count(L, 2)) { return 0; } + + struct Object* o = (struct Object*)smlua_to_cobject(L, 1, LOT_OBJECT); + if (!gSmLuaConvertSuccess) { return 0; } + int behaviorId = smlua_to_integer(L, 2); + if (!gSmLuaConvertSuccess) { return 0; } + + lua_pushinteger(L, obj_has_behavior_id(o, behaviorId)); + + return 1; +} + +int smlua_func_obj_has_model_extended(lua_State* L) { + if(!smlua_functions_valid_param_count(L, 2)) { return 0; } + + struct Object* o = (struct Object*)smlua_to_cobject(L, 1, LOT_OBJECT); + if (!gSmLuaConvertSuccess) { return 0; } + int modelId = smlua_to_integer(L, 2); + if (!gSmLuaConvertSuccess) { return 0; } + + lua_pushinteger(L, obj_has_model_extended(o, modelId)); + + return 1; +} + int smlua_func_obj_set_model_extended(lua_State* L) { if(!smlua_functions_valid_param_count(L, 2)) { return 0; } @@ -8493,6 +8519,8 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "obj_get_next_with_same_behavior_id", smlua_func_obj_get_next_with_same_behavior_id); smlua_bind_function(L, "obj_get_next_with_same_behavior_id_and_field_f32", smlua_func_obj_get_next_with_same_behavior_id_and_field_f32); smlua_bind_function(L, "obj_get_next_with_same_behavior_id_and_field_s32", smlua_func_obj_get_next_with_same_behavior_id_and_field_s32); + smlua_bind_function(L, "obj_has_behavior_id", smlua_func_obj_has_behavior_id); + smlua_bind_function(L, "obj_has_model_extended", smlua_func_obj_has_model_extended); smlua_bind_function(L, "obj_set_model_extended", smlua_func_obj_set_model_extended); smlua_bind_function(L, "spawn_sync_object", smlua_func_spawn_sync_object); diff --git a/src/pc/lua/smlua_obj_utils.c b/src/pc/lua/smlua_obj_utils.c index a2971205..c570a136 100644 --- a/src/pc/lua/smlua_obj_utils.c +++ b/src/pc/lua/smlua_obj_utils.c @@ -78,6 +78,16 @@ struct Object* spawn_non_sync_object(enum BehaviorId behaviorId, enum ModelExten spawn_object_internal(behaviorId, modelId, x, y, z, 0, false); } +s32 obj_has_behavior_id(struct Object *o, enum BehaviorId behaviorId) { + const BehaviorScript *behavior = get_behavior_from_id(behaviorId); + return o->behavior == behavior; +} + +s32 obj_has_model_extended(struct Object *o, enum ModelExtendedId modelId) { + struct GraphNode *model = gLoadedGraphNodes[smlua_model_util_load(modelId)]; + return o->header.gfx.sharedChild == model; +} + void obj_set_model_extended(struct Object *o, enum ModelExtendedId modelId) { o->header.gfx.sharedChild = gLoadedGraphNodes[smlua_model_util_load(modelId)]; } diff --git a/src/pc/lua/smlua_obj_utils.h b/src/pc/lua/smlua_obj_utils.h index 8cda418f..494d7aa7 100644 --- a/src/pc/lua/smlua_obj_utils.h +++ b/src/pc/lua/smlua_obj_utils.h @@ -10,6 +10,8 @@ struct Object* spawn_sync_object(enum BehaviorId behaviorId, enum ModelExtendedI // this is too dangerous for now //struct Object* spawn_non_sync_object(enum BehaviorId behaviorId, enum ModelExtendedId modelId, f32 x, f32 y, f32 z); +s32 obj_has_behavior_id(struct Object *o, enum BehaviorId behaviorId); +s32 obj_has_model_extended(struct Object *o, enum ModelExtendedId modelId); void obj_set_model_extended(struct Object *o, enum ModelExtendedId modelId); // From b97834a03e01b03f23d1c20df99cf16a09ace3a3 Mon Sep 17 00:00:00 2001 From: Amy54Desu <69287652+Amy54Desu@users.noreply.github.com> Date: Sat, 5 Mar 2022 18:09:35 -0500 Subject: [PATCH 2/2] This should solve the problem where players can reset the drowning animation under water. (#13) This solves the issues where punching someone under water resets their drowning animation. This is done by setting their invincibility timer to 2. I chose 2 so they don't begin flashing since that would look weird. --- src/game/mario_actions_submerged.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/game/mario_actions_submerged.c b/src/game/mario_actions_submerged.c index 542c67b6..47a9c1e8 100644 --- a/src/game/mario_actions_submerged.c +++ b/src/game/mario_actions_submerged.c @@ -940,6 +940,7 @@ static s32 act_drowning(struct MarioState *m) { play_character_sound_if_no_flag(m, CHAR_SOUND_DROWNING, MARIO_ACTION_SOUND_PLAYED); stationary_slow_down(m); perform_water_step(m); + m->invincTimer = 2; return FALSE; } @@ -949,6 +950,7 @@ static s32 act_water_death(struct MarioState *m) { perform_water_step(m); m->marioBodyState->eyeState = MARIO_EYES_DEAD; + m->invincTimer = 2; set_mario_animation(m, MARIO_ANIM_WATER_DYING); if (set_mario_animation(m, MARIO_ANIM_WATER_DYING) == 35) {