diff --git a/autogen/lua_definitions/constants.lua b/autogen/lua_definitions/constants.lua index a3143cc5..dfd74aa6 100644 --- a/autogen/lua_definitions/constants.lua +++ b/autogen/lua_definitions/constants.lua @@ -12584,9 +12584,21 @@ GRAPH_NODE_GUARD = 0xAA --- @type integer MAX_PLAYERS = 16 +--- @type integer +OBJECT_CUSTOM_FIELDS_START = (OBJECT_NUM_REGULAR_FIELDS) + --- @type integer OBJECT_MAX_BHV_STACK = 16 +--- @type integer +OBJECT_NUM_CUSTOM_FIELDS = 0x10 + +--- @type integer +OBJECT_NUM_FIELDS = (OBJECT_CUSTOM_FIELDS_START + OBJECT_NUM_CUSTOM_FIELDS) + +--- @type integer +OBJECT_NUM_REGULAR_FIELDS = 0x50 + --- @type integer PLAY_MODE_CHANGE_AREA = 3 diff --git a/autogen/lua_definitions/functions.lua b/autogen/lua_definitions/functions.lua index 172ac491..b9acd8cd 100644 --- a/autogen/lua_definitions/functions.lua +++ b/autogen/lua_definitions/functions.lua @@ -9386,6 +9386,35 @@ function obj_get_collided_object(o, index) -- ... end +--- @param o Object +--- @param fieldIndex integer +--- @return number +function obj_get_field_f32(o, fieldIndex) + -- ... +end + +--- @param o Object +--- @param fieldIndex integer +--- @param fieldSubIndex integer +--- @return integer +function obj_get_field_s16(o, fieldIndex, fieldSubIndex) + -- ... +end + +--- @param o Object +--- @param fieldIndex integer +--- @return integer +function obj_get_field_s32(o, fieldIndex) + -- ... +end + +--- @param o Object +--- @param fieldIndex integer +--- @return integer +function obj_get_field_u32(o, fieldIndex) + -- ... +end + --- @param objList ObjectList --- @return Object function obj_get_first(objList) @@ -9532,6 +9561,39 @@ function obj_move_xyz(o, dx, dy, dz) -- ... end +--- @param o Object +--- @param fieldIndex integer +--- @param value number +--- @return nil +function obj_set_field_f32(o, fieldIndex, value) + -- ... +end + +--- @param o Object +--- @param fieldIndex integer +--- @param fieldSubIndex integer +--- @param value integer +--- @return nil +function obj_set_field_s16(o, fieldIndex, fieldSubIndex, value) + -- ... +end + +--- @param o Object +--- @param fieldIndex integer +--- @param value integer +--- @return nil +function obj_set_field_s32(o, fieldIndex, value) + -- ... +end + +--- @param o Object +--- @param fieldIndex integer +--- @param value integer +--- @return nil +function obj_set_field_u32(o, fieldIndex, value) + -- ... +end + --- @param o Object --- @param modelId ModelExtendedId --- @return nil diff --git a/docs/lua/constants.md b/docs/lua/constants.md index f180873e..2deced44 100644 --- a/docs/lua/constants.md +++ b/docs/lua/constants.md @@ -4459,7 +4459,11 @@ - COOP_OBJ_FLAG_NON_SYNC - GRAPH_NODE_GUARD - MAX_PLAYERS +- OBJECT_CUSTOM_FIELDS_START - OBJECT_MAX_BHV_STACK +- OBJECT_NUM_CUSTOM_FIELDS +- OBJECT_NUM_FIELDS +- OBJECT_NUM_REGULAR_FIELDS - PLAY_MODE_CHANGE_AREA - PLAY_MODE_CHANGE_LEVEL - PLAY_MODE_FRAME_ADVANCE diff --git a/docs/lua/functions-5.md b/docs/lua/functions-5.md index 2383065f..88d79b70 100644 --- a/docs/lua/functions-5.md +++ b/docs/lua/functions-5.md @@ -2618,6 +2618,91 @@
+## [obj_get_field_f32](#obj_get_field_f32) + +### Lua Example +`local numberValue = obj_get_field_f32(o, fieldIndex)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | +| fieldIndex | `integer` | + +### Returns +- `number` + +### C Prototype +`f32 obj_get_field_f32(struct Object *o, s32 fieldIndex);` + +[:arrow_up_small:](#) + +
+ +## [obj_get_field_s16](#obj_get_field_s16) + +### Lua Example +`local integerValue = obj_get_field_s16(o, fieldIndex, fieldSubIndex)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | +| fieldIndex | `integer` | +| fieldSubIndex | `integer` | + +### Returns +- `integer` + +### C Prototype +`s16 obj_get_field_s16(struct Object *o, s32 fieldIndex, s32 fieldSubIndex);` + +[:arrow_up_small:](#) + +
+ +## [obj_get_field_s32](#obj_get_field_s32) + +### Lua Example +`local integerValue = obj_get_field_s32(o, fieldIndex)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | +| fieldIndex | `integer` | + +### Returns +- `integer` + +### C Prototype +`s32 obj_get_field_s32(struct Object *o, s32 fieldIndex);` + +[:arrow_up_small:](#) + +
+ +## [obj_get_field_u32](#obj_get_field_u32) + +### Lua Example +`local integerValue = obj_get_field_u32(o, fieldIndex)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | +| fieldIndex | `integer` | + +### Returns +- `integer` + +### C Prototype +`u32 obj_get_field_u32(struct Object *o, s32 fieldIndex);` + +[:arrow_up_small:](#) + +
+ ## [obj_get_first](#obj_get_first) ### Lua Example @@ -3072,6 +3157,95 @@
+## [obj_set_field_f32](#obj_set_field_f32) + +### Lua Example +`obj_set_field_f32(o, fieldIndex, value)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | +| fieldIndex | `integer` | +| value | `number` | + +### Returns +- None + +### C Prototype +`void obj_set_field_f32(struct Object *o, s32 fieldIndex, f32 value);` + +[:arrow_up_small:](#) + +
+ +## [obj_set_field_s16](#obj_set_field_s16) + +### Lua Example +`obj_set_field_s16(o, fieldIndex, fieldSubIndex, value)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | +| fieldIndex | `integer` | +| fieldSubIndex | `integer` | +| value | `integer` | + +### Returns +- None + +### C Prototype +`void obj_set_field_s16(struct Object *o, s32 fieldIndex, s32 fieldSubIndex, s16 value);` + +[:arrow_up_small:](#) + +
+ +## [obj_set_field_s32](#obj_set_field_s32) + +### Lua Example +`obj_set_field_s32(o, fieldIndex, value)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | +| fieldIndex | `integer` | +| value | `integer` | + +### Returns +- None + +### C Prototype +`void obj_set_field_s32(struct Object *o, s32 fieldIndex, s32 value);` + +[:arrow_up_small:](#) + +
+ +## [obj_set_field_u32](#obj_set_field_u32) + +### Lua Example +`obj_set_field_u32(o, fieldIndex, value)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | +| fieldIndex | `integer` | +| value | `integer` | + +### Returns +- None + +### C Prototype +`void obj_set_field_u32(struct Object *o, s32 fieldIndex, u32 value);` + +[:arrow_up_small:](#) + +
+ ## [obj_set_model_extended](#obj_set_model_extended) ### Lua Example diff --git a/docs/lua/functions.md b/docs/lua/functions.md index 6c32e341..75955e61 100644 --- a/docs/lua/functions.md +++ b/docs/lua/functions.md @@ -1739,6 +1739,10 @@ - [obj_check_overlap_with_hitbox_params](functions-5.md#obj_check_overlap_with_hitbox_params) - [obj_count_objects_with_behavior_id](functions-5.md#obj_count_objects_with_behavior_id) - [obj_get_collided_object](functions-5.md#obj_get_collided_object) + - [obj_get_field_f32](functions-5.md#obj_get_field_f32) + - [obj_get_field_s16](functions-5.md#obj_get_field_s16) + - [obj_get_field_s32](functions-5.md#obj_get_field_s32) + - [obj_get_field_u32](functions-5.md#obj_get_field_u32) - [obj_get_first](functions-5.md#obj_get_first) - [obj_get_first_with_behavior_id](functions-5.md#obj_get_first_with_behavior_id) - [obj_get_first_with_behavior_id_and_field_f32](functions-5.md#obj_get_first_with_behavior_id_and_field_f32) @@ -1761,6 +1765,10 @@ - [obj_is_secret](functions-5.md#obj_is_secret) - [obj_is_valid_for_interaction](functions-5.md#obj_is_valid_for_interaction) - [obj_move_xyz](functions-5.md#obj_move_xyz) + - [obj_set_field_f32](functions-5.md#obj_set_field_f32) + - [obj_set_field_s16](functions-5.md#obj_set_field_s16) + - [obj_set_field_s32](functions-5.md#obj_set_field_s32) + - [obj_set_field_u32](functions-5.md#obj_set_field_u32) - [obj_set_model_extended](functions-5.md#obj_set_model_extended) - [obj_set_vel](functions-5.md#obj_set_vel) - [set_whirlpools](functions-5.md#set_whirlpools) diff --git a/include/types.h b/include/types.h index 547021e7..2d77d927 100644 --- a/include/types.h +++ b/include/types.h @@ -19,8 +19,6 @@ #define BAD_RETURN(cmd) cmd #endif -#define OBJECT_MAX_BHV_STACK 16 - struct Controller { /*0x00*/ s16 rawStickX; // @@ -190,6 +188,12 @@ struct ObjectNode // NOTE: Since ObjectNode is the first member of Object, it is difficult to determine // whether some of these pointers point to ObjectNode or Object. +#define OBJECT_MAX_BHV_STACK 16 +#define OBJECT_NUM_REGULAR_FIELDS 0x50 +#define OBJECT_NUM_CUSTOM_FIELDS 0x10 +#define OBJECT_CUSTOM_FIELDS_START (OBJECT_NUM_REGULAR_FIELDS) +#define OBJECT_NUM_FIELDS (OBJECT_CUSTOM_FIELDS_START + OBJECT_NUM_CUSTOM_FIELDS) + struct Object { /*0x000*/ struct ObjectNode header; @@ -203,21 +207,21 @@ struct Object union { // Object fields. See object_fields.h. - u32 asU32[0x50]; - s32 asS32[0x50]; - s16 asS16[0x50][2]; - f32 asF32[0x50]; + u32 asU32[OBJECT_NUM_FIELDS]; + s32 asS32[OBJECT_NUM_FIELDS]; + s16 asS16[OBJECT_NUM_FIELDS][2]; + f32 asF32[OBJECT_NUM_FIELDS]; } rawData; union { - s16 *asS16P[0x50]; - s32 *asS32P[0x50]; - struct AnimationTable *asAnims[0x50]; - struct Waypoint *asWaypoint[0x50]; - struct ChainSegment *asChainSegment[0x50]; - struct Object *asObject[0x50]; - struct Surface *asSurface[0x50]; - void *asVoidPtr[0x50]; - const void *asConstVoidPtr[0x50]; + s16 *asS16P[OBJECT_NUM_FIELDS]; + s32 *asS32P[OBJECT_NUM_FIELDS]; + struct AnimationTable *asAnims[OBJECT_NUM_FIELDS]; + struct Waypoint *asWaypoint[OBJECT_NUM_FIELDS]; + struct ChainSegment *asChainSegment[OBJECT_NUM_FIELDS]; + struct Object *asObject[OBJECT_NUM_FIELDS]; + struct Surface *asSurface[OBJECT_NUM_FIELDS]; + void *asVoidPtr[OBJECT_NUM_FIELDS]; + const void *asConstVoidPtr[OBJECT_NUM_FIELDS]; } ptrData; /*0x1C8*/ u32 unused1; /*0x1CC*/ const BehaviorScript *curBhvCommand; diff --git a/src/game/spawn_object.c b/src/game/spawn_object.c index c903b1b3..497cfab2 100644 --- a/src/game/spawn_object.c +++ b/src/game/spawn_object.c @@ -279,7 +279,7 @@ struct Object *allocate_object(struct ObjectNode *objList) { obj->collidedObjInteractTypes = 0; obj->numCollidedObjs = 0; - for (s32 i = 0; i < 0x50; i++) { + for (s32 i = 0; i < OBJECT_NUM_FIELDS; i++) { obj->rawData.asS32[i] = 0; obj->ptrData.asVoidPtr[i] = NULL; } diff --git a/src/pc/lua/smlua_cobject.c b/src/pc/lua/smlua_cobject.c index 9eaebc0f..9cc36f28 100644 --- a/src/pc/lua/smlua_cobject.c +++ b/src/pc/lua/smlua_cobject.c @@ -124,7 +124,12 @@ bool smlua_valid_lvt(u16 lvt) { // obj behavior // ////////////////// -#define CUSTOM_FIELD_MAX 11 +static const struct { enum LuaValueType lvt; const char *name; } sCustomFieldValidTypes[] = { + { LVT_U32, "u32" }, + { LVT_S32, "s32" }, + { LVT_F32, "f32" }, +}; + #define CUSTOM_FIELD_ITEM_LEN 48 struct CustomFieldItem { char key[CUSTOM_FIELD_ITEM_LEN]; @@ -168,6 +173,24 @@ static void smlua_add_custom_field_linked(struct CustomFieldItem** head, struct } } +static enum LuaValueType smlua_get_custom_field_type(const char *name) { + for (s32 i = 0; i != ARRAY_COUNT(sCustomFieldValidTypes); ++i) { + if (strcmp(name, sCustomFieldValidTypes[i].name) == 0) { + return sCustomFieldValidTypes[i].lvt; + } + } + return LVT_MAX; +} + +static const char *smlua_get_custom_field_type_name(enum LuaValueType lvt) { + for (s32 i = 0; i != ARRAY_COUNT(sCustomFieldValidTypes); ++i) { + if (lvt == sCustomFieldValidTypes[i].lvt) { + return sCustomFieldValidTypes[i].name; + } + } + return NULL; +} + static int smlua_func_define_custom_obj_fields(lua_State* L) { LUA_STACK_CHECK_BEGIN(); if (!smlua_functions_valid_param_count(L, 1)) { return 0; } @@ -183,7 +206,7 @@ static int smlua_func_define_custom_obj_fields(lua_State* L) { } struct CustomFieldItem* customFieldsHead = NULL; - struct CustomFieldItem customFields[CUSTOM_FIELD_MAX] = { 0 }; + struct CustomFieldItem customFields[OBJECT_NUM_CUSTOM_FIELDS] = { 0 }; u16 customFieldCount = 0; // get _custom_object_fields @@ -227,16 +250,13 @@ static int smlua_func_define_custom_obj_fields(lua_State* L) { } const char* value = smlua_to_string(L, valueIndex); - enum LuaValueType lvt = LVT_U32; - if (!strcmp(value, "u32")) { lvt = LVT_U32; } - else if (!strcmp(value, "s32")) { lvt = LVT_S32; } - else if (!strcmp(value, "f32")) { lvt = LVT_F32; } - else { + enum LuaValueType lvt = smlua_get_custom_field_type(value); + if (lvt == LVT_MAX) { LOG_LUA_LINE("Invalid value name for define_custom_obj_fields()"); return 0; } - if (customFieldCount >= CUSTOM_FIELD_MAX) { + if (customFieldCount >= OBJECT_NUM_CUSTOM_FIELDS) { LOG_LUA_LINE("Ran out of custom fields!"); return 0; } @@ -250,14 +270,9 @@ static int smlua_func_define_custom_obj_fields(lua_State* L) { lua_settop(L, iterationTop); struct CustomFieldItem* node = customFieldsHead; - u32 fieldIndex = 0x1B; + u32 fieldIndex = OBJECT_CUSTOM_FIELDS_START; while (node != NULL) { - // keep fieldIndex in range - if (fieldIndex < 0x1B) { - fieldIndex = 0x1B; - } else if (fieldIndex > 0x22 && fieldIndex < 0x48) { - fieldIndex = 0x48; - } else if (fieldIndex > 0x4A) { + if (fieldIndex >= OBJECT_NUM_FIELDS) { LOG_LUA_LINE("Ran out of custom fields!"); return 0; } @@ -278,7 +293,7 @@ static int smlua_func_define_custom_obj_fields(lua_State* L) { } lua_settable(L, -3); // set _custom_object_fields - LOG_INFO("Registered custom object field: %02X - %s", fieldIndex, node->key); + LOG_INFO("Registered custom object field: 0x%02X as %s - %s", fieldIndex, smlua_get_custom_field_type_name(node->lvt), node->key); fieldIndex++; @@ -326,7 +341,7 @@ struct LuaObjectField* smlua_get_custom_field(lua_State* L, u32 lot, int keyInde lua_rawget(L, -2); u32 fieldIndex = smlua_to_integer(L, -1); lua_pop(L, 1); - bool validFieldIndex = (fieldIndex >= 0x1B && fieldIndex <= 0x22) || (fieldIndex >= 0x48 && fieldIndex <= 0x4A); + bool validFieldIndex = (fieldIndex >= OBJECT_CUSTOM_FIELDS_START && fieldIndex < OBJECT_NUM_FIELDS); if (!gSmLuaConvertSuccess || !validFieldIndex) { lua_pop(L, 1); // pop value table lua_pop(L, 1); // pop _custom_fields diff --git a/src/pc/lua/smlua_constants_autogen.c b/src/pc/lua/smlua_constants_autogen.c index f6722c90..e63748b2 100644 --- a/src/pc/lua/smlua_constants_autogen.c +++ b/src/pc/lua/smlua_constants_autogen.c @@ -4381,7 +4381,6 @@ char gSmluaConstants[] = "" "TERRAIN_WATER = 0x0005\n" "TERRAIN_SLIDE = 0x0006\n" "TERRAIN_MASK = 0x0007\n" -"OBJECT_MAX_BHV_STACK = 16\n" "SPTASK_STATE_NOT_STARTED = 0\n" "SPTASK_STATE_RUNNING = 1\n" "SPTASK_STATE_INTERRUPTED = 2\n" @@ -4399,6 +4398,11 @@ char gSmluaConstants[] = "" "ANIM_FLAG_6 = (1 << 6)\n" "ANIM_FLAG_7 = (1 << 7)\n" "GRAPH_NODE_GUARD = 0xAA\n" +"OBJECT_MAX_BHV_STACK = 16\n" +"OBJECT_NUM_REGULAR_FIELDS = 0x50\n" +"OBJECT_NUM_CUSTOM_FIELDS = 0x10\n" +"OBJECT_CUSTOM_FIELDS_START = (OBJECT_NUM_REGULAR_FIELDS)\n" +"OBJECT_NUM_FIELDS = (OBJECT_CUSTOM_FIELDS_START + OBJECT_NUM_CUSTOM_FIELDS)\n" "PLAY_MODE_NORMAL = 0\n" "PLAY_MODE_PAUSED = 2\n" "PLAY_MODE_CHANGE_AREA = 3\n" diff --git a/src/pc/lua/smlua_functions_autogen.c b/src/pc/lua/smlua_functions_autogen.c index 79c414ed..611697ad 100644 --- a/src/pc/lua/smlua_functions_autogen.c +++ b/src/pc/lua/smlua_functions_autogen.c @@ -30656,6 +30656,84 @@ int smlua_func_obj_get_collided_object(lua_State* L) { return 1; } +int smlua_func_obj_get_field_f32(lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 2) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "obj_get_field_f32", 2, top); + return 0; + } + + struct Object* o = (struct Object*)smlua_to_cobject(L, 1, LOT_OBJECT); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "obj_get_field_f32"); return 0; } + s32 fieldIndex = smlua_to_integer(L, 2); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "obj_get_field_f32"); return 0; } + + lua_pushnumber(L, obj_get_field_f32(o, fieldIndex)); + + return 1; +} + +int smlua_func_obj_get_field_s16(lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 3) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "obj_get_field_s16", 3, top); + return 0; + } + + struct Object* o = (struct Object*)smlua_to_cobject(L, 1, LOT_OBJECT); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "obj_get_field_s16"); return 0; } + s32 fieldIndex = smlua_to_integer(L, 2); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "obj_get_field_s16"); return 0; } + s32 fieldSubIndex = smlua_to_integer(L, 3); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "obj_get_field_s16"); return 0; } + + lua_pushinteger(L, obj_get_field_s16(o, fieldIndex, fieldSubIndex)); + + return 1; +} + +int smlua_func_obj_get_field_s32(lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 2) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "obj_get_field_s32", 2, top); + return 0; + } + + struct Object* o = (struct Object*)smlua_to_cobject(L, 1, LOT_OBJECT); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "obj_get_field_s32"); return 0; } + s32 fieldIndex = smlua_to_integer(L, 2); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "obj_get_field_s32"); return 0; } + + lua_pushinteger(L, obj_get_field_s32(o, fieldIndex)); + + return 1; +} + +int smlua_func_obj_get_field_u32(lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 2) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "obj_get_field_u32", 2, top); + return 0; + } + + struct Object* o = (struct Object*)smlua_to_cobject(L, 1, LOT_OBJECT); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "obj_get_field_u32"); return 0; } + s32 fieldIndex = smlua_to_integer(L, 2); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "obj_get_field_u32"); return 0; } + + lua_pushinteger(L, obj_get_field_u32(o, fieldIndex)); + + return 1; +} + int smlua_func_obj_get_first(lua_State* L) { if (L == NULL) { return 0; } @@ -31058,6 +31136,92 @@ int smlua_func_obj_move_xyz(lua_State* L) { return 1; } +int smlua_func_obj_set_field_f32(lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 3) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "obj_set_field_f32", 3, top); + return 0; + } + + struct Object* o = (struct Object*)smlua_to_cobject(L, 1, LOT_OBJECT); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "obj_set_field_f32"); return 0; } + s32 fieldIndex = smlua_to_integer(L, 2); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "obj_set_field_f32"); return 0; } + f32 value = smlua_to_number(L, 3); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "obj_set_field_f32"); return 0; } + + obj_set_field_f32(o, fieldIndex, value); + + return 1; +} + +int smlua_func_obj_set_field_s16(lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 4) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "obj_set_field_s16", 4, top); + return 0; + } + + struct Object* o = (struct Object*)smlua_to_cobject(L, 1, LOT_OBJECT); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "obj_set_field_s16"); return 0; } + s32 fieldIndex = smlua_to_integer(L, 2); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "obj_set_field_s16"); return 0; } + s32 fieldSubIndex = smlua_to_integer(L, 3); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "obj_set_field_s16"); return 0; } + s16 value = smlua_to_integer(L, 4); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 4, "obj_set_field_s16"); return 0; } + + obj_set_field_s16(o, fieldIndex, fieldSubIndex, value); + + return 1; +} + +int smlua_func_obj_set_field_s32(lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 3) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "obj_set_field_s32", 3, top); + return 0; + } + + struct Object* o = (struct Object*)smlua_to_cobject(L, 1, LOT_OBJECT); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "obj_set_field_s32"); return 0; } + s32 fieldIndex = smlua_to_integer(L, 2); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "obj_set_field_s32"); return 0; } + s32 value = smlua_to_integer(L, 3); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "obj_set_field_s32"); return 0; } + + obj_set_field_s32(o, fieldIndex, value); + + return 1; +} + +int smlua_func_obj_set_field_u32(lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 3) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "obj_set_field_u32", 3, top); + return 0; + } + + struct Object* o = (struct Object*)smlua_to_cobject(L, 1, LOT_OBJECT); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "obj_set_field_u32"); return 0; } + s32 fieldIndex = smlua_to_integer(L, 2); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "obj_set_field_u32"); return 0; } + u32 value = smlua_to_integer(L, 3); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "obj_set_field_u32"); return 0; } + + obj_set_field_u32(o, fieldIndex, value); + + return 1; +} + int smlua_func_obj_set_model_extended(lua_State* L) { if (L == NULL) { return 0; } @@ -33812,6 +33976,10 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "obj_check_overlap_with_hitbox_params", smlua_func_obj_check_overlap_with_hitbox_params); smlua_bind_function(L, "obj_count_objects_with_behavior_id", smlua_func_obj_count_objects_with_behavior_id); smlua_bind_function(L, "obj_get_collided_object", smlua_func_obj_get_collided_object); + smlua_bind_function(L, "obj_get_field_f32", smlua_func_obj_get_field_f32); + smlua_bind_function(L, "obj_get_field_s16", smlua_func_obj_get_field_s16); + smlua_bind_function(L, "obj_get_field_s32", smlua_func_obj_get_field_s32); + smlua_bind_function(L, "obj_get_field_u32", smlua_func_obj_get_field_u32); smlua_bind_function(L, "obj_get_first", smlua_func_obj_get_first); smlua_bind_function(L, "obj_get_first_with_behavior_id", smlua_func_obj_get_first_with_behavior_id); smlua_bind_function(L, "obj_get_first_with_behavior_id_and_field_f32", smlua_func_obj_get_first_with_behavior_id_and_field_f32); @@ -33834,6 +34002,10 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "obj_is_secret", smlua_func_obj_is_secret); smlua_bind_function(L, "obj_is_valid_for_interaction", smlua_func_obj_is_valid_for_interaction); smlua_bind_function(L, "obj_move_xyz", smlua_func_obj_move_xyz); + smlua_bind_function(L, "obj_set_field_f32", smlua_func_obj_set_field_f32); + smlua_bind_function(L, "obj_set_field_s16", smlua_func_obj_set_field_s16); + smlua_bind_function(L, "obj_set_field_s32", smlua_func_obj_set_field_s32); + smlua_bind_function(L, "obj_set_field_u32", smlua_func_obj_set_field_u32); smlua_bind_function(L, "obj_set_model_extended", smlua_func_obj_set_model_extended); smlua_bind_function(L, "obj_set_vel", smlua_func_obj_set_vel); smlua_bind_function(L, "set_whirlpools", smlua_func_set_whirlpools); diff --git a/src/pc/lua/smlua_hooks.c b/src/pc/lua/smlua_hooks.c index 9c3f7df9..31f1dfc2 100644 --- a/src/pc/lua/smlua_hooks.c +++ b/src/pc/lua/smlua_hooks.c @@ -1379,7 +1379,7 @@ int smlua_hook_custom_bhv(BehaviorScript *bhvScript, const char *bhvName) { if (L != NULL) { lua_pushinteger(L, customBehaviorId); lua_setglobal(L, bhvName); - LOG_INFO("Registered custom behavior: %04hX - %s", customBehaviorId, bhvName); + LOG_INFO("Registered custom behavior: 0x%04hX - %s", customBehaviorId, bhvName); } return 1; @@ -1518,7 +1518,7 @@ int smlua_hook_behavior(lua_State* L) { // It's also used for some things that would normally access a LUA behavior instead. lua_pushinteger(L, customBehaviorId); lua_setglobal(L, bhvName); - LOG_INFO("Registered custom behavior: %04hX - %s", customBehaviorId, bhvName); + LOG_INFO("Registered custom behavior: 0x%04hX - %s", customBehaviorId, bhvName); // return behavior ID lua_pushinteger(L, customBehaviorId); diff --git a/src/pc/lua/utils/smlua_obj_utils.c b/src/pc/lua/utils/smlua_obj_utils.c index e2a5e955..3a891633 100644 --- a/src/pc/lua/utils/smlua_obj_utils.c +++ b/src/pc/lua/utils/smlua_obj_utils.c @@ -138,7 +138,7 @@ struct Object *obj_get_first_with_behavior_id(enum BehaviorId behaviorId) { } struct Object *obj_get_first_with_behavior_id_and_field_s32(enum BehaviorId behaviorId, s32 fieldIndex, s32 value) { - if (fieldIndex < 0 || fieldIndex >= 0x50) { return NULL; } + if (fieldIndex < 0 || fieldIndex >= OBJECT_NUM_FIELDS) { return NULL; } const BehaviorScript* behavior = get_behavior_from_id(behaviorId); u32 sanityDepth = 0; behavior = smlua_override_behavior(behavior); @@ -155,7 +155,7 @@ struct Object *obj_get_first_with_behavior_id_and_field_s32(enum BehaviorId beha } struct Object *obj_get_first_with_behavior_id_and_field_f32(enum BehaviorId behaviorId, s32 fieldIndex, f32 value) { - if (fieldIndex < 0 || fieldIndex >= 0x50) { return NULL; } + if (fieldIndex < 0 || fieldIndex >= OBJECT_NUM_FIELDS) { return NULL; } const BehaviorScript* behavior = get_behavior_from_id(behaviorId); behavior = smlua_override_behavior(behavior); if (behavior) { @@ -229,7 +229,7 @@ struct Object *obj_get_next_with_same_behavior_id(struct Object *o) { } struct Object *obj_get_next_with_same_behavior_id_and_field_s32(struct Object *o, s32 fieldIndex, s32 value) { - if (fieldIndex < 0 || fieldIndex >= 0x50) { return NULL; } + if (fieldIndex < 0 || fieldIndex >= OBJECT_NUM_FIELDS) { return NULL; } if (o) { for (struct Object *obj = obj_get_next(o); obj != NULL; obj = obj_get_next(obj)) { if (obj->behavior == o->behavior && obj->activeFlags != ACTIVE_FLAG_DEACTIVATED && obj->OBJECT_FIELD_S32(fieldIndex) == value) { @@ -241,7 +241,7 @@ struct Object *obj_get_next_with_same_behavior_id_and_field_s32(struct Object *o } struct Object *obj_get_next_with_same_behavior_id_and_field_f32(struct Object *o, s32 fieldIndex, f32 value) { - if (fieldIndex < 0 || fieldIndex >= 0x50) { return NULL; } + if (fieldIndex < 0 || fieldIndex >= OBJECT_NUM_FIELDS) { return NULL; } if (o) { for (struct Object *obj = obj_get_next(o); obj != NULL; obj = obj_get_next(obj)) { if (obj->behavior == o->behavior && obj->activeFlags != ACTIVE_FLAG_DEACTIVATED && obj->OBJECT_FIELD_F32(fieldIndex) == value) { @@ -259,6 +259,66 @@ struct Object *obj_get_collided_object(struct Object *o, s16 index) { return NULL; } +// +// Object fields +// + +u32 obj_get_field_u32(struct Object *o, s32 fieldIndex) { + if (o && fieldIndex >= 0 && fieldIndex < OBJECT_NUM_FIELDS) { + return o->OBJECT_FIELD_U32(fieldIndex); + } + return 0; +} + +s32 obj_get_field_s32(struct Object *o, s32 fieldIndex) { + if (o && fieldIndex >= 0 && fieldIndex < OBJECT_NUM_FIELDS) { + return o->OBJECT_FIELD_S32(fieldIndex); + } + return 0; +} + +f32 obj_get_field_f32(struct Object *o, s32 fieldIndex) { + if (o && fieldIndex >= 0 && fieldIndex < OBJECT_NUM_FIELDS) { + return o->OBJECT_FIELD_F32(fieldIndex); + } + return 0; +} + +s16 obj_get_field_s16(struct Object *o, s32 fieldIndex, s32 fieldSubIndex) { + if (o && fieldIndex >= 0 && fieldIndex < OBJECT_NUM_FIELDS && fieldSubIndex >= 0 && fieldSubIndex < 2) { + return o->OBJECT_FIELD_S16(fieldIndex, fieldSubIndex); + } + return 0; +} + +void obj_set_field_u32(struct Object *o, s32 fieldIndex, u32 value) { + if (o && fieldIndex >= 0 && fieldIndex < OBJECT_NUM_FIELDS) { + o->OBJECT_FIELD_U32(fieldIndex) = value; + } +} + +void obj_set_field_s32(struct Object *o, s32 fieldIndex, s32 value) { + if (o && fieldIndex >= 0 && fieldIndex < OBJECT_NUM_FIELDS) { + o->OBJECT_FIELD_S32(fieldIndex) = value; + } +} + +void obj_set_field_f32(struct Object *o, s32 fieldIndex, f32 value) { + if (o && fieldIndex >= 0 && fieldIndex < OBJECT_NUM_FIELDS) { + o->OBJECT_FIELD_F32(fieldIndex) = value; + } +} + +void obj_set_field_s16(struct Object *o, s32 fieldIndex, s32 fieldSubIndex, s16 value) { + if (o && fieldIndex >= 0 && fieldIndex < OBJECT_NUM_FIELDS && fieldSubIndex >= 0 && fieldSubIndex < 2) { + o->OBJECT_FIELD_S16(fieldIndex, fieldSubIndex) = value; + } +} + +// +// Misc object helpers +// + struct SpawnParticlesInfo* obj_get_temp_spawn_particles_info(enum ModelExtendedId modelId) { static struct SpawnParticlesInfo sTmpSpi = { 0 }; memset(&sTmpSpi, 0, sizeof(struct SpawnParticlesInfo)); @@ -413,7 +473,7 @@ void set_whirlpools(f32 x, f32 y, f32 z, s16 strength, s16 area, s32 index) { #ifdef DEVELOPMENT void obj_randomize(struct Object* o) { if (!o) { return; } - for (int i = 0; i < 80; i++) { + for (int i = 0; i < OBJECT_NUM_FIELDS; i++) { if (rand() % 10 < 5) { o->rawData.asU32[i] = rand() % 10; } else { diff --git a/src/pc/lua/utils/smlua_obj_utils.h b/src/pc/lua/utils/smlua_obj_utils.h index 48b0963f..e90fac0e 100644 --- a/src/pc/lua/utils/smlua_obj_utils.h +++ b/src/pc/lua/utils/smlua_obj_utils.h @@ -34,7 +34,23 @@ s32 obj_count_objects_with_behavior_id(enum BehaviorId behaviorId); struct Object *obj_get_collided_object(struct Object *o, s16 index); -// misc obj helpers +// +// Object fields +// + +u32 obj_get_field_u32(struct Object *o, s32 fieldIndex); +s32 obj_get_field_s32(struct Object *o, s32 fieldIndex); +f32 obj_get_field_f32(struct Object *o, s32 fieldIndex); +s16 obj_get_field_s16(struct Object *o, s32 fieldIndex, s32 fieldSubIndex); + +void obj_set_field_u32(struct Object *o, s32 fieldIndex, u32 value); +void obj_set_field_s32(struct Object *o, s32 fieldIndex, s32 value); +void obj_set_field_f32(struct Object *o, s32 fieldIndex, f32 value); +void obj_set_field_s16(struct Object *o, s32 fieldIndex, s32 fieldSubIndex, s16 value); + +// +// Misc object helpers +// struct SpawnParticlesInfo* obj_get_temp_spawn_particles_info(enum ModelExtendedId modelId); struct ObjectHitbox* get_temp_object_hitbox(void); diff --git a/src/pc/network/packets/packet_object.c b/src/pc/network/packets/packet_object.c index 459e051d..b1ec3fca 100644 --- a/src/pc/network/packets/packet_object.c +++ b/src/pc/network/packets/packet_object.c @@ -150,7 +150,7 @@ static void packet_write_object_full_sync(struct Packet* p, struct Object* o) { if (!so || !so->fullObjectSync) { return; } // write all of raw data - packet_write(p, o->rawData.asU32, sizeof(u32) * 80); + packet_write(p, o->rawData.asU32, sizeof(u32) * OBJECT_NUM_FIELDS); } static void packet_read_object_full_sync(struct Packet* p, struct Object* o) { @@ -158,7 +158,7 @@ static void packet_read_object_full_sync(struct Packet* p, struct Object* o) { if (!so || !so->fullObjectSync) { return; } // read all of raw data - packet_read(p, o->rawData.asU32, sizeof(u32) * 80); + packet_read(p, o->rawData.asU32, sizeof(u32) * OBJECT_NUM_FIELDS); } // ----- standard fields ----- // diff --git a/src/pc/network/packets/packet_player.c b/src/pc/network/packets/packet_player.c index aa3c89e8..38f44cb7 100644 --- a/src/pc/network/packets/packet_player.c +++ b/src/pc/network/packets/packet_player.c @@ -18,7 +18,7 @@ #pragma pack(1) struct PacketPlayerData { - u32 rawData[80]; + u32 rawData[OBJECT_NUM_REGULAR_FIELDS]; s16 cRawStickX; s16 cRawStickY; @@ -86,7 +86,7 @@ static void read_packet_data(struct PacketPlayerData* data, struct MarioState* m u8 customFlags = SET_BIT((m->freeze > 0), 0); - memcpy(data->rawData, m->marioObj->rawData.asU32, sizeof(u32) * 80); + memcpy(data->rawData, m->marioObj->rawData.asU32, sizeof(u32) * OBJECT_NUM_REGULAR_FIELDS); data->nodeFlags = m->marioObj->header.gfx.node.flags; data->cRawStickX = m->controller->rawStickX; @@ -148,7 +148,7 @@ static void write_packet_data(struct PacketPlayerData* data, struct MarioState* u8* customFlags, u32* heldSyncID, u32* heldBySyncID, u32* riddenSyncID, u32* interactSyncID, u32* usedSyncID, u32* platformSyncID) { - memcpy(m->marioObj->rawData.asU32, data->rawData, sizeof(u32) * 80); + memcpy(m->marioObj->rawData.asU32, data->rawData, sizeof(u32) * OBJECT_NUM_REGULAR_FIELDS); m->marioObj->header.gfx.node.flags = data->nodeFlags; m->controller->rawStickX = data->cRawStickX; diff --git a/src/pc/network/packets/packet_spawn_objects.c b/src/pc/network/packets/packet_spawn_objects.c index 89e8f40a..37ee7373 100644 --- a/src/pc/network/packets/packet_spawn_objects.c +++ b/src/pc/network/packets/packet_spawn_objects.c @@ -22,7 +22,7 @@ struct SpawnObjectData { u32 model; u32 behaviorId; s16 activeFlags; - s32 rawData[80]; + s32 rawData[OBJECT_NUM_FIELDS]; u8 setHome; u8 globalPlayerIndex; u16 extendedModelId; @@ -102,7 +102,7 @@ void network_send_spawn_objects_to(u8 sendToLocalIndex, struct Object* objects[] packet_write(&p, &model, sizeof(u32)); packet_write(&p, &behaviorId, sizeof(u32)); packet_write(&p, &o->activeFlags, sizeof(s16)); - packet_write(&p, o->rawData.asU32, sizeof(u32) * 0x50); + packet_write(&p, o->rawData.asU32, sizeof(u32) * OBJECT_NUM_FIELDS); packet_write(&p, &o->header.gfx.scale[0], sizeof(f32)); packet_write(&p, &o->header.gfx.scale[1], sizeof(f32)); packet_write(&p, &o->header.gfx.scale[2], sizeof(f32)); @@ -144,7 +144,7 @@ void network_receive_spawn_objects(struct Packet* p) { packet_read(p, &data.model, sizeof(u32)); packet_read(p, &data.behaviorId, sizeof(u32)); packet_read(p, &data.activeFlags, sizeof(s16)); - packet_read(p, &data.rawData, sizeof(u32) * 0x50); + packet_read(p, &data.rawData, sizeof(u32) * OBJECT_NUM_FIELDS); packet_read(p, &scale[0], sizeof(f32)); packet_read(p, &scale[1], sizeof(f32)); packet_read(p, &scale[2], sizeof(f32)); @@ -227,7 +227,7 @@ void network_receive_spawn_objects(struct Packet* p) { o->coopFlags |= COOP_OBJ_FLAG_NETWORK; o->setHome = data.setHome; - memcpy(o->rawData.asU32, data.rawData, sizeof(u32) * 80); + memcpy(o->rawData.asU32, data.rawData, sizeof(u32) * OBJECT_NUM_FIELDS); o->header.gfx.scale[0] = scale[0]; o->header.gfx.scale[1] = scale[1];