From fb142de49500089011a291a8ef86cc71c1f62e8f Mon Sep 17 00:00:00 2001
From: Alaux <73968015+MrAlaux@users.noreply.github.com>
Date: Sat, 28 Oct 2023 01:24:29 -0300
Subject: [PATCH 01/15] Remove existing `over_under` implementation
---
src/p_map.c | 37 +------------------------------------
src/p_mobj.c | 11 ++---------
src/p_mobj.h | 5 ++---
3 files changed, 5 insertions(+), 48 deletions(-)
diff --git a/src/p_map.c b/src/p_map.c
index 8cb2c83d2..3cc93f959 100644
--- a/src/p_map.c
+++ b/src/p_map.c
@@ -552,14 +552,6 @@ static boolean PIT_CheckThing(mobj_t *thing) // killough 3/26/98: make static
int damage = ((P_Random(pr_skullfly)%8)+1)*tmthing->info->damage;
- // [Nugget]: [crispy] check if attacking skull flies over/under thing
- if (casual_play && over_under) {
- if (tmthing->z > thing->z + thing->height)
- { return true; } // over
- else if (tmthing->z + tmthing->height < thing->z)
- { return true; } // under
- }
-
// [Nugget] Fix lost soul collision
if (casual_play && comp_lscollision && !(thing->flags & MF_SHOOTABLE))
{ return !(thing->flags & MF_SOLID); }
@@ -571,7 +563,7 @@ static boolean PIT_CheckThing(mobj_t *thing) // killough 3/26/98: make static
// [Nugget] Fix forgetful lost soul
if (casual_play && comp_lsamnesia)
- { P_SetMobjState(tmthing, tmthing->info->seestate); }
+ P_SetMobjState(tmthing, tmthing->info->seestate);
else
P_SetMobjState (tmthing, tmthing->info->spawnstate);
@@ -661,33 +653,6 @@ static boolean PIT_CheckThing(mobj_t *thing) // killough 3/26/98: make static
return !solid;
}
- // [Nugget] Allow things to move over/under solid things
- if (casual_play && over_under && (thing->flags & MF_SOLID))
- {
- if (tmthing->z >= thing->z + thing->height) { // Over
- thing->intflags |= MIF_OVERUNDER;
- tmthing->intflags |= MIF_OVERUNDER;
-
- tmfloorz = MAX(thing->z + thing->height, tmfloorz);
- thing->ceilingz = MIN(tmthing->z, thing->ceilingz);
-
- return true;
- }
- else if (tmthing->z + tmthing->height <= thing->z) { // Under
- thing->intflags |= MIF_OVERUNDER;
- tmthing->intflags |= MIF_OVERUNDER;
-
- tmceilingz = MIN(thing->z, tmceilingz);
- thing->floorz = MAX(tmthing->z + tmthing->height, thing->floorz);
-
- return true;
- }
- else {
- thing->intflags &= ~MIF_OVERUNDER;
- tmthing->intflags &= ~MIF_OVERUNDER;
- }
- }
-
// RjY
// comperr_hangsolid, an attempt to handle blocking hanging bodies
// A solid hanging body will allow sufficiently small things underneath it.
diff --git a/src/p_mobj.c b/src/p_mobj.c
index 4b80abd3f..c3038b3a6 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -145,8 +145,7 @@ void P_XYMovement (mobj_t* mo)
fixed_t oldx,oldy; // phares 9/10/98: reducing bobbing/momentum on ice
- if (!(mo->momx | mo->momy) // Any momentum?
- && !(mo->intflags & MIF_OVERUNDER)) // [Nugget]
+ if (!(mo->momx | mo->momy)) // Any momentum?
{
if (mo->flags & MF_SKULLFLY)
{
@@ -774,14 +773,8 @@ void P_MobjThinker (mobj_t* mobj)
// removed old code which looked at target references
// (we use pointer reference counting now)
- // [Nugget] Things with both MF_SKULLFLY and MIF_OVERUNDER
- // have buggy behavior, so take the latter away
- if ((mobj->flags & MF_SKULLFLY) && (mobj->intflags & MIF_OVERUNDER))
- { mobj->intflags &= ~MIF_OVERUNDER; }
-
// momentum movement
- if (mobj->momx | mobj->momy || mobj->flags & MF_SKULLFLY
- || mobj->intflags & MIF_OVERUNDER) // [Nugget]
+ if (mobj->momx | mobj->momy || mobj->flags & MF_SKULLFLY)
{
P_XYMovement(mobj);
mobj->intflags &= ~MIF_SCROLLING;
diff --git a/src/p_mobj.h b/src/p_mobj.h
index 8dd355beb..e60c6a53a 100644
--- a/src/p_mobj.h
+++ b/src/p_mobj.h
@@ -235,9 +235,8 @@ enum {
MIF_FLIP = 16,
// [Nugget]
MIF_CROUCHING = 32, // Mobj (player) is crouching
- MIF_OVERUNDER = 64, // Mobj is over/under another mobj
- MIF_EXTRASPAWNED = 128, // [So Doom] Nightmare-spawned, Icon of Sin-spawned and Archvile-resurrected monsters
- MIF_CHEESE = 256,
+ MIF_EXTRASPAWNED = 64, // [So Doom] Nightmare-spawned, Icon of Sin-spawned and Archvile-resurrected monsters
+ MIF_CHEESE = 128,
};
// Map Object definition.
From a46e795674edef380ea2c28b18882ad68546a3f3 Mon Sep 17 00:00:00 2001
From: Alaux <73968015+MrAlaux@users.noreply.github.com>
Date: Sat, 28 Oct 2023 18:59:40 -0300
Subject: [PATCH 02/15] New `over_under` implementation, from DSDA
Issues so far:
- The check for being on a mobj fails every other tic, resulting in less friction and choppy bobbing while moving on things
- The player can get stuck in things if crouching while on them
- Lift-lowered (and raised?) things can clip into other things
---
src/p_map.c | 157 +++++++++++++++++++++++++++++++++++++++++++++++++++
src/p_map.h | 2 +
src/p_mobj.c | 58 ++++++++++++++++++-
src/p_mobj.h | 3 +-
src/p_user.c | 9 ++-
5 files changed, 222 insertions(+), 7 deletions(-)
diff --git a/src/p_map.c b/src/p_map.c
index 3cc93f959..1ee952d62 100644
--- a/src/p_map.c
+++ b/src/p_map.c
@@ -543,6 +543,15 @@ static boolean PIT_CheckThing(mobj_t *thing) // killough 3/26/98: make static
return true;
}
+ // [Nugget]: [DSDA] check if a mobj passed over/under another object
+ if (casual_play && over_under
+ && (tmthing->flags & MF_SOLID) && !(thing->flags & MF_SPECIAL)
+ && ( ( thing->z + thing->height <= tmthing->z) // Over
+ || (tmthing->z + tmthing->height < thing->z))) // Under
+ {
+ return true;
+ }
+
// check for skulls slamming into things
if (tmthing->flags & MF_SKULLFLY)
@@ -2445,6 +2454,154 @@ void P_MapEnd(void)
tmthing = NULL;
}
+// [Nugget]: [DSDA] heretic /-------------------------------------------------
+
+mobj_t *onmobj;
+
+boolean PIT_CheckOnmobjZ(mobj_t *thing)
+{
+ fixed_t blockdist;
+
+ if (!(thing->flags & (MF_SOLID|MF_SPECIAL|MF_SHOOTABLE)))
+ { return true; } // Can't hit thing
+
+ blockdist = thing->radius + tmthing->radius;
+
+ if (abs(thing->x - tmx) >= blockdist || abs(thing->y - tmy) >= blockdist)
+ { return true; } // Didn't hit thing
+
+ if (thing == tmthing)
+ { return true; } // Don't clip against self
+
+ if ( ( thing->z + thing->height <= tmthing->z) // Over thing
+ || (tmthing->z + tmthing->height < thing->z)) // Under thing
+ { return true; }
+
+ if (thing->flags & MF_SOLID)
+ { onmobj = thing; }
+
+ return (!(thing->flags & MF_SOLID));
+}
+
+void P_FakeZMovement(mobj_t *mo)
+{
+ int dist;
+ int delta;
+
+ // Adjust height
+ mo->z += mo->momz;
+ if (mo->flags & MF_FLOAT && mo->target)
+ {
+ // Float down towards target if too close
+ if (!(mo->flags & MF_SKULLFLY) && !(mo->flags & MF_INFLOAT))
+ {
+ dist = P_AproxDistance(mo->x - mo->target->x, mo->y - mo->target->y);
+ delta = (mo->target->z + (mo->height >> 1)) - mo->z;
+
+ if (delta < 0 && dist < -(delta * 3)) { mo->z -= FLOATSPEED; }
+ else if (delta > 0 && dist < (delta * 3)) { mo->z += FLOATSPEED; }
+ }
+ }
+
+ // Clip movement
+ if (mo->z <= mo->floorz)
+ {
+ // Hit the floor
+
+ mo->z = mo->floorz;
+
+ if (mo->momz < 0) { mo->momz = 0; }
+
+ if (mo->flags & MF_SKULLFLY)
+ { mo->momz = -mo->momz; } // The skull slammed into something
+ }
+ else if (mo->flags2 & MF2_LOGRAV)
+ {
+ if (mo->momz == 0) { mo->momz = -(GRAVITY >> 3) * 2; }
+ else { mo->momz -= GRAVITY >> 3; }
+ }
+ else if (!(mo->flags & MF_NOGRAVITY))
+ {
+ if (mo->momz == 0) { mo->momz = -GRAVITY * 2; }
+ else { mo->momz -= GRAVITY; }
+ }
+
+ if (mo->z + mo->height > mo->ceilingz)
+ {
+ // Hit the ceiling
+
+ mo->z = mo->ceilingz - mo->height;
+
+ if (mo->momz > 0) { mo->momz = 0; }
+
+ if (mo->flags & MF_SKULLFLY)
+ { mo->momz = -mo->momz; } // The skull slammed into something
+ }
+}
+
+// Checks if the new Z position is legal
+mobj_t *P_CheckOnmobj(mobj_t *thing)
+{
+ int xl, xh, yl, yh, bx, by;
+ subsector_t *newsubsec;
+ fixed_t x;
+ fixed_t y;
+ mobj_t oldmo;
+
+ x = thing->x;
+ y = thing->y;
+ tmthing = thing;
+ tmflags = thing->flags;
+ oldmo = *thing; // Save the old mobj before the fake zmovement
+ P_FakeZMovement(tmthing);
+
+ tmx = x;
+ tmy = y;
+
+ tmbbox[BOXTOP] = y + tmthing->radius;
+ tmbbox[BOXBOTTOM] = y - tmthing->radius;
+ tmbbox[BOXRIGHT] = x + tmthing->radius;
+ tmbbox[BOXLEFT] = x - tmthing->radius;
+
+ newsubsec = R_PointInSubsector(x, y);
+ ceilingline = NULL;
+
+ // The base floor / ceiling is from the subsector that contains the
+ // point. Any contacted lines the step closer together will adjust them
+ tmfloorz = tmdropoffz = newsubsec->sector->floorheight;
+ tmceilingz = newsubsec->sector->ceilingheight;
+
+ validcount++;
+ numspechit = 0;
+
+ if (tmflags & MF_NOCLIP) {
+ *tmthing = oldmo;
+ return NULL;
+ }
+
+ // Check things first, possibly picking things up
+ // the bounding box is extended by MAXRADIUS because mobj_ts are grouped
+ // into mapblocks based on their origin point, and can overlap into adjacent
+ // blocks by up to MAXRADIUS units
+ xl = (tmbbox[BOXLEFT] - bmaporgx - MAXRADIUS) >> MAPBLOCKSHIFT;
+ xh = (tmbbox[BOXRIGHT] - bmaporgx + MAXRADIUS) >> MAPBLOCKSHIFT;
+ yl = (tmbbox[BOXBOTTOM] - bmaporgy - MAXRADIUS) >> MAPBLOCKSHIFT;
+ yh = (tmbbox[BOXTOP] - bmaporgy + MAXRADIUS) >> MAPBLOCKSHIFT;
+
+ for (bx = xl; bx <= xh; bx++)
+ for (by = yl; by <= yh; by++)
+ if (!P_BlockThingsIterator(bx, by, PIT_CheckOnmobjZ))
+ {
+ *tmthing = oldmo;
+ return onmobj;
+ }
+
+ *tmthing = oldmo;
+ return NULL;
+}
+
+// [Nugget] -----------------------------------------------------------------/
+
// [FG] SPECHITS overflow emulation from Chocolate Doom / PrBoom+
static void SpechitOverrun(line_t *ld)
diff --git a/src/p_map.h b/src/p_map.h
index df0171fb5..ad591fafd 100644
--- a/src/p_map.h
+++ b/src/p_map.h
@@ -78,6 +78,8 @@ extern msecnode_t *sector_list; // phares 3/16/98
extern fixed_t tmbbox[4]; // phares 3/20/98
extern line_t *blockline; // killough 8/11/98
+mobj_t *P_CheckOnmobj(mobj_t *thing); // [Nugget]: [DSDA]
+
extern boolean boomshot; // [Nugget] Explosive hitscan cheat
#endif // __P_MAP__
diff --git a/src/p_mobj.c b/src/p_mobj.c
index c3038b3a6..100626163 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -292,8 +292,10 @@ void P_XYMovement (mobj_t* mo)
// no friction for missiles or skulls ever, no friction when airborne
if (mo->flags & (MF_MISSILE | MF_SKULLFLY)
- // [Nugget] Do apply friction if airborne with the flight cheat on
- || (!(player && player->cheats & CF_FLY) && (mo->z > mo->floorz)))
+ // [Nugget] Do apply friction if...
+ || ((mo->z > mo->floorz)
+ && !( (player && player->cheats & CF_FLY) // ... using flight cheat
+ || (mo->intflags & MIF_ONMOBJ)))) // ... on top of a mobj
return;
// killough 8/11/98: add bouncers
@@ -784,7 +786,57 @@ void P_MobjThinker (mobj_t* mobj)
if (mobj->z != mobj->floorz || mobj->momz)
{
- P_ZMovement(mobj);
+ // [Nugget]
+ if (casual_play && over_under && (mobj->flags & MF_SOLID))
+ {
+ mobj_t *onmo;
+
+ if (!(onmo = P_CheckOnmobj(mobj)))
+ {
+ P_ZMovement(mobj);
+ mobj->intflags &= ~MIF_ONMOBJ;
+ }
+ else
+ {
+ if (mobj->player)
+ {
+ if (mobj->momz < 0)
+ {
+ mobj->intflags |= MIF_ONMOBJ;
+ mobj->momz = 0;
+ }
+
+ if (onmo->player)
+ {
+ mobj->momx = onmo->momx;
+ mobj->momy = onmo->momy;
+
+ if (onmo->z < onmo->floorz)
+ {
+ mobj->z += onmo->floorz - onmo->z;
+
+ onmo->player->viewheight -= onmo->floorz - onmo->z;
+ onmo->player->deltaviewheight = ((!strictmode ? viewheight_value*FRACUNIT : VIEWHEIGHT)
+ - onmo->player->viewheight) >> 3;
+
+ onmo->z = onmo->floorz;
+ }
+ }
+ }
+ else {
+ mobj->momz = 0;
+
+ if (onmo->z + onmo->height - mobj->z <= 24 * FRACUNIT)
+ {
+ mobj->z = onmo->z + onmo->height;
+ mobj->intflags |= MIF_ONMOBJ;
+ }
+ }
+ }
+ }
+ else
+ P_ZMovement(mobj);
+
if (mobj->thinker.function.p1 == (actionf_p1)P_RemoveThinkerDelayed) // killough
return; // mobj was removed
}
diff --git a/src/p_mobj.h b/src/p_mobj.h
index e60c6a53a..87e30701c 100644
--- a/src/p_mobj.h
+++ b/src/p_mobj.h
@@ -235,8 +235,9 @@ enum {
MIF_FLIP = 16,
// [Nugget]
MIF_CROUCHING = 32, // Mobj (player) is crouching
- MIF_EXTRASPAWNED = 64, // [So Doom] Nightmare-spawned, Icon of Sin-spawned and Archvile-resurrected monsters
+ MIF_EXTRASPAWNED = 64, // [So Doom] Nightmare-spawned, Icon of Sin-spawned and Archvile-resurrected monsters
MIF_CHEESE = 128,
+ MIF_ONMOBJ = 256, // [DSDA] mobj is resting on top of another
};
// Map Object definition.
diff --git a/src/p_user.c b/src/p_user.c
index ba417f11c..9fec98a2d 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -221,9 +221,11 @@ void P_MovePlayer (player_t* player)
int cforwardmove, csidemove;
mo->angle += cmd->angleturn << 16;
- onground = mo->z <= mo->floorz;
- // [Nugget] Allow mid-air control with noclip or fly enabled
- onground |= ((player->mo->flags & MF_NOCLIP) || (player->cheats & CF_FLY));
+ onground = (mo->z <= mo->floorz
+ // [Nugget]
+ || (casual_play && (mo->intflags & MIF_ONMOBJ)) // [DSDA]
+ // Mid-air control with noclip or flight cheat enabled
+ || (player->mo->flags & MF_NOCLIP) || (player->cheats & CF_FLY));
// [Nugget]
if (player->cheats & CF_FLY)
@@ -269,6 +271,7 @@ void P_MovePlayer (player_t* player)
{ // Jump
player->mo->momz = 8*FRACUNIT;
player->jumptics = 20;
+// player->mo->intflags &= ~MIF_ONMOBJ; // [DSDA]
// [NS] Jump sound.
S_StartSoundOptional(player->mo, sfx_pljump, -1);
// [crispy] squat down weapon sprite a bit
From 7eee8a528cf906767dadbbb871a4035dd0411743 Mon Sep 17 00:00:00 2001
From: Alaux <73968015+MrAlaux@users.noreply.github.com>
Date: Mon, 30 Oct 2023 04:00:12 -0300
Subject: [PATCH 03/15] Some fixes
Thanks to these, the check for being on a mobj doesn't fail anymore, fixing the reduced friction and choppy bobbing, and seemingly the crouching issue too.
---
src/p_map.c | 14 +++++++-------
src/p_mobj.c | 39 +++++++++------------------------------
2 files changed, 16 insertions(+), 37 deletions(-)
diff --git a/src/p_map.c b/src/p_map.c
index 1ee952d62..dffcdae5f 100644
--- a/src/p_map.c
+++ b/src/p_map.c
@@ -547,7 +547,7 @@ static boolean PIT_CheckThing(mobj_t *thing) // killough 3/26/98: make static
if (casual_play && over_under
&& (tmthing->flags & MF_SOLID) && !(thing->flags & MF_SPECIAL)
&& ( ( thing->z + thing->height <= tmthing->z) // Over
- || (tmthing->z + tmthing->height < thing->z))) // Under
+ || (tmthing->z + tmthing->height <= thing->z))) // Under
{
return true;
}
@@ -2473,8 +2473,8 @@ boolean PIT_CheckOnmobjZ(mobj_t *thing)
if (thing == tmthing)
{ return true; } // Don't clip against self
- if ( ( thing->z + thing->height <= tmthing->z) // Over thing
- || (tmthing->z + tmthing->height < thing->z)) // Under thing
+ if ( ( thing->z + thing->height < tmthing->z) // Over thing
+ || (tmthing->z + tmthing->height < thing->z)) // Under thing
{ return true; }
if (thing->flags & MF_SOLID)
@@ -2517,13 +2517,13 @@ void P_FakeZMovement(mobj_t *mo)
}
else if (mo->flags2 & MF2_LOGRAV)
{
- if (mo->momz == 0) { mo->momz = -(GRAVITY >> 3) * 2; }
- else { mo->momz -= GRAVITY >> 3; }
+ if (!mo->momz) { mo->momz = -(GRAVITY >> 3) * 2; }
+ else { mo->momz -= GRAVITY >> 3; }
}
else if (!(mo->flags & MF_NOGRAVITY))
{
- if (mo->momz == 0) { mo->momz = -GRAVITY * 2; }
- else { mo->momz -= GRAVITY; }
+ if (!mo->momz) { mo->momz = -GRAVITY; }
+ else { mo->momz -= GRAVITY; }
}
if (mo->z + mo->height > mo->ceilingz)
diff --git a/src/p_mobj.c b/src/p_mobj.c
index 100626163..7f73f0fda 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -798,39 +798,18 @@ void P_MobjThinker (mobj_t* mobj)
}
else
{
- if (mobj->player)
- {
- if (mobj->momz < 0)
- {
- mobj->intflags |= MIF_ONMOBJ;
- mobj->momz = 0;
- }
-
- if (onmo->player)
- {
- mobj->momx = onmo->momx;
- mobj->momy = onmo->momy;
-
- if (onmo->z < onmo->floorz)
- {
- mobj->z += onmo->floorz - onmo->z;
+ mobj->momz = 0;
- onmo->player->viewheight -= onmo->floorz - onmo->z;
- onmo->player->deltaviewheight = ((!strictmode ? viewheight_value*FRACUNIT : VIEWHEIGHT)
- - onmo->player->viewheight) >> 3;
-
- onmo->z = onmo->floorz;
- }
+ if (onmo->z + onmo->height - mobj->z <= 24 * FRACUNIT)
+ {
+ if (mobj->player) {
+ mobj->player->viewheight -= onmo->z + onmo->height - mobj->z;
+ mobj->player->deltaviewheight = ((!strictmode ? viewheight_value*FRACUNIT : VIEWHEIGHT)
+ - mobj->player->viewheight) >> 3;
}
- }
- else {
- mobj->momz = 0;
- if (onmo->z + onmo->height - mobj->z <= 24 * FRACUNIT)
- {
- mobj->z = onmo->z + onmo->height;
- mobj->intflags |= MIF_ONMOBJ;
- }
+ mobj->z = onmo->z + onmo->height;
+ mobj->intflags |= MIF_ONMOBJ;
}
}
}
From 420f7a5077a784ba0ff515bbf435596357a5c9c3 Mon Sep 17 00:00:00 2001
From: Alaux <73968015+MrAlaux@users.noreply.github.com>
Date: Mon, 30 Oct 2023 04:14:26 -0300
Subject: [PATCH 04/15] Little cleanup
---
src/p_user.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/p_user.c b/src/p_user.c
index 9fec98a2d..837fc31ce 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -223,7 +223,7 @@ void P_MovePlayer (player_t* player)
mo->angle += cmd->angleturn << 16;
onground = (mo->z <= mo->floorz
// [Nugget]
- || (casual_play && (mo->intflags & MIF_ONMOBJ)) // [DSDA]
+ || (mo->intflags & MIF_ONMOBJ) // [DSDA]
// Mid-air control with noclip or flight cheat enabled
|| (player->mo->flags & MF_NOCLIP) || (player->cheats & CF_FLY));
@@ -271,7 +271,6 @@ void P_MovePlayer (player_t* player)
{ // Jump
player->mo->momz = 8*FRACUNIT;
player->jumptics = 20;
-// player->mo->intflags &= ~MIF_ONMOBJ; // [DSDA]
// [NS] Jump sound.
S_StartSoundOptional(player->mo, sfx_pljump, -1);
// [crispy] squat down weapon sprite a bit
From 3f39013dba33f02fb2b13fad39fbc65146f9041a Mon Sep 17 00:00:00 2001
From: Alaux <73968015+MrAlaux@users.noreply.github.com>
Date: Sun, 26 Nov 2023 07:40:58 -0300
Subject: [PATCH 05/15] Tweaks
Flying things can still get stuck in each other.
---
src/p_map.c | 65 +++++++++++++++++++++-------------------------------
src/p_mobj.c | 2 +-
2 files changed, 27 insertions(+), 40 deletions(-)
diff --git a/src/p_map.c b/src/p_map.c
index 1c79be933..2b7ff2e4e 100644
--- a/src/p_map.c
+++ b/src/p_map.c
@@ -2465,9 +2465,9 @@ void P_MapEnd(void)
// [Nugget]: [DSDA] heretic /-------------------------------------------------
-mobj_t *onmobj;
+static mobj_t *onmobj;
-boolean PIT_CheckOnmobjZ(mobj_t *thing)
+static boolean PIT_CheckOnmobjZ(mobj_t *thing)
{
fixed_t blockdist;
@@ -2489,27 +2489,22 @@ boolean PIT_CheckOnmobjZ(mobj_t *thing)
if (thing->flags & MF_SOLID)
{ onmobj = thing; }
- return (!(thing->flags & MF_SOLID));
+ return !((thing->flags & MF_SOLID && !(thing->flags & MF_NOCLIP))
+ && (tmthing->flags & MF_SOLID || demo_compatibility));
}
-void P_FakeZMovement(mobj_t *mo)
+static void P_FakeZMovement(mobj_t *mo)
{
- int dist;
- int delta;
-
// Adjust height
mo->z += mo->momz;
- if (mo->flags & MF_FLOAT && mo->target)
+
+ // Float down towards target if too close
+ if (!((mo->flags ^ MF_FLOAT) & (MF_FLOAT | MF_SKULLFLY | MF_INFLOAT)) && mo->target)
{
- // Float down towards target if too close
- if (!(mo->flags & MF_SKULLFLY) && !(mo->flags & MF_INFLOAT))
- {
- dist = P_AproxDistance(mo->x - mo->target->x, mo->y - mo->target->y);
- delta = (mo->target->z + (mo->height >> 1)) - mo->z;
+ const fixed_t delta = mo->target->z + (mo->height >> 1) - mo->z;
- if (delta < 0 && dist < -(delta * 3)) { mo->z -= FLOATSPEED; }
- else if (delta > 0 && dist < (delta * 3)) { mo->z += FLOATSPEED; }
- }
+ if (P_AproxDistance(mo->x - mo->target->x, mo->y - mo->target->y) < abs(delta) * 3)
+ { mo->z += (delta < 0) ? -FLOATSPEED : FLOATSPEED; }
}
// Clip movement
@@ -2553,27 +2548,20 @@ mobj_t *P_CheckOnmobj(mobj_t *thing)
{
int xl, xh, yl, yh, bx, by;
subsector_t *newsubsec;
- fixed_t x;
- fixed_t y;
- mobj_t oldmo;
+ mobj_t oldmo = *thing; // Save the old mobj before the fake movement
- x = thing->x;
- y = thing->y;
+ tmx = thing->x;
+ tmy = thing->y;
tmthing = thing;
tmflags = thing->flags;
- oldmo = *thing; // Save the old mobj before the fake zmovement
- P_FakeZMovement(tmthing);
-
- tmx = x;
- tmy = y;
- tmbbox[BOXTOP] = y + tmthing->radius;
- tmbbox[BOXBOTTOM] = y - tmthing->radius;
- tmbbox[BOXRIGHT] = x + tmthing->radius;
- tmbbox[BOXLEFT] = x - tmthing->radius;
+ tmbbox[BOXTOP] = tmy + tmthing->radius;
+ tmbbox[BOXBOTTOM] = tmy - tmthing->radius;
+ tmbbox[BOXRIGHT] = tmx + tmthing->radius;
+ tmbbox[BOXLEFT] = tmx - tmthing->radius;
- newsubsec = R_PointInSubsector(x, y);
- ceilingline = NULL;
+ newsubsec = R_PointInSubsector(tmx, tmy);
+ floorline = blockline = ceilingline = NULL;
// The base floor / ceiling is from the subsector that contains the
// point. Any contacted lines the step closer together will adjust them
@@ -2583,19 +2571,18 @@ mobj_t *P_CheckOnmobj(mobj_t *thing)
validcount++;
numspechit = 0;
- if (tmflags & MF_NOCLIP) {
- *tmthing = oldmo;
- return NULL;
- }
+ if (tmflags & MF_NOCLIP) { return NULL; }
// Check things first, possibly picking things up
// the bounding box is extended by MAXRADIUS because mobj_ts are grouped
// into mapblocks based on their origin point, and can overlap into adjacent
// blocks by up to MAXRADIUS units
- xl = (tmbbox[BOXLEFT] - bmaporgx - MAXRADIUS) >> MAPBLOCKSHIFT;
- xh = (tmbbox[BOXRIGHT] - bmaporgx + MAXRADIUS) >> MAPBLOCKSHIFT;
+ xl = (tmbbox[BOXLEFT] - bmaporgx - MAXRADIUS) >> MAPBLOCKSHIFT;
+ xh = (tmbbox[BOXRIGHT] - bmaporgx + MAXRADIUS) >> MAPBLOCKSHIFT;
yl = (tmbbox[BOXBOTTOM] - bmaporgy - MAXRADIUS) >> MAPBLOCKSHIFT;
- yh = (tmbbox[BOXTOP] - bmaporgy + MAXRADIUS) >> MAPBLOCKSHIFT;
+ yh = (tmbbox[BOXTOP] - bmaporgy + MAXRADIUS) >> MAPBLOCKSHIFT;
+
+ P_FakeZMovement(tmthing);
for (bx = xl; bx <= xh; bx++)
for (by = yl; by <= yh; by++)
diff --git a/src/p_mobj.c b/src/p_mobj.c
index 8dd76bd4c..94d772e2b 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -789,7 +789,7 @@ void P_MobjThinker (mobj_t* mobj)
if (mobj->z != mobj->floorz || mobj->momz)
{
- // [Nugget]
+ // [Nugget]: [DSDA]
if (casual_play && over_under && (mobj->flags & MF_SOLID))
{
mobj_t *onmo;
From 1e60f242861af2ef9bcef7e4712d1e3786f02e80 Mon Sep 17 00:00:00 2001
From: Alaux <73968015+MrAlaux@users.noreply.github.com>
Date: Sun, 26 Nov 2023 08:22:42 -0300
Subject: [PATCH 06/15] Add checks in `P_Move()`
The `z` movement in `P_Move()` would seemingly not account for the possibility of things being over/under other things. This commit appears to fix that.
---
src/p_enemy.c | 16 +++++++++++++++-
src/p_map.c | 4 +++-
2 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/src/p_enemy.c b/src/p_enemy.c
index 762a0454b..dc65d4e72 100644
--- a/src/p_enemy.c
+++ b/src/p_enemy.c
@@ -407,11 +407,25 @@ static boolean P_Move(mobj_t *actor, boolean dropoff) // killough 9/12/98
if (actor->flags & MF_FLOAT && floatok)
{
+ const mobj_t *onmo; // [Nugget]
+
if (actor->z < tmfloorz) // must adjust height
- actor->z += FLOATSPEED;
+ {
+ actor->z += FLOATSPEED;
+
+ // [Nugget]
+ if ((onmo = P_CheckOnmobj(actor)))
+ { actor->z = onmo->z - actor->height; }
+ }
else
+ {
actor->z -= FLOATSPEED;
+ // [Nugget]
+ if ((onmo = P_CheckOnmobj(actor)))
+ { actor->z = onmo->z + onmo->height; }
+ }
+
actor->flags |= MF_INFLOAT;
return true;
diff --git a/src/p_map.c b/src/p_map.c
index 2b7ff2e4e..5ed314ae7 100644
--- a/src/p_map.c
+++ b/src/p_map.c
@@ -2548,7 +2548,9 @@ mobj_t *P_CheckOnmobj(mobj_t *thing)
{
int xl, xh, yl, yh, bx, by;
subsector_t *newsubsec;
- mobj_t oldmo = *thing; // Save the old mobj before the fake movement
+ const mobj_t oldmo = *thing; // Save the old mobj before the fake movement
+
+ if (!(casual_play && over_under)) { return NULL; }
tmx = thing->x;
tmy = thing->y;
From 8eb4afbbe2471b59d0a391e442d6ffd2d66bae50 Mon Sep 17 00:00:00 2001
From: Alaux <73968015+MrAlaux@users.noreply.github.com>
Date: Sun, 26 Nov 2023 20:26:45 -0300
Subject: [PATCH 07/15] Don't perform fake movement for `P_Move()` checks
---
src/p_enemy.c | 4 ++--
src/p_map.c | 4 ++--
src/p_map.h | 2 +-
src/p_mobj.c | 2 +-
4 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/p_enemy.c b/src/p_enemy.c
index dc65d4e72..016244e9e 100644
--- a/src/p_enemy.c
+++ b/src/p_enemy.c
@@ -414,7 +414,7 @@ static boolean P_Move(mobj_t *actor, boolean dropoff) // killough 9/12/98
actor->z += FLOATSPEED;
// [Nugget]
- if ((onmo = P_CheckOnmobj(actor)))
+ if ((onmo = P_CheckOnmobj(actor, false)))
{ actor->z = onmo->z - actor->height; }
}
else
@@ -422,7 +422,7 @@ static boolean P_Move(mobj_t *actor, boolean dropoff) // killough 9/12/98
actor->z -= FLOATSPEED;
// [Nugget]
- if ((onmo = P_CheckOnmobj(actor)))
+ if ((onmo = P_CheckOnmobj(actor, false)))
{ actor->z = onmo->z + onmo->height; }
}
diff --git a/src/p_map.c b/src/p_map.c
index 5ed314ae7..3233c3204 100644
--- a/src/p_map.c
+++ b/src/p_map.c
@@ -2544,7 +2544,7 @@ static void P_FakeZMovement(mobj_t *mo)
}
// Checks if the new Z position is legal
-mobj_t *P_CheckOnmobj(mobj_t *thing)
+mobj_t *P_CheckOnmobj(mobj_t *thing, boolean fakemove)
{
int xl, xh, yl, yh, bx, by;
subsector_t *newsubsec;
@@ -2584,7 +2584,7 @@ mobj_t *P_CheckOnmobj(mobj_t *thing)
yl = (tmbbox[BOXBOTTOM] - bmaporgy - MAXRADIUS) >> MAPBLOCKSHIFT;
yh = (tmbbox[BOXTOP] - bmaporgy + MAXRADIUS) >> MAPBLOCKSHIFT;
- P_FakeZMovement(tmthing);
+ if (fakemove) { P_FakeZMovement(tmthing); }
for (bx = xl; bx <= xh; bx++)
for (by = yl; by <= yh; by++)
diff --git a/src/p_map.h b/src/p_map.h
index ad591fafd..f92f60524 100644
--- a/src/p_map.h
+++ b/src/p_map.h
@@ -78,7 +78,7 @@ extern msecnode_t *sector_list; // phares 3/16/98
extern fixed_t tmbbox[4]; // phares 3/20/98
extern line_t *blockline; // killough 8/11/98
-mobj_t *P_CheckOnmobj(mobj_t *thing); // [Nugget]: [DSDA]
+mobj_t *P_CheckOnmobj(mobj_t *thing, boolean fakemove); // [Nugget]: [DSDA]
extern boolean boomshot; // [Nugget] Explosive hitscan cheat
diff --git a/src/p_mobj.c b/src/p_mobj.c
index 94d772e2b..c87db2a0e 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -794,7 +794,7 @@ void P_MobjThinker (mobj_t* mobj)
{
mobj_t *onmo;
- if (!(onmo = P_CheckOnmobj(mobj)))
+ if (!(onmo = P_CheckOnmobj(mobj, true)))
{
P_ZMovement(mobj);
mobj->intflags &= ~MIF_ONMOBJ;
From 97980507ee45f791ce0a5d27a5a1553b79e2d23f Mon Sep 17 00:00:00 2001
From: Alaux <73968015+MrAlaux@users.noreply.github.com>
Date: Tue, 28 Nov 2023 04:02:10 -0300
Subject: [PATCH 08/15] `P_Move()`: Do horiz. move if vert. is blocked
---
src/p_enemy.c | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/src/p_enemy.c b/src/p_enemy.c
index 016244e9e..9d4abc6d5 100644
--- a/src/p_enemy.c
+++ b/src/p_enemy.c
@@ -407,13 +407,15 @@ static boolean P_Move(mobj_t *actor, boolean dropoff) // killough 9/12/98
if (actor->flags & MF_FLOAT && floatok)
{
- const mobj_t *onmo; // [Nugget]
+ // [Nugget] Over/Under
+ const mobj_t *onmo;
+ const fixed_t oldz = actor->z;
if (actor->z < tmfloorz) // must adjust height
{
actor->z += FLOATSPEED;
- // [Nugget]
+ // [Nugget] Don't ascend into other things
if ((onmo = P_CheckOnmobj(actor, false)))
{ actor->z = onmo->z - actor->height; }
}
@@ -421,14 +423,17 @@ static boolean P_Move(mobj_t *actor, boolean dropoff) // killough 9/12/98
{
actor->z -= FLOATSPEED;
- // [Nugget]
+ // [Nugget] Don't descend into other things
if ((onmo = P_CheckOnmobj(actor, false)))
{ actor->z = onmo->z + onmo->height; }
}
- actor->flags |= MF_INFLOAT;
-
- return true;
+ // [Nugget] Conditions: only if we actually moved
+ if (casual_play && actor->z != oldz)
+ {
+ actor->flags |= MF_INFLOAT;
+ return true;
+ }
}
if (!numspechit)
From a645004f190829133cd24f68cdba8434553d0c6b Mon Sep 17 00:00:00 2001
From: Alaux <73968015+MrAlaux@users.noreply.github.com>
Date: Tue, 28 Nov 2023 05:14:26 -0300
Subject: [PATCH 09/15] Allow player-only over/under
---
src/m_menu.c | 8 ++++++--
src/m_misc.c | 4 ++--
src/p_map.c | 1 +
3 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/src/m_menu.c b/src/m_menu.c
index 3b776a2b0..200e79ddd 100644
--- a/src/m_menu.c
+++ b/src/m_menu.c
@@ -4840,6 +4840,10 @@ setup_menu_t gen_settings5[] = { // General Settings screen5
// [Nugget] /-----------------------------------------------------------------
+static const char *over_under_str[] = {
+ "Off", "Player Only", "All Things", NULL
+};
+
static const char *impact_pitch_str[] = {
"Off", "Fall", "Damage", "Both", NULL
};
@@ -4852,8 +4856,8 @@ setup_menu_t gen_settings6[] = {
{"Nugget - Gameplay", S_SKIP|S_TITLE, m_null, M_X, M_Y + gen6_title1 * M_SPC},
- {"Things Move Over/Under Things", S_YESNO|S_STRICT|S_CRITICAL, m_null, M_X, M_Y + gen6_overunder * M_SPC, {"over_under"}},
- {"Allow Jumping/Crouching", S_YESNO|S_STRICT|S_CRITICAL, m_null, M_X, M_Y + gen6_jump_crouch * M_SPC, {"jump_crouch"}},
+ {"Move Over/Under Things", S_CHOICE|S_STRICT|S_CRITICAL, m_null, M_X, M_Y + gen6_overunder * M_SPC, {"over_under"}, 0, NULL, over_under_str},
+ {"Allow Jumping/Crouching", S_YESNO |S_STRICT|S_CRITICAL, m_null, M_X, M_Y + gen6_jump_crouch * M_SPC, {"jump_crouch"}},
{"", S_SKIP, m_null, M_X, M_Y + gen6_stub1 * M_SPC},
{"Nugget - View", S_SKIP|S_TITLE, m_null, M_X, M_Y + gen6_title2 * M_SPC},
diff --git a/src/m_misc.c b/src/m_misc.c
index bb3f0895e..4a6b84347 100644
--- a/src/m_misc.c
+++ b/src/m_misc.c
@@ -719,8 +719,8 @@ default_t defaults[] = {
{
"over_under",
(config_t *) &over_under, NULL,
- {0}, {0,1}, number, ss_gen, wad_yes,
- "1 to allow things to move over/under other things"
+ {0}, {0,2}, number, ss_gen, wad_yes,
+ "Allow movement over/under things (1 = Player only, 2 = All things)"
},
{
diff --git a/src/p_map.c b/src/p_map.c
index 3233c3204..ae30406bc 100644
--- a/src/p_map.c
+++ b/src/p_map.c
@@ -546,6 +546,7 @@ static boolean PIT_CheckThing(mobj_t *thing) // killough 3/26/98: make static
// [Nugget]: [DSDA] check if a mobj passed over/under another object
if (casual_play && over_under
&& (tmthing->flags & MF_SOLID) && !(thing->flags & MF_SPECIAL)
+ && ((over_under == 2) || tmthing->player || thing->player)
&& ( ( thing->z + thing->height <= tmthing->z) // Over
|| (tmthing->z + tmthing->height <= thing->z))) // Under
{
From 734be5a589c8ec7e216bd2293bb44089a465c369 Mon Sep 17 00:00:00 2001
From: Alaux <73968015+MrAlaux@users.noreply.github.com>
Date: Thu, 7 Dec 2023 01:31:34 -0300
Subject: [PATCH 10/15] The Grand Rework
Instead of using a flag, mobjs now have pointers to the mobjs right below and above them.
Thanks to this, lift logic has been improved, and non-player mobjs can actually walk on other mobjs now.
---
src/p_enemy.c | 27 ++++--
src/p_map.c | 239 ++++++++++++++++++++++++++++++++++++++++++--------
src/p_map.h | 8 +-
src/p_mobj.c | 59 +++++++++----
src/p_mobj.h | 1 -
src/p_user.c | 3 +-
6 files changed, 273 insertions(+), 64 deletions(-)
diff --git a/src/p_enemy.c b/src/p_enemy.c
index 9d4abc6d5..d72a15903 100644
--- a/src/p_enemy.c
+++ b/src/p_enemy.c
@@ -408,28 +408,33 @@ static boolean P_Move(mobj_t *actor, boolean dropoff) // killough 9/12/98
if (actor->flags & MF_FLOAT && floatok)
{
// [Nugget] Over/Under
- const mobj_t *onmo;
const fixed_t oldz = actor->z;
if (actor->z < tmfloorz) // must adjust height
{
actor->z += FLOATSPEED;
- // [Nugget] Don't ascend into other things
- if ((onmo = P_CheckOnmobj(actor, false)))
- { actor->z = onmo->z - actor->height; }
+ // [Nugget] Over/Under: don't ascend into other things
+ if (actor->above_thing
+ && (actor->above_thing->z < (actor->z + actor->height)))
+ {
+ actor->z = actor->above_thing->z - actor->height;
+ }
}
else
{
actor->z -= FLOATSPEED;
- // [Nugget] Don't descend into other things
- if ((onmo = P_CheckOnmobj(actor, false)))
- { actor->z = onmo->z + onmo->height; }
+ // [Nugget] Over/Under: don't descend into other things
+ if (actor->below_thing
+ && (actor->z < (actor->below_thing->z + actor->below_thing->height)))
+ {
+ actor->z = actor->below_thing->z + actor->below_thing->height;
+ }
}
// [Nugget] Conditions: only if we actually moved
- if (casual_play && actor->z != oldz)
+ if (NOTCASUALPLAY(actor->z != oldz))
{
actor->flags |= MF_INFLOAT;
return true;
@@ -479,8 +484,14 @@ static boolean P_Move(mobj_t *actor, boolean dropoff) // killough 9/12/98
// killough 11/98: fall more slowly, under gravity, if felldown==true
if (!(actor->flags & MF_FLOAT) && (!felldown || demo_version < 203))
+ {
actor->z = actor->floorz;
+ // [Nugget] Over/Under
+ if (actor->below_thing)
+ { actor->z = MAX(actor->floorz, actor->below_thing->z + actor->below_thing->height); }
+ }
+
return true;
}
diff --git a/src/p_map.c b/src/p_map.c
index ae30406bc..5e5b505fe 100644
--- a/src/p_map.c
+++ b/src/p_map.c
@@ -494,6 +494,11 @@ static boolean P_ProjectileImmune(mobj_t *target, mobj_t *source)
);
}
+// [Nugget] Over/Under: potential over/under mobjs
+static mobj_t *p_below_tmthing, *p_above_tmthing, // For `tmthing`
+ *p_below_thing_s, *p_above_thing_s, // For `thing` ("setter")
+ *p_below_thing_g, *p_above_thing_g; // `thing` itself ("getter")
+
static boolean PIT_CheckThing(mobj_t *thing) // killough 3/26/98: make static
{
fixed_t blockdist;
@@ -546,11 +551,46 @@ static boolean PIT_CheckThing(mobj_t *thing) // killough 3/26/98: make static
// [Nugget]: [DSDA] check if a mobj passed over/under another object
if (casual_play && over_under
&& (tmthing->flags & MF_SOLID) && !(thing->flags & MF_SPECIAL)
- && ((over_under == 2) || tmthing->player || thing->player)
- && ( ( thing->z + thing->height <= tmthing->z) // Over
- || (tmthing->z + tmthing->height <= thing->z))) // Under
+ && ((over_under == 2) || tmthing->player || thing->player))
{
- return true;
+ if (thing->z + thing->height <= tmthing->z)
+ {
+ // Over
+
+ if ((!p_below_tmthing)
+ || ((p_below_tmthing->z + p_below_tmthing->height) < (thing->z + thing->height)))
+ {
+ p_below_tmthing = thing;
+ }
+
+ if ((!p_above_thing_s)
+ || (tmthing->z < p_above_thing_s->z))
+ {
+ p_above_thing_s = tmthing;
+ p_above_thing_g = thing;
+ }
+
+ return true;
+ }
+ else if (tmthing->z + tmthing->height <= thing->z)
+ {
+ // Under
+
+ if ((!p_above_tmthing)
+ || (thing->z < p_above_tmthing->z))
+ {
+ p_above_tmthing = thing;
+ }
+
+ if ((!p_below_thing_s)
+ || ((p_below_thing_s->z + p_below_thing_s->height) < (tmthing->z + tmthing->height)))
+ {
+ p_below_thing_s = tmthing;
+ p_below_thing_g = thing;
+ }
+
+ return true;
+ }
}
// check for skulls slamming into things
@@ -811,6 +851,10 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
yl = (tmbbox[BOXBOTTOM] - bmaporgy - MAXRADIUS)>>MAPBLOCKSHIFT;
yh = (tmbbox[BOXTOP] - bmaporgy + MAXRADIUS)>>MAPBLOCKSHIFT;
+ // [Nugget] Over/Under
+ p_below_tmthing = p_below_thing_s = p_below_thing_g =
+ p_above_tmthing = p_above_thing_s = p_above_thing_g = NULL;
+
for (bx=xl ; bx<=xh ; bx++)
for (by=yl ; by<=yh ; by++)
if (!P_BlockThingsIterator(bx,by,PIT_CheckThing))
@@ -856,6 +900,30 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean dropoff)
if (!P_CheckPosition(thing, x, y))
return false; // solid wall or thing
+ // [Nugget] Over/Under: if move was valid, set new over/under mobjs
+ if (casual_play && over_under)
+ {
+ mobj_t *pbtg = p_below_thing_g ? p_below_thing_g->below_thing : NULL,
+ *pbts = p_below_thing_s,
+ *patg = p_above_thing_g ? p_above_thing_g->above_thing : NULL,
+ *pats = p_above_thing_s;
+
+ thing->below_thing = p_below_tmthing;
+ thing->above_thing = p_above_tmthing;
+
+ if (p_below_thing_g
+ && ((!pbtg) || ((pbtg->z + pbtg->height) < (pbts->z + pbts->height))))
+ {
+ p_below_thing_g->below_thing = p_below_thing_s;
+ }
+
+ if (p_above_thing_g
+ && ((!patg) || (pats->z < patg->z)))
+ {
+ p_above_thing_g->above_thing = p_above_thing_s;
+ }
+ }
+
if (!(thing->flags & MF_NOCLIP))
{
// killough 7/26/98: reformatted slightly
@@ -1101,8 +1169,42 @@ static boolean P_ThingHeightClip(mobj_t *thing)
if (onfloor) // walking monsters rise and fall with the floor
{
+ // [Nugget] Over/Under
+ const fixed_t oldz = thing->z;
+
thing->z = thing->floorz;
+ if (casual_play && over_under)
+ {
+ if (thing->z < oldz && thing->below_thing)
+ { thing->z = MAX(thing->z, thing->below_thing->z + thing->below_thing->height); }
+
+ if (oldz < thing->z)
+ {
+ mobj_t *below_thing = thing, *above_thing;
+
+ do {
+ if ((above_thing = below_thing->above_thing))
+ {
+ above_thing->z = MAX(above_thing->z, below_thing->z + below_thing->height);
+ }
+ } while ((below_thing = below_thing->above_thing));
+ }
+ else if (thing->z < oldz)
+ {
+ mobj_t *below_thing = thing, *above_thing;
+ const fixed_t diff = oldz - thing->z;
+
+ do {
+ if ((above_thing = below_thing->above_thing)
+ && ((above_thing->z - diff) == (below_thing->z + below_thing->height)))
+ {
+ above_thing->z = below_thing->z + below_thing->height;
+ }
+ } while ((below_thing = below_thing->above_thing));
+ }
+ }
+
// killough 11/98: Possibly upset balance of objects hanging off ledges
if (thing->intflags & MIF_FALLING && thing->gear >= MAXGEAR)
thing->gear = 0;
@@ -2466,36 +2568,12 @@ void P_MapEnd(void)
// [Nugget]: [DSDA] heretic /-------------------------------------------------
-static mobj_t *onmobj;
-
-static boolean PIT_CheckOnmobjZ(mobj_t *thing)
-{
- fixed_t blockdist;
-
- if (!(thing->flags & (MF_SOLID|MF_SPECIAL|MF_SHOOTABLE)))
- { return true; } // Can't hit thing
-
- blockdist = thing->radius + tmthing->radius;
-
- if (abs(thing->x - tmx) >= blockdist || abs(thing->y - tmy) >= blockdist)
- { return true; } // Didn't hit thing
-
- if (thing == tmthing)
- { return true; } // Don't clip against self
-
- if ( ( thing->z + thing->height < tmthing->z) // Over thing
- || (tmthing->z + tmthing->height < thing->z)) // Under thing
- { return true; }
-
- if (thing->flags & MF_SOLID)
- { onmobj = thing; }
-
- return !((thing->flags & MF_SOLID && !(thing->flags & MF_NOCLIP))
- && (tmthing->flags & MF_SOLID || demo_compatibility));
-}
+static overunder_t zdir = OU_NONE;
static void P_FakeZMovement(mobj_t *mo)
{
+ const fixed_t oldz = mo->z;
+
// Adjust height
mo->z += mo->momz;
@@ -2542,16 +2620,77 @@ static void P_FakeZMovement(mobj_t *mo)
if (mo->flags & MF_SKULLFLY)
{ mo->momz = -mo->momz; } // The skull slammed into something
}
+
+ zdir = (oldz < mo->z) ? OU_OVER : OU_UNDER;
+}
+
+static boolean PIT_CheckOverUnderMobjZ(mobj_t *thing)
+{
+ fixed_t blockdist;
+
+ if (!(thing->flags & (MF_SOLID|MF_SPECIAL|MF_SHOOTABLE)))
+ { return true; } // Can't hit thing
+
+ blockdist = thing->radius + tmthing->radius;
+
+ if (abs(thing->x - tmx) >= blockdist || abs(thing->y - tmy) >= blockdist)
+ { return true; } // Didn't hit thing
+
+ if (thing == tmthing)
+ { return true; } // Don't clip against self
+
+ if (thing->z + thing->height <= tmthing->z)
+ {
+ // Over
+
+ if ((!p_below_tmthing)
+ || ((p_below_tmthing->z + p_below_tmthing->height) < (thing->z + thing->height)))
+ {
+ p_below_tmthing = thing;
+ }
+
+ if ((!p_above_thing_s)
+ || (tmthing->z < p_above_thing_s->z))
+ {
+ p_above_thing_s = tmthing;
+ p_above_thing_g = thing;
+ }
+
+ return true;
+ }
+ else if (tmthing->z + tmthing->height <= thing->z)
+ {
+ // Under
+
+ if ((!p_above_tmthing)
+ || (thing->z < p_above_tmthing->z))
+ {
+ p_above_tmthing = thing;
+ }
+
+ if ((!p_below_thing_s)
+ || ((p_below_thing_s->z + p_below_thing_s->height) < (tmthing->z + tmthing->height)))
+ {
+ p_below_thing_s = tmthing;
+ p_below_thing_g = thing;
+ }
+
+ return true;
+ }
+
+ return !((thing->flags & MF_SOLID && !(thing->flags & MF_NOCLIP))
+ && (tmthing->flags & MF_SOLID || demo_compatibility));
}
// Checks if the new Z position is legal
-mobj_t *P_CheckOnmobj(mobj_t *thing, boolean fakemove)
+overunder_t P_CheckOverUnderMobj(mobj_t *thing, boolean fakemove)
{
int xl, xh, yl, yh, bx, by;
subsector_t *newsubsec;
const mobj_t oldmo = *thing; // Save the old mobj before the fake movement
+ overunder_t ret = OU_NONE;
- if (!(casual_play && over_under)) { return NULL; }
+ if (!(casual_play && over_under)) { return ret; }
tmx = thing->x;
tmy = thing->y;
@@ -2574,7 +2713,7 @@ mobj_t *P_CheckOnmobj(mobj_t *thing, boolean fakemove)
validcount++;
numspechit = 0;
- if (tmflags & MF_NOCLIP) { return NULL; }
+ if (tmflags & MF_NOCLIP) { return ret; }
// Check things first, possibly picking things up
// the bounding box is extended by MAXRADIUS because mobj_ts are grouped
@@ -2585,18 +2724,42 @@ mobj_t *P_CheckOnmobj(mobj_t *thing, boolean fakemove)
yl = (tmbbox[BOXBOTTOM] - bmaporgy - MAXRADIUS) >> MAPBLOCKSHIFT;
yh = (tmbbox[BOXTOP] - bmaporgy + MAXRADIUS) >> MAPBLOCKSHIFT;
+ p_below_tmthing = p_below_thing_s = p_below_thing_g =
+ p_above_tmthing = p_above_thing_s = p_above_thing_g = NULL;
+
+ zdir = OU_NONE;
+
if (fakemove) { P_FakeZMovement(tmthing); }
for (bx = xl; bx <= xh; bx++)
for (by = yl; by <= yh; by++)
- if (!P_BlockThingsIterator(bx, by, PIT_CheckOnmobjZ))
+ if (!P_BlockThingsIterator(bx, by, PIT_CheckOverUnderMobjZ))
{
- *tmthing = oldmo;
- return onmobj;
+ mobj_t *pbtg = p_below_thing_g ? p_below_thing_g->below_thing : NULL,
+ *pbts = p_below_thing_s,
+ *patg = p_above_thing_g ? p_above_thing_g->above_thing : NULL,
+ *pats = p_above_thing_s;
+
+ tmthing->below_thing = p_below_tmthing;
+ tmthing->above_thing = p_above_tmthing;
+
+ if (p_below_thing_g
+ && ((!pbtg) || ((pbtg->z + pbtg->height) < (pbts->z + pbts->height))))
+ {
+ p_below_thing_g->below_thing = p_below_thing_s;
+ }
+
+ if (p_above_thing_g
+ && ((!patg) || (pats->z < patg->z)))
+ {
+ p_above_thing_g->above_thing = p_above_thing_s;
+ }
+
+ ret = zdir;
}
*tmthing = oldmo;
- return NULL;
+ return ret;
}
// [Nugget] -----------------------------------------------------------------/
diff --git a/src/p_map.h b/src/p_map.h
index f92f60524..1b9d071bf 100644
--- a/src/p_map.h
+++ b/src/p_map.h
@@ -78,7 +78,13 @@ extern msecnode_t *sector_list; // phares 3/16/98
extern fixed_t tmbbox[4]; // phares 3/20/98
extern line_t *blockline; // killough 8/11/98
-mobj_t *P_CheckOnmobj(mobj_t *thing, boolean fakemove); // [Nugget]: [DSDA]
+typedef enum {
+ OU_UNDER = -1,
+ OU_NONE,
+ OU_OVER,
+} overunder_t;
+
+overunder_t P_CheckOverUnderMobj(mobj_t *thing, boolean fakemove); // [Nugget]: [DSDA]
extern boolean boomshot; // [Nugget] Explosive hitscan cheat
diff --git a/src/p_mobj.c b/src/p_mobj.c
index c87db2a0e..181e9a396 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -295,7 +295,8 @@ void P_XYMovement (mobj_t* mo)
// [Nugget] Do apply friction if...
|| ((mo->z > mo->floorz)
&& !( (player && player->cheats & CF_FLY) // ... using flight cheat
- || (mo->intflags & MIF_ONMOBJ)))) // ... on top of a mobj
+ || (mo->below_thing // ... on top of a mobj
+ && (mo->z == (mo->below_thing->z + mo->below_thing->height))))))
return;
// killough 8/11/98: add bouncers
@@ -729,6 +730,7 @@ static inline void MusInfoThinker (mobj_t *thing)
void P_MobjThinker (mobj_t* mobj)
{
extern boolean cheese; // [Nugget] cheese :)
+ boolean oucheck = false; // [Nugget] Over/Under
// [crispy] support MUSINFO lump (dynamic music changing)
if (mobj->type == MT_MUSICSOURCE)
@@ -785,6 +787,8 @@ void P_MobjThinker (mobj_t* mobj)
mobj->intflags &= ~MIF_SCROLLING;
if (mobj->thinker.function.p1 == (actionf_p1)P_RemoveThinkerDelayed) // killough
return; // mobj was removed
+
+ oucheck = true; // [Nugget] Over/Under
}
if (mobj->z != mobj->floorz || mobj->momz)
@@ -792,28 +796,20 @@ void P_MobjThinker (mobj_t* mobj)
// [Nugget]: [DSDA]
if (casual_play && over_under && (mobj->flags & MF_SOLID))
{
- mobj_t *onmo;
+ overunder_t zdir;
- if (!(onmo = P_CheckOnmobj(mobj, true)))
+ if (!(zdir = P_CheckOverUnderMobj(mobj, true)))
{
P_ZMovement(mobj);
- mobj->intflags &= ~MIF_ONMOBJ;
}
else
{
mobj->momz = 0;
- if (onmo->z + onmo->height - mobj->z <= 24 * FRACUNIT)
- {
- if (mobj->player) {
- mobj->player->viewheight -= onmo->z + onmo->height - mobj->z;
- mobj->player->deltaviewheight = ((!strictmode ? viewheight_value*FRACUNIT : VIEWHEIGHT)
- - mobj->player->viewheight) >> 3;
- }
-
- mobj->z = onmo->z + onmo->height;
- mobj->intflags |= MIF_ONMOBJ;
- }
+ if (zdir == OU_UNDER && mobj->below_thing)
+ { mobj->z = mobj->below_thing->z + mobj->below_thing->height; }
+ else if (mobj->above_thing)
+ { mobj->z = mobj->above_thing->z - mobj->height; }
}
}
else
@@ -821,6 +817,8 @@ void P_MobjThinker (mobj_t* mobj)
if (mobj->thinker.function.p1 == (actionf_p1)P_RemoveThinkerDelayed) // killough
return; // mobj was removed
+
+ oucheck = true; // [Nugget] Over/Under
}
else
if (!(mobj->momx | mobj->momy) && !sentient(mobj))
@@ -838,6 +836,37 @@ void P_MobjThinker (mobj_t* mobj)
mobj->intflags &= ~MIF_FALLING, mobj->gear = 0; // Reset torque
}
+ // [Nugget] Over/Under: if we didn't check for over/under mobjs already,
+ // it means that this mobj is immobile, and its over/under mobjs, if any,
+ // were set by other mobj(s); check if they're still valid
+ if (casual_play && over_under && !oucheck)
+ {
+ mobj_t *oumobj;
+ fixed_t blockdist;
+
+ if ((oumobj = mobj->below_thing))
+ {
+ blockdist = mobj->radius + oumobj->radius;
+
+ if ( abs(mobj->x - oumobj->x) >= blockdist
+ || abs(mobj->y - oumobj->y) >= blockdist)
+ {
+ mobj->below_thing = NULL;
+ }
+ }
+
+ if ((oumobj = mobj->above_thing))
+ {
+ blockdist = mobj->radius + oumobj->radius;
+
+ if ( abs(mobj->x - oumobj->x) >= blockdist
+ || abs(mobj->y - oumobj->y) >= blockdist)
+ {
+ mobj->above_thing = NULL;
+ }
+ }
+ }
+
if (mbf21)
{
sector_t* sector = mobj->subsector->sector;
diff --git a/src/p_mobj.h b/src/p_mobj.h
index 87e30701c..9db5afeb0 100644
--- a/src/p_mobj.h
+++ b/src/p_mobj.h
@@ -237,7 +237,6 @@ enum {
MIF_CROUCHING = 32, // Mobj (player) is crouching
MIF_EXTRASPAWNED = 64, // [So Doom] Nightmare-spawned, Icon of Sin-spawned and Archvile-resurrected monsters
MIF_CHEESE = 128,
- MIF_ONMOBJ = 256, // [DSDA] mobj is resting on top of another
};
// Map Object definition.
diff --git a/src/p_user.c b/src/p_user.c
index 78c401dd9..07d849774 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -226,7 +226,8 @@ void P_MovePlayer (player_t* player)
mo->angle += cmd->angleturn << 16;
onground = (mo->z <= mo->floorz
// [Nugget]
- || (mo->intflags & MIF_ONMOBJ) // [DSDA]
+ // On top of a mobj
+ || (mo->below_thing && (mo->z == (mo->below_thing->z + mo->below_thing->height)))
// Mid-air control with noclip or flight cheat enabled
|| (player->mo->flags & MF_NOCLIP) || (player->cheats & CF_FLY));
From 352987f16f7eff65af6b9f265f31b367b0dd44aa Mon Sep 17 00:00:00 2001
From: Alaux <73968015+MrAlaux@users.noreply.github.com>
Date: Sat, 9 Dec 2023 04:45:39 -0300
Subject: [PATCH 11/15] Reformatting
---
src/p_map.c | 84 +++++++++++++++++++++++-----------------------------
src/p_mobj.c | 14 ++++-----
2 files changed, 44 insertions(+), 54 deletions(-)
diff --git a/src/p_map.c b/src/p_map.c
index 5e5b505fe..685c50bab 100644
--- a/src/p_map.c
+++ b/src/p_map.c
@@ -494,11 +494,41 @@ static boolean P_ProjectileImmune(mobj_t *target, mobj_t *source)
);
}
-// [Nugget] Over/Under: potential over/under mobjs
+// [Nugget] Over/Under /------------------------------------------------------
+
+// Potential over/under mobjs
static mobj_t *p_below_tmthing, *p_above_tmthing, // For `tmthing`
*p_below_thing_s, *p_above_thing_s, // For `thing` ("setter")
*p_below_thing_g, *p_above_thing_g; // `thing` itself ("getter")
+static void P_SetOverUnderMobjs(mobj_t *thing)
+{
+ if (casual_play && over_under)
+ {
+ mobj_t *pbtg = p_below_thing_g ? p_below_thing_g->below_thing : NULL,
+ *pbts = p_below_thing_s,
+ *patg = p_above_thing_g ? p_above_thing_g->above_thing : NULL,
+ *pats = p_above_thing_s;
+
+ thing->below_thing = p_below_tmthing;
+ thing->above_thing = p_above_tmthing;
+
+ if (p_below_thing_g
+ && ((!pbtg) || ((pbtg->z + pbtg->height) < (pbts->z + pbts->height))))
+ {
+ p_below_thing_g->below_thing = p_below_thing_s;
+ }
+
+ if (p_above_thing_g
+ && ((!patg) || (pats->z < patg->z)))
+ {
+ p_above_thing_g->above_thing = p_above_thing_s;
+ }
+ }
+}
+
+// [Nugget] -----------------------------------------------------------------/
+
static boolean PIT_CheckThing(mobj_t *thing) // killough 3/26/98: make static
{
fixed_t blockdist;
@@ -901,28 +931,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean dropoff)
return false; // solid wall or thing
// [Nugget] Over/Under: if move was valid, set new over/under mobjs
- if (casual_play && over_under)
- {
- mobj_t *pbtg = p_below_thing_g ? p_below_thing_g->below_thing : NULL,
- *pbts = p_below_thing_s,
- *patg = p_above_thing_g ? p_above_thing_g->above_thing : NULL,
- *pats = p_above_thing_s;
-
- thing->below_thing = p_below_tmthing;
- thing->above_thing = p_above_tmthing;
-
- if (p_below_thing_g
- && ((!pbtg) || ((pbtg->z + pbtg->height) < (pbts->z + pbts->height))))
- {
- p_below_thing_g->below_thing = p_below_thing_s;
- }
-
- if (p_above_thing_g
- && ((!patg) || (pats->z < patg->z)))
- {
- p_above_thing_g->above_thing = p_above_thing_s;
- }
- }
+ P_SetOverUnderMobjs(thing);
if (!(thing->flags & MF_NOCLIP))
{
@@ -1169,11 +1178,11 @@ static boolean P_ThingHeightClip(mobj_t *thing)
if (onfloor) // walking monsters rise and fall with the floor
{
- // [Nugget] Over/Under
- const fixed_t oldz = thing->z;
+ const fixed_t oldz = thing->z; // [Nugget] Over/Under
thing->z = thing->floorz;
+ // [Nugget] Over/Under
if (casual_play && over_under)
{
if (thing->z < oldz && thing->below_thing)
@@ -1193,11 +1202,11 @@ static boolean P_ThingHeightClip(mobj_t *thing)
else if (thing->z < oldz)
{
mobj_t *below_thing = thing, *above_thing;
- const fixed_t diff = oldz - thing->z;
+ const fixed_t zdiff = oldz - thing->z;
do {
if ((above_thing = below_thing->above_thing)
- && ((above_thing->z - diff) == (below_thing->z + below_thing->height)))
+ && ((above_thing->z - zdiff) == (below_thing->z + below_thing->height)))
{
above_thing->z = below_thing->z + below_thing->height;
}
@@ -2735,26 +2744,7 @@ overunder_t P_CheckOverUnderMobj(mobj_t *thing, boolean fakemove)
for (by = yl; by <= yh; by++)
if (!P_BlockThingsIterator(bx, by, PIT_CheckOverUnderMobjZ))
{
- mobj_t *pbtg = p_below_thing_g ? p_below_thing_g->below_thing : NULL,
- *pbts = p_below_thing_s,
- *patg = p_above_thing_g ? p_above_thing_g->above_thing : NULL,
- *pats = p_above_thing_s;
-
- tmthing->below_thing = p_below_tmthing;
- tmthing->above_thing = p_above_tmthing;
-
- if (p_below_thing_g
- && ((!pbtg) || ((pbtg->z + pbtg->height) < (pbts->z + pbts->height))))
- {
- p_below_thing_g->below_thing = p_below_thing_s;
- }
-
- if (p_above_thing_g
- && ((!patg) || (pats->z < patg->z)))
- {
- p_above_thing_g->above_thing = p_above_thing_s;
- }
-
+ P_SetOverUnderMobjs(tmthing);
ret = zdir;
}
diff --git a/src/p_mobj.c b/src/p_mobj.c
index 181e9a396..b716f33b6 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -806,9 +806,9 @@ void P_MobjThinker (mobj_t* mobj)
{
mobj->momz = 0;
- if (zdir == OU_UNDER && mobj->below_thing)
+ if (mobj->below_thing && zdir == OU_UNDER)
{ mobj->z = mobj->below_thing->z + mobj->below_thing->height; }
- else if (mobj->above_thing)
+ else if (mobj->above_thing) // zdir == OU_OVER
{ mobj->z = mobj->above_thing->z - mobj->height; }
}
}
@@ -841,15 +841,15 @@ void P_MobjThinker (mobj_t* mobj)
// were set by other mobj(s); check if they're still valid
if (casual_play && over_under && !oucheck)
{
- mobj_t *oumobj;
+ const mobj_t *oumobj;
fixed_t blockdist;
if ((oumobj = mobj->below_thing))
{
blockdist = mobj->radius + oumobj->radius;
- if ( abs(mobj->x - oumobj->x) >= blockdist
- || abs(mobj->y - oumobj->y) >= blockdist)
+ if ( (abs(mobj->x - oumobj->x) >= blockdist)
+ || (abs(mobj->y - oumobj->y) >= blockdist))
{
mobj->below_thing = NULL;
}
@@ -859,8 +859,8 @@ void P_MobjThinker (mobj_t* mobj)
{
blockdist = mobj->radius + oumobj->radius;
- if ( abs(mobj->x - oumobj->x) >= blockdist
- || abs(mobj->y - oumobj->y) >= blockdist)
+ if ( (abs(mobj->x - oumobj->x) >= blockdist)
+ || (abs(mobj->y - oumobj->y) >= blockdist))
{
mobj->above_thing = NULL;
}
From 7ca1b66f49b3e145682c6ffa7d2801174f235908 Mon Sep 17 00:00:00 2001
From: Alaux <73968015+MrAlaux@users.noreply.github.com>
Date: Sat, 9 Dec 2023 06:50:32 -0300
Subject: [PATCH 12/15] Further improve lift logic
Things on and near lifts now get their over/under mobjs set and/or cleared in `P_ThingHeightClip()`.
---
src/p_map.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/p_map.c b/src/p_map.c
index 685c50bab..6d877eb55 100644
--- a/src/p_map.c
+++ b/src/p_map.c
@@ -1169,6 +1169,8 @@ static boolean P_ThingHeightClip(mobj_t *thing)
P_CheckPosition(thing, thing->x, thing->y);
+ P_SetOverUnderMobjs(tmthing); // [Nugget] Over/Under
+
// what about stranding a monster partially off an edge?
// killough 11/98: Answer: see below (upset balance if hanging off ledge)
From 12a2447a4fd16e63dd964a59823a50fdd3585d3b Mon Sep 17 00:00:00 2001
From: Alaux <73968015+MrAlaux@users.noreply.github.com>
Date: Fri, 15 Dec 2023 20:03:18 -0300
Subject: [PATCH 13/15] Fix clipping into things when moving up steps
---
src/p_map.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/src/p_map.c b/src/p_map.c
index 4292e643e..94424af6b 100644
--- a/src/p_map.c
+++ b/src/p_map.c
@@ -930,8 +930,16 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean dropoff)
if (!P_CheckPosition(thing, x, y))
return false; // solid wall or thing
- // [Nugget] Over/Under: if move was valid, set new over/under mobjs
- P_SetOverUnderMobjs(thing);
+ // [Nugget] Over/Under
+ if (casual_play && over_under)
+ {
+ // `tmfloorz` may have changed, so make sure the thing fits
+ if (p_above_tmthing && (p_above_tmthing->z < (tmfloorz + thing->height)))
+ { return false; }
+
+ // If move was valid, set new over/under mobjs
+ P_SetOverUnderMobjs(thing);
+ }
if (!(thing->flags & MF_NOCLIP))
{
From 1f834504aaccd750cfbf2b8f951a3455f26510fd Mon Sep 17 00:00:00 2001
From: Alaux <73968015+MrAlaux@users.noreply.github.com>
Date: Thu, 28 Dec 2023 07:14:38 -0300
Subject: [PATCH 14/15] Update documentation
---
CHANGELOG.md | 5 +++++
README.md | 2 +-
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5afb0c207..7d925e065 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,9 +4,14 @@
## Changes
+- **Reimplemented _Move Over/Under Things_ feature**ยน, making it much less bug-prone
- **Improved Automap line thickening when the window is downscaled**
- **Tweaked zooming effect**
+**1\.** Among other changes, the setting itself has been extended: a value of `1` enables the feature only for players,
+while a value of `2` enables it for all Things. This differs from the previous implementation, wherein `1` would enable
+the feature for all Things.
+
## Bug Fixes
- **FOV effects not being cleared thoroughly upon loading levels**
diff --git a/README.md b/README.md
index daa6ce2d8..61e88792d 100644
--- a/README.md
+++ b/README.md
@@ -39,7 +39,7 @@ For these settings, their CVAR names are provided alongside the _CFG-Only_ label
- **Extended _Level Brightness_ range:** [-8, 8]
- **_"Direct + Auto"_ mode for Vertical Aiming**
- **_Direct Vertical Aiming_ for melee attacks**
-- **_Things move over/under things_** setting [p.f. Crispy Doom]
+- **_Move Over/Under Things_** setting [partially p.f. Crispy Doom, DSDA-Doom]
- **Jumping** (default key: Alt, must be enabled first) [p.f. Crispy Doom]
- **Crouching/ducking** (default key: C, must be enabled first) [i.b. ZDoom]
- **_Field of View_** setting [p.f. Doom Retro]
From b4b3d811174ea6588c4eeb20e6e84374e87fdd2e Mon Sep 17 00:00:00 2001
From: Alaux <73968015+MrAlaux@users.noreply.github.com>
Date: Thu, 28 Dec 2023 07:48:47 -0300
Subject: [PATCH 15/15] Fix excess speed when airborne with noclip
---
src/p_mobj.c | 22 ++++++++++++++++------
src/p_user.c | 16 ++++++++++------
2 files changed, 26 insertions(+), 12 deletions(-)
diff --git a/src/p_mobj.c b/src/p_mobj.c
index b716f33b6..c4d7d35b5 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -291,14 +291,24 @@ void P_XYMovement (mobj_t* mo)
}
// no friction for missiles or skulls ever, no friction when airborne
- if (mo->flags & (MF_MISSILE | MF_SKULLFLY)
- // [Nugget] Do apply friction if...
- || ((mo->z > mo->floorz)
- && !( (player && player->cheats & CF_FLY) // ... using flight cheat
- || (mo->below_thing // ... on top of a mobj
- && (mo->z == (mo->below_thing->z + mo->below_thing->height))))))
+ if (mo->flags & (MF_MISSILE | MF_SKULLFLY))
return;
+ // [Nugget] Do apply friction if airborne...
+ if (
+ (mo->z > mo->floorz)
+ && !(casual_play
+ && ( // ... using noclip or flight cheat
+ (player && player->cheats & (CF_NOCLIP|CF_FLY))
+ // ... on top of a mobj
+ || (mo->below_thing && (mo->z == (mo->below_thing->z + mo->below_thing->height)))
+ )
+ )
+ )
+ {
+ return;
+ }
+
// killough 8/11/98: add bouncers
// killough 9/15/98: add objects falling off ledges
// killough 11/98: only include bouncers hanging off ledges
diff --git a/src/p_user.c b/src/p_user.c
index 2ef56795c..2d17bb139 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -233,12 +233,16 @@ void P_MovePlayer (player_t* player)
static boolean crouchKeyDown = false; // [Nugget]
mo->angle += cmd->angleturn << 16;
- onground = (mo->z <= mo->floorz
- // [Nugget]
- // On top of a mobj
- || (mo->below_thing && (mo->z == (mo->below_thing->z + mo->below_thing->height)))
- // Mid-air control with noclip or flight cheat enabled
- || (player->mo->flags & MF_NOCLIP) || (player->cheats & CF_FLY));
+ onground = mo->z <= mo->floorz;
+
+ // [Nugget] Allow movement if...
+ if (casual_play) {
+ onground |=
+ // ... using noclip or flight cheat
+ (player->cheats & (CF_NOCLIP|CF_FLY))
+ // ... on top of a mobj
+ || (mo->below_thing && (mo->z == (mo->below_thing->z + mo->below_thing->height)));
+ }
// [Nugget]
if (player->cheats & CF_FLY)