add a way for mods to get dynamic surfaces that belong to specific objects (#59)

Adding this for collision minimap, but I'm sure it'd be useful for many other mods that deal with collision in this kind of way

exposes a function, obj_get_surface_from_index. pass in an object, and the index of the surface you want. numSurfaces is also added to know when to stop iterating through surfaces

Thanks to peachy for coming up with the better method of doing this

Co-authored-by: PeachyPeach <72323920+PeachyPeachSM64@users.noreply.github.com>
This commit is contained in:
Isaac0-dev 2024-06-06 17:24:28 +10:00 committed by GitHub
parent d1bbc05ece
commit eaeaeb0f7f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 86 additions and 2 deletions

View file

@ -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" ],

View file

@ -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

View file

@ -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

View file

@ -4734,6 +4734,27 @@
<br />
## [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:](#)
<br />
---
[< prev](functions-4.md) | [1](functions.md) | [2](functions-2.md) | [3](functions-3.md) | [4](functions-4.md) | 5]

View file

@ -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)
<br />

View file

@ -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) | |

View file

@ -251,6 +251,8 @@ struct Object
/*?????*/ u8 setHome;
/*?????*/ u8 allowRemoteInteractions;
/*?????*/ u8 ctx;
/*?????*/ u32 firstSurface;
/*?????*/ u32 numSurfaces;
};
struct ObjectHitbox

View file

@ -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;
}

View file

@ -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

View file

@ -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;
}

View file

@ -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 },

View file

@ -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);
}