diff --git a/autogen/lua_constants/constants.lua b/autogen/lua_constants/constants.lua index 6b820d99..583d73be 100644 --- a/autogen/lua_constants/constants.lua +++ b/autogen/lua_constants/constants.lua @@ -10,7 +10,8 @@ HOOK_BEFORE_PHYS_STEP = 4 HOOK_ON_PVP_ATTACK = 5 HOOK_ON_PLAYER_CONNECTED = 6 HOOK_ON_PLAYER_DISCONNECTED = 7 -HOOK_MAX = 8 +HOOK_ON_CHAT_COMMAND = 8 +HOOK_MAX = 9 _CObject = { __index = function (t,k) diff --git a/docs/lua/constants.md b/docs/lua/constants.md index d1ba7103..374d166e 100644 --- a/docs/lua/constants.md +++ b/docs/lua/constants.md @@ -633,6 +633,7 @@ - HOOK_ON_PVP_ATTACK - HOOK_ON_PLAYER_CONNECTED - HOOK_ON_PLAYER_DISCONNECTED +- HOOK_ON_CHAT_COMMAND - HOOK_MAX [:arrow_up_small:](#) diff --git a/src/pc/djui/djui_chat_box.c b/src/pc/djui/djui_chat_box.c index 807d49dd..81cb2b13 100644 --- a/src/pc/djui/djui_chat_box.c +++ b/src/pc/djui/djui_chat_box.c @@ -1,6 +1,7 @@ #include #include #include "pc/network/network.h" +#include "pc/lua/smlua_hooks.h" #include "djui.h" struct DjuiChatBox* gDjuiChatBox = NULL; @@ -31,8 +32,14 @@ static void djui_chat_box_input_enter(struct DjuiInputbox* chatInput) { djui_interactable_set_input_focus(NULL); if (strlen(chatInput->buffer) != 0) { - djui_chat_message_create_from(gNetworkPlayerLocal->globalIndex, chatInput->buffer); - network_send_chat(chatInput->buffer, gNetworkPlayerLocal->globalIndex); + if (chatInput->buffer[0] == '/') { + if (!smlua_call_event_hook_on_chat_command(chatInput->buffer)) { + djui_chat_message_create("Unrecognized chat command."); + } + } else { + djui_chat_message_create_from(gNetworkPlayerLocal->globalIndex, chatInput->buffer); + network_send_chat(chatInput->buffer, gNetworkPlayerLocal->globalIndex); + } } djui_inputbox_set_text(chatInput, ""); diff --git a/src/pc/lua/smlua_constants_autogen.c b/src/pc/lua/smlua_constants_autogen.c index 1f6b0c98..56d6927b 100644 --- a/src/pc/lua/smlua_constants_autogen.c +++ b/src/pc/lua/smlua_constants_autogen.c @@ -6,7 +6,8 @@ char gSmluaConstants[] = "HOOK_UPDATE = 0\n" "HOOK_ON_PVP_ATTACK = 5\n" "HOOK_ON_PLAYER_CONNECTED = 6\n" "HOOK_ON_PLAYER_DISCONNECTED = 7\n" -"HOOK_MAX = 8\n" +"HOOK_ON_CHAT_COMMAND = 8\n" +"HOOK_MAX = 9\n" "_CObject = {\n" " __index = function (t,k)\n" " return _get_field(t['_lot'], t['_pointer'], k)\n" diff --git a/src/pc/lua/smlua_hooks.c b/src/pc/lua/smlua_hooks.c index 002f633a..3fb4eafa 100644 --- a/src/pc/lua/smlua_hooks.c +++ b/src/pc/lua/smlua_hooks.c @@ -125,6 +125,31 @@ void smlua_call_event_hooks_network_player_param(enum LuaHookedEventType hookTyp } } +bool smlua_call_event_hook_on_chat_command(char* message) { + lua_State* L = gLuaState; + if (L == NULL) { return false; } + bool ret = false; + + struct LuaHookedEvent* hook = &sHookedEvents[HOOK_ON_CHAT_COMMAND]; + for (int i = 0; i < hook->count; i++) { + // push the callback onto the stack + lua_rawgeti(L, LUA_REGISTRYINDEX, hook->reference[i]); + + // push message + lua_pushstring(L, message); + + // call the callback + if (0 != lua_pcall(L, 1, 1, 0)) { + LOG_LUA("Failed to call the callback: %s", lua_tostring(L, -1)); + continue; + } + + ret = ret || smlua_to_boolean(L, -1); + } + + return ret; +} + //////////////////// // hooked actions // //////////////////// diff --git a/src/pc/lua/smlua_hooks.h b/src/pc/lua/smlua_hooks.h index de55b514..855852c6 100644 --- a/src/pc/lua/smlua_hooks.h +++ b/src/pc/lua/smlua_hooks.h @@ -12,6 +12,7 @@ enum LuaHookedEventType { HOOK_ON_PVP_ATTACK, HOOK_ON_PLAYER_CONNECTED, HOOK_ON_PLAYER_DISCONNECTED, + HOOK_ON_CHAT_COMMAND, HOOK_MAX, }; @@ -24,12 +25,14 @@ static char* LuaHookedEventTypeName[] = { "HOOK_ON_PVP_ATTACK", "HOOK_ON_PLAYER_CONNECTED", "HOOK_ON_PLAYER_DISCONNECTED", + "HOOK_ON_CHAT_COMMAND", "HOOK_MAX" }; void smlua_call_event_hooks(enum LuaHookedEventType hookType); void smlua_call_event_hooks_mario_param(enum LuaHookedEventType hookType, struct MarioState* m); void smlua_call_event_hooks_mario_params(enum LuaHookedEventType hookType, struct MarioState* m1, struct MarioState* m2); +bool smlua_call_event_hook_on_chat_command(char* message); bool smlua_call_action_hook(struct MarioState* m, s32* returnValue);