diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 96902c73..a6c6dbe0 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -48,6 +48,7 @@ #ifdef HAVE_BLUA #include "lua_hud.h" +#include "lua_hook.h" #endif // coords are scaled @@ -514,6 +515,11 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) } } +#ifdef HAVE_BLUA + if (LUAh_PlayerMsg(playernum, target, flags, msg)) + return; +#endif + // If it's a CSAY, just CECHO and be done with it. if (flags & HU_CSAY) { diff --git a/src/lua_hook.h b/src/lua_hook.h index 0c22092a..a19516cd 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -36,6 +36,7 @@ enum hook { hook_BotTiccmd, hook_BotAI, hook_LinedefExecute, + hook_PlayerMsg, hook_MAX // last hook }; @@ -61,5 +62,6 @@ boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source); // Ho boolean LUAh_BotTiccmd(player_t *bot, ticcmd_t *cmd); // Hook for B_BuildTiccmd boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd); // Hook for B_BuildTailsTiccmd by skin name boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo); // Hook for linedef executors +boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg); // Hook for chat messages #endif diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index ed9f53d2..608cfa0b 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -14,6 +14,7 @@ #ifdef HAVE_BLUA #include "doomstat.h" #include "p_mobj.h" +#include "g_game.h" #include "r_things.h" #include "b_bot.h" #include "z_zone.h" @@ -46,6 +47,7 @@ const char *const hookNames[hook_MAX+1] = { "BotTiccmd", "BotAI", "LinedefExecute", + "PlayerMsg", NULL }; @@ -862,4 +864,58 @@ boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo) return true; } +// Hook for PlayerMsg -Red +boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg) +{ + boolean handled = false; + + if (!gL || !(hooksAvailable[hook_PlayerMsg/8] & (1<<(hook_PlayerMsg%8)))) + return false; + + lua_getfield(gL, LUA_REGISTRYINDEX, "hook"); + I_Assert(lua_istable(gL, -1)); + lua_rawgeti(gL, -1, hook_PlayerMsg); + lua_remove(gL, -2); + I_Assert(lua_istable(gL, -1)); + + LUA_PushUserdata(gL, &players[source], META_PLAYER); // Source player + + if (flags & 2 /*HU_CSAY*/) { // csay TODO: make HU_CSAY accessible outside hu_stuff.c + lua_pushinteger(gL, 3); // type + lua_pushnil(gL); // target + } else if (target == -1) { // sayteam + lua_pushinteger(gL, 1); // type + lua_pushnil(gL); // target + } else if (target == 0) { // say + lua_pushinteger(gL, 0); // type + lua_pushnil(gL); // target + } else { // sayto + lua_pushinteger(gL, 2); // type + LUA_PushUserdata(gL, &players[target-1], META_PLAYER); // target + } + + lua_pushstring(gL, msg); // msg + + lua_pushnil(gL); + + while (lua_next(gL, -6)) { + lua_pushvalue(gL, -6); // source + lua_pushvalue(gL, -6); // type + lua_pushvalue(gL, -6); // target + lua_pushvalue(gL, -6); // msg + if (lua_pcall(gL, 4, 1, 0)) { + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1)); + lua_pop(gL, 1); + continue; + } + if (lua_toboolean(gL, -1)) + handled = true; + lua_pop(gL, 1); // pop return value + } + lua_pop(gL, 4); // pop arguments and mobjtype table + + lua_gc(gL, LUA_GCSTEP, 1); + return handled; +} + #endif