From 9c73424b4b6038a90db53a44a5b8d4784b6fa4ea Mon Sep 17 00:00:00 2001 From: sphere Date: Sun, 14 Jul 2019 02:17:44 +0200 Subject: [PATCH 01/19] Add spring flags: float for horizontal & no gravity for diagonal. --- src/p_mobj.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index a57998ea0..0428dd83b 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -4662,7 +4662,7 @@ static void P_Boss4PinchSpikeballs(mobj_t *mobj, angle_t angle, fixed_t dz) } dz /= 9; - + while ((base = base->tracer)) // there are 10 per spoke, remember that { dx = (originx + P_ReturnThrustX(mobj, angle, (9*132)<x)/9; @@ -11964,6 +11964,15 @@ ML_EFFECT5 : Don't stop thinking when too far away if (i == MT_YELLOWDIAG || i == MT_REDDIAG) mobj->angle += ANGLE_22h; + if (i == MT_YELLOWHORIZ || i == MT_REDHORIZ || i == MT_BLUEHORIZ) + { + if (mthing->options & MTF_OBJECTFLIP) + mobj->z -= 16*FRACUNIT; + else + mobj->z += 16*FRACUNIT; + } + + if (mobj->flags & MF_NIGHTSITEM) { // Spawn already displayed @@ -11991,6 +12000,9 @@ ML_EFFECT5 : Don't stop thinking when too far away if (mthing->options & MTF_OBJECTSPECIAL) { + if (i == MT_YELLOWDIAG || i == MT_REDDIAG) + mobj->flags |= MF_NOGRAVITY; + if ((mobj->flags & MF_MONITOR) && mobj->info->speed != 0) { // flag for strong/weak random boxes @@ -12570,9 +12582,9 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime) if (mthing->options & MTF_AMBUSH) // Special flag for rings { if (mthing->options & MTF_OBJECTFLIP) - z -= 24*FRACUNIT; + z -= 64*FRACUNIT; else - z += 24*FRACUNIT; + z += 64*FRACUNIT; } mthing->z = (INT16)(z>>FRACBITS); From 911b0262ee77cdae5ac71df98496e3232fc1a4d4 Mon Sep 17 00:00:00 2001 From: sphere Date: Sun, 14 Jul 2019 02:31:33 +0200 Subject: [PATCH 02/19] Whoops, forgot to revert this. --- src/p_mobj.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 0428dd83b..d13b9a57c 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -12582,9 +12582,9 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime) if (mthing->options & MTF_AMBUSH) // Special flag for rings { if (mthing->options & MTF_OBJECTFLIP) - z -= 64*FRACUNIT; + z -= 24*FRACUNIT; else - z += 64*FRACUNIT; + z += 24*FRACUNIT; } mthing->z = (INT16)(z>>FRACBITS); From 438c4d1d51502c7cc81bb6379ac58988e47422cb Mon Sep 17 00:00:00 2001 From: toaster Date: Wed, 17 Jul 2019 21:33:18 +0100 Subject: [PATCH 03/19] Fix spindash being broken in quicksand # Conflicts: # src/p_mobj.c # src/p_user.c --- src/p_local.h | 2 +- src/p_mobj.c | 2 +- src/p_user.c | 160 ++++++++++++++++++++++++++------------------------ 3 files changed, 84 insertions(+), 80 deletions(-) diff --git a/src/p_local.h b/src/p_local.h index cb8f95533..3c62d6277 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -142,7 +142,7 @@ boolean P_IsObjectOnGround(mobj_t *mo); boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec); boolean P_InSpaceSector(mobj_t *mo); boolean P_InQuicksand(mobj_t *mo); -boolean P_PlayerHitFloor(player_t *player); +boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff); void P_SetObjectMomZ(mobj_t *mo, fixed_t value, boolean relative); void P_RestoreMusic(player_t *player); diff --git a/src/p_mobj.c b/src/p_mobj.c index 9a6e0f2bb..a7ab4e30d 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -3047,7 +3047,7 @@ static void P_PlayerZMovement(mobj_t *mo) } } - clipmomz = P_PlayerHitFloor(mo->player); + clipmomz = P_PlayerHitFloor(mo->player, true); if (!(mo->player->pflags & PF_SPINNING) && mo->player->powers[pw_carry] != CR_NIGHTSMODE) mo->player->pflags &= ~PF_STARTDASH; diff --git a/src/p_user.c b/src/p_user.c index 6761d567d..3427ed168 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2007,7 +2007,7 @@ boolean P_InSpaceSector(mobj_t *mo) // Returns true if you are in space // // Handles player hitting floor surface. // Returns whether to clip momz. -boolean P_PlayerHitFloor(player_t *player) +boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff) { boolean clipmomz; @@ -2015,92 +2015,96 @@ boolean P_PlayerHitFloor(player_t *player) if ((clipmomz = !(P_CheckDeathPitCollide(player->mo))) && player->mo->health && !player->spectator) { - if ((player->charability2 == CA2_SPINDASH) && !(player->pflags & PF_THOKKED) && (player->cmd.buttons & BT_USE) && (FixedHypot(player->mo->momx, player->mo->momy) > (5*player->mo->scale))) + if (dorollstuff) { - player->pflags |= PF_SPINNING; - P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); - S_StartSound(player->mo, sfx_spin); + if ((player->charability2 == CA2_SPINDASH) && !(player->pflags & PF_THOKKED) && (player->cmd.buttons & BT_USE) && (FixedHypot(player->mo->momx, player->mo->momy) > (5*player->mo->scale))) + { + player->pflags |= PF_SPINNING; + P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); + S_StartSound(player->mo, sfx_spin); + } + else + player->pflags &= ~PF_SPINNING; } - else + + if (player->pflags & PF_GLIDING) // ground gliding { - player->pflags &= ~PF_SPINNING; - - if (player->pflags & PF_GLIDING) // ground gliding - { + if (!player->skidtime) player->skidtime = TICRATE; - player->mo->tics = -1; - } - else if (player->charability2 == CA2_MELEE && (player->panim == PA_ABILITY2 && player->mo->state-states != S_PLAY_MELEE_LANDING)) + player->mo->tics = -1; + } + else if (player->charability2 == CA2_MELEE && (player->panim == PA_ABILITY2 && player->mo->state-states != S_PLAY_MELEE_LANDING)) + { + mobjtype_t type = player->revitem; + P_SetPlayerMobjState(player->mo, S_PLAY_MELEE_LANDING); + player->mo->tics = (player->mo->movefactor == FRACUNIT) ? TICRATE/2 : (FixedDiv(35<<(FRACBITS-1), FixedSqrt(player->mo->movefactor)))>>FRACBITS; + S_StartSound(player->mo, sfx_s3k8b); + player->pflags |= PF_FULLSTASIS; + + // hearticles + if (type) { - mobjtype_t type = player->revitem; - P_SetPlayerMobjState(player->mo, S_PLAY_MELEE_LANDING); - player->mo->tics = (player->mo->movefactor == FRACUNIT) ? TICRATE/2 : (FixedDiv(35<<(FRACBITS-1), FixedSqrt(player->mo->movefactor)))>>FRACBITS; - S_StartSound(player->mo, sfx_s3k8b); - player->pflags |= PF_FULLSTASIS; - - // hearticles - if (type) + UINT8 i = 0; + angle_t throwang = -(2*ANG30); + fixed_t xo = P_ReturnThrustX(player->mo, player->drawangle, 16*player->mo->scale); + fixed_t yo = P_ReturnThrustY(player->mo, player->drawangle, 16*player->mo->scale); + fixed_t zo = 6*player->mo->scale; + fixed_t mu = FixedMul(player->maxdash, player->mo->scale); + fixed_t mu2 = FixedHypot(player->mo->momx, player->mo->momy); + fixed_t ev; + mobj_t *missile; + if (mu2 < mu) + mu2 = mu; + ev = (50*FRACUNIT - (mu/25))/50; + while (i < 5) { - UINT8 i = 0; - angle_t throwang = -(2*ANG30); - fixed_t xo = P_ReturnThrustX(player->mo, player->drawangle, 16*player->mo->scale); - fixed_t yo = P_ReturnThrustY(player->mo, player->drawangle, 16*player->mo->scale); - fixed_t zo = 6*player->mo->scale; - fixed_t mu = FixedMul(player->maxdash, player->mo->scale); - fixed_t mu2 = FixedHypot(player->mo->momx, player->mo->momy); - fixed_t ev; - mobj_t *missile; - if (mu2 < mu) - mu2 = mu; - ev = (50*FRACUNIT - (mu/25))/50; - while (i < 5) - { - missile = P_SpawnMobjFromMobj(player->mo, xo, yo, zo, type); - P_SetTarget(&missile->target, player->mo); - missile->angle = throwang + player->drawangle; - P_Thrust(missile, player->drawangle + ANGLE_90, - P_ReturnThrustY(missile, throwang, mu)); // side to side component - P_Thrust(missile, player->drawangle, mu2); // forward component - P_SetObjectMomZ(missile, (4 + ((i&1)<<1))*FRACUNIT, true); - missile->fuse = TICRATE/2; - missile->extravalue2 = ev; + missile = P_SpawnMobjFromMobj(player->mo, xo, yo, zo, type); + P_SetTarget(&missile->target, player->mo); + missile->angle = throwang + player->drawangle; + P_Thrust(missile, player->drawangle + ANGLE_90, + P_ReturnThrustY(missile, throwang, mu)); // side to side component + P_Thrust(missile, player->drawangle, mu2); // forward component + P_SetObjectMomZ(missile, (4 + ((i&1)<<1))*FRACUNIT, true); + missile->fuse = TICRATE/2; + missile->extravalue2 = ev; - i++; - throwang += ANG30; - } - if (mobjinfo[type].seesound) - S_StartSound(missile, missile->info->seesound); + i++; + throwang += ANG30; } + if (mobjinfo[type].seesound) + S_StartSound(missile, missile->info->seesound); } - else if (player->pflags & PF_JUMPED || !(player->pflags & PF_SPINNING) + } + else if (player->charability2 == CA2_GUNSLINGER && player->panim == PA_ABILITY2) + ; + else if (player->pflags & PF_JUMPED || !(player->pflags & PF_SPINNING) || player->powers[pw_tailsfly] || player->mo->state-states == S_PLAY_FLY_TIRED) + { + if (player->cmomx || player->cmomy) { - if (player->cmomx || player->cmomy) - { - if (player->charflags & SF_DASHMODE && player->dashmode >= 3*TICRATE && player->panim != PA_DASH) - P_SetPlayerMobjState(player->mo, S_PLAY_DASH); - else if (player->speed >= FixedMul(player->runspeed, player->mo->scale) - && (player->panim != PA_RUN || player->mo->state-states == S_PLAY_FLOAT_RUN)) - P_SetPlayerMobjState(player->mo, S_PLAY_RUN); - else if ((player->rmomx || player->rmomy) - && (player->panim != PA_WALK || player->mo->state-states == S_PLAY_FLOAT)) - P_SetPlayerMobjState(player->mo, S_PLAY_WALK); - else if (!player->rmomx && !player->rmomy && player->panim != PA_IDLE) - P_SetPlayerMobjState(player->mo, S_PLAY_STND); - } - else - { - if (player->charflags & SF_DASHMODE && player->dashmode >= 3*TICRATE && player->panim != PA_DASH) - P_SetPlayerMobjState(player->mo, S_PLAY_DASH); - else if (player->speed >= FixedMul(player->runspeed, player->mo->scale) - && (player->panim != PA_RUN || player->mo->state-states == S_PLAY_FLOAT_RUN)) - P_SetPlayerMobjState(player->mo, S_PLAY_RUN); - else if ((player->mo->momx || player->mo->momy) - && (player->panim != PA_WALK || player->mo->state-states == S_PLAY_FLOAT)) - P_SetPlayerMobjState(player->mo, S_PLAY_WALK); - else if (!player->mo->momx && !player->mo->momy && player->panim != PA_IDLE) - P_SetPlayerMobjState(player->mo, S_PLAY_STND); - } + if (player->charflags & SF_DASHMODE && player->dashmode >= 3*TICRATE && player->panim != PA_DASH) + P_SetPlayerMobjState(player->mo, S_PLAY_DASH); + else if (player->speed >= FixedMul(player->runspeed, player->mo->scale) + && (player->panim != PA_RUN || player->mo->state-states == S_PLAY_FLOAT_RUN)) + P_SetPlayerMobjState(player->mo, S_PLAY_RUN); + else if ((player->rmomx || player->rmomy) + && (player->panim != PA_WALK || player->mo->state-states == S_PLAY_FLOAT)) + P_SetPlayerMobjState(player->mo, S_PLAY_WALK); + else if (!player->rmomx && !player->rmomy && player->panim != PA_IDLE) + P_SetPlayerMobjState(player->mo, S_PLAY_STND); + } + else + { + if (player->charflags & SF_DASHMODE && player->dashmode >= 3*TICRATE && player->panim != PA_DASH) + P_SetPlayerMobjState(player->mo, S_PLAY_DASH); + else if (player->speed >= FixedMul(player->runspeed, player->mo->scale) + && (player->panim != PA_RUN || player->mo->state-states == S_PLAY_FLOAT_RUN)) + P_SetPlayerMobjState(player->mo, S_PLAY_RUN); + else if ((player->mo->momx || player->mo->momy) + && (player->panim != PA_WALK || player->mo->state-states == S_PLAY_FLOAT)) + P_SetPlayerMobjState(player->mo, S_PLAY_WALK); + else if (!player->mo->momx && !player->mo->momy && player->panim != PA_IDLE) + P_SetPlayerMobjState(player->mo, S_PLAY_STND); } } @@ -2537,7 +2541,7 @@ static void P_CheckQuicksand(player_t *player) player->mo->z = ceilingheight - player->mo->height; if (player->mo->momz <= 0) - P_PlayerHitFloor(player); + P_PlayerHitFloor(player, false); } else { @@ -2549,7 +2553,7 @@ static void P_CheckQuicksand(player_t *player) player->mo->z = floorheight; if (player->mo->momz >= 0) - P_PlayerHitFloor(player); + P_PlayerHitFloor(player, false); } friction = abs(rover->master->v1->y - rover->master->v2->y)>>6; From 385d34e67ec7780d7fb57d2c7e00a78e4e04f56b Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 25 Sep 2017 20:35:04 +0100 Subject: [PATCH 04/19] * Make busting a FOF through any in-game means (or not providing a target sector to EV_CrumbleChain) bust all FOFs with the same control sector. * Make CA2_GUNSLINGER not get overridden by being in quicksand. --- src/lua_baselib.c | 4 ++-- src/p_floor.c | 46 +++++++++++++++++++++++++++++++++------------- src/p_mobj.c | 4 ++-- src/p_user.c | 4 ++-- 4 files changed, 39 insertions(+), 19 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 1d69b238b..712bc4045 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -2051,8 +2051,8 @@ static int lib_evCrumbleChain(lua_State *L) ffloor_t *rover = *((ffloor_t **)luaL_checkudata(L, 2, META_FFLOOR)); NOHUD INLEVEL - if (!sec) - return LUA_ErrInvalid(L, "sector_t"); + /*if (!sec) + return LUA_ErrInvalid(L, "sector_t");*/ if (!rover) return LUA_ErrInvalid(L, "ffloor_t"); EV_CrumbleChain(sec, rover); diff --git a/src/p_floor.c b/src/p_floor.c index c01e568d0..0b20a3b17 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -3029,20 +3029,40 @@ INT32 EV_DoElevator(line_t *line, elevator_e elevtype, boolean customspeed) void EV_CrumbleChain(sector_t *sec, ffloor_t *rover) { - size_t i; - size_t leftmostvertex = 0, rightmostvertex = 0; - size_t topmostvertex = 0, bottommostvertex = 0; - fixed_t leftx, rightx; - fixed_t topy, bottomy; - fixed_t topz, bottomz; - fixed_t widthfactor = FRACUNIT, heightfactor = FRACUNIT; - fixed_t a, b, c; - mobjtype_t type = MT_ROCKCRUMBLE1; - fixed_t spacing = (32<master->frontsector + sector_t *controlsec = rover->master->frontsector; + + if (sec == NULL) + { + if (controlsec->numattached) + { + for (i = 0; i < controlsec->numattached; i++) + { + sec = §ors[controlsec->attached[i]]; + if (!sec->ffloors) + continue; + + for (rover = sec->ffloors; rover; rover = rover->next) + { + if (rover->master->frontsector == controlsec) + EV_CrumbleChain(sec, rover); + } + } + } + return; + } + + leftmostvertex = rightmostvertex = topmostvertex = bottommostvertex = 0; + widthfactor = heightfactor = FRACUNIT; + spacing = (32<tag != 0) { diff --git a/src/p_mobj.c b/src/p_mobj.c index a7ab4e30d..6cfad95a0 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1784,7 +1784,7 @@ static void P_PushableCheckBustables(mobj_t *mo) continue; } - EV_CrumbleChain(node->m_sector, rover); + EV_CrumbleChain(NULL, rover); // node->m_sector // Run a linedef executor?? if (rover->master->flags & ML_EFFECT5) @@ -3129,7 +3129,7 @@ nightsdone: { // DO THE MARIO! if (rover->flags & FF_SHATTERBOTTOM) // Brick block! - EV_CrumbleChain(node->m_sector, rover); + EV_CrumbleChain(NULL, rover); // node->m_sector else // Question block! EV_MarioBlock(rover, node->m_sector, mo); } diff --git a/src/p_user.c b/src/p_user.c index 3427ed168..706260a61 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2033,7 +2033,7 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff) player->skidtime = TICRATE; player->mo->tics = -1; } - else if (player->charability2 == CA2_MELEE && (player->panim == PA_ABILITY2 && player->mo->state-states != S_PLAY_MELEE_LANDING)) + else if (player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2 && player->mo->state-states != S_PLAY_MELEE_LANDING) { mobjtype_t type = player->revitem; P_SetPlayerMobjState(player->mo, S_PLAY_MELEE_LANDING); @@ -2324,7 +2324,7 @@ static void P_CheckBustableBlocks(player_t *player) //if (metalrecording) // G_RecordBustup(rover); - EV_CrumbleChain(node->m_sector, rover); + EV_CrumbleChain(NULL, rover); // node->m_sector // Run a linedef executor?? if (rover->master->flags & ML_EFFECT5) From 82acf2de6b8aa607cf84ce991f53b4386a92568f Mon Sep 17 00:00:00 2001 From: toaster Date: Wed, 17 Jul 2019 23:24:44 +0100 Subject: [PATCH 05/19] Fix Knuckles-in-quicksand messup. --- src/p_user.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 706260a61..9c4e5b6b9 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2029,9 +2029,13 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff) if (player->pflags & PF_GLIDING) // ground gliding { - if (!player->skidtime) + if (dorollstuff) + { player->skidtime = TICRATE; - player->mo->tics = -1; + player->mo->tics = -1; + } + else + player->pflags &= ~PF_GLIDING; } else if (player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2 && player->mo->state-states != S_PLAY_MELEE_LANDING) { From 1d5e8e249e2195ea4e0c9c6d7a971bd494261aee Mon Sep 17 00:00:00 2001 From: toaster Date: Wed, 17 Jul 2019 23:25:49 +0100 Subject: [PATCH 06/19] Successfully cause landing events when the ground moves up to hit you, as opposed to just when you move down to the ground. --- src/p_map.c | 8 +++++++- src/p_user.c | 5 +++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/p_map.c b/src/p_map.c index e78dd1e84..767370587 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2820,7 +2820,7 @@ boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y) static boolean P_ThingHeightClip(mobj_t *thing) { boolean floormoved; - fixed_t oldfloorz = thing->floorz; + fixed_t oldfloorz = thing->floorz, oldz = thing->z; ffloor_t *oldfloorrover = thing->floorrover; ffloor_t *oldceilingrover = thing->ceilingrover; boolean onfloor = P_IsObjectOnGround(thing);//(thing->z <= thing->floorz); @@ -2879,6 +2879,12 @@ static boolean P_ThingHeightClip(mobj_t *thing) thing->z = thing->ceilingz - thing->height; } + if (thing->z != oldz) + { + if (thing->player) + P_PlayerHitFloor(thing->player, false); + } + // debug: be sure it falls to the floor thing->eflags &= ~MFE_ONGROUND; diff --git a/src/p_user.c b/src/p_user.c index 9c4e5b6b9..1e293d24c 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2069,6 +2069,7 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff) P_ReturnThrustY(missile, throwang, mu)); // side to side component P_Thrust(missile, player->drawangle, mu2); // forward component P_SetObjectMomZ(missile, (4 + ((i&1)<<1))*FRACUNIT, true); + missile->momz += player->mo->pmomz; missile->fuse = TICRATE/2; missile->extravalue2 = ev; @@ -4418,6 +4419,10 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) { player->mo->z += P_MobjFlip(player->mo); P_SetObjectMomZ(player->mo, player->mindash, false); + if (P_MobjFlip(player->mo)*player->mo->pmomz > 0) + player->mo->momz += player->mo->pmomz; // Add the platform's momentum to your jump. + else + player->mo->pmomz = 0; if (player->mo->eflags & MFE_UNDERWATER) player->mo->momz >>= 1; #if 0 From 64517a136229c251f3e6a94678909a94ff02b1b2 Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 18 Jul 2019 00:16:01 +0100 Subject: [PATCH 07/19] Fix !150, too --- src/p_floor.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/p_floor.c b/src/p_floor.c index 0b20a3b17..7887dc530 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -719,6 +719,8 @@ void T_ContinuousFalling(levelspecthink_t *faller) } } + P_CheckSector(faller->sector, false); // you might think this is irrelevant. you would be wrong + faller->sector->floorspeed = faller->speed*faller->direction; faller->sector->ceilspeed = 42; faller->sector->moved = true; From 1d799630af754e7aec7aa01745c21e1d152f0e49 Mon Sep 17 00:00:00 2001 From: toaster Date: Sun, 28 Jul 2019 22:45:20 +0100 Subject: [PATCH 08/19] Made it possible to just call `EV_CrumbleChain(rover)` in Lua --- src/lua_baselib.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 712bc4045..97d2fdc24 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -2047,12 +2047,19 @@ static int lib_pStartQuake(lua_State *L) static int lib_evCrumbleChain(lua_State *L) { - sector_t *sec = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR)); - ffloor_t *rover = *((ffloor_t **)luaL_checkudata(L, 2, META_FFLOOR)); + sector_t *sec = NULL; + ffloor_t *rover = NULL; NOHUD INLEVEL - /*if (!sec) - return LUA_ErrInvalid(L, "sector_t");*/ + if (lua_isuserdata(L, 2)) + { + sec = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR)); + rover = *((ffloor_t **)luaL_checkudata(L, 2, META_FFLOOR)); + if (!sec) + return LUA_ErrInvalid(L, "sector_t"); + } + else + rover = *((ffloor_t **)luaL_checkudata(L, 1, META_FFLOOR)); if (!rover) return LUA_ErrInvalid(L, "ffloor_t"); EV_CrumbleChain(sec, rover); From 5dc095a47d3ae35c189c482f5ee5c1ad6a8051f9 Mon Sep 17 00:00:00 2001 From: toaster Date: Sun, 28 Jul 2019 22:53:27 +0100 Subject: [PATCH 09/19] Further improvements on MI's request, just to be safe. --- src/lua_baselib.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 97d2fdc24..767ab2dd3 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -2051,12 +2051,15 @@ static int lib_evCrumbleChain(lua_State *L) ffloor_t *rover = NULL; NOHUD INLEVEL - if (lua_isuserdata(L, 2)) + if (!lua_isnone(L, 2)) { - sec = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR)); + if (!lua_isnil(L, 1)) + { + sec = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR)); + if (!sec) + return LUA_ErrInvalid(L, "sector_t"); + } rover = *((ffloor_t **)luaL_checkudata(L, 2, META_FFLOOR)); - if (!sec) - return LUA_ErrInvalid(L, "sector_t"); } else rover = *((ffloor_t **)luaL_checkudata(L, 1, META_FFLOOR)); From 62c708e64a6ec889f8b0107dc0b07cd641ee14d3 Mon Sep 17 00:00:00 2001 From: toaster Date: Mon, 29 Jul 2019 20:29:02 +0100 Subject: [PATCH 10/19] Two one liners related to angles, so doin' em in a single branch. * If a spring has vertical speed AND horizontal speed, always set the player's angle when touching it. * If you have less than 32 rings and spill them, they now get launched away from the player's motion, rather than in the direction of the camera. --- src/p_inter.c | 9 +++++++-- src/p_map.c | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index abf33429f..5b52f2ffb 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3652,7 +3652,7 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings) { INT32 i; mobj_t *mo; - angle_t fa; + angle_t fa, va; fixed_t ns; fixed_t z; boolean nightsreplace = ((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap)); @@ -3674,6 +3674,11 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings) // Spill weapons first P_PlayerWeaponPanelOrAmmoBurst(player); + if (abs(player->mo->momx) > player->mo->scale || abs(player->mo->momy) > player->mo->scale) + va = R_PointToAngle2(player->mo->momx, player->mo->momy, 0, 0)>>ANGLETOFINESHIFT; + else + va = player->mo->angle>>ANGLETOFINESHIFT; + for (i = 0; i < num_rings; i++) { INT32 objType = mobjinfo[MT_RING].reactiontime; @@ -3695,7 +3700,7 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings) P_SetScale(mo, player->mo->scale); // Angle offset by player angle, then slightly offset by amount of rings - fa = ((i*FINEANGLES/16) + (player->mo->angle>>ANGLETOFINESHIFT) - ((num_rings-1)*FINEANGLES/32)) & FINEMASK; + fa = ((i*FINEANGLES/16) + va - ((num_rings-1)*FINEANGLES/32)) & FINEMASK; // Make rings spill out around the player in 16 directions like SA, but spill like Sonic 2. // Technically a non-SA way of spilling rings. They just so happen to be a little similar. diff --git a/src/p_map.c b/src/p_map.c index e78dd1e84..8fe9fb4ae 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -342,7 +342,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) if (horizspeed) { object->player->drawangle = spring->angle; - if (object->player->cmd.forwardmove == 0 && object->player->cmd.sidemove == 0) + if (vertispeed || (object->player->cmd.forwardmove == 0 && object->player->cmd.sidemove == 0)) { object->angle = spring->angle; From a6a3048c8f9ae1c8dd914754789f12713f84c1af Mon Sep 17 00:00:00 2001 From: toaster Date: Mon, 29 Jul 2019 21:03:28 +0100 Subject: [PATCH 11/19] * Fix diagonal spring ring assortments being forced up/down with slopes. --- src/p_mobj.c | 82 +++++++++++++++++++++++++++++----------------------- 1 file changed, 46 insertions(+), 36 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 1cb7f742d..7c50967cb 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -12355,28 +12355,33 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime) if (nightsreplace) ringthing = MT_NIGHTSSTAR; + if (mthing->options & MTF_OBJECTFLIP) + { + z = ( +#ifdef ESLOPE + sec->c_slope ? P_GetZAt(sec->c_slope, x, y) : +#endif + sec->ceilingheight) - mobjinfo[ringthing].height; + if (mthing->options >> ZSHIFT) + z -= ((mthing->options >> ZSHIFT) << FRACBITS); + } + else + { + z = ( +#ifdef ESLOPE + sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : +#endif + sec->floorheight); + if (mthing->options >> ZSHIFT) + z += ((mthing->options >> ZSHIFT) << FRACBITS); + } + for (r = 1; r <= 5; r++) { if (mthing->options & MTF_OBJECTFLIP) - { - z = ( -#ifdef ESLOPE - sec->c_slope ? P_GetZAt(sec->c_slope, x, y) : -#endif - sec->ceilingheight) - mobjinfo[ringthing].height - dist*r; - if (mthing->options >> ZSHIFT) - z -= ((mthing->options >> ZSHIFT) << FRACBITS); - } + z -= dist; else - { - z = ( -#ifdef ESLOPE - sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : -#endif - sec->floorheight) + dist*r; - if (mthing->options >> ZSHIFT) - z += ((mthing->options >> ZSHIFT) << FRACBITS); - } + z += dist; mobj = P_SpawnMobj(x, y, z, ringthing); @@ -12410,31 +12415,36 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime) closestangle = FixedAngle(mthing->angle*FRACUNIT); fa = (closestangle >> ANGLETOFINESHIFT); + if (mthing->options & MTF_OBJECTFLIP) + { + z = ( +#ifdef ESLOPE + sec->c_slope ? P_GetZAt(sec->c_slope, x, y) : +#endif + sec->ceilingheight) - mobjinfo[ringthing].height; + if (mthing->options >> ZSHIFT) + z -= ((mthing->options >> ZSHIFT) << FRACBITS); + } + else + { + z = ( +#ifdef ESLOPE + sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : +#endif + sec->floorheight); + if (mthing->options >> ZSHIFT) + z += ((mthing->options >> ZSHIFT) << FRACBITS); + } + for (r = 1; r <= iterations; r++) { x += FixedMul(64*FRACUNIT, FINECOSINE(fa)); y += FixedMul(64*FRACUNIT, FINESINE(fa)); if (mthing->options & MTF_OBJECTFLIP) - { - z = ( -#ifdef ESLOPE - sec->c_slope ? P_GetZAt(sec->c_slope, x, y) : -#endif - sec->ceilingheight) - mobjinfo[ringthing].height - 64*FRACUNIT*r; - if (mthing->options >> ZSHIFT) - z -= ((mthing->options >> ZSHIFT) << FRACBITS); - } + z -= 64*FRACUNIT; else - { - z = ( -#ifdef ESLOPE - sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : -#endif - sec->floorheight) + 64*FRACUNIT*r; - if (mthing->options >> ZSHIFT) - z += ((mthing->options >> ZSHIFT) << FRACBITS); - } + z += 64*FRACUNIT; mobj = P_SpawnMobj(x, y, z, ringthing); From deaee586ed035859662037d10f2f5c152fda0c0e Mon Sep 17 00:00:00 2001 From: toaster Date: Mon, 29 Jul 2019 21:05:30 +0100 Subject: [PATCH 12/19] Make MANIASPHERES' #define'd away stuff also recreatable with SOC, since I want to release it publically if the team don't want it. --- src/info.c | 6 +++++- src/p_setup.c | 12 +----------- src/st_stuff.c | 6 +----- 3 files changed, 7 insertions(+), 17 deletions(-) diff --git a/src/info.c b/src/info.c index a4446d657..0ae723546 100644 --- a/src/info.c +++ b/src/info.c @@ -1791,7 +1791,11 @@ state_t states[NUMSTATES] = // Blue Sphere for special stages {SPR_SPHR, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_BLUESPHERE - {SPR_SPHR, FF_FULLBRIGHT|FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 1, 4, S_NULL}, // S_BLUESPHEREBONUS + {SPR_SPHR, FF_FULLBRIGHT +#ifdef MANIASPHERES + |FF_ANIMATE|FF_RANDOMANIM +#endif + , -1, {NULL}, 1, 4, S_NULL}, // S_BLUESPHEREBONUS {SPR_SPHR, 0, 20, {NULL}, 0, 0, S_NULL}, // S_BLUESPHERESPARK // Bomb Sphere diff --git a/src/p_setup.c b/src/p_setup.c index c0aa7ffa3..0b391f390 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -859,12 +859,7 @@ void P_ReloadRings(void) mt->z = (INT16)(R_PointInSubsector(mt->x << FRACBITS, mt->y << FRACBITS) ->sector->floorheight>>FRACBITS); - P_SpawnHoopsAndRings(mt, -#ifdef MANIASPHERES - true); -#else - !G_IsSpecialStage(gamemap)); // prevent flashing spheres in special stages -#endif + P_SpawnHoopsAndRings(mt, true); } } for (i = 0; i < numHoops; i++) @@ -878,11 +873,6 @@ void P_SwitchSpheresBonusMode(boolean bonustime) mobj_t *mo; thinker_t *th; -#ifndef MANIASPHERES - if (G_IsSpecialStage(gamemap)) // prevent flashing spheres in special stages - return; -#endif - // scan the thinkers to find spheres to switch for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { diff --git a/src/st_stuff.c b/src/st_stuff.c index 4122793ad..3b8fc749d 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1617,12 +1617,8 @@ static void ST_drawNiGHTSHUD(void) #endif ST_DrawTopLeftOverlayPatch(16, 8, nbracket); if (G_IsSpecialStage(gamemap)) -#ifdef MANIASPHERES ST_DrawTopLeftOverlayPatch(24, 16, ( - (stplyr->bonustime && (leveltime & 4)) ? nssbon : nsshud)); -#else - ST_DrawTopLeftOverlayPatch(24, 16, (nsshud)); -#endif + (stplyr->bonustime && (leveltime & 4) && (states[S_BLUESPHEREBONUS].frame & FF_ANIMATE)) ? nssbon : nsshud)); else ST_DrawTopLeftOverlayPatch(24, 16, *(((stplyr->bonustime) ? nbon : nhud)+((leveltime/2)%12))); From 18e43a5cef6a45ee1f4c5c779bcf8e48ff9e7d65 Mon Sep 17 00:00:00 2001 From: toaster Date: Tue, 30 Jul 2019 16:44:40 +0100 Subject: [PATCH 13/19] * Fix "exitlevel" being counted as a special stage success despite not giving you an emerald by inverting stagefailed's default value, since there's only a limited number of ways you can WIN at a special stage. * Correct a potential source of desync in P_GiveEmerald. --- src/p_inter.c | 3 +++ src/p_setup.c | 2 +- src/p_tick.c | 3 --- src/p_user.c | 37 ++++++++++++++++++++++++++++++------- 4 files changed, 34 insertions(+), 11 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index abf33429f..486c39fb7 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -670,7 +670,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) P_DoMatchSuper(player); } else + { emeralds |= special->info->speed; + stagefailed = false; + } if (special->target && special->target->type == MT_EMERALDSPAWN) { diff --git a/src/p_setup.c b/src/p_setup.c index c0aa7ffa3..976d19190 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2215,7 +2215,7 @@ static void P_LevelInitStuff(void) ssspheres = timeinmap = 0; // special stage - stagefailed = false; + stagefailed = true; // assume failed unless proven otherwise - P_GiveEmerald or emerald touchspecial // Reset temporary record data memset(&ntemprecords, 0, sizeof(nightsdata_t)); diff --git a/src/p_tick.c b/src/p_tick.c index a0f6edef9..cfdd54eb2 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -518,10 +518,7 @@ static inline void P_DoSpecialStageStuff(void) } } else - { sstimer = 0; - stagefailed = true; - } } } diff --git a/src/p_user.c b/src/p_user.c index b758cebe4..cdf8c246c 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -302,15 +302,39 @@ void P_GiveEmerald(boolean spawnObj) S_StartSound(NULL, sfx_cgot); // Got the emerald! emeralds |= (1 << em); + stagefailed = false; - if (spawnObj && playeringame[consoleplayer]) + if (spawnObj) { // The Chaos Emerald begins to orbit us! - // Only give it to ONE person! - mobj_t *emmo = P_SpawnMobjFromMobj(players[consoleplayer].mo, 0, 0, players[consoleplayer].mo->height, MT_GOTEMERALD); - P_SetTarget(&emmo->target, players[consoleplayer].mo); - P_SetMobjState(emmo, mobjinfo[MT_GOTEMERALD].meleestate + em); - P_SetTarget(&players[consoleplayer].mo->tracer, emmo); + // Only visibly give it to ONE person! + UINT8 i, pnum = ((playeringame[consoleplayer]) && (!players[consoleplayer].spectator) && (players[consoleplayer].mo)) ? consoleplayer : 255; + for (i = 0; i < MAXPLAYERS; i++) + { + mobj_t *emmo; + if (!playeringame[i]) + continue; + if (players[i].spectator) + continue; + if (!players[i].mo) + continue; + + emmo = P_SpawnMobjFromMobj(players[i].mo, 0, 0, players[i].mo->height, MT_GOTEMERALD); + P_SetTarget(&emmo->target, players[i].mo); + P_SetMobjState(emmo, mobjinfo[MT_GOTEMERALD].meleestate + em); + P_SetTarget(&players[i].mo->tracer, emmo); + + if (pnum == 255) + { + i = pnum; + continue; + } + + if (i == pnum) + continue; + + emmo->flags2 |= MF2_DONTDRAW; + } } } @@ -615,7 +639,6 @@ static void P_DeNightserizePlayer(player_t *player) if (playeringame[i] && players[i].powers[pw_carry] == CR_NIGHTSMODE) players[i].nightstime = 1; // force everyone else to fall too. player->exiting = 3*TICRATE; - stagefailed = true; // NIGHT OVER // If you screwed up, kiss your score and ring bonus goodbye. // But only do this in special stage (and instakill!) In regular stages, wait til we hit the ground. From d541bb7eadb791416450d13cf7e2d28e541f2677 Mon Sep 17 00:00:00 2001 From: toaster Date: Tue, 30 Jul 2019 17:24:21 +0100 Subject: [PATCH 14/19] * Fix something I neglected earlier when fixing Ghosts and Replays for 2.2 - the fact that the player's skin will change if they don't have NiGHTS sprites like Sonic does not being accomodated. --- src/g_game.c | 8 +++++++- src/g_game.h | 4 +++- src/p_user.c | 3 ++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 95cc2288d..3cb5da1b5 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -4366,7 +4366,7 @@ void G_WriteGhostTic(mobj_t *ghost) ghostext.flags = 0; } - if (ghost->player && ghost->player->followmobj) + if (ghost->player && ghost->player->followmobj) // bloats tails runs but what can ya do { INT16 temp; @@ -4592,6 +4592,9 @@ void G_GhostTicker(void) switch(g->color) { default: + case GHC_RETURNSKIN: + g->mo->skin = g->oldmo.skin; + // fallthru case GHC_NORMAL: // Go back to skin color g->mo->color = g->oldmo.color; break; @@ -4602,6 +4605,9 @@ void G_GhostTicker(void) case GHC_FIREFLOWER: // Fireflower g->mo->color = SKINCOLOR_WHITE; break; + case GHC_NIGHTSSKIN: // not actually a colour + g->mo->skin = &skins[DEFAULTNIGHTSSKIN]; + break; } } if (xziptic & EZT_FLIP) diff --git a/src/g_game.h b/src/g_game.h index 3cbde9a3c..96a192ee8 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -140,7 +140,9 @@ typedef enum GHC_NORMAL = 0, GHC_SUPER, GHC_FIREFLOWER, - GHC_INVINCIBLE + GHC_INVINCIBLE, + GHC_NIGHTSSKIN, // not actually a colour + GHC_RETURNSKIN // ditto } ghostcolor_t; // Record/playback tics diff --git a/src/p_user.c b/src/p_user.c index cdf8c246c..7bd2af127 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -621,7 +621,7 @@ static void P_DeNightserizePlayer(player_t *player) player->mo->skin = &skins[player->skin]; player->followitem = skins[player->skin].followitem; player->mo->color = player->skincolor; - G_GhostAddColor(GHC_NORMAL); + G_GhostAddColor(GHC_RETURNSKIN); // Restore aiming angle if (player == &players[consoleplayer]) @@ -739,6 +739,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) if (!(cv_debug || devparm) && !(netgame || multiplayer || demoplayback)) player->mo->color = skins[DEFAULTNIGHTSSKIN].prefcolor; player->followitem = skins[DEFAULTNIGHTSSKIN].followitem; + G_GhostAddColor(GHC_NIGHTSSKIN); } player->nightstime = player->startedtime = player->lapstartedtime = nighttime*TICRATE; From 69e573517f31a9b3c19d31f0f42f6e3cbde32862 Mon Sep 17 00:00:00 2001 From: toaster Date: Tue, 30 Jul 2019 17:48:13 +0100 Subject: [PATCH 15/19] Fix lua scripts erroring on the title screen because they're run there but it's not counted as GS_LEVEL (aka #168). --- src/f_finale.h | 1 - src/g_state.h | 1 + src/lua_baselib.c | 2 +- src/lua_consolelib.c | 2 +- src/lua_maplib.c | 51 +++++++++++++++++--------------------------- src/lua_mobjlib.c | 9 ++++---- src/lua_playerlib.c | 9 ++++---- src/lua_thinkerlib.c | 9 ++++---- 8 files changed, 37 insertions(+), 47 deletions(-) diff --git a/src/f_finale.h b/src/f_finale.h index c0c6360c3..29e9b4d8c 100644 --- a/src/f_finale.h +++ b/src/f_finale.h @@ -82,7 +82,6 @@ typedef enum // Current menu parameters -extern UINT8 titlemapinaction; extern mobj_t *titlemapcameraref; extern char curbgname[8]; extern SINT8 curfadevalue; diff --git a/src/g_state.h b/src/g_state.h index 76c9bd16f..7ee0cfb63 100644 --- a/src/g_state.h +++ b/src/g_state.h @@ -50,6 +50,7 @@ typedef enum } gameaction_t; extern gamestate_t gamestate; +extern UINT8 titlemapinaction; extern UINT8 ultimatemode; // was sk_insane extern gameaction_t gameaction; diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 1d69b238b..7592fdf48 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -33,7 +33,7 @@ #define NOHUD if (hud_running)\ return luaL_error(L, "HUD rendering code should not call this function!"); -#define INLEVEL if (gamestate != GS_LEVEL)\ +#define INLEVEL if (gamestate != GS_LEVEL && !titlemapinaction)\ return luaL_error(L, "This function can only be used in a level!"); boolean luaL_checkboolean(lua_State *L, int narg) { diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index 98d18d8db..ed0295ca1 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -29,7 +29,7 @@ return luaL_error(L, "HUD rendering code should not call this function!"); #define NOHOOK if (!lua_lumploading)\ return luaL_error(L, "This function cannot be called from within a hook or coroutine!"); // for functions only allowed within a level -#define INLEVEL if (gamestate != GS_LEVEL)\ +#define INLEVEL if (gamestate != GS_LEVEL && !titlemapinaction)\ return luaL_error(L, "This function can only be used in a level!"); static const char *cvname = NULL; diff --git a/src/lua_maplib.c b/src/lua_maplib.c index ded90daf0..1ab2828bf 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -29,6 +29,9 @@ #include "fastcmp.h" #include "doomstat.h" +#define INLEVEL if (gamestate != GS_LEVEL && !titlemapinaction)\ +return luaL_error(L, "This function can only be used in a level!"); + enum sector_e { sector_valid = 0, sector_floorheight, @@ -333,8 +336,7 @@ static int lib_iterateSectorThinglist(lua_State *L) mobj_t *state = NULL; mobj_t *thing = NULL; - if (gamestate != GS_LEVEL) - return luaL_error(L, "This function can only be used in a level!"); + INLEVEL if (lua_gettop(L) < 2) return luaL_error(L, "Don't call sector.thinglist() directly, use it as 'for rover in sector.thinglist do end'."); @@ -369,8 +371,7 @@ static int lib_iterateSectorFFloors(lua_State *L) ffloor_t *state = NULL; ffloor_t *ffloor = NULL; - if (gamestate != GS_LEVEL) - return luaL_error(L, "This function can only be used in a level!"); + INLEVEL if (lua_gettop(L) < 2) return luaL_error(L, "Don't call sector.ffloors() directly, use it as 'for rover in sector.ffloors do end'."); @@ -1251,8 +1252,7 @@ static int bbox_get(lua_State *L) static int lib_iterateSectors(lua_State *L) { size_t i = 0; - if (gamestate != GS_LEVEL) - return luaL_error(L, "This function can only be used in a level!"); + INLEVEL if (lua_gettop(L) < 2) return luaL_error(L, "Don't call sectors.iterate() directly, use it as 'for sector in sectors.iterate do end'."); lua_settop(L, 2); @@ -1270,8 +1270,7 @@ static int lib_iterateSectors(lua_State *L) static int lib_getSector(lua_State *L) { int field; - if (gamestate != GS_LEVEL) - return luaL_error(L, "You cannot access this outside of a level!"); + INLEVEL lua_settop(L, 2); lua_remove(L, 1); // dummy userdata table is unused. if (lua_isnumber(L, 1)) @@ -1305,8 +1304,7 @@ static int lib_numsectors(lua_State *L) static int lib_iterateSubsectors(lua_State *L) { size_t i = 0; - if (gamestate != GS_LEVEL) - return luaL_error(L, "This function can only be used in a level!"); + INLEVEL if (lua_gettop(L) < 2) return luaL_error(L, "Don't call subsectors.iterate() directly, use it as 'for subsector in subsectors.iterate do end'."); lua_settop(L, 2); @@ -1324,8 +1322,7 @@ static int lib_iterateSubsectors(lua_State *L) static int lib_getSubsector(lua_State *L) { int field; - if (gamestate != GS_LEVEL) - return luaL_error(L, "You cannot access this outside of a level!"); + INLEVEL lua_settop(L, 2); lua_remove(L, 1); // dummy userdata table is unused. if (lua_isnumber(L, 1)) @@ -1359,8 +1356,7 @@ static int lib_numsubsectors(lua_State *L) static int lib_iterateLines(lua_State *L) { size_t i = 0; - if (gamestate != GS_LEVEL) - return luaL_error(L, "This function can only be used in a level!"); + INLEVEL if (lua_gettop(L) < 2) return luaL_error(L, "Don't call lines.iterate() directly, use it as 'for line in lines.iterate do end'."); lua_settop(L, 2); @@ -1378,8 +1374,7 @@ static int lib_iterateLines(lua_State *L) static int lib_getLine(lua_State *L) { int field; - if (gamestate != GS_LEVEL) - return luaL_error(L, "You cannot access this outside of a level!"); + INLEVEL lua_settop(L, 2); lua_remove(L, 1); // dummy userdata table is unused. if (lua_isnumber(L, 1)) @@ -1413,8 +1408,7 @@ static int lib_numlines(lua_State *L) static int lib_iterateSides(lua_State *L) { size_t i = 0; - if (gamestate != GS_LEVEL) - return luaL_error(L, "This function can only be used in a level!"); + INLEVEL if (lua_gettop(L) < 2) return luaL_error(L, "Don't call sides.iterate() directly, use it as 'for side in sides.iterate do end'."); lua_settop(L, 2); @@ -1432,8 +1426,7 @@ static int lib_iterateSides(lua_State *L) static int lib_getSide(lua_State *L) { int field; - if (gamestate != GS_LEVEL) - return luaL_error(L, "You cannot access this outside of a level!"); + INLEVEL lua_settop(L, 2); lua_remove(L, 1); // dummy userdata table is unused. if (lua_isnumber(L, 1)) @@ -1467,8 +1460,7 @@ static int lib_numsides(lua_State *L) static int lib_iterateVertexes(lua_State *L) { size_t i = 0; - if (gamestate != GS_LEVEL) - return luaL_error(L, "This function can only be used in a level!"); + INLEVEL if (lua_gettop(L) < 2) return luaL_error(L, "Don't call vertexes.iterate() directly, use it as 'for vertex in vertexes.iterate do end'."); lua_settop(L, 2); @@ -1486,8 +1478,7 @@ static int lib_iterateVertexes(lua_State *L) static int lib_getVertex(lua_State *L) { int field; - if (gamestate != GS_LEVEL) - return luaL_error(L, "You cannot access this outside of a level!"); + INLEVEL lua_settop(L, 2); lua_remove(L, 1); // dummy userdata table is unused. if (lua_isnumber(L, 1)) @@ -1523,8 +1514,7 @@ static int lib_numvertexes(lua_State *L) static int lib_iterateSegs(lua_State *L) { size_t i = 0; - if (gamestate != GS_LEVEL) - return luaL_error(L, "This function can only be used in a level!"); + INLEVEL if (lua_gettop(L) < 2) return luaL_error(L, "Don't call segs.iterate() directly, use it as 'for seg in segs.iterate do end'."); lua_settop(L, 2); @@ -1542,8 +1532,7 @@ static int lib_iterateSegs(lua_State *L) static int lib_getSeg(lua_State *L) { int field; - if (gamestate != GS_LEVEL) - return luaL_error(L, "You cannot access this outside of a level!"); + INLEVEL lua_settop(L, 2); lua_remove(L, 1); // dummy userdata table is unused. if (lua_isnumber(L, 1)) @@ -1577,8 +1566,7 @@ static int lib_numsegs(lua_State *L) static int lib_iterateNodes(lua_State *L) { size_t i = 0; - if (gamestate != GS_LEVEL) - return luaL_error(L, "This function can only be used in a level!"); + INLEVEL if (lua_gettop(L) < 2) return luaL_error(L, "Don't call nodes.iterate() directly, use it as 'for node in nodes.iterate do end'."); lua_settop(L, 2); @@ -1596,8 +1584,7 @@ static int lib_iterateNodes(lua_State *L) static int lib_getNode(lua_State *L) { int field; - if (gamestate != GS_LEVEL) - return luaL_error(L, "You cannot access this outside of a level!"); + INLEVEL lua_settop(L, 2); lua_remove(L, 1); // dummy userdata table is unused. if (lua_isnumber(L, 1)) diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index 8bbbebe1d..5ddcb0ca7 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -22,6 +22,9 @@ #include "lua_libs.h" #include "lua_hud.h" // hud_running errors +#define INLEVEL if (gamestate != GS_LEVEL && !titlemapinaction)\ +return luaL_error(L, "This function can only be used in a level!"); + static const char *const array_opt[] ={"iterate",NULL}; enum mobj_e { @@ -816,8 +819,7 @@ static int mapthing_set(lua_State *L) static int lib_iterateMapthings(lua_State *L) { size_t i = 0; - if (gamestate != GS_LEVEL) - return luaL_error(L, "This function can only be used in a level!"); + INLEVEL if (lua_gettop(L) < 2) return luaL_error(L, "Don't call mapthings.iterate() directly, use it as 'for mapthing in mapthings.iterate do end'."); lua_settop(L, 2); @@ -835,8 +837,7 @@ static int lib_iterateMapthings(lua_State *L) static int lib_getMapthing(lua_State *L) { int field; - if (gamestate != GS_LEVEL) - return luaL_error(L, "You cannot access this outside of a level!"); + INLEVEL lua_settop(L, 2); lua_remove(L, 1); // dummy userdata table is unused. if (lua_isnumber(L, 1)) diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 700dab211..c4b092c6f 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -22,11 +22,13 @@ #include "lua_libs.h" #include "lua_hud.h" // hud_running errors +#define INLEVEL if (gamestate != GS_LEVEL && !titlemapinaction)\ +return luaL_error(L, "This function can only be used in a level!"); + static int lib_iteratePlayers(lua_State *L) { INT32 i = -1; - if (gamestate != GS_LEVEL) - return luaL_error(L, "This function can only be used in a level!"); + INLEVEL if (lua_gettop(L) < 2) { //return luaL_error(L, "Don't call players.iterate() directly, use it as 'for player in players.iterate do end'."); @@ -53,8 +55,7 @@ static int lib_getPlayer(lua_State *L) { const char *field; // i -> players[i] - if (gamestate != GS_LEVEL) - return luaL_error(L, "You cannot access this outside of a level!"); + INLEVEL if (lua_type(L, 2) == LUA_TNUMBER) { lua_Integer i = luaL_checkinteger(L, 2); diff --git a/src/lua_thinkerlib.c b/src/lua_thinkerlib.c index 63eb15846..8fa2869c8 100644 --- a/src/lua_thinkerlib.c +++ b/src/lua_thinkerlib.c @@ -16,6 +16,9 @@ #include "lua_script.h" #include "lua_libs.h" +#define INLEVEL if (gamestate != GS_LEVEL && !titlemapinaction)\ +return luaL_error(L, "This function can only be used in a level!"); + #define META_ITERATIONSTATE "iteration state" /*static const char *const iter_opt[] = { @@ -56,8 +59,7 @@ static int lib_iterateThinkers(lua_State *L) thinker_t *th = NULL, *next = NULL; struct iterationState *it; - if (gamestate != GS_LEVEL) - return luaL_error(L, "This function can only be used in a level!"); + INLEVEL it = luaL_checkudata(L, 1, META_ITERATIONSTATE); @@ -112,8 +114,7 @@ static int lib_startIterate(lua_State *L) { struct iterationState *it; - if (gamestate != GS_LEVEL) - return luaL_error(L, "This function can only be used in a level!"); + INLEVEL lua_pushvalue(L, lua_upvalueindex(1)); it = lua_newuserdata(L, sizeof(struct iterationState)); From 7bff3056720c34bd7419ca3ace4903da0951e418 Mon Sep 17 00:00:00 2001 From: toaster Date: Tue, 30 Jul 2019 17:57:57 +0100 Subject: [PATCH 16/19] * Strip the word "function" from INLEVEL error messages, since they're now shared between access and function cases. * Move it into lua_script.h, so it's available to everything that needs it. --- src/lua_baselib.c | 2 -- src/lua_consolelib.c | 3 --- src/lua_maplib.c | 3 --- src/lua_mobjlib.c | 3 --- src/lua_playerlib.c | 3 --- src/lua_script.h | 4 ++++ src/lua_thinkerlib.c | 3 --- 7 files changed, 4 insertions(+), 17 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 7592fdf48..3fd58f637 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -33,8 +33,6 @@ #define NOHUD if (hud_running)\ return luaL_error(L, "HUD rendering code should not call this function!"); -#define INLEVEL if (gamestate != GS_LEVEL && !titlemapinaction)\ -return luaL_error(L, "This function can only be used in a level!"); boolean luaL_checkboolean(lua_State *L, int narg) { luaL_checktype(L, narg, LUA_TBOOLEAN); diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index ed0295ca1..c6856b426 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -28,9 +28,6 @@ return luaL_error(L, "HUD rendering code should not call this function!"); // for functions not allowed in hooks or coroutines (supercedes above) #define NOHOOK if (!lua_lumploading)\ return luaL_error(L, "This function cannot be called from within a hook or coroutine!"); -// for functions only allowed within a level -#define INLEVEL if (gamestate != GS_LEVEL && !titlemapinaction)\ -return luaL_error(L, "This function can only be used in a level!"); static const char *cvname = NULL; diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 1ab2828bf..82843db4e 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -29,9 +29,6 @@ #include "fastcmp.h" #include "doomstat.h" -#define INLEVEL if (gamestate != GS_LEVEL && !titlemapinaction)\ -return luaL_error(L, "This function can only be used in a level!"); - enum sector_e { sector_valid = 0, sector_floorheight, diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index 5ddcb0ca7..de1b854f6 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -22,9 +22,6 @@ #include "lua_libs.h" #include "lua_hud.h" // hud_running errors -#define INLEVEL if (gamestate != GS_LEVEL && !titlemapinaction)\ -return luaL_error(L, "This function can only be used in a level!"); - static const char *const array_opt[] ={"iterate",NULL}; enum mobj_e { diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index c4b092c6f..b7bdaa1be 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -22,9 +22,6 @@ #include "lua_libs.h" #include "lua_hud.h" // hud_running errors -#define INLEVEL if (gamestate != GS_LEVEL && !titlemapinaction)\ -return luaL_error(L, "This function can only be used in a level!"); - static int lib_iteratePlayers(lua_State *L) { INT32 i = -1; diff --git a/src/lua_script.h b/src/lua_script.h index b690e4fa7..fcbca2937 100644 --- a/src/lua_script.h +++ b/src/lua_script.h @@ -15,6 +15,7 @@ #include "m_fixed.h" #include "doomtype.h" #include "d_player.h" +#include "g_state.h" #include "blua/lua.h" #include "blua/lualib.h" @@ -97,4 +98,7 @@ void COM_Lua_f(void); // uncomment if you want seg_t/node_t in Lua // #define HAVE_LUA_SEGS +#define INLEVEL if (gamestate != GS_LEVEL && !titlemapinaction)\ +return luaL_error(L, "This can only be used in a level!"); + #endif diff --git a/src/lua_thinkerlib.c b/src/lua_thinkerlib.c index 8fa2869c8..877294898 100644 --- a/src/lua_thinkerlib.c +++ b/src/lua_thinkerlib.c @@ -16,9 +16,6 @@ #include "lua_script.h" #include "lua_libs.h" -#define INLEVEL if (gamestate != GS_LEVEL && !titlemapinaction)\ -return luaL_error(L, "This function can only be used in a level!"); - #define META_ITERATIONSTATE "iteration state" /*static const char *const iter_opt[] = { From 39c15e71b061099465938907fe2398102fc5411b Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 1 Aug 2019 08:01:29 -0400 Subject: [PATCH 17/19] Was reviewing old merge requests as a procrastination technique, and discovered that the followmobj's scale was being inaccurately handled for Smiles' tails! Fixed that... --- src/p_user.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index b758cebe4..2ca6c3535 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -11641,7 +11641,6 @@ void P_PlayerAfterThink(player_t *player) player->followmobj->threshold = player->mo->z; player->followmobj->movecount = player->panim; player->followmobj->angle = horizangle; - player->followmobj->scale = player->mo->scale; P_SetScale(player->followmobj, player->mo->scale); player->followmobj->destscale = player->mo->destscale; player->followmobj->radius = player->mo->radius; From f2349c5ce485ef169fcc9322e790e722cd0744c6 Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 2 Aug 2019 13:18:57 +0100 Subject: [PATCH 18/19] fixed sphere's CA2_MELEE stasis issue --- src/p_user.c | 77 +++++++++++++++++++++++++++------------------------- 1 file changed, 40 insertions(+), 37 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 29e29d7c1..4a804ace8 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2037,47 +2037,50 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff) else player->pflags &= ~PF_GLIDING; } - else if (player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2 && player->mo->state-states != S_PLAY_MELEE_LANDING) + else if (player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2) { - mobjtype_t type = player->revitem; - P_SetPlayerMobjState(player->mo, S_PLAY_MELEE_LANDING); - player->mo->tics = (player->mo->movefactor == FRACUNIT) ? TICRATE/2 : (FixedDiv(35<<(FRACBITS-1), FixedSqrt(player->mo->movefactor)))>>FRACBITS; - S_StartSound(player->mo, sfx_s3k8b); - player->pflags |= PF_FULLSTASIS; - - // hearticles - if (type) + if (player->mo->state-states != S_PLAY_MELEE_LANDING) { - UINT8 i = 0; - angle_t throwang = -(2*ANG30); - fixed_t xo = P_ReturnThrustX(player->mo, player->drawangle, 16*player->mo->scale); - fixed_t yo = P_ReturnThrustY(player->mo, player->drawangle, 16*player->mo->scale); - fixed_t zo = 6*player->mo->scale; - fixed_t mu = FixedMul(player->maxdash, player->mo->scale); - fixed_t mu2 = FixedHypot(player->mo->momx, player->mo->momy); - fixed_t ev; - mobj_t *missile = NULL; - if (mu2 < mu) - mu2 = mu; - ev = (50*FRACUNIT - (mu/25))/50; - while (i < 5) - { - missile = P_SpawnMobjFromMobj(player->mo, xo, yo, zo, type); - P_SetTarget(&missile->target, player->mo); - missile->angle = throwang + player->drawangle; - P_Thrust(missile, player->drawangle + ANGLE_90, - P_ReturnThrustY(missile, throwang, mu)); // side to side component - P_Thrust(missile, player->drawangle, mu2); // forward component - P_SetObjectMomZ(missile, (4 + ((i&1)<<1))*FRACUNIT, true); - missile->momz += player->mo->pmomz; - missile->fuse = TICRATE/2; - missile->extravalue2 = ev; + mobjtype_t type = player->revitem; + P_SetPlayerMobjState(player->mo, S_PLAY_MELEE_LANDING); + player->mo->tics = (player->mo->movefactor == FRACUNIT) ? TICRATE/2 : (FixedDiv(35<<(FRACBITS-1), FixedSqrt(player->mo->movefactor)))>>FRACBITS; + S_StartSound(player->mo, sfx_s3k8b); + player->pflags |= PF_FULLSTASIS; - i++; - throwang += ANG30; + // hearticles + if (type) + { + UINT8 i = 0; + angle_t throwang = -(2*ANG30); + fixed_t xo = P_ReturnThrustX(player->mo, player->drawangle, 16*player->mo->scale); + fixed_t yo = P_ReturnThrustY(player->mo, player->drawangle, 16*player->mo->scale); + fixed_t zo = 6*player->mo->scale; + fixed_t mu = FixedMul(player->maxdash, player->mo->scale); + fixed_t mu2 = FixedHypot(player->mo->momx, player->mo->momy); + fixed_t ev; + mobj_t *missile = NULL; + if (mu2 < mu) + mu2 = mu; + ev = (50*FRACUNIT - (mu/25))/50; + while (i < 5) + { + missile = P_SpawnMobjFromMobj(player->mo, xo, yo, zo, type); + P_SetTarget(&missile->target, player->mo); + missile->angle = throwang + player->drawangle; + P_Thrust(missile, player->drawangle + ANGLE_90, + P_ReturnThrustY(missile, throwang, mu)); // side to side component + P_Thrust(missile, player->drawangle, mu2); // forward component + P_SetObjectMomZ(missile, (4 + ((i&1)<<1))*FRACUNIT, true); + missile->momz += player->mo->pmomz; + missile->fuse = TICRATE/2; + missile->extravalue2 = ev; + + i++; + throwang += ANG30; + } + if (mobjinfo[type].seesound && missile) + S_StartSound(missile, missile->info->seesound); } - if (mobjinfo[type].seesound && missile) - S_StartSound(missile, missile->info->seesound); } } else if (player->charability2 == CA2_GUNSLINGER && player->panim == PA_ABILITY2) From 8d561334256bc6704634004940fd066aed716b5f Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 2 Aug 2019 20:02:55 +0100 Subject: [PATCH 19/19] Fix old Special Stage failure sounds not always playing. --- src/p_spec.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/p_spec.c b/src/p_spec.c index 3cd0461e2..7e1230528 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4601,7 +4601,10 @@ DoneSection2: if (player->bot) break; if (!(maptol & TOL_NIGHTS) && G_IsSpecialStage(gamemap) && player->nightstime > 6) + { player->nightstime = 6; // Just let P_Ticker take care of the rest. + return; + } // Exit (for FOF exits; others are handled in P_PlayerThink in p_user.c) {