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