diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c61e181a5..ef2304410 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -159,6 +159,9 @@ stages: Debian testing GCC: stage: build + + when: manual + image: debian:testing-slim allow_failure: true @@ -198,6 +201,8 @@ Debian testing GCC: Windows x86: stage: build + when: on_success + artifacts: paths: - "bin/" @@ -228,6 +233,8 @@ Windows x86: Debian stable:amd64: stage: build + when: on_success + artifacts: paths: - "bin/" @@ -270,6 +277,8 @@ Debian stable:amd64: Debian stable:i386: stage: build + when: manual + artifacts: paths: - "bin/" @@ -311,6 +320,8 @@ Debian stable:i386: Debian stable:arm64: stage: build + when: manual + artifacts: paths: - "bin/" @@ -353,6 +364,8 @@ Debian stable:arm64: Windows x64: stage: build + when: manual + artifacts: paths: - "bin/" @@ -383,6 +396,8 @@ Windows x64: Debian stable Clang: stage: build + when: manual + allow_failure: true artifacts: @@ -422,6 +437,8 @@ Debian stable Clang: Debian stable musl: stage: build + when: manual + allow_failure: true artifacts: @@ -459,6 +476,8 @@ Debian stable musl: Debian testing Clang: extends: Debian stable Clang + when: manual + image: debian:testing-slim artifacts: @@ -473,6 +492,8 @@ Debian testing Clang: Debian testing musl: extends: Debian stable musl + when: manual + image: debian:testing-slim artifacts: diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 45bb162c4..ecd3e2fa8 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -1031,6 +1031,20 @@ static int lib_pRailThinker(lua_State *L) return 1; } +static int lib_pCheckSkyHit(lua_State *L) +{ + mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + line_t *line = *((line_t **)luaL_checkudata(L, 2, META_LINE)); + //HUDSAFE + INLEVEL + if (!mobj) + return LUA_ErrInvalid(L, "mobj_t"); + if (!line) + return LUA_ErrInvalid(L, "line_t"); + lua_pushboolean(L, P_CheckSkyHit(mobj, line)); + return 1; +} + static int lib_pXYMovement(lua_State *L) { mobj_t *actor = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); @@ -1425,6 +1439,18 @@ static int lib_pGivePlayerRings(lua_State *L) return 0; } +static int lib_pGivePlayerSpheres(lua_State *L) +{ + player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + INT32 num_spheres = (INT32)luaL_checkinteger(L, 2); + NOHUD + INLEVEL + if (!player) + return LUA_ErrInvalid(L, "player_t"); + P_GivePlayerSpheres(player, num_spheres); + return 0; +} + static int lib_pGivePlayerLives(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); @@ -1680,6 +1706,17 @@ static int lib_pDoJump(lua_State *L) return 0; } +static int lib_pDoSpinDashDust(lua_State *L) +{ + player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + NOHUD + INLEVEL + if (!player) + return LUA_ErrInvalid(L, "player_t"); + P_DoSpinDashDust(player); + return 0; +} + static int lib_pSpawnThokMobj(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); @@ -1730,6 +1767,48 @@ static int lib_pSwitchShield(lua_State *L) return 0; } +static int lib_pDoTailsOverlay(lua_State *L) +{ + player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + mobj_t *tails = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); + NOHUD + INLEVEL + if (!player) + return LUA_ErrInvalid(L, "player_t"); + if (!tails) + return LUA_ErrInvalid(L, "mobj_t"); + P_DoTailsOverlay(player, tails); + return 0; +} + +static int lib_pDoMetalJetFume(lua_State *L) +{ + player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + mobj_t *fume = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); + NOHUD + INLEVEL + if (!player) + return LUA_ErrInvalid(L, "player_t"); + if (!fume) + return LUA_ErrInvalid(L, "mobj_t"); + P_DoMetalJetFume(player, fume); + return 0; +} + +static int lib_pDoFollowMobj(lua_State *L) +{ + player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + mobj_t *followmobj = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); + NOHUD + INLEVEL + if (!player) + return LUA_ErrInvalid(L, "player_t"); + if (!followmobj) + return LUA_ErrInvalid(L, "mobj_t"); + P_DoFollowMobj(player, followmobj); + return 0; +} + static int lib_pPlayerCanEnterSpinGaps(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); @@ -2211,6 +2290,21 @@ static int lib_pDoMatchSuper(lua_State *L) return 0; } +static int lib_pTouchSpecialThing(lua_State *L) +{ + mobj_t *special = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + mobj_t *toucher = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); + boolean heightcheck = lua_optboolean(L, 3); + NOHUD + INLEVEL + if (!special || !toucher) + return LUA_ErrInvalid(L, "mobj_t"); + if (!toucher->player) + return luaL_error(L, "P_TouchSpecialThing requires a valid toucher.player."); + P_TouchSpecialThing(special, toucher, heightcheck); + return 0; +} + // P_SPEC //////////// @@ -4126,6 +4220,7 @@ static luaL_Reg lib[] = { {"P_CreateFloorSpriteSlope",lib_pCreateFloorSpriteSlope}, {"P_RemoveFloorSpriteSlope",lib_pRemoveFloorSpriteSlope}, {"P_RailThinker",lib_pRailThinker}, + {"P_CheckSkyHit",lib_pCheckSkyHit}, {"P_XYMovement",lib_pXYMovement}, {"P_RingXYMovement",lib_pRingXYMovement}, {"P_SceneryXYMovement",lib_pSceneryXYMovement}, @@ -4158,6 +4253,7 @@ static luaL_Reg lib[] = { {"P_SpawnShieldOrb",lib_pSpawnShieldOrb}, {"P_SpawnGhostMobj",lib_pSpawnGhostMobj}, {"P_GivePlayerRings",lib_pGivePlayerRings}, + {"P_GivePlayerSpheres",lib_pGivePlayerSpheres}, {"P_GivePlayerLives",lib_pGivePlayerLives}, {"P_GiveCoopLives",lib_pGiveCoopLives}, {"P_ResetScore",lib_pResetScore}, @@ -4179,10 +4275,14 @@ static luaL_Reg lib[] = { {"P_HomingAttack",lib_pHomingAttack}, {"P_SuperReady",lib_pSuperReady}, {"P_DoJump",lib_pDoJump}, + {"P_DoSpinDashDust",lib_pDoSpinDashDust}, {"P_SpawnThokMobj",lib_pSpawnThokMobj}, {"P_SpawnSpinMobj",lib_pSpawnSpinMobj}, {"P_Telekinesis",lib_pTelekinesis}, {"P_SwitchShield",lib_pSwitchShield}, + {"P_DoTailsOverlay",lib_pDoTailsOverlay}, + {"P_DoMetalJetFume",lib_pDoMetalJetFume}, + {"P_DoFollowMobj",lib_pDoFollowMobj}, {"P_PlayerCanEnterSpinGaps",lib_pPlayerCanEnterSpinGaps}, {"P_PlayerShouldUseSpinHeight",lib_pPlayerShouldUseSpinHeight}, @@ -4201,6 +4301,7 @@ static luaL_Reg lib[] = { {"P_FloorzAtPos",lib_pFloorzAtPos}, {"P_CeilingzAtPos",lib_pCeilingzAtPos}, {"P_DoSpring",lib_pDoSpring}, + {"P_TouchSpecialThing",lib_pTouchSpecialThing}, {"P_TryCameraMove", lib_pTryCameraMove}, {"P_TeleportCameraMove", lib_pTeleportCameraMove}, diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index 0ab8ad9c3..9b3fd2ea0 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -374,6 +374,9 @@ static int lib_cvRegisterVar(lua_State *L) size_t count = 0; CV_PossibleValue_t *cvpv; + const char * const MINMAX[2] = {"MIN", "MAX"}; + int minmax_unset = 3; + lua_pushnil(L); while (lua_next(L, 4)) { @@ -392,16 +395,45 @@ static int lib_cvRegisterVar(lua_State *L) lua_pushnil(L); while (lua_next(L, 4)) { + INT32 n; + const char * strval; + // stack: [...] PossibleValue table, index, value // 4 5 6 if (lua_type(L, 5) != LUA_TSTRING || lua_type(L, 6) != LUA_TNUMBER) FIELDERROR("PossibleValue", "custom PossibleValue table requires a format of string=integer, i.e. {MIN=0, MAX=9999}"); - cvpv[i].strvalue = Z_StrDup(lua_tostring(L, 5)); - cvpv[i].value = (INT32)lua_tonumber(L, 6); - i++; + + strval = lua_tostring(L, 5); + + if ( + stricmp(strval, MINMAX[n=0]) == 0 || + stricmp(strval, MINMAX[n=1]) == 0 + ){ + /* need to shift forward */ + if (minmax_unset == 3) + { + memmove(&cvpv[2], &cvpv[0], + i * sizeof *cvpv); + i += 2; + } + cvpv[n].strvalue = MINMAX[n]; + minmax_unset &= ~(1 << n); + } + else + { + n = i++; + cvpv[n].strvalue = Z_StrDup(strval); + } + + cvpv[n].value = (INT32)lua_tonumber(L, 6); + lua_pop(L, 1); } + + if (minmax_unset && minmax_unset != 3) + FIELDERROR("PossibleValue", "custom PossibleValue table requires requires both MIN and MAX keys if one is present"); + cvpv[i].value = 0; cvpv[i].strvalue = NULL; cvar->PossibleValue = cvpv; diff --git a/src/p_local.h b/src/p_local.h index 007954312..c26c09860 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -204,6 +204,7 @@ void P_Earthquake(mobj_t *inflictor, mobj_t *source, fixed_t radius); boolean P_HomingAttack(mobj_t *source, mobj_t *enemy); /// \todo doesn't belong in p_user boolean P_SuperReady(player_t *player); void P_DoJump(player_t *player, boolean soundandstate); +void P_DoSpinDashDust(player_t *player); #define P_AnalogMove(player) (P_ControlStyle(player) == CS_LMAOGALOG) boolean P_TransferToNextMare(player_t *player); UINT8 P_FindLowestMare(void); @@ -214,6 +215,10 @@ void P_SpawnThokMobj(player_t *player); void P_SpawnSpinMobj(player_t *player, mobjtype_t type); void P_Telekinesis(player_t *player, fixed_t thrust, fixed_t range); +void P_DoTailsOverlay(player_t *player, mobj_t *tails); +void P_DoMetalJetFume(player_t *player, mobj_t *fume); +void P_DoFollowMobj(player_t *player, mobj_t *followmobj); + void P_PlayLivesJingle(player_t *player); #define P_PlayRinglossSound(s) S_StartSound(s, (mariomode) ? sfx_mario8 : sfx_altow1 + P_RandomKey(4)); #define P_PlayDeathSound(s) S_StartSound(s, sfx_altdi1 + P_RandomKey(4)); @@ -298,6 +303,7 @@ void P_RunOverlays(void); void P_HandleMinecartSegments(mobj_t *mobj); void P_MobjThinker(mobj_t *mobj); boolean P_RailThinker(mobj_t *mobj); +boolean P_CheckSkyHit(mobj_t *mo, line_t *line); void P_PushableThinker(mobj_t *mobj); void P_SceneryThinker(mobj_t *mobj); diff --git a/src/p_mobj.c b/src/p_mobj.c index 8bc74e3b8..4b17b7c11 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1779,14 +1779,15 @@ bustupdone: // // P_CheckSkyHit // -static boolean P_CheckSkyHit(mobj_t *mo) +boolean P_CheckSkyHit(mobj_t *mo, line_t *line) { - if (ceilingline && ceilingline->backsector - && ceilingline->backsector->ceilingpic == skyflatnum - && ceilingline->frontsector - && ceilingline->frontsector->ceilingpic == skyflatnum - && (mo->z >= ceilingline->frontsector->ceilingheight - || mo->z >= ceilingline->backsector->ceilingheight)) + if (line && (line->special == 41 || + (line->backsector + && line->backsector->ceilingpic == skyflatnum + && line->frontsector + && line->frontsector->ceilingpic == skyflatnum + && (mo->z >= line->frontsector->ceilingheight + || mo->z >= line->backsector->ceilingheight)))) return true; return false; } @@ -1893,7 +1894,7 @@ void P_XYMovement(mobj_t *mo) mo->fuse += ((5 - mo->threshold) * TICRATE); // Check for hit against sky here - if (P_CheckSkyHit(mo)) + if (P_CheckSkyHit(mo, ceilingline)) { // Hack to prevent missiles exploding // against the sky. @@ -1913,7 +1914,7 @@ void P_XYMovement(mobj_t *mo) mo->flags &= ~MF_STICKY; //Don't check again! // Check for hit against sky here - if (P_CheckSkyHit(mo)) + if (P_CheckSkyHit(mo, ceilingline)) { // Hack to prevent missiles exploding // against the sky. @@ -1972,7 +1973,7 @@ void P_XYMovement(mobj_t *mo) else if (mo->flags & MF_MISSILE) { // explode a missile - if (P_CheckSkyHit(mo)) + if (P_CheckSkyHit(mo, ceilingline)) { // Hack to prevent missiles exploding // against the sky. diff --git a/src/p_user.c b/src/p_user.c index 7aed5269f..3da9461c3 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4601,7 +4601,7 @@ void P_DoJump(player_t *player, boolean soundandstate) } } -static void P_DoSpinDashDust(player_t *player) +void P_DoSpinDashDust(player_t *player) { UINT32 i; mobj_t *particle; @@ -11191,7 +11191,7 @@ static void P_MinecartThink(player_t *player) } // Handle Tails' fluff -static void P_DoTailsOverlay(player_t *player, mobj_t *tails) +void P_DoTailsOverlay(player_t *player, mobj_t *tails) { // init... boolean smilesonground = P_IsObjectOnGround(player->mo); @@ -11396,7 +11396,7 @@ static void P_DoTailsOverlay(player_t *player, mobj_t *tails) } // Metal Sonic's jet fume -static void P_DoMetalJetFume(player_t *player, mobj_t *fume) +void P_DoMetalJetFume(player_t *player, mobj_t *fume) { static const UINT8 FUME_SKINCOLORS[] = { @@ -11534,6 +11534,30 @@ static void P_DoMetalJetFume(player_t *player, mobj_t *fume) } } +// Handle Followmobj behavior +void P_DoFollowMobj(player_t *player, mobj_t *followmobj) +{ + if (LUA_HookFollowMobj(player, followmobj) || P_MobjWasRemoved(followmobj)) + {;} + else + { + switch (followmobj->type) + { + case MT_TAILSOVERLAY: // c: + P_DoTailsOverlay(player, followmobj); + break; + case MT_METALJETFUME: + P_DoMetalJetFume(player, followmobj); + break; + default: + var1 = 1; + var2 = 0; + A_CapeChase(followmobj); + break; + } + } +} + // // P_PlayerThink // @@ -13010,27 +13034,7 @@ void P_PlayerAfterThink(player_t *player) } if (player->followmobj) - { - if (LUA_HookFollowMobj(player, player->followmobj) || P_MobjWasRemoved(player->followmobj)) - {;} - else - { - switch (player->followmobj->type) - { - case MT_TAILSOVERLAY: // c: - P_DoTailsOverlay(player, player->followmobj); - break; - case MT_METALJETFUME: - P_DoMetalJetFume(player, player->followmobj); - break; - default: - var1 = 1; - var2 = 0; - A_CapeChase(player->followmobj); - break; - } - } - } + P_DoFollowMobj(player, player->followmobj); } P_DoPlayerHeadSigns(player); // Spawn Tag/CTF signs over player's head