add obj_get_model_id_extended, remember regular model ids

This commit is contained in:
Isaac0-dev 2025-03-04 15:09:09 +10:00
parent 0695a532b7
commit d6e243c4a7
10 changed files with 130 additions and 7 deletions

View file

@ -10076,6 +10076,13 @@ function obj_get_first_with_behavior_id_and_field_s32(behaviorId, fieldIndex, va
-- ...
end
--- @param o Object
--- @return ModelExtendedId
--- Returns an object's extended model id
function obj_get_model_id_extended(o)
-- ...
end
--- @param o Object
--- @param behaviorId BehaviorId
--- @return Object

View file

@ -6,10 +6,9 @@ extern "C" {
#include "engine/geo_layout.h"
#include "engine/graph_node.h"
#include "model_ids.h"
#include "pc/lua/utils/smlua_model_utils.h"
}
#define VANILLA_ID_END 255
enum ModelLoadType {
MLT_GEO,
MLT_DL,
@ -58,7 +57,7 @@ void DynOS_Model_Dump() {
}
}
struct GraphNode* DynOS_Model_LoadCommon(u32* aId, enum ModelPool aModelPool, void* aAsset, u8 aLayer, struct GraphNode* aGraphNode, bool aDeDuplicate, enum ModelLoadType mlt) {
static struct GraphNode* DynOS_Model_LoadCommonInternal(u32* aId, enum ModelPool aModelPool, void* aAsset, u8 aLayer, struct GraphNode* aGraphNode, bool aDeDuplicate, enum ModelLoadType mlt) {
// sanity check pool
if (aModelPool >= MODEL_POOL_MAX) { return NULL; }
@ -124,6 +123,12 @@ struct GraphNode* DynOS_Model_LoadCommon(u32* aId, enum ModelPool aModelPool, vo
return node;
}
static struct GraphNode* DynOS_Model_LoadCommon(u32* aId, enum ModelPool aModelPool, void* aAsset, u8 aLayer, struct GraphNode* aGraphNode, bool aDeDuplicate, enum ModelLoadType mlt) {
struct GraphNode* node = DynOS_Model_LoadCommonInternal(aId, aModelPool, aAsset, aLayer, aGraphNode, aDeDuplicate, mlt);
smlua_model_util_register_model_id(*aId, aAsset);
return node;
}
struct GraphNode* DynOS_Model_LoadGeo(u32* aId, enum ModelPool aModelPool, void* aAsset, bool aDeDuplicate) {
return DynOS_Model_LoadCommon(aId, aModelPool, aAsset, 0, NULL, aDeDuplicate, MLT_GEO);
}

View file

@ -2215,6 +2215,29 @@ Gets the first object loaded with `behaviorId` and object signed 32-bit integer
<br />
## [obj_get_model_id_extended](#obj_get_model_id_extended)
### Description
Returns an object's extended model id
### Lua Example
`local enumValue = obj_get_model_id_extended(o)`
### Parameters
| Field | Type |
| ----- | ---- |
| o | [Object](structs.md#Object) |
### Returns
[enum ModelExtendedId](constants.md#enum-ModelExtendedId)
### C Prototype
`enum ModelExtendedId obj_get_model_id_extended(struct Object *o);`
[:arrow_up_small:](#)
<br />
## [obj_get_nearest_object_with_behavior_id](#obj_get_nearest_object_with_behavior_id)
### Description

View file

@ -1847,6 +1847,7 @@
- [obj_get_first_with_behavior_id](functions-6.md#obj_get_first_with_behavior_id)
- [obj_get_first_with_behavior_id_and_field_f32](functions-6.md#obj_get_first_with_behavior_id_and_field_f32)
- [obj_get_first_with_behavior_id_and_field_s32](functions-6.md#obj_get_first_with_behavior_id_and_field_s32)
- [obj_get_model_id_extended](functions-6.md#obj_get_model_id_extended)
- [obj_get_nearest_object_with_behavior_id](functions-6.md#obj_get_nearest_object_with_behavior_id)
- [obj_get_next](functions-6.md#obj_get_next)
- [obj_get_next_with_same_behavior_id](functions-6.md#obj_get_next_with_same_behavior_id)

View file

@ -19,6 +19,8 @@
#define COIN_FORMATION_FLAG_ARROW (1 << 2)
#define COIN_FORMATION_FLAG_FLYING (1 << 4)
#define VANILLA_ID_END 255
#define MODEL_NONE 0x00
/* Global models that are loaded for every level */

View file

@ -30547,6 +30547,23 @@ int smlua_func_obj_get_first_with_behavior_id_and_field_s32(lua_State* L) {
return 1;
}
int smlua_func_obj_get_model_id_extended(lua_State* L) {
if (L == NULL) { return 0; }
int top = lua_gettop(L);
if (top != 1) {
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "obj_get_model_id_extended", 1, 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_model_id_extended"); return 0; }
lua_pushinteger(L, obj_get_model_id_extended(o));
return 1;
}
int smlua_func_obj_get_nearest_object_with_behavior_id(lua_State* L) {
if (L == NULL) { return 0; }
@ -33857,6 +33874,7 @@ void smlua_bind_functions_autogen(void) {
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);
smlua_bind_function(L, "obj_get_first_with_behavior_id_and_field_s32", smlua_func_obj_get_first_with_behavior_id_and_field_s32);
smlua_bind_function(L, "obj_get_model_id_extended", smlua_func_obj_get_model_id_extended);
smlua_bind_function(L, "obj_get_nearest_object_with_behavior_id", smlua_func_obj_get_nearest_object_with_behavior_id);
smlua_bind_function(L, "obj_get_next", smlua_func_obj_get_next);
smlua_bind_function(L, "obj_get_next_with_same_behavior_id", smlua_func_obj_get_next_with_same_behavior_id);

View file

@ -486,8 +486,10 @@ void smlua_model_util_store_in_slot(u32 slot, const char* name) {
dynos_model_overwrite_slot(slot, loadedId);
}
// Takes an extended model id, loads the model, and returns the regular model id
u16 smlua_model_util_load(enum ModelExtendedId extId) {
if ((u32)extId >= (u32)E_MODEL_MAX + (u32)sCustomModelsCount) { extId = E_MODEL_ERROR_MODEL; }
if (extId == E_MODEL_NONE) { return MODEL_NONE; }
if (!extId || (u32)extId >= (u32)E_MODEL_MAX + (u32)sCustomModelsCount) { extId = E_MODEL_ERROR_MODEL; }
struct ModelUtilsInfo* info = (extId < E_MODEL_MAX)
? &sModels[extId]
@ -502,6 +504,61 @@ u16 smlua_model_util_load(enum ModelExtendedId extId) {
return (u16)id;
}
// Links the regular model id created by DynOS to our models list
void smlua_model_util_register_model_id(u32 id, const void *asset) {
if (id < VANILLA_ID_END) {
for (u32 i = 0; i < E_MODEL_MAX; i++) {
struct ModelUtilsInfo* m = &sModels[i];
if (m->asset == asset) {
m->loadedId = id;
return;
}
}
} else {
for (u32 i = 0; i < sCustomModelsCount; i++) {
struct ModelUtilsInfo* m = &sCustomModels[i];
if (m->asset == asset) {
m->loadedId = id;
return;
}
}
}
}
// Translates an extended model id to a regular model id
u16 smlua_model_util_ext_id_to_id(enum ModelExtendedId extId) {
if (extId == E_MODEL_NONE) { return MODEL_NONE; }
if ((u32)extId >= (u32)E_MODEL_MAX + (u32)sCustomModelsCount) { return MODEL_ERROR_MODEL; }
struct ModelUtilsInfo* info = (extId < E_MODEL_MAX)
? &sModels[extId]
: &sCustomModels[extId - E_MODEL_MAX];
return info->loadedId != UNLOADED_ID ? info->loadedId : MODEL_ERROR_MODEL;
}
// Translates a regular model id to an extended model id
enum ModelExtendedId smlua_model_util_id_to_ext_id(u16 id) {
if (!id) { return E_MODEL_NONE; }
// Check built-in models
for (u32 i = 0; i < E_MODEL_MAX; i++) {
struct ModelUtilsInfo* m = &sModels[i];
if (m->loadedId == id) {
return m->extId;
}
}
// Check custom models
for (u32 i = 0; i < sCustomModelsCount; i++) {
struct ModelUtilsInfo* m = &sCustomModels[i];
if (m->loadedId == id) {
return m->extId;
}
}
return E_MODEL_ERROR_MODEL;
}
enum ModelExtendedId smlua_model_util_get_id(const char* name) {
// Find geolayout
const void* asset = dynos_geolayout_get(name);

View file

@ -399,6 +399,9 @@ void smlua_model_util_initialize(void);
void smlua_model_util_clear(void);
void smlua_model_util_store_in_slot(u32 slot, const char* name);
u16 smlua_model_util_load(enum ModelExtendedId extId);
void smlua_model_util_register_model_id(u32 id, const void *asset);
u16 smlua_model_util_ext_id_to_id(enum ModelExtendedId extId);
enum ModelExtendedId smlua_model_util_id_to_ext_id(u16 id);
/* |description|Gets the extended model ID for the `name` of a `GeoLayout`|descriptionEnd| */
enum ModelExtendedId smlua_model_util_get_id(const char* name);

View file

@ -92,9 +92,14 @@ s32 obj_has_behavior_id(struct Object *o, enum BehaviorId behaviorId) {
s32 obj_has_model_extended(struct Object *o, enum ModelExtendedId modelId) {
if (!o) { return 0; }
u16 slot = smlua_model_util_load(modelId);
struct GraphNode *model = dynos_model_get_geo(slot);
return o->header.gfx.sharedChild == model;
if (!o->header.gfx.sharedChild && modelId == E_MODEL_NONE) { return 1; }
return dynos_model_get_id_from_graph_node(o->header.gfx.sharedChild) == smlua_model_util_ext_id_to_id(modelId);
}
enum ModelExtendedId obj_get_model_id_extended(struct Object *o) {
if (!o) { return E_MODEL_NONE; }
if (!o->header.gfx.sharedChild) { return E_MODEL_NONE; }
return smlua_model_util_id_to_ext_id(dynos_model_get_id_from_graph_node(o->header.gfx.sharedChild));
}
void obj_set_model_extended(struct Object *o, enum ModelExtendedId modelId) {

View file

@ -20,6 +20,8 @@ struct Object* spawn_non_sync_object(enum BehaviorId behaviorId, enum ModelExten
s32 obj_has_behavior_id(struct Object *o, enum BehaviorId behaviorId);
/* |description|Checks if an object's model is equal to `modelId`|descriptionEnd| */
s32 obj_has_model_extended(struct Object *o, enum ModelExtendedId modelId);
/* |description|Returns an object's extended model id|descriptionEnd| */
enum ModelExtendedId obj_get_model_id_extended(struct Object *o);
/* |description|Sets an object's model to `modelId`|descriptionEnd| */
void obj_set_model_extended(struct Object *o, enum ModelExtendedId modelId);