Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/doom/p_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,9 @@ extern line_t* ceilingline;
extern line_t** spechit; // [crispy] remove SPECHIT limit
extern int numspechit;

void P_ResyncAboveThings(mobj_t* supporter);
void P_UpdateMobjHeights(mobj_t* mo); // i dont want to redefine this everywhere i use it

boolean P_CheckPosition (mobj_t *thing, fixed_t x, fixed_t y);
boolean P_TryMove (mobj_t* thing, fixed_t x, fixed_t y);
boolean P_TeleportMove (mobj_t* thing, fixed_t x, fixed_t y);
Expand Down
195 changes: 141 additions & 54 deletions src/doom/p_map.c
Original file line number Diff line number Diff line change
Expand Up @@ -312,8 +312,8 @@ boolean PIT_CheckThing (mobj_t* thing)
// check for skulls slamming into things
if (tmthing->flags & MF_SKULLFLY)
{
// [crispy] check if attacking skull flies over player
if (critical->overunder && thing->player)
// [crispy] check if attacking skull flies over target
if (critical->overunder)
{
if (tmthing->z > thing->z + thing->height)
{
Expand Down Expand Up @@ -394,67 +394,138 @@ boolean PIT_CheckThing (mobj_t* thing)
return !solid;
}

if (critical->overunder)
if (critical->overunder && !(tmthing->flags & MF_MISSILE) && (thing->flags & MF_SOLID) && !(thing->flags & MF_NOBLOCKMAP))
{
// [crispy] a solid hanging body will allow sufficiently small things underneath it
if (thing->flags & MF_SOLID && thing->flags & MF_SPAWNCEILING)
// [crispy] allow the usual 24 units step-up even across monsters' heads,
// only if the current height has not been reached by "low" jumping
fixed_t step_up = (tmthing->player && tmthing->player->jumpTics > 7) ? 0 : 24*FRACUNIT;

if (tmthing->z + step_up >= thing->z + thing->height)
{
if (tmthing->z + tmthing->height <= thing->z)
{
if (thing->z < tmceilingz)
{
tmceilingz = thing->z;
}
return true;
}
// walk over object
tmfloorz = MAX(thing->z + thing->height, tmfloorz);
return true;
}

// [crispy] allow players to walk over/under shootable objects
if (tmthing->player && thing->flags & MF_SHOOTABLE)
else if (tmthing->z + tmthing->height <= thing->z)
{
// [crispy] allow the usual 24 units step-up even across monsters' heads,
// only if the current height has not been reached by "low" jumping
fixed_t step_up = tmthing->player->jumpTics > 7 ? 0 : 24*FRACUNIT;
// walk underneath object
tmceilingz = MIN(thing->z, tmceilingz);
return true;
}

if (tmthing->z + step_up >= thing->z + thing->height)
{
// player walks over object
tmfloorz = MAX(thing->z + thing->height, tmfloorz);
thing->ceilingz = MIN(tmthing->z, thing->ceilingz);
return true;
}
else
if (tmthing->z + tmthing->height <= thing->z)
{
// player walks underneath object
tmceilingz = MIN(thing->z, tmceilingz);
thing->floorz = MAX(tmthing->z + tmthing->height, thing->floorz);
return true;
}
// [crispy] check if things are stuck and allow them to move further apart
// taken from doomretro/src/p_map.c:319-332
if (tmx == tmthing->x && tmy == tmthing->y)
{
unblocking = true;
}
else if (thing->flags & MF_SHOOTABLE)
{
fixed_t newdist = P_AproxDistance(thing->x - tmx, thing->y - tmy);
fixed_t olddist = P_AproxDistance(thing->x - tmthing->x, thing->y - tmthing->y);

// [crispy] check if things are stuck and allow them to move further apart
// taken from doomretro/src/p_map.c:319-332
if (tmx == tmthing->x && tmy == tmthing->y)
if (newdist > olddist)
{
unblocking = true;
}
else
{
fixed_t newdist = P_AproxDistance(thing->x - tmx, thing->y - tmy);
fixed_t olddist = P_AproxDistance(thing->x - tmthing->x, thing->y - tmthing->y);

if (newdist > olddist)
{
unblocking = (tmthing->z < thing->z + thing->height
&& tmthing->z + tmthing->height > thing->z);
}
unblocking = (tmthing->z < thing->z + thing->height
&& tmthing->z + tmthing->height > thing->z);
}
}
}

return !(thing->flags & MF_SOLID) || unblocking;
}

mobj_t* resync_supporter;

//
// P_UpdateMobjHeights
//
void P_UpdateMobjHeights(mobj_t* mo)
{
if (critical->overunder)
{
P_CheckPosition(mo, mo->x, mo->y);
mo->floorz = tmfloorz;
mo->ceilingz = tmceilingz;
}
}

//
// Paf - the atcual reyncer
// PIT_ResyncThing
//
boolean PIT_ResyncThing(mobj_t *thing)
{
if (thing == resync_supporter)
return true;

if (resync_supporter)
{
// they are overlapping, check if thing is above supporter
if (abs(thing->x - resync_supporter->x) < (thing->radius + resync_supporter->radius) &&
abs(thing->y - resync_supporter->y) < (thing->radius + resync_supporter->radius))
{
if (thing->z < resync_supporter->z + resync_supporter->height)
return true;
}
}

if (critical->overunder && (thing->flags & (MF_SHOOTABLE | MF_SOLID)))
{
P_UpdateMobjHeights(thing);

if ((thing->flags & MF_SHOOTABLE) && thing->z < thing->floorz)
thing->z = thing->floorz;
}
return true;
}

//
// Paf - resync stacked objects with the sector when their support leaves
// P_CheckThingsAbove
//
void P_CheckThingsAbove(int x, int y, mobj_t *supporter)
{
int z, height, radius;
int xl, xh, yl, yh;
int bx, by;

z = supporter->z;
height = supporter->height;
radius = supporter->radius;

resync_supporter = supporter; // can be NULL if we just want to check an area i think

xl = (x - radius - MAPBLOCKSIZE - bmaporgx) >> MAPBLOCKSHIFT;
xh = (x + radius + MAPBLOCKSIZE - bmaporgx) >> MAPBLOCKSHIFT;
yl = (y - radius - MAPBLOCKSIZE - bmaporgy) >> MAPBLOCKSHIFT;
yh = (y + radius + MAPBLOCKSIZE - bmaporgy) >> MAPBLOCKSHIFT;

if (xl < 0) xl = 0;
if (yl < 0) yl = 0;
if (xh >= bmapwidth) xh = bmapwidth - 1;
if (yh >= bmapheight) yh = bmapheight - 1;

for (bx = xl; bx <= xh; bx++)
for (by = yl; by <= yh; by++)
P_BlockThingsIterator(bx, by, PIT_ResyncThing);
}

//
// P_ResyncAboveThings
//
void P_ResyncAboveThings(mobj_t *supporter)
{
if (!(supporter->flags & MF_SOLID) ||
(supporter->flags &
(MF_SPECIAL || MF_PICKUP || MF_CORPSE)) || !critical->overunder) // i believe these are the only cases we shouldn't do this
{
return;
}

P_CheckThingsAbove(supporter->x, supporter->y, supporter);
}


//
// MOVEMENT CLIPPING
Expand Down Expand Up @@ -574,7 +645,7 @@ P_TryMove

floatok = false;
if (!P_CheckPosition (thing, x, y))
return false; // solid wall or thing
return false; // solid wall or thing

if ( !(thing->flags & MF_NOCLIP) )
{
Expand Down Expand Up @@ -608,7 +679,7 @@ P_TryMove
thing->y = y;

P_SetThingPosition (thing);

// if any special lines were hit, do the effect
if (! (thing->flags&(MF_TELEPORT|MF_NOCLIP)) )
{
Expand All @@ -626,10 +697,21 @@ P_TryMove
}
}

if (critical->overunder)
{
// resync at old position
if (thing->flags & MF_SOLID)
P_CheckThingsAbove(oldx, oldy, thing);

// resync at new position (we might have moved under)
P_ResyncAboveThings(thing);
}

return true;
}


boolean P_IsZMovementLegal (mobj_t* mo);
boolean P_IsResyncNeeded(mobj_t* mo);
//
// P_ThingHeightClip
// Takes a valid thing and adjusts the thing->floorz,
Expand Down Expand Up @@ -665,8 +747,13 @@ boolean P_ThingHeightClip (mobj_t* thing)
}

if (thing->ceilingz - thing->floorz < thing->height)
return false;

{
return false;
}

if (critical->overunder)
P_ResyncAboveThings(thing);

return true;
}

Expand Down
38 changes: 38 additions & 0 deletions src/doom/p_mobj.c
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,31 @@ void P_XYMovement (mobj_t* mo)
mo->momx = FixedMul (mo->momx, FRICTION);
mo->momy = FixedMul (mo->momy, FRICTION);
}

if (critical->overunder && (mo->flags & MF_SHOOTABLE))
{
P_UpdateMobjHeights(mo);
P_ResyncAboveThings(mo);
}
}


void P_ResyncAboveThings(mobj_t *supporter);
//
// P_IsZMovementLegal
//
boolean P_IsZMovementLegal (mobj_t* mo) {
if (critical->overunder && (!(mo->flags & MF_SOLID) || (mo->flags & (MF_SPECIAL|MF_PICKUP|MF_CORPSE)))) {
return true;
}

P_UpdateMobjHeights(mo);

if (mo->z+mo->height > mo->ceilingz)
return false;

P_ResyncAboveThings(mo);
return true;
}

//
Expand Down Expand Up @@ -474,6 +499,8 @@ void P_ZMovement (mobj_t* mo)
return;
}
}
if (critical->overunder)
P_ResyncAboveThings(mo);
}


Expand Down Expand Up @@ -582,6 +609,11 @@ void P_MobjThinker (mobj_t* mobj)
mobj->oldangle = mobj->angle;
}

if (critical->overunder && (mobj->flags & MF_SHOOTABLE))
{
P_UpdateMobjHeights(mobj);
}

// momentum movement
if (mobj->momx
|| mobj->momy
Expand All @@ -593,6 +625,7 @@ void P_MobjThinker (mobj_t* mobj)
if (mobj->thinker.function.acv == (actionf_v) (-1))
return; // mobj was removed
}

if ( (mobj->z != mobj->floorz)
|| mobj->momz )
{
Expand Down Expand Up @@ -737,6 +770,11 @@ P_SpawnMobjSafe
mobj->thinker.function.acp1 = (actionf_p1)P_MobjThinker;

P_AddThinker (&mobj->thinker);
if (critical->overunder && (mobj->flags & MF_SHOOTABLE))
{
P_UpdateMobjHeights(mobj);
P_IsZMovementLegal(mobj);
}

return mobj;
}
Expand Down
Loading