Custom geo function and switch nodes with Lua callback (#593)

This commit is contained in:
PeachyPeach 2024-12-31 01:23:13 +01:00 committed by GitHub
parent c17b82a7a3
commit 96932f5bf1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
21 changed files with 303 additions and 21 deletions

View file

@ -82,7 +82,7 @@ override_allowed_functions = {
"src/game/save_file.h": [ "save_file_get_", "save_file_set_flags", "save_file_clear_flags", "save_file_reload", "save_file_erase_current_backup_save", "save_file_set_star_flags", "save_file_is_cannon_unlocked", "touch_coin_score_age", "save_file_set_course_coin_score", "save_file_do_save", "save_file_remove_star_flags", "save_file_erase" ],
"src/pc/lua/utils/smlua_model_utils.h": [ "smlua_model_util_get_id" ],
"src/game/object_list_processor.h": [ "set_object_respawn_info_bits" ],
"src/game/mario_misc.h": [ "bhv_toad.*", "bhv_unlock_door.*" ],
"src/game/mario_misc.h": [ "bhv_toad.*", "bhv_unlock_door.*", "geo_get_.*_state" ],
"src/pc/utils/misc.h": [ "update_all_mario_stars" ],
"src/game/level_update.h": [ "level_trigger_warp", "get_painting_warp_node", "initiate_painting_warp", "warp_special", "lvl_set_current_level", "level_control_timer_running", "fade_into_special_warp" ],
"src/game/area.h": [ "area_get_warp_node" ],

View file

@ -88,6 +88,7 @@ override_field_invisible = {
"MarioState": [ "visibleToEnemies" ],
"NetworkPlayer": [ "gag", "moderator", "discordId" ],
"GraphNode": [ "_guard1", "_guard2" ],
"FnGraphNode": [ "luaTokenIndex" ],
"Object": [ "firstSurface" ],
"ModAudio": [ "sound", "decoder", "buffer", "bufferSize", "sampleCopiesTail" ],
}

View file

@ -5788,6 +5788,18 @@ function bhv_unlock_door_star_loop()
-- ...
end
--- @return MarioBodyState
--- When used in a geo function, retrieve the MarioBodyState associated to the current processed object
function geo_get_body_state()
-- ...
end
--- @return MarioState
--- When used in a geo function, retrieve the MarioState associated to the current processed object
function geo_get_mario_state()
-- ...
end
--- @return number
--- Always returns zero. May have been originally used for beta trampolines
function get_additive_y_vel_for_jumps()

View file

@ -35,8 +35,9 @@ void dynos_generate_packs(const char* directory);
// -- geos -- //
void dynos_actor_override(struct Object* obj, void** aSharedChild);
void dynos_add_actor_custom(const char *filePath, const char* geoName);
void dynos_add_actor_custom(s32 modIndex, const char *filePath, const char* geoName);
const void* dynos_geolayout_get(const char *name);
bool dynos_actor_get_mod_index_and_token(struct GraphNode *graphNode, u32 tokenIndex, s32 *modIndex, const char **token);
// -- collisions -- //
void dynos_add_collision(const char *filePath, const char* collisionName);

View file

@ -882,8 +882,9 @@ void DynOS_Pack_AddTex(PackData* aPackData, DataNode<TexData>* aTexData);
// Actor Manager
//
void DynOS_Actor_AddCustom(const SysPath &aFilename, const char *aActorName);
void DynOS_Actor_AddCustom(s32 aModIndex, const SysPath &aFilename, const char *aActorName);
const void *DynOS_Actor_GetLayoutFromName(const char *aActorName);
bool DynOS_Actor_GetModIndexAndToken(const GraphNode *aGraphNode, u32 aTokenIndex, s32 *outModIndex, const char **outToken);
ActorGfx* DynOS_Actor_GetActorGfx(const GraphNode* aGraphNode);
void DynOS_Actor_Valid(const void* aGeoref, ActorGfx& aActorGfx);
void DynOS_Actor_Invalid(const void* aGeoref, s32 aPackIndex);
@ -977,7 +978,7 @@ void DynOS_Model_ClearPool(enum ModelPool aModelPool);
typedef s64 (*RDConstantFunc)(const String& _Arg, bool* found);
u32 DynOS_Lua_RememberVariable(GfxData* aGfxData, void* aPtr, String& token);
u32 DynOS_Lua_RememberVariable(GfxData* aGfxData, void* aPtr, const String& token);
void DynOS_Gfx_GeneratePacks(const char* directory);
s64 DynOS_RecursiveDescent_Parse(const char* expr, bool* success, RDConstantFunc func);
void DynOS_Read_Source(GfxData *aGfxData, const SysPath &aFilename);

View file

@ -307,7 +307,6 @@ static void ParseGeoSymbol(GfxData* aGfxData, DataNode<GeoLayout>* aNode, GeoLay
geo_symbol_2(GEO_DISPLAY_LIST, 1);
geo_symbol_3(GEO_SHADOW, 0);
geo_symbol_0(GEO_RENDER_OBJ);
geo_symbol_2(GEO_ASM, 1);
geo_symbol_1(GEO_BACKGROUND_COLOR, 0);
geo_symbol_0(GEO_NOP_1A);
geo_symbol_5(GEO_HELD_OBJECT, 2);
@ -317,6 +316,26 @@ static void ParseGeoSymbol(GfxData* aGfxData, DataNode<GeoLayout>* aNode, GeoLay
geo_symbol_0(GEO_NOP_1F);
geo_symbol_1(GEO_CULLING_RADIUS, 0);
// Geo function node
if (_Symbol == "GEO_ASM") {
s64 _Arg0 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex);
const String& _Arg1 = aNode->mTokens[aTokenIndex++];
const void *_FunctionPtr = DynOS_Builtin_Func_GetFromName(_Arg1.begin());
if (_FunctionPtr != NULL) {
aGfxData->mPointerList.Add(aHead + 1);
GeoLayout _Gl[] = { GEO_ASM(_Arg0, _FunctionPtr) };
memcpy(aHead, _Gl, sizeof(_Gl));
aHead += (sizeof(_Gl) / sizeof(_Gl[0]));
} else {
u32 _FuncIndex = DynOS_Lua_RememberVariable(aGfxData, aHead + 1, _Arg1);
GeoLayout _Gl[] = { GEO_ASM_EXT(_Arg0, _FuncIndex) };
memcpy(aHead, _Gl, sizeof(_Gl));
aHead += (sizeof(_Gl) / sizeof(_Gl[0]));
}
return;
}
// Switch node
if (_Symbol == "GEO_SWITCH_CASE") {
@ -324,11 +343,20 @@ static void ParseGeoSymbol(GfxData* aGfxData, DataNode<GeoLayout>* aNode, GeoLay
aSwitchNodes.Add(0);
s64 _Arg0 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex);
s64 _Arg1 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex);
aGfxData->mPointerList.Add(aHead + 1);
GeoLayout _Gl[] = { GEO_SWITCH_CASE(_Arg0, _Arg1) };
memcpy(aHead, _Gl, sizeof(_Gl));
aHead += (sizeof(_Gl) / sizeof(_Gl[0]));
const String& _Arg1 = aNode->mTokens[aTokenIndex++];
const void *_FunctionPtr = DynOS_Builtin_Func_GetFromName(_Arg1.begin());
if (_FunctionPtr != NULL) {
aGfxData->mPointerList.Add(aHead + 1);
GeoLayout _Gl[] = { GEO_SWITCH_CASE(_Arg0, _FunctionPtr) };
memcpy(aHead, _Gl, sizeof(_Gl));
aHead += (sizeof(_Gl) / sizeof(_Gl[0]));
} else {
u32 _FuncIndex = DynOS_Lua_RememberVariable(aGfxData, aHead + 1, _Arg1);
GeoLayout _Gl[] = { GEO_SWITCH_CASE_EXT(_Arg0, _FuncIndex) };
memcpy(aHead, _Gl, sizeof(_Gl));
aHead += (sizeof(_Gl) / sizeof(_Gl[0]));
}
return;
}
@ -444,6 +472,8 @@ void DynOS_Geo_Write(BinFile *aFile, GfxData *aGfxData, DataNode<GeoLayout> *aNo
GeoLayout *_Head = &aNode->mData[i];
if (aGfxData->mPointerList.Find((void *) _Head) != -1) {
DynOS_Pointer_Write(aFile, (const void *) (*_Head), aGfxData);
} else if (aGfxData->mLuaPointerList.Find((void *) _Head) != -1) {
DynOS_Pointer_Lua_Write(aFile, *(u32 *)_Head, aGfxData);
} else {
aFile->Write<u32>(*((u32 *) _Head));
}

View file

@ -125,7 +125,7 @@ void DynOS_Gfx_Free(GfxData* aGfxData) {
}
}
u32 DynOS_Lua_RememberVariable(GfxData* aGfxData, void* aPtr, String& token) {
u32 DynOS_Lua_RememberVariable(GfxData* aGfxData, void* aPtr, const String& token) {
// remember as lua pointer
aGfxData->mLuaPointerList.Add(aPtr);

View file

@ -111,14 +111,18 @@ void dynos_actor_override(struct Object* obj, void** aSharedChild) {
DynOS_Actor_Override(obj, aSharedChild);
}
void dynos_add_actor_custom(const char *filePath, const char* geoName) {
DynOS_Actor_AddCustom(filePath, geoName);
void dynos_add_actor_custom(s32 modIndex, const char *filePath, const char* geoName) {
DynOS_Actor_AddCustom(modIndex, filePath, geoName);
}
const void* dynos_geolayout_get(const char *name) {
return DynOS_Actor_GetLayoutFromName(name);
}
bool dynos_actor_get_mod_index_and_token(struct GraphNode *graphNode, u32 tokenIndex, s32 *modIndex, const char **token) {
return DynOS_Actor_GetModIndexAndToken(graphNode, tokenIndex, modIndex, token);
}
// -- collisions -- //
void dynos_add_collision(const char *filePath, const char* collisionName) {

View file

@ -24,7 +24,7 @@ static Array<Pair<const char*, void *>>& DynosCustomActors() {
// TODO: the cleanup/refactor didn't really go as planned.
// clean up the actor management code more
void DynOS_Actor_AddCustom(const SysPath &aFilename, const char *aActorName) {
void DynOS_Actor_AddCustom(s32 aModIndex, const SysPath &aFilename, const char *aActorName) {
const void* georef = DynOS_Builtin_Actor_GetFromName(aActorName);
u16 actorLen = strlen(aActorName);
@ -37,6 +37,7 @@ void DynOS_Actor_AddCustom(const SysPath &aFilename, const char *aActorName) {
free(actorName);
return;
}
_GfxData->mModIndex = aModIndex;
void* geoLayout = (*(_GfxData->mGeoLayouts.end() - 1))->mData;
if (!geoLayout) {
@ -109,6 +110,26 @@ const void *DynOS_Actor_GetLayoutFromName(const char *aActorName) {
return NULL;
}
bool DynOS_Actor_GetModIndexAndToken(const GraphNode *aGraphNode, u32 aTokenIndex, s32 *outModIndex, const char **outToken) {
ActorGfx *_ActorGfx = DynOS_Actor_GetActorGfx(aGraphNode);
if (_ActorGfx) {
GfxData *_GfxData = _ActorGfx->mGfxData;
if (_GfxData) {
if (outModIndex) {
*outModIndex = _GfxData->mModIndex;
}
if (outToken) {
if (!aTokenIndex || aTokenIndex > _GfxData->mLuaTokenList.Count()) {
return false;
}
*outToken = _GfxData->mLuaTokenList[aTokenIndex - 1].begin(); // token index is 1-indexed
}
return true;
}
}
return false;
}
ActorGfx* DynOS_Actor_GetActorGfx(const GraphNode* aGraphNode) {
if (aGraphNode == NULL) { return NULL; }
auto& _ValidActors = DynosValidActors();

View file

@ -2195,6 +2195,48 @@ Behavior loop function for Star Door unlock object
<br />
## [geo_get_body_state](#geo_get_body_state)
### Description
When used in a geo function, retrieve the MarioBodyState associated to the current processed object
### Lua Example
`local MarioBodyStateValue = geo_get_body_state()`
### Parameters
- None
### Returns
[MarioBodyState](structs.md#MarioBodyState)
### C Prototype
`struct MarioBodyState *geo_get_body_state(void);`
[:arrow_up_small:](#)
<br />
## [geo_get_mario_state](#geo_get_mario_state)
### Description
When used in a geo function, retrieve the MarioState associated to the current processed object
### Lua Example
`local MarioStateValue = geo_get_mario_state()`
### Parameters
- None
### Returns
[MarioState](structs.md#MarioState)
### C Prototype
`struct MarioState *geo_get_mario_state(void);`
[:arrow_up_small:](#)
<br />
---
# functions from mario_step.h

View file

@ -1130,6 +1130,8 @@
- [bhv_toad_message_loop](functions-4.md#bhv_toad_message_loop)
- [bhv_unlock_door_star_init](functions-4.md#bhv_unlock_door_star_init)
- [bhv_unlock_door_star_loop](functions-4.md#bhv_unlock_door_star_loop)
- [geo_get_body_state](functions-4.md#geo_get_body_state)
- [geo_get_mario_state](functions-4.md#geo_get_mario_state)
<br />

View file

@ -439,4 +439,21 @@
CMD_PTR(background), \
CMD_PTR(function)
/**
* 0x22: Create switch-case scene graph node with a custom Lua callback
*/
#define GEO_SWITCH_CASE_EXT(count, luaTokenIndex) \
CMD_BBH(0x22, 0x00, count), \
CMD_W(luaTokenIndex)
/**
* 0x23: Create dynamically generated displaylist scene graph node with a custom Lua callback
*/
#define GEO_ASM_EXT(param, luaTokenIndex) \
CMD_BBH(0x23, 0x00, param), \
CMD_W(luaTokenIndex)
#endif // GEO_COMMANDS_H

View file

@ -45,6 +45,8 @@ GeoLayoutCommandProc GeoLayoutJumpTable[] = {
geo_layout_cmd_node_culling_radius,
// coop
geo_layout_cmd_node_background_ext,
geo_layout_cmd_node_switch_case_ext,
geo_layout_cmd_node_generated_ext,
};
struct GraphNode gObjParentGraphNode;
@ -790,6 +792,44 @@ void geo_layout_cmd_node_background_ext(void) {
gGeoLayoutCommand += 0x0C << CMD_SIZE_SHIFT;
}
/*
0x22: Create switch-case scene graph node with a custom Lua callback
*/
void geo_layout_cmd_node_switch_case_ext(void) {
struct GraphNodeSwitchCase *graphNode;
graphNode = init_graph_node_switch_case(
gGraphNodePool, NULL,
cur_geo_cmd_s16(0x02), // num cases
0,
(GraphNodeFunc) geo_process_lua_function,
0
);
graphNode->fnNode.luaTokenIndex = cur_geo_cmd_u32(0x04);
register_scene_graph_node(&graphNode->fnNode.node);
gGeoLayoutCommand += 0x08 << CMD_SIZE_SHIFT;
}
/*
0x23: Create dynamically generated displaylist scene graph node with a custom Lua callback
*/
void geo_layout_cmd_node_generated_ext(void) {
struct GraphNodeGenerated *graphNode;
graphNode = init_graph_node_generated(
gGraphNodePool, NULL,
(GraphNodeFunc) geo_process_lua_function,
cur_geo_cmd_s16(0x02) // parameter
);
graphNode->fnNode.luaTokenIndex = cur_geo_cmd_u32(0x04);
register_scene_graph_node(&graphNode->fnNode.node);
gGeoLayoutCommand += 0x08 << CMD_SIZE_SHIFT;
}
struct GraphNode *process_geo_layout(struct DynamicPool *pool, void *segptr) {
// set by register_scene_graph_node when gCurGraphNodeIndex is 0
// and gCurRootGraphNode is NULL

View file

@ -82,6 +82,8 @@ void geo_layout_cmd_copy_view(void);
void geo_layout_cmd_node_held_obj(void);
void geo_layout_cmd_node_culling_radius(void);
void geo_layout_cmd_node_background_ext(void);
void geo_layout_cmd_node_switch_case_ext(void);
void geo_layout_cmd_node_generated_ext(void);
struct GraphNode *process_geo_layout(struct DynamicPool *a0, void *segptr);

View file

@ -653,6 +653,16 @@ struct GraphNode *geo_make_first_child(struct GraphNode *newFirstChild) {
return parent;
}
// A sharedChild graph node has either a parent of type GRAPH_NODE_TYPE_OBJECT or GRAPH_NODE_TYPE_OBJECT_PARENT, or no parent at all
struct GraphNode *geo_find_shared_child(struct GraphNode *graphNode) {
while (graphNode->parent &&
graphNode->parent->type != GRAPH_NODE_TYPE_OBJECT &&
graphNode->parent->type != GRAPH_NODE_TYPE_OBJECT_PARENT) {
graphNode = graphNode->parent;
}
return graphNode;
}
/**
* Helper function for geo_call_global_function_nodes that recursively
* traverses the scene graph and calls the functions of global nodes.

View file

@ -79,6 +79,7 @@ struct FnGraphNode
{
/*0x00*/ struct GraphNode node;
/*0x14*/ GraphNodeFunc func;
u32 luaTokenIndex; // reference to lua function resolved during geo_process_lua_function (1-indexed)
};
/** The very root of the geo tree. Specifies the viewport.
@ -431,6 +432,7 @@ struct GraphNode *geo_add_child(struct GraphNode *parent, struct GraphNode *chil
struct GraphNode* geo_remove_child_from_parent(struct GraphNode* parent, struct GraphNode* graphNode);
struct GraphNode *geo_remove_child(struct GraphNode *graphNode);
struct GraphNode *geo_make_first_child(struct GraphNode *newFirstChild);
struct GraphNode *geo_find_shared_child(struct GraphNode *graphNode);
void geo_call_global_function_nodes_helper(struct GraphNode *graphNode, s32 callContext);
void geo_call_global_function_nodes(struct GraphNode *graphNode, s32 callContext);

View file

@ -26,6 +26,7 @@
#include "sound_init.h"
#include "pc/network/network.h"
#include "pc/lua/smlua_hooks.h"
#include "pc/mods/mods.h"
#define TOAD_STAR_1_REQUIREMENT gBehaviorValues.ToadStar1Requirement
#define TOAD_STAR_2_REQUIREMENT gBehaviorValues.ToadStar2Requirement
@ -346,12 +347,12 @@ static u8 geo_get_processing_object_index(void) {
return (index >= MAX_PLAYERS) ? 0 : index;
}
static struct MarioState* geo_get_mario_state(void) {
struct MarioState *geo_get_mario_state(void) {
u8 index = geo_get_processing_object_index();
return &gMarioStates[index];
}
static struct MarioBodyState* geo_get_body_state(void) {
struct MarioBodyState *geo_get_body_state(void) {
u8 index = geo_get_processing_object_index();
return &gBodyStates[index];
}
@ -838,3 +839,63 @@ Gfx* geo_mario_cap_display_list(s32 callContext, struct GraphNode* node, UNUSED
asGenerated->fnNode.node.flags = (asGenerated->fnNode.node.flags & 0xFF) | (character->capEnemyLayer << 8);
return gfx;
}
Gfx *geo_process_lua_function(s32 callContext, struct GraphNode *node, UNUSED Mat4 *c) {
extern s16 gMatStackIndex;
lua_State *L = gLuaState;
// Do nothing outside of geo_process
if (callContext != GEO_CONTEXT_RENDER) {
return NULL;
}
// Check node type
if (!node || !(node->type & GRAPH_NODE_TYPE_FUNCTIONAL)) {
return NULL;
}
struct FnGraphNode *fnNode = (struct FnGraphNode *) node;
struct GraphNode *sharedChild = geo_find_shared_child(node);
// Retrieve mod index and function name
s32 modIndex = -1;
const char *funcStr = NULL;
if (!dynos_actor_get_mod_index_and_token(sharedChild, fnNode->luaTokenIndex, &modIndex, &funcStr)) {
if (modIndex == -1) {
LOG_ERROR("Could not find graph node mod index");
} else if (funcStr == NULL) {
LOG_ERROR("Could not find graph node function name");
}
return NULL;
}
// Retrieve function ref
gSmLuaConvertSuccess = true;
LuaFunction funcRef = smlua_get_function_mod_variable(modIndex, funcStr);
if (!gSmLuaConvertSuccess) {
gSmLuaConvertSuccess = true;
funcRef = smlua_get_any_function_mod_variable(funcStr);
}
if (!gSmLuaConvertSuccess || funcRef == 0) {
LOG_LUA("Failed to call lua function, could not find lua function '%s'", funcStr);
return NULL;
}
// Get the mod
if (modIndex >= gActiveMods.entryCount) {
LOG_LUA("Failed to call lua function, could not find mod");
return NULL;
}
struct Mod *mod = gActiveMods.entries[modIndex];
// Push the callback, the graph node and the current matrix stack index
lua_rawgeti(L, LUA_REGISTRYINDEX, funcRef);
smlua_push_object(L, LOT_GRAPHNODE, node);
lua_pushinteger(L, gMatStackIndex);
// Call the callback
if (0 != smlua_call_hook(L, 2, 0, 0, mod)) {
LOG_LUA("Failed to call the function callback: '%s'", funcStr);
}
return NULL;
}

View file

@ -18,6 +18,10 @@ void bhv_toad_message_loop(void);
void bhv_unlock_door_star_init(void);
/* |description|Behavior loop function for Star Door unlock object|descriptionEnd| */
void bhv_unlock_door_star_loop(void);
/* |description|When used in a geo function, retrieve the MarioState associated to the current processed object|descriptionEnd| */
struct MarioState *geo_get_mario_state(void);
/* |description|When used in a geo function, retrieve the MarioBodyState associated to the current processed object|descriptionEnd| */
struct MarioBodyState *geo_get_body_state(void);
Gfx *geo_mirror_mario_set_alpha(s32 callContext, struct GraphNode *node, UNUSED Mat4 *c);
Gfx *geo_switch_mario_stand_run(s32 callContext, struct GraphNode *node, UNUSED Mat4 *mtx);
Gfx *geo_switch_mario_eyes(s32 callContext, struct GraphNode *node, UNUSED Mat4 *c);
@ -33,5 +37,6 @@ Gfx *geo_render_mirror_mario(s32 callContext, struct GraphNode *node, UNUSED Mat
Gfx *geo_mirror_mario_backface_culling(s32 callContext, struct GraphNode *node, UNUSED Mat4 *c);
Gfx* geo_mario_set_player_colors(s32 callContext, struct GraphNode* node, UNUSED Mat4* c);
Gfx* geo_mario_cap_display_list(s32 callContext, struct GraphNode* node, UNUSED Mat4* c);
Gfx *geo_process_lua_function(s32 callContext, struct GraphNode *node, UNUSED Mat4 *c);
#endif // MARIO_MISC_H

View file

@ -800,8 +800,7 @@ static void geo_process_display_list(struct GraphNodeDisplayList *node) {
*/
static void geo_process_generated_list(struct GraphNodeGenerated *node) {
if (node->fnNode.func != NULL) {
Gfx *list = node->fnNode.func(GEO_CONTEXT_RENDER, &node->fnNode.node,
(struct DynamicPool *) gMatStack[gMatStackIndex]);
Gfx *list = node->fnNode.func(GEO_CONTEXT_RENDER, &node->fnNode.node, gMatStack[gMatStackIndex]);
if (list != NULL) {
geo_append_display_list((void *) VIRTUAL_TO_PHYSICAL(list), node->fnNode.node.flags >> 8);

View file

@ -17977,6 +17977,36 @@ int smlua_func_bhv_unlock_door_star_loop(UNUSED lua_State* L) {
return 1;
}
int smlua_func_geo_get_body_state(UNUSED lua_State* L) {
if (L == NULL) { return 0; }
int top = lua_gettop(L);
if (top != 0) {
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "geo_get_body_state", 0, top);
return 0;
}
smlua_push_object(L, LOT_MARIOBODYSTATE, geo_get_body_state());
return 1;
}
int smlua_func_geo_get_mario_state(UNUSED lua_State* L) {
if (L == NULL) { return 0; }
int top = lua_gettop(L);
if (top != 0) {
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "geo_get_mario_state", 0, top);
return 0;
}
smlua_push_object(L, LOT_MARIOSTATE, geo_get_mario_state());
return 1;
}
//////////////////
// mario_step.h //
//////////////////
@ -32992,6 +33022,8 @@ void smlua_bind_functions_autogen(void) {
smlua_bind_function(L, "bhv_toad_message_loop", smlua_func_bhv_toad_message_loop);
smlua_bind_function(L, "bhv_unlock_door_star_init", smlua_func_bhv_unlock_door_star_init);
smlua_bind_function(L, "bhv_unlock_door_star_loop", smlua_func_bhv_unlock_door_star_loop);
smlua_bind_function(L, "geo_get_body_state", smlua_func_geo_get_body_state);
smlua_bind_function(L, "geo_get_mario_state", smlua_func_geo_get_mario_state);
// mario_step.h
smlua_bind_function(L, "get_additive_y_vel_for_jumps", smlua_func_get_additive_y_vel_for_jumps);

View file

@ -21,7 +21,7 @@ size_t mod_get_lua_size(struct Mod* mod) {
return size;
}
static void mod_activate_bin(struct ModFile* file) {
static void mod_activate_bin(struct Mod* mod, struct ModFile* file) {
// copy geo name
char geoName[64] = { 0 };
if (snprintf(geoName, 63, "%s", path_basename(file->relativePath)) < 0) {
@ -41,7 +41,7 @@ static void mod_activate_bin(struct ModFile* file) {
// Add to custom actors
LOG_INFO("Activating DynOS bin: '%s', '%s'", file->cachedPath, geoName);
dynos_add_actor_custom(file->cachedPath, geoName);
dynos_add_actor_custom(mod->index, file->cachedPath, geoName);
}
static void mod_activate_col(struct ModFile* file) {
@ -148,7 +148,7 @@ void mod_activate(struct Mod* mod) {
}
if (str_ends_with(file->relativePath, ".bin")) {
mod_activate_bin(file);
mod_activate_bin(mod, file);
}
if (str_ends_with(file->relativePath, ".col")) {
mod_activate_col(file);