diff --git a/autogen/convert_structs.py b/autogen/convert_structs.py index b333088f..6a53e222 100644 --- a/autogen/convert_structs.py +++ b/autogen/convert_structs.py @@ -84,6 +84,7 @@ override_field_invisible = { "MarioState": [ "visibleToEnemies" ], "NetworkPlayer": [ "gag", "moderator"], "GraphNode": [ "_guard1", "_guard2" ], + "Object": [ "firstSurface" ], } override_field_deprecated = { @@ -98,7 +99,7 @@ override_field_immutable = { "Character": [ "*" ], "NetworkPlayer": [ "*" ], "TextureInfo": [ "*" ], - "Object": ["oSyncID", "coopFlags", "oChainChompSegments", "oWigglerSegments", "oHauntedChairUnk100", "oTTCTreadmillBigSurface", "oTTCTreadmillSmallSurface", "bhvStackIndex", "respawnInfoType" ], + "Object": ["oSyncID", "coopFlags", "oChainChompSegments", "oWigglerSegments", "oHauntedChairUnk100", "oTTCTreadmillBigSurface", "oTTCTreadmillSmallSurface", "bhvStackIndex", "respawnInfoType", "numSurfaces" ], "GlobalObjectAnimations": [ "*"], "SpawnParticlesInfo": [ "model" ], "MarioBodyState": [ "updateTorsoTime" ], diff --git a/autogen/lua_definitions/functions.lua b/autogen/lua_definitions/functions.lua index b6ae3887..c76fa629 100644 --- a/autogen/lua_definitions/functions.lua +++ b/autogen/lua_definitions/functions.lua @@ -8908,6 +8908,13 @@ function load_object_collision_model() -- ... end +--- @param o Object +--- @param index integer +--- @return Surface +function obj_get_surface_from_index(o, index) + -- ... +end + --- @class Pointer_integer --- @class Pointer_BehaviorScript --- @class Pointer_number diff --git a/autogen/lua_definitions/structs.lua b/autogen/lua_definitions/structs.lua index f39f25ba..39299403 100644 --- a/autogen/lua_definitions/structs.lua +++ b/autogen/lua_definitions/structs.lua @@ -1145,6 +1145,7 @@ --- @field public hurtboxHeight number --- @field public hurtboxRadius number --- @field public numCollidedObjs integer +--- @field public numSurfaces integer --- @field public o1UpForceSpawn integer --- @field public o1UpHiddenUnkF4 integer --- @field public oAction integer diff --git a/docs/lua/functions-5.md b/docs/lua/functions-5.md index 41330aef..33eecbd0 100644 --- a/docs/lua/functions-5.md +++ b/docs/lua/functions-5.md @@ -4734,6 +4734,27 @@
+## [obj_get_surface_from_index](#obj_get_surface_from_index) + +### Lua Example +`local SurfaceValue = obj_get_surface_from_index(o, index)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | +| index | `integer` | + +### Returns +[Surface](structs.md#Surface) + +### C Prototype +`struct Surface *obj_get_surface_from_index(struct Object *o, u32 index);` + +[:arrow_up_small:](#) + +
+ --- [< prev](functions-4.md) | [1](functions.md) | [2](functions-2.md) | [3](functions-3.md) | [4](functions-4.md) | 5] diff --git a/docs/lua/functions.md b/docs/lua/functions.md index 9b1eb885..80abecba 100644 --- a/docs/lua/functions.md +++ b/docs/lua/functions.md @@ -1846,6 +1846,7 @@ - [get_area_terrain_size](functions-5.md#get_area_terrain_size) - [load_area_terrain](functions-5.md#load_area_terrain) - [load_object_collision_model](functions-5.md#load_object_collision_model) + - [obj_get_surface_from_index](functions-5.md#obj_get_surface_from_index)
diff --git a/docs/lua/structs.md b/docs/lua/structs.md index bededb1e..39c29bd7 100644 --- a/docs/lua/structs.md +++ b/docs/lua/structs.md @@ -1559,6 +1559,7 @@ | hurtboxHeight | `number` | | | hurtboxRadius | `number` | | | numCollidedObjs | `integer` | | +| numSurfaces | `integer` | read-only | | parentObj | [Object](structs.md#Object) | | | platform | [Object](structs.md#Object) | | | prevObj | [Object](structs.md#Object) | | diff --git a/include/types.h b/include/types.h index 9c7efcc2..a39ec00b 100644 --- a/include/types.h +++ b/include/types.h @@ -251,6 +251,8 @@ struct Object /*?????*/ u8 setHome; /*?????*/ u8 allowRemoteInteractions; /*?????*/ u8 ctx; + /*?????*/ u32 firstSurface; + /*?????*/ u32 numSurfaces; }; struct ObjectHitbox diff --git a/src/engine/surface_load.c b/src/engine/surface_load.c index 3015b7b7..66b2067d 100644 --- a/src/engine/surface_load.c +++ b/src/engine/surface_load.c @@ -595,6 +595,12 @@ void clear_dynamic_surfaces(void) { gSurfaceNodesAllocated = gNumStaticSurfaceNodes; clear_spatial_partition(&gDynamicSurfacePartition[0][0]); + + for (u16 i = 0; i < OBJECT_POOL_CAPACITY; i++) { + struct Object *obj = &gObjectPool[i]; + obj->firstSurface = 0; + obj->numSurfaces = 0; + } } } @@ -674,6 +680,15 @@ void load_object_surfaces(s16** data, s16* vertexData) { struct Surface* surface = read_surface_data(vertexData, data); if (surface != NULL) { + + // Set index of first surface + if (gCurrentObject->firstSurface == 0) { + gCurrentObject->firstSurface = gSurfacesAllocated - 1; + } + + // Increase surface count + gCurrentObject->numSurfaces++; + surface->object = gCurrentObject; surface->type = surfaceType; @@ -763,3 +778,10 @@ void load_object_collision_model(void) { gCurrentObject->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE; } } + +struct Surface *obj_get_surface_from_index(struct Object *o, u32 index) { + if (!o || o->firstSurface == 0) { return NULL; } + if (index >= o->numSurfaces) { return NULL; } + struct Surface *surf = sSurfacePool->buffer[o->firstSurface + index]; + return surf; +} diff --git a/src/engine/surface_load.h b/src/engine/surface_load.h index 30558132..e948c2e9 100644 --- a/src/engine/surface_load.h +++ b/src/engine/surface_load.h @@ -34,5 +34,6 @@ u32 get_area_terrain_size(s16 *data); void load_area_terrain(s16 index, s16 *data, s8 *surfaceRooms, s16 *macroObjects); void clear_dynamic_surfaces(void); void load_object_collision_model(void); +struct Surface *obj_get_surface_from_index(struct Object *o, u32 index); #endif // SURFACE_LOAD_H diff --git a/src/game/spawn_object.c b/src/game/spawn_object.c index 497cfab2..23c1fb5f 100644 --- a/src/game/spawn_object.c +++ b/src/game/spawn_object.c @@ -233,6 +233,9 @@ void unload_object(struct Object *obj) { smlua_call_event_hooks_object_param(HOOK_ON_SYNC_OBJECT_UNLOAD, obj); } + obj->firstSurface = 0; + obj->numSurfaces = 0; + smlua_call_event_hooks_object_param(HOOK_ON_OBJECT_UNLOAD, obj); deallocate_object(&gFreeObjectList, &obj->header); @@ -338,6 +341,9 @@ struct Object *allocate_object(struct ObjectNode *objList) { obj->usingObj = NULL; + obj->firstSurface = 0; + obj->numSurfaces = 0; + return obj; } diff --git a/src/pc/lua/smlua_cobject_autogen.c b/src/pc/lua/smlua_cobject_autogen.c index 3b9a7d61..ad533bd1 100644 --- a/src/pc/lua/smlua_cobject_autogen.c +++ b/src/pc/lua/smlua_cobject_autogen.c @@ -1269,7 +1269,7 @@ static struct LuaObjectField sNetworkPlayerFields[LUA_NETWORK_PLAYER_FIELD_COUNT { "type", LVT_U8, offsetof(struct NetworkPlayer, type), true, LOT_NONE }, }; -#define LUA_OBJECT_FIELD_COUNT 758 +#define LUA_OBJECT_FIELD_COUNT 759 static struct LuaObjectField sObjectFields[LUA_OBJECT_FIELD_COUNT] = { { "activeFlags", LVT_S16, offsetof(struct Object, activeFlags), false, LOT_NONE }, { "allowRemoteInteractions", LVT_U8, offsetof(struct Object, allowRemoteInteractions), false, LOT_NONE }, @@ -1297,6 +1297,7 @@ static struct LuaObjectField sObjectFields[LUA_OBJECT_FIELD_COUNT] = { { "hurtboxHeight", LVT_F32, offsetof(struct Object, hurtboxHeight), false, LOT_NONE }, { "hurtboxRadius", LVT_F32, offsetof(struct Object, hurtboxRadius), false, LOT_NONE }, { "numCollidedObjs", LVT_S16, offsetof(struct Object, numCollidedObjs), false, LOT_NONE }, + { "numSurfaces", LVT_U32, offsetof(struct Object, numSurfaces), true, LOT_NONE }, { "o1UpForceSpawn", LVT_S32, offsetof(struct Object, o1UpForceSpawn), false, LOT_NONE }, { "o1UpHiddenUnkF4", LVT_S32, offsetof(struct Object, o1UpHiddenUnkF4), false, LOT_NONE }, { "oAction", LVT_S32, offsetof(struct Object, oAction), false, LOT_NONE }, diff --git a/src/pc/lua/smlua_functions_autogen.c b/src/pc/lua/smlua_functions_autogen.c index 200b8672..961f695c 100644 --- a/src/pc/lua/smlua_functions_autogen.c +++ b/src/pc/lua/smlua_functions_autogen.c @@ -32470,6 +32470,25 @@ int smlua_func_load_object_collision_model(UNUSED lua_State* L) { return 1; } +int smlua_func_obj_get_surface_from_index(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_surface_from_index", 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_surface_from_index"); return 0; } + u32 index = smlua_to_integer(L, 2); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "obj_get_surface_from_index"); return 0; } + + smlua_push_object(L, LOT_SURFACE, obj_get_surface_from_index(o, index)); + + return 1; +} + void smlua_bind_functions_autogen(void) { @@ -34235,5 +34254,6 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "get_area_terrain_size", smlua_func_get_area_terrain_size); smlua_bind_function(L, "load_area_terrain", smlua_func_load_area_terrain); smlua_bind_function(L, "load_object_collision_model", smlua_func_load_object_collision_model); + smlua_bind_function(L, "obj_get_surface_from_index", smlua_func_obj_get_surface_from_index); }