diff --git a/autogen/lua_constants/constants.lua b/autogen/lua_constants/constants.lua index 70d15cdc..287e3cc0 100644 --- a/autogen/lua_constants/constants.lua +++ b/autogen/lua_constants/constants.lua @@ -7,7 +7,8 @@ HOOK_MARIO_UPDATE = 1 HOOK_BEFORE_MARIO_UPDATE = 2 HOOK_ON_SET_MARIO_ACTION = 3 HOOK_BEFORE_PHYS_STEP = 4 -HOOK_MAX = 5 +HOOK_ON_PVP_ATTACK = 5 +HOOK_MAX = 6 _CObject = { __index = function (t,k) @@ -139,6 +140,15 @@ CT_TOAD = 2 CT_WALUIGI = 3 CT_MAX = 4 +NPT_UNKNOWN = 0 +NPT_LOCAL = 1 +NPT_SERVER = 2 +NPT_CLIENT = 3 + +UNKNOWN_LOCAL_INDEX = -1 +UNKNOWN_GLOBAL_INDEX = -1 +UNKNOWN_NETWORK_INDEX = -1 + ------------ -- layers -- ------------ diff --git a/docs/lua/constants.md b/docs/lua/constants.md index 35cab3dc..1ac984de 100644 --- a/docs/lua/constants.md +++ b/docs/lua/constants.md @@ -617,6 +617,7 @@ - HOOK_BEFORE_MARIO_UPDATE - HOOK_ON_SET_MARIO_ACTION - HOOK_BEFORE_PHYS_STEP +- HOOK_ON_PVP_ATTACK - HOOK_MAX [:arrow_up_small:](#) diff --git a/src/game/interaction.c b/src/game/interaction.c index 9577b389..b51bb5c6 100644 --- a/src/game/interaction.c +++ b/src/game/interaction.c @@ -27,6 +27,7 @@ #include "pc/configfile.h" #include "pc/network/network.h" +#include "pc/lua/smlua_hooks.h" #define INT_GROUND_POUND_OR_TWIRL (1 << 0) // 0x01 #define INT_PUNCH (1 << 1) // 0x02 @@ -1339,9 +1340,10 @@ u32 interact_player(struct MarioState* m, UNUSED u32 interactType, struct Object // attacked u8 isInCutscene = ((m->action & ACT_GROUP_MASK) == ACT_GROUP_CUTSCENE) || ((m2->action & ACT_GROUP_MASK) == ACT_GROUP_CUTSCENE); isInCutscene = isInCutscene || (m->action == ACT_IN_CANNON) || (m2->action == ACT_IN_CANNON); + u8 isAttackerInvulnerable = (m->action & ACT_FLAG_INVULNERABLE) || m->invincTimer != 0 || m->hurtCounter != 0; u8 isInvulnerable = (m2->action & ACT_FLAG_INVULNERABLE) || m2->invincTimer != 0 || m2->hurtCounter != 0 || isInCutscene; u8 isIgnoredAttack = (m->action == ACT_JUMP || m->action == ACT_DOUBLE_JUMP); - if ((interaction & INT_ANY_ATTACK) && !(interaction & INT_HIT_FROM_ABOVE) && !isInvulnerable && !isIgnoredAttack) { + if ((interaction & INT_ANY_ATTACK) && !(interaction & INT_HIT_FROM_ABOVE) && !isInvulnerable && !isIgnoredAttack && !isAttackerInvulnerable) { // determine if slide attack should be ignored if ((interaction & INT_ATTACK_SLIDE) && player_is_sliding(m2)) { @@ -1388,6 +1390,8 @@ u32 interact_player(struct MarioState* m, UNUSED u32 interactType, struct Object take_damage_and_knock_back(m2, m->marioObj); bounce_back_from_attack(m, interaction); m2->interactObj = NULL; + + smlua_call_event_hooks_mario_params(HOOK_ON_PVP_ATTACK, m, m2); return FALSE; } diff --git a/src/pc/lua/smlua_constants_autogen.c b/src/pc/lua/smlua_constants_autogen.c index 5c22c4b1..18558c40 100644 --- a/src/pc/lua/smlua_constants_autogen.c +++ b/src/pc/lua/smlua_constants_autogen.c @@ -3,7 +3,8 @@ char gSmluaConstants[] = "HOOK_UPDATE = 0\n" "HOOK_BEFORE_MARIO_UPDATE = 2\n" "HOOK_ON_SET_MARIO_ACTION = 3\n" "HOOK_BEFORE_PHYS_STEP = 4\n" -"HOOK_MAX = 5\n" +"HOOK_ON_PVP_ATTACK = 5\n" +"HOOK_MAX = 6\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 d20ccee8..f505296c 100644 --- a/src/pc/lua/smlua_hooks.c +++ b/src/pc/lua/smlua_hooks.c @@ -75,6 +75,34 @@ void smlua_call_event_hooks_mario_param(enum LuaHookedEventType hookType, struct } } +void smlua_call_event_hooks_mario_params(enum LuaHookedEventType hookType, struct MarioState* m1, struct MarioState* m2) { + lua_State* L = gLuaState; + if (L == NULL) { return; } + struct LuaHookedEvent* hook = &sHookedEvents[hookType]; + for (int i = 0; i < hook->count; i++) { + // push the callback onto the stack + lua_rawgeti(L, LUA_REGISTRYINDEX, hook->reference[i]); + + // push mario state + lua_getglobal(L, "gMarioStates"); + lua_pushinteger(L, m1->playerIndex); + lua_gettable(L, -2); + lua_remove(L, -2); + + // push mario state + lua_getglobal(L, "gMarioStates"); + lua_pushinteger(L, m2->playerIndex); + lua_gettable(L, -2); + lua_remove(L, -2); + + // call the callback + if (0 != lua_pcall(L, 2, 0, 0)) { + LOG_LUA("Failed to call the callback: %s", lua_tostring(L, -1)); + continue; + } + } +} + //////////////////// // hooked actions // //////////////////// diff --git a/src/pc/lua/smlua_hooks.h b/src/pc/lua/smlua_hooks.h index 8b9cb23c..f487ace1 100644 --- a/src/pc/lua/smlua_hooks.h +++ b/src/pc/lua/smlua_hooks.h @@ -9,6 +9,7 @@ enum LuaHookedEventType { HOOK_BEFORE_MARIO_UPDATE, HOOK_ON_SET_MARIO_ACTION, HOOK_BEFORE_PHYS_STEP, + HOOK_ON_PVP_ATTACK, HOOK_MAX, }; @@ -18,11 +19,13 @@ static char* LuaHookedEventTypeName[] = { "HOOK_BEFORE_MARIO_UPDATE", "HOOK_ON_SET_MARIO_ACTION", "HOOK_BEFORE_PHYS_STEP", + "HOOK_ON_PVP_ATTACK", "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_action_hook(struct MarioState* m, s32* returnValue); void smlua_bind_hooks(void);