diff --git a/autogen/convert_structs.py b/autogen/convert_structs.py
index d0f04df2d..224535fe4 100644
--- a/autogen/convert_structs.py
+++ b/autogen/convert_structs.py
@@ -21,6 +21,7 @@ in_files = [
'src/game/spawn_sound.h',
'src/pc/network/network.h',
'src/game/hardcoded.h',
+ 'src/pc/mods/mod.h',
]
out_filename_c = 'src/pc/lua/smlua_cobject_autogen.c'
@@ -70,6 +71,10 @@ override_field_mutable = {
"NetworkPlayer": [ "overrideModelIndex", "overridePaletteIndex" ],
}
+override_field_invisible = {
+ "Mod": [ "files" ]
+}
+
override_field_immutable = {
"MarioState": [ "playerIndex" ],
"Character": [ "*" ],
@@ -80,10 +85,13 @@ override_field_immutable = {
"SpawnParticlesInfo": [ "model" ],
"MarioBodyState": [ "updateTorsoTime" ],
"Area": [ "localAreaTimer" ],
+ "Mod": [ "*" ],
+ "ModFile": [ "*" ],
}
override_allowed_structs = {
- "src/pc/network/network.h": [ 'ServerSettings' ]
+ "src/pc/network/network.h": [ 'ServerSettings' ],
+ "src/pc/mods/mod.h": [ 'Mod' ],
}
sLuaManuallyDefinedStructs = [{
@@ -248,6 +256,10 @@ def build_struct(struct):
for field in struct['fields']:
fid, ftype, fimmutable, lvt, lot = get_struct_field_info(struct, field)
+ if sid in override_field_invisible:
+ if fid in override_field_invisible[sid]:
+ continue
+
row = []
row.append(' { ' )
row.append('"%s", ' % fid )
@@ -341,6 +353,11 @@ def doc_struct_index(structs):
def doc_struct_field(struct, field):
fid, ftype, fimmutable, lvt, lot = get_struct_field_info(struct, field)
+ sid = struct['identifier']
+ if sid in override_field_invisible:
+ if fid in override_field_invisible[sid]:
+ return ''
+
if '???' in lvt or '???' in lot:
return ''
@@ -425,6 +442,10 @@ def def_struct(struct):
for field in struct['fields']:
fid, ftype, fimmutable, lvt, lot = get_struct_field_info(struct, field)
+ if sid in override_field_invisible:
+ if fid in override_field_invisible[sid]:
+ continue
+
if '???' in lvt or '???' in lot:
continue
diff --git a/autogen/lua_definitions/manual.lua b/autogen/lua_definitions/manual.lua
index da0707344..6f778dc64 100644
--- a/autogen/lua_definitions/manual.lua
+++ b/autogen/lua_definitions/manual.lua
@@ -8,6 +8,9 @@ gMarioStates = {}
--- @type NetworkPlayer[]
gNetworkPlayers = {}
+--- @type Mod[]
+gActiveMods = {}
+
--- @type Character[]
gCharacter = {}
diff --git a/autogen/lua_definitions/structs.lua b/autogen/lua_definitions/structs.lua
index dd5e185f4..19aacaf44 100644
--- a/autogen/lua_definitions/structs.lua
+++ b/autogen/lua_definitions/structs.lua
@@ -680,6 +680,18 @@
--- @field public wasNetworkVisible integer
--- @field public waterLevel integer
+--- @class Mod
+--- @field public basePath string
+--- @field public description string
+--- @field public enabled boolean
+--- @field public fileCount integer
+--- @field public incompatible string
+--- @field public index integer
+--- @field public isDirectory boolean
+--- @field public name string
+--- @field public relativePath string
+--- @field public selectable boolean
+
--- @class ModeTransitionInfo
--- @field public frame integer
--- @field public lastMode integer
diff --git a/docs/lua/globals.md b/docs/lua/globals.md
index feb938225..9115dfbb1 100644
--- a/docs/lua/globals.md
+++ b/docs/lua/globals.md
@@ -23,6 +23,13 @@ It is indexed by the local `playerIndex`, so `gNetworkPlayers[0]` is always the
+## [gActiveMods](#gNetworkPlayers)
+The `gActiveMods[]` table is an array that starts at `0`, and contains a [Mod](structs.md#Mod) struct for each active mod.
+
+[:arrow_up_small:](#)
+
+
+
## [gCharacter](#gCharacter)
The `gCharacter[]` table is an array from `0` to `(CT_MAX - 1)` that contains a [Character](structs.md#Character) struct for each possible character.
diff --git a/docs/lua/structs.md b/docs/lua/structs.md
index eec212df9..a6dca7494 100644
--- a/docs/lua/structs.md
+++ b/docs/lua/structs.md
@@ -34,6 +34,7 @@
- [MarioAnimation](#MarioAnimation)
- [MarioBodyState](#MarioBodyState)
- [MarioState](#MarioState)
+- [Mod](#Mod)
- [ModeTransitionInfo](#ModeTransitionInfo)
- [NetworkPlayer](#NetworkPlayer)
- [Object](#Object)
@@ -974,6 +975,25 @@
+## [Mod](#Mod)
+
+| Field | Type | Access |
+| ----- | ---- | ------ |
+| basePath | `string` | read-only |
+| description | `string` | read-only |
+| enabled | `boolean` | read-only |
+| fileCount | `integer` | read-only |
+| incompatible | `string` | read-only |
+| index | `integer` | read-only |
+| isDirectory | `boolean` | read-only |
+| name | `string` | read-only |
+| relativePath | `string` | read-only |
+| selectable | `boolean` | read-only |
+
+[:arrow_up_small:](#)
+
+
+
## [ModeTransitionInfo](#ModeTransitionInfo)
| Field | Type | Access |
diff --git a/src/pc/lua/smlua_cobject.c b/src/pc/lua/smlua_cobject.c
index 31ee76ba5..4ba2ae42d 100644
--- a/src/pc/lua/smlua_cobject.c
+++ b/src/pc/lua/smlua_cobject.c
@@ -533,6 +533,17 @@ void smlua_cobject_init_globals(void) {
lua_setglobal(L, "gNetworkPlayers");
}
+ {
+ lua_newtable(L);
+ int t = lua_gettop(gLuaState);
+ for (s32 i = 0; i < gActiveMods.entryCount; i++) {
+ lua_pushinteger(L, i);
+ smlua_push_object(L, LOT_MOD, gActiveMods.entries[i]);
+ lua_settable(L, t);
+ }
+ lua_setglobal(L, "gActiveMods");
+ }
+
{
lua_newtable(L);
int t = lua_gettop(gLuaState);
diff --git a/src/pc/lua/smlua_cobject_autogen.c b/src/pc/lua/smlua_cobject_autogen.c
index 987a27f21..c3ac4768c 100644
--- a/src/pc/lua/smlua_cobject_autogen.c
+++ b/src/pc/lua/smlua_cobject_autogen.c
@@ -16,6 +16,7 @@
#include "src/game/spawn_sound.h"
#include "src/pc/network/network.h"
#include "src/game/hardcoded.h"
+#include "src/pc/mods/mod.h"
#include "include/object_fields.h"
@@ -790,6 +791,21 @@ static struct LuaObjectField sMarioStateFields[LUA_MARIO_STATE_FIELD_COUNT] = {
{ "waterLevel", LVT_S16, offsetof(struct MarioState, waterLevel), false, LOT_NONE },
};
+#define LUA_MOD_FIELD_COUNT 10
+static struct LuaObjectField sModFields[LUA_MOD_FIELD_COUNT] = {
+ { "basePath", LVT_STRING, offsetof(struct Mod, basePath), true, LOT_NONE },
+ { "description", LVT_STRING_P, offsetof(struct Mod, description), true, LOT_NONE },
+ { "enabled", LVT_BOOL, offsetof(struct Mod, enabled), true, LOT_NONE },
+ { "fileCount", LVT_U16, offsetof(struct Mod, fileCount), true, LOT_NONE },
+ { "incompatible", LVT_STRING_P, offsetof(struct Mod, incompatible), true, LOT_NONE },
+ { "index", LVT_S32, offsetof(struct Mod, index), true, LOT_NONE },
+ { "isDirectory", LVT_BOOL, offsetof(struct Mod, isDirectory), true, LOT_NONE },
+ { "name", LVT_STRING_P, offsetof(struct Mod, name), true, LOT_NONE },
+ { "relativePath", LVT_STRING, offsetof(struct Mod, relativePath), true, LOT_NONE },
+ { "selectable", LVT_BOOL, offsetof(struct Mod, selectable), true, LOT_NONE },
+// { "size", LVT_???, offsetof(struct Mod, size), true, LOT_??? }, <--- UNIMPLEMENTED
+};
+
#define LUA_MODE_TRANSITION_INFO_FIELD_COUNT 6
static struct LuaObjectField sModeTransitionInfoFields[LUA_MODE_TRANSITION_INFO_FIELD_COUNT] = {
{ "frame", LVT_S16, offsetof(struct ModeTransitionInfo, frame), false, LOT_NONE },
@@ -1908,6 +1924,7 @@ struct LuaObjectTable sLuaObjectAutogenTable[LOT_AUTOGEN_MAX - LOT_AUTOGEN_MIN]
{ LOT_MARIOANIMATION, sMarioAnimationFields, LUA_MARIO_ANIMATION_FIELD_COUNT },
{ LOT_MARIOBODYSTATE, sMarioBodyStateFields, LUA_MARIO_BODY_STATE_FIELD_COUNT },
{ LOT_MARIOSTATE, sMarioStateFields, LUA_MARIO_STATE_FIELD_COUNT },
+ { LOT_MOD, sModFields, LUA_MOD_FIELD_COUNT },
{ LOT_MODETRANSITIONINFO, sModeTransitionInfoFields, LUA_MODE_TRANSITION_INFO_FIELD_COUNT },
{ LOT_NETWORKPLAYER, sNetworkPlayerFields, LUA_NETWORK_PLAYER_FIELD_COUNT },
{ LOT_OBJECT, sObjectFields, LUA_OBJECT_FIELD_COUNT },
diff --git a/src/pc/lua/smlua_cobject_autogen.h b/src/pc/lua/smlua_cobject_autogen.h
index 0b4428d61..b6d33f209 100644
--- a/src/pc/lua/smlua_cobject_autogen.h
+++ b/src/pc/lua/smlua_cobject_autogen.h
@@ -37,6 +37,7 @@ enum LuaObjectAutogenType {
LOT_MARIOANIMATION,
LOT_MARIOBODYSTATE,
LOT_MARIOSTATE,
+ LOT_MOD,
LOT_MODETRANSITIONINFO,
LOT_NETWORKPLAYER,
LOT_OBJECT,