diff --git a/src/lua_hook.h b/src/lua_hook.h index 5cfcb8360..0d631aa4e 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -61,6 +61,8 @@ enum hook { hook_GameQuit, hook_PlayerCmd, hook_MusicChange, + hook_PlayerHeight, + hook_PlayerCanEnterSpinGaps, hook_MAX // last hook }; @@ -118,3 +120,5 @@ boolean LUAh_ShouldJingleContinue(player_t *player, const char *musname); // Hoo void LUAh_GameQuit(boolean quitting); // Hook for game quitting boolean LUAh_PlayerCmd(player_t *player, ticcmd_t *cmd); // Hook for building player's ticcmd struct (Ported from SRB2Kart) boolean LUAh_MusicChange(const char *oldname, char *newname, UINT16 *mflags, boolean *looping, UINT32 *position, UINT32 *prefadems, UINT32 *fadeinms); // Hook for music changes +fixed_t LUAh_PlayerHeight(player_t *player); +UINT8 LUAh_PlayerCanEnterSpinGaps(player_t *player); diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 29c15a4de..6e9b9d65c 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -77,6 +77,8 @@ const char *const hookNames[hook_MAX+1] = { "GameQuit", "PlayerCmd", "MusicChange", + "PlayerHeight", + "PlayerCanEnterSpinGaps", NULL }; @@ -221,6 +223,8 @@ static int lib_addHook(lua_State *L) case hook_ShieldSpawn: case hook_ShieldSpecial: case hook_PlayerThink: + case hook_PlayerHeight: + case hook_PlayerCanEnterSpinGaps: lastp = &playerhooks; break; case hook_LinedefExecute: @@ -1971,3 +1975,89 @@ boolean LUAh_MusicChange(const char *oldname, char *newname, UINT16 *mflags, boo newname[6] = 0; return hooked; } + +// Hook for determining player height +fixed_t LUAh_PlayerHeight(player_t *player) +{ + hook_p hookp; + fixed_t newheight = -1; + if (!gL || !(hooksAvailable[hook_PlayerHeight/8] & (1<<(hook_PlayerHeight%8)))) + return 0; + + lua_settop(gL, 0); + lua_pushcfunction(gL, LUA_GetErrorMessage); + + for (hookp = playerhooks; hookp; hookp = hookp->next) + { + if (hookp->type != hook_PlayerHeight) + continue; + + ps_lua_mobjhooks++; + if (lua_gettop(gL) == 1) + LUA_PushUserdata(gL, player, META_PLAYER); + PushHook(gL, hookp); + lua_pushvalue(gL, -2); + if (lua_pcall(gL, 1, 1, 1)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + continue; + } + if (!lua_isnil(gL, -1)) + { + fixed_t returnedheight = lua_tonumber(gL, -1); + // 0 height has... strange results, but it's not problematic like negative heights are. + // when an object's height is set to a negative number directly with lua, it's forced to 0 instead. + // here, I think it's better to ignore negatives so that they don't replace any results of previous hooks! + if (returnedheight >= 0) + newheight = returnedheight; + } + lua_pop(gL, 1); + } + + lua_settop(gL, 0); + return newheight; +} + +// Hook for determining whether players are allowed passage through spin gaps +UINT8 LUAh_PlayerCanEnterSpinGaps(player_t *player) +{ + hook_p hookp; + UINT8 canEnter = 0; // 0 = default, 1 = force yes, 2 = force no. + if (!gL || !(hooksAvailable[hook_PlayerCanEnterSpinGaps/8] & (1<<(hook_PlayerCanEnterSpinGaps%8)))) + return 0; + + lua_settop(gL, 0); + lua_pushcfunction(gL, LUA_GetErrorMessage); + + for (hookp = playerhooks; hookp; hookp = hookp->next) + { + if (hookp->type != hook_PlayerCanEnterSpinGaps) + continue; + + ps_lua_mobjhooks++; + if (lua_gettop(gL) == 1) + LUA_PushUserdata(gL, player, META_PLAYER); + PushHook(gL, hookp); + lua_pushvalue(gL, -2); + if (lua_pcall(gL, 1, 1, 1)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + continue; + } + if (!lua_isnil(gL, -1)) + { // if nil, leave canEnter = 0. + if (lua_toboolean(gL, -1)) + canEnter = 1; // Force yes + else + canEnter = 2; // Force no + } + lua_pop(gL, 1); + } + + lua_settop(gL, 0); + return canEnter; +} diff --git a/src/p_user.c b/src/p_user.c index 63942e0be..56767f433 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8651,9 +8651,16 @@ void P_MovePlayer(player_t *player) { boolean atspinheight = false; fixed_t oldheight = player->mo->height; + fixed_t luaheight = LUAh_PlayerHeight(player); + if (luaheight != -1) + { + player->mo->height = luaheight; + if (luaheight <= P_GetPlayerSpinHeight(player)) + atspinheight = true; // spinning will not save you from being crushed + } // Less height while spinning. Good for spinning under things...? - if (P_PlayerShouldUseSpinHeight(player)) + else if (P_PlayerShouldUseSpinHeight(player)) { player->mo->height = P_GetPlayerSpinHeight(player); atspinheight = true; @@ -12958,6 +12965,12 @@ boolean P_PlayerFullbright(player_t *player) // returns true if the player can enter a sector that they could not if standing at their skin's full height boolean P_PlayerCanEnterSpinGaps(player_t *player) { + UINT8 canEnter = LUAh_PlayerCanEnterSpinGaps(player); + if (canEnter == 1) + return true; + else if (canEnter == 2) + return false; + return ((player->pflags & (PF_SPINNING|PF_GLIDING)) // players who are spinning or gliding || (player->charability == CA_GLIDEANDCLIMB && player->mo->state-states == S_PLAY_GLIDE_LANDING) // players who are landing from a glide || JUMPCURLED(player)); // players who are jumpcurled, but only if they would normally jump that way @@ -12966,9 +12979,11 @@ boolean P_PlayerCanEnterSpinGaps(player_t *player) // returns true if the player should use their skin's spinheight instead of their skin's height boolean P_PlayerShouldUseSpinHeight(player_t *player) { - return (P_PlayerCanEnterSpinGaps(player) + return ((player->pflags & (PF_SPINNING|PF_GLIDING)) || (player->mo->state == &states[player->mo->info->painstate]) || (player->panim == PA_ROLL) || ((player->powers[pw_tailsfly] || (player->charability == CA_FLY && player->mo->state-states == S_PLAY_FLY_TIRED)) - && !(player->charflags & SF_NOJUMPSPIN))); + && !(player->charflags & SF_NOJUMPSPIN)) + || (player->charability == CA_GLIDEANDCLIMB && player->mo->state-states == S_PLAY_GLIDE_LANDING) + || JUMPCURLED(player)); }