From 42a36de4595fc55fdbba6ffcd61d94690cf174b6 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 2 Aug 2019 16:51:44 +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 | 99 ++++++++++++++++++++++++++++++++++++++++++++++++- src/p_polyobj.c | 8 ++-- 2 files changed, 101 insertions(+), 6 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index f7e1d72c8..76bb99bff 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2089,6 +2089,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) #ifdef ESLOPE tmfloorslope = NULL; #endif + tmfloorrover = NULL; } if (polybottom < tmceilingz && abs(delta1) >= abs(delta2)) { @@ -2096,6 +2097,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) #ifdef ESLOPE tmceilingslope = NULL; #endif + tmceilingrover = NULL; } } plink = (polymaplink_t *)(plink->link.next); @@ -4079,6 +4081,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; @@ -4093,9 +4096,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++) { @@ -4155,9 +4206,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 475fa41b7..857e6f3d1 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -1873,7 +1873,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; @@ -1887,7 +1887,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)); } @@ -2050,7 +2050,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 @@ -2065,7 +2065,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)); } }