Add hooked behaviors to get_id_from_behavior_name (#1104)
Some checks failed
Build coop / build-linux (push) Has been cancelled
Build coop / build-steamos (push) Has been cancelled
Build coop / build-windows-opengl (push) Has been cancelled
Build coop / build-windows-directx (push) Has been cancelled
Build coop / build-macos-arm (push) Has been cancelled
Build coop / build-macos-intel (push) Has been cancelled

* Add hooked behaviors to get_id_from_behavior_name

* Fix comment capitalization
This commit is contained in:
Agent X 2026-02-12 15:41:55 -05:00 committed by GitHub
parent 16c92c25d8
commit dd233f26be
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 52 additions and 43 deletions

View file

@ -597,5 +597,11 @@ enum BehaviorId get_id_from_behavior_name(const char* name) {
return i;
}
}
for (int i = 0; i < gHookedBehaviorsCount; i++) {
struct LuaHookedBehavior *hooked = &gHookedBehaviors[i];
if (hooked->bhvName && !strcmp(name, hooked->bhvName)) {
return hooked->overrideId;
}
}
return id_bhv_max_count;
}

View file

@ -557,7 +557,7 @@ enum BehaviorId get_id_from_vanilla_behavior(const BehaviorScript* behavior);
const BehaviorScript* get_behavior_from_id(enum BehaviorId id);
/* |description|Gets a behavior name from a behavior ID (bhvMyGreatMODCustom004)|descriptionEnd| */
const char* get_behavior_name_from_id(enum BehaviorId id);
/* |description|gets a behavior ID from a behavior name|descriptionEnd| */
/* |description|Gets a behavior ID from a behavior name|descriptionEnd| */
enum BehaviorId get_id_from_behavior_name(const char* name);
#endif

View file

@ -398,30 +398,13 @@ u32 smlua_get_action_interaction_type(struct MarioState* m) {
// hooked behaviors //
//////////////////////
struct LuaHookedBehavior {
u32 behaviorId;
u32 overrideId;
u32 originalId;
BehaviorScript *behavior;
const BehaviorScript* originalBehavior;
const char* bhvName;
int initReference;
int loopReference;
bool replace;
bool luaBehavior;
struct Mod* mod;
struct ModFile* modFile;
};
#define MAX_HOOKED_BEHAVIORS 1024
static struct LuaHookedBehavior sHookedBehaviors[MAX_HOOKED_BEHAVIORS] = { 0 };
static int sHookedBehaviorsCount = 0;
struct LuaHookedBehavior gHookedBehaviors[MAX_HOOKED_BEHAVIORS] = { 0 };
int gHookedBehaviorsCount = 0;
enum BehaviorId smlua_get_original_behavior_id(const BehaviorScript* behavior) {
enum BehaviorId id = get_id_from_behavior(behavior);
for (int i = 0; i < sHookedBehaviorsCount; i++) {
struct LuaHookedBehavior* hooked = &sHookedBehaviors[i];
for (int i = 0; i < gHookedBehaviorsCount; i++) {
struct LuaHookedBehavior* hooked = &gHookedBehaviors[i];
if (hooked->behavior == behavior) {
id = hooked->overrideId;
}
@ -443,8 +426,8 @@ const BehaviorScript* smlua_get_hooked_behavior_from_id(enum BehaviorId id, bool
lua_State *L = gLuaState;
if (L == NULL) { return NULL; }
for (int i = 0; i < sHookedBehaviorsCount; i++) {
struct LuaHookedBehavior* hooked = &sHookedBehaviors[i];
for (int i = 0; i < gHookedBehaviorsCount; i++) {
struct LuaHookedBehavior* hooked = &gHookedBehaviors[i];
if (hooked->behaviorId != id && hooked->overrideId != id) { continue; }
if (returnOriginal && !hooked->replace) { return hooked->originalBehavior; }
return hooked->behavior;
@ -457,8 +440,8 @@ bool smlua_is_behavior_hooked(const BehaviorScript *behavior) {
if (L == NULL) { return false; }
enum BehaviorId id = get_id_from_behavior(behavior);
for (int i = 0; i < sHookedBehaviorsCount; i++) {
struct LuaHookedBehavior *hooked = &sHookedBehaviors[i];
for (int i = 0; i < gHookedBehaviorsCount; i++) {
struct LuaHookedBehavior *hooked = &gHookedBehaviors[i];
if (hooked->behaviorId != id && hooked->overrideId != id) { continue; }
return hooked->luaBehavior;
}
@ -467,8 +450,8 @@ bool smlua_is_behavior_hooked(const BehaviorScript *behavior) {
}
const char* smlua_get_name_from_hooked_behavior_id(enum BehaviorId id) {
for (int i = 0; i < sHookedBehaviorsCount; i++) {
struct LuaHookedBehavior *hooked = &sHookedBehaviors[i];
for (int i = 0; i < gHookedBehaviorsCount; i++) {
struct LuaHookedBehavior *hooked = &gHookedBehaviors[i];
if (hooked->behaviorId != id && hooked->overrideId != id) { continue; }
return hooked->bhvName;
}
@ -476,7 +459,7 @@ const char* smlua_get_name_from_hooked_behavior_id(enum BehaviorId id) {
}
int smlua_hook_custom_bhv(BehaviorScript *bhvScript, const char *bhvName) {
if (sHookedBehaviorsCount >= MAX_HOOKED_BEHAVIORS) {
if (gHookedBehaviorsCount >= MAX_HOOKED_BEHAVIORS) {
LOG_ERROR("Hooked behaviors exceeded maximum references!");
return 0;
}
@ -490,8 +473,8 @@ int smlua_hook_custom_bhv(BehaviorScript *bhvScript, const char *bhvName) {
u8 newBehavior = originalBehaviorId >= id_bhv_max_count;
struct LuaHookedBehavior *hooked = &sHookedBehaviors[sHookedBehaviorsCount];
u16 customBehaviorId = (sHookedBehaviorsCount & 0xFFFF) | LUA_BEHAVIOR_FLAG;
struct LuaHookedBehavior *hooked = &gHookedBehaviors[gHookedBehaviorsCount];
u16 customBehaviorId = (gHookedBehaviorsCount & 0xFFFF) | LUA_BEHAVIOR_FLAG;
hooked->behavior = bhvScript;
hooked->behavior[1] = (BehaviorScript)BC_B0H(0x39, customBehaviorId); // This is ID(customBehaviorId)
hooked->behaviorId = customBehaviorId;
@ -506,7 +489,7 @@ int smlua_hook_custom_bhv(BehaviorScript *bhvScript, const char *bhvName) {
hooked->mod = gLuaActiveMod;
hooked->modFile = gLuaActiveModFile;
sHookedBehaviorsCount++;
gHookedBehaviorsCount++;
// We want to push the behavior into the global LUA state. So mods can access it.
// It's also used for some things that would normally access a LUA behavior instead.
@ -531,7 +514,7 @@ int smlua_hook_behavior(lua_State* L) {
int paramCount = lua_gettop(L);
if (sHookedBehaviorsCount >= MAX_HOOKED_BEHAVIORS) {
if (gHookedBehaviorsCount >= MAX_HOOKED_BEHAVIORS) {
LOG_LUA_LINE("Hooked behaviors exceeded maximum references!");
return 0;
}
@ -634,8 +617,8 @@ int smlua_hook_behavior(lua_State* L) {
bhvName = sGenericBhvName;
}
struct LuaHookedBehavior* hooked = &sHookedBehaviors[sHookedBehaviorsCount];
u16 customBehaviorId = (sHookedBehaviorsCount & 0xFFFF) | LUA_BEHAVIOR_FLAG;
struct LuaHookedBehavior* hooked = &gHookedBehaviors[gHookedBehaviorsCount];
u16 customBehaviorId = (gHookedBehaviorsCount & 0xFFFF) | LUA_BEHAVIOR_FLAG;
hooked->behavior = calloc(4, sizeof(BehaviorScript));
hooked->behavior[0] = (BehaviorScript)BC_BB(0x00, objectList); // This is BEGIN(objectList)
hooked->behavior[1] = (BehaviorScript)BC_B0H(0x39, customBehaviorId); // This is ID(customBehaviorId)
@ -653,7 +636,7 @@ int smlua_hook_behavior(lua_State* L) {
hooked->mod = gLuaActiveMod;
hooked->modFile = gLuaActiveModFile;
sHookedBehaviorsCount++;
gHookedBehaviorsCount++;
// We want to push the behavior into the global LUA state. So mods can access it.
// It's also used for some things that would normally access a LUA behavior instead.
@ -670,8 +653,8 @@ int smlua_hook_behavior(lua_State* L) {
bool smlua_call_behavior_hook(const BehaviorScript** behavior, struct Object* object, bool before) {
lua_State* L = gLuaState;
if (L == NULL) { return false; }
for (int i = 0; i < sHookedBehaviorsCount; i++) {
struct LuaHookedBehavior* hooked = &sHookedBehaviors[i];
for (int i = 0; i < gHookedBehaviorsCount; i++) {
struct LuaHookedBehavior* hooked = &gHookedBehaviors[i];
// find behavior
if (object->behavior != hooked->behavior) {
@ -1518,8 +1501,8 @@ void smlua_hook_replace_function_references(lua_State* L, int oldReference, int
smlua_hook_replace_function_reference(L, &hooked->reference, oldReference, newReference);
}
for (int i = 0; i < sHookedBehaviorsCount; i++) {
struct LuaHookedBehavior* hooked = &sHookedBehaviors[i];
for (int i = 0; i < gHookedBehaviorsCount; i++) {
struct LuaHookedBehavior* hooked = &gHookedBehaviors[i];
smlua_hook_replace_function_reference(L, &hooked->initReference, oldReference, newReference);
smlua_hook_replace_function_reference(L, &hooked->loopReference, oldReference, newReference);
}
@ -1574,8 +1557,8 @@ void smlua_clear_hooks(void) {
}
gHookedModMenuElementsCount = 0;
for (int i = 0; i < sHookedBehaviorsCount; i++) {
struct LuaHookedBehavior* hooked = &sHookedBehaviors[i];
for (int i = 0; i < gHookedBehaviorsCount; i++) {
struct LuaHookedBehavior* hooked = &gHookedBehaviors[i];
// If this is NULL. We can't do anything with it.
if (hooked->behavior != NULL) {
@ -1601,7 +1584,7 @@ void smlua_clear_hooks(void) {
hooked->mod = NULL;
hooked->modFile = NULL;
}
sHookedBehaviorsCount = 0;
gHookedBehaviorsCount = 0;
memset(gLuaMarioActionIndex, 0, sizeof(gLuaMarioActionIndex));
}

View file

@ -127,6 +127,26 @@ extern u32 gLuaMarioActionIndex[];
extern struct LuaHookedModMenuElement gHookedModMenuElements[];
extern int gHookedModMenuElementsCount;
#define MAX_HOOKED_BEHAVIORS 1024
struct LuaHookedBehavior {
u32 behaviorId;
u32 overrideId;
u32 originalId;
BehaviorScript *behavior;
const BehaviorScript* originalBehavior;
const char* bhvName;
int initReference;
int loopReference;
bool replace;
bool luaBehavior;
struct Mod* mod;
struct ModFile* modFile;
};
extern int gHookedBehaviorsCount;
extern struct LuaHookedBehavior gHookedBehaviors[MAX_HOOKED_BEHAVIORS];
#define OUTPUT
#define SMLUA_EVENT_HOOK(hookEventType, hookReturn, ...) bool smlua_call_event_hooks_##hookEventType(__VA_ARGS__);
#include "smlua_hook_events.inl"