From 8fa54c1ab4a5d21be0183def857948f6ab6a052a Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 15 Aug 2019 14:20:52 +0100 Subject: [PATCH] Modify P_CheckSector with a modified version of Sal's attempted proper fix for polyobjects crushing, so that we only need to check the polyobject's control sector directly in the waypoints code. This time I've definitely fixed that teleport to ground issue I'm pretty sure, I don't get it in my tests at least. --- src/p_map.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++- src/p_polyobj.c | 8 ++-- 2 files changed, 99 insertions(+), 6 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index 95ad02588..6540a99b2 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -3345,6 +3345,7 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush) boolean P_CheckSector(sector_t *sector, boolean crunch) { msecnode_t *n; + size_t i; nofit = false; crushchange = crunch; @@ -3359,9 +3360,57 @@ boolean P_CheckSector(sector_t *sector, boolean crunch) // First, let's see if anything will keep it from crushing. + + // Sal: This stupid function chain is required to fix polyobjects not being able to crush. + // Monster Iestyn: don't use P_CheckSector actually just look for objects in the blockmap instead + validcount++; + + for (i = 0; i < sector->linecount; i++) + { + if (sector->lines[i]->polyobj) + { + polyobj_t *po = sector->lines[i]->polyobj; + if (po->validcount == validcount) + continue; // skip if already checked + if (!(po->flags & POF_SOLID)) + continue; + if (po->lines[0]->backsector == sector) // Make sure you're currently checking the control sector + { + INT32 x, y; + po->validcount = validcount; + + for (y = po->blockbox[BOXBOTTOM]; y <= po->blockbox[BOXTOP]; ++y) + { + for (x = po->blockbox[BOXLEFT]; x <= po->blockbox[BOXRIGHT]; ++x) + { + mobj_t *mo; + + if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight) + continue; + + mo = blocklinks[y * bmapwidth + x]; + + for (; mo; mo = mo->bnext) + { + // Monster Iestyn: do we need to check if a mobj has already been checked? ...probably not I suspect + + if (!P_MobjTouchingPolyobj(po, mo)) + continue; + + if (!PIT_ChangeSector(mo, false)) + { + nofit = true; + return nofit; + } + } + } + } + } + } + } + if (sector->numattached) { - size_t i; sector_t *sec; for (i = 0; i < sector->numattached; i++) { @@ -3421,9 +3470,53 @@ boolean P_CheckSector(sector_t *sector, boolean crunch) } while (n); // repeat from scratch until all things left are marked valid // Nothing blocked us, so lets crush for real! + + // Sal: This stupid function chain is required to fix polyobjects not being able to crush. + // Monster Iestyn: don't use P_CheckSector actually just look for objects in the blockmap instead + validcount++; + + for (i = 0; i < sector->linecount; i++) + { + if (sector->lines[i]->polyobj) + { + polyobj_t *po = sector->lines[i]->polyobj; + if (po->validcount == validcount) + continue; // skip if already checked + if (!(po->flags & POF_SOLID)) + continue; + if (po->lines[0]->backsector == sector) // Make sure you're currently checking the control sector + { + INT32 x, y; + po->validcount = validcount; + + for (y = po->blockbox[BOXBOTTOM]; y <= po->blockbox[BOXTOP]; ++y) + { + for (x = po->blockbox[BOXLEFT]; x <= po->blockbox[BOXRIGHT]; ++x) + { + mobj_t *mo; + + if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight) + continue; + + mo = blocklinks[y * bmapwidth + x]; + + for (; mo; mo = mo->bnext) + { + // Monster Iestyn: do we need to check if a mobj has already been checked? ...probably not I suspect + + if (!P_MobjTouchingPolyobj(po, mo)) + continue; + + PIT_ChangeSector(mo, true); + return nofit; + } + } + } + } + } + } if (sector->numattached) { - size_t i; sector_t *sec; for (i = 0; i < sector->numattached; i++) { diff --git a/src/p_polyobj.c b/src/p_polyobj.c index 82c57c85b..21d8af5f2 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -1860,7 +1860,7 @@ void T_PolyObjWaypoint(polywaypoint_t *th) po->lines[0]->backsector->floorheight = target->z - amtz; po->lines[0]->backsector->ceilingheight = target->z + amtz; // Sal: Remember to check your sectors! - P_CheckSector(po->lines[0]->frontsector, (boolean)(po->damage)); + //P_CheckSector(po->lines[0]->frontsector, (boolean)(po->damage)); P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage)); // Apply action to mirroring polyobjects as well start = 0; @@ -1874,7 +1874,7 @@ void T_PolyObjWaypoint(polywaypoint_t *th) po->lines[0]->backsector->floorheight += diffz; // move up/down by same amount as the parent did po->lines[0]->backsector->ceilingheight += diffz; // Sal: Remember to check your sectors! - P_CheckSector(po->lines[0]->frontsector, (boolean)(po->damage)); + //P_CheckSector(po->lines[0]->frontsector, (boolean)(po->damage)); P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage)); } @@ -2037,7 +2037,7 @@ void T_PolyObjWaypoint(polywaypoint_t *th) po->lines[0]->backsector->floorheight += momz; po->lines[0]->backsector->ceilingheight += momz; // Sal: Remember to check your sectors! - P_CheckSector(po->lines[0]->frontsector, (boolean)(po->damage)); // frontsector is NEEDED for crushing + //P_CheckSector(po->lines[0]->frontsector, (boolean)(po->damage)); // frontsector is NEEDED for crushing P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage)); // backsector may not be necessary, but just in case // Apply action to mirroring polyobjects as well @@ -2052,7 +2052,7 @@ void T_PolyObjWaypoint(polywaypoint_t *th) po->lines[0]->backsector->floorheight += momz; po->lines[0]->backsector->ceilingheight += momz; // Sal: Remember to check your sectors! - P_CheckSector(po->lines[0]->frontsector, (boolean)(po->damage)); + //P_CheckSector(po->lines[0]->frontsector, (boolean)(po->damage)); P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage)); } }