From 8735cf96adf5c876f953cb911793403afdeaa4d7 Mon Sep 17 00:00:00 2001
From: EmeraldLockdown <86802223+EmeraldLoc@users.noreply.github.com>
Date: Sun, 15 Mar 2026 15:49:01 -0500
Subject: [PATCH] Add `get_mod_files` (#1091)
* Add `get_mod_files`
* Dont allocate memory, use the stack
* Implement peachy's suggestion
* Actually allow optional to wrok
---
autogen/lua_definitions/functions.lua | 8 +++++
docs/lua/functions-7.md | 24 ++++++++++++++
docs/lua/functions.md | 1 +
src/pc/lua/smlua_functions_autogen.c | 23 +++++++++++++
src/pc/lua/utils/smlua_misc_utils.c | 48 +++++++++++++++++++++++++++
src/pc/lua/utils/smlua_misc_utils.h | 4 ++-
6 files changed, 107 insertions(+), 1 deletion(-)
diff --git a/autogen/lua_definitions/functions.lua b/autogen/lua_definitions/functions.lua
index 746a8f4c4..c716033b3 100644
--- a/autogen/lua_definitions/functions.lua
+++ b/autogen/lua_definitions/functions.lua
@@ -11647,6 +11647,14 @@ function get_active_mod()
-- ...
end
+--- @param mod Mod
+--- @param subDirectory? string
+--- @return table
+--- Gets all files a mod contains
+function get_mod_files(mod, subDirectory)
+ -- ...
+end
+
--- @param title string
--- Sets the window title to a custom title
function set_window_title(title)
diff --git a/docs/lua/functions-7.md b/docs/lua/functions-7.md
index 207edbb6f..1dd27c2d7 100644
--- a/docs/lua/functions-7.md
+++ b/docs/lua/functions-7.md
@@ -2107,6 +2107,30 @@ Gets the mod currently being processed
+## [get_mod_files](#get_mod_files)
+
+### Description
+Gets all files a mod contains
+
+### Lua Example
+`local tableValue = get_mod_files(mod, subDirectory)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| mod | [Mod](structs.md#Mod) |
+| subDirectory | `string` |
+
+### Returns
+- `table`
+
+### C Prototype
+`LuaTable get_mod_files(struct Mod* mod, OPTIONAL const char* subDirectory);`
+
+[:arrow_up_small:](#)
+
+
+
## [set_window_title](#set_window_title)
### Description
diff --git a/docs/lua/functions.md b/docs/lua/functions.md
index 4076375df..ecce742d3 100644
--- a/docs/lua/functions.md
+++ b/docs/lua/functions.md
@@ -2071,6 +2071,7 @@
- [set_environment_region](functions-7.md#set_environment_region)
- [mod_file_exists](functions-7.md#mod_file_exists)
- [get_active_mod](functions-7.md#get_active_mod)
+ - [get_mod_files](functions-7.md#get_mod_files)
- [set_window_title](functions-7.md#set_window_title)
- [reset_window_title](functions-7.md#reset_window_title)
- [get_os_name](functions-7.md#get_os_name)
diff --git a/src/pc/lua/smlua_functions_autogen.c b/src/pc/lua/smlua_functions_autogen.c
index e227a54aa..70d040309 100644
--- a/src/pc/lua/smlua_functions_autogen.c
+++ b/src/pc/lua/smlua_functions_autogen.c
@@ -34301,6 +34301,28 @@ int smlua_func_get_active_mod(UNUSED lua_State* L) {
return 1;
}
+int smlua_func_get_mod_files(lua_State* L) {
+ if (L == NULL) { return 0; }
+
+ int top = lua_gettop(L);
+ if (top < 1 || top > 2) {
+ LOG_LUA_LINE("Improper param count for '%s': Expected between %u and %u, Received %u", "get_mod_files", 1, 2, top);
+ return 0;
+ }
+
+ struct Mod* mod = (struct Mod*)smlua_to_cobject(L, 1, LOT_MOD);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "get_mod_files"); return 0; }
+ const char* subDirectory = (const char*) NULL;
+ if (top >= 2) {
+ subDirectory = smlua_to_string(L, 2);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "get_mod_files"); return 0; }
+ }
+
+ smlua_push_lua_table(L, get_mod_files(mod, subDirectory));
+
+ return 1;
+}
+
int smlua_func_set_window_title(lua_State* L) {
if (L == NULL) { return 0; }
@@ -38685,6 +38707,7 @@ void smlua_bind_functions_autogen(void) {
smlua_bind_function(L, "set_environment_region", smlua_func_set_environment_region);
smlua_bind_function(L, "mod_file_exists", smlua_func_mod_file_exists);
smlua_bind_function(L, "get_active_mod", smlua_func_get_active_mod);
+ smlua_bind_function(L, "get_mod_files", smlua_func_get_mod_files);
smlua_bind_function(L, "set_window_title", smlua_func_set_window_title);
smlua_bind_function(L, "reset_window_title", smlua_func_reset_window_title);
smlua_bind_function(L, "get_os_name", smlua_func_get_os_name);
diff --git a/src/pc/lua/utils/smlua_misc_utils.c b/src/pc/lua/utils/smlua_misc_utils.c
index de447b3d1..9e90a45fb 100644
--- a/src/pc/lua/utils/smlua_misc_utils.c
+++ b/src/pc/lua/utils/smlua_misc_utils.c
@@ -607,6 +607,54 @@ struct Mod* get_active_mod(void) {
return gLuaActiveMod;
}
+LuaTable get_mod_files(struct Mod* mod, OPTIONAL const char* subDirectory) {
+ if (!mod) {
+ struct lua_State *L = gLuaState;
+ if (L) {
+ lua_newtable(L);
+ return smlua_to_lua_table(L, -1);
+ }
+ return 0;
+ }
+
+ char normalizedSubDir[SYS_MAX_PATH] = { 0 };
+ snprintf(normalizedSubDir, SYS_MAX_PATH, "%s", subDirectory ? subDirectory : "");
+ normalize_path(normalizedSubDir);
+
+ size_t subDirLen = strlen(normalizedSubDir);
+ if (subDirLen > 0 && subDirLen + 1 < SYS_MAX_PATH && normalizedSubDir[subDirLen - 1] != '/') {
+ strcat(normalizedSubDir, "/");
+ subDirLen = strlen(normalizedSubDir);
+ }
+
+ struct lua_State *L = gLuaState;
+ if (!L) { return 0; }
+
+ LUA_STACK_CHECK_BEGIN_NUM(L, 1);
+
+ lua_newtable(L);
+
+ int luaTableIndex = 1;
+ for (int i = 0; i < mod->fileCount; i++) {
+ struct ModFile* file = &mod->files[i];
+ char normalizedPath[SYS_MAX_PATH] = { 0 };
+ if (snprintf(normalizedPath, SYS_MAX_PATH, "%s", file->relativePath) < 0) {
+ LOG_ERROR("Failed to copy relativePath for normalization: %s", file->relativePath);
+ continue;
+ }
+ normalize_path(normalizedPath);
+
+ if (strncmp(normalizedPath, normalizedSubDir, subDirLen) == 0) {
+ lua_pushstring(L, file->relativePath);
+ lua_rawseti(L, -2, luaTableIndex++);
+ }
+ }
+
+ LUA_STACK_CHECK_END(L);
+
+ return smlua_to_lua_table(L, -1);
+}
+
///
void set_window_title(const char* title) {
diff --git a/src/pc/lua/utils/smlua_misc_utils.h b/src/pc/lua/utils/smlua_misc_utils.h
index e4bb3c1eb..1b7d929cb 100644
--- a/src/pc/lua/utils/smlua_misc_utils.h
+++ b/src/pc/lua/utils/smlua_misc_utils.h
@@ -37,7 +37,7 @@ enum ActSelectHudPart {
ACT_SELECT_HUD_ACT_NAME = 1 << 3,
ACT_SELECT_HUD_STAR_NUM = 1 << 4,
ACT_SELECT_HUD_PLAYERS_IN_LEVEL = 1 << 5,
-
+
ACT_SELECT_HUD_NONE = 0,
ACT_SELECT_HUD_ALL = ACT_SELECT_HUD_SCORE | ACT_SELECT_HUD_LEVEL_NAME | ACT_SELECT_HUD_COURSE_NUM | ACT_SELECT_HUD_ACT_NAME |ACT_SELECT_HUD_STAR_NUM | ACT_SELECT_HUD_PLAYERS_IN_LEVEL
};
@@ -246,6 +246,8 @@ void set_environment_region(u8 index, s16 value);
bool mod_file_exists(const char* filename);
/* |description|Gets the mod currently being processed|descriptionEnd| */
struct Mod* get_active_mod(void);
+/* |description|Gets all files a mod contains|descriptionEnd| */
+LuaTable get_mod_files(struct Mod* mod, OPTIONAL const char* subDirectory);
/* |description|Sets the window title to a custom title|descriptionEnd| */
void set_window_title(const char* title);