From 2cfe575c20cd1cd2f5de3d0e966b480bf73223cc Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 1 Aug 2019 18:56:00 +0100 Subject: [PATCH 1/5] Add openfloorrover and openceilingrover vars so that PIT_CheckLine can update tmfloorrover and tmceilingrover properly via P_LineOpening ...which should hopefully stop that issue where you just teleport back to the ground. Assuming this works as expected. Also this is untested lol. --- src/p_maputl.c | 13 +++++++++++++ src/p_maputl.h | 1 + 2 files changed, 14 insertions(+) diff --git a/src/p_maputl.c b/src/p_maputl.c index 0ca84096a..4dafbcc7f 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -311,6 +311,7 @@ fixed_t opentop, openbottom, openrange, lowfloor, highceiling; #ifdef ESLOPE pslope_t *opentopslope, *openbottomslope; #endif +ffloor_t *openfloorrover, *openceilingrover; // P_CameraLineOpening // P_LineOpening, but for camera @@ -517,6 +518,8 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) I_Assert(front != NULL); I_Assert(back != NULL); + openfloorrover = openceilingrover = NULL; + { // Set open and high/low values here fixed_t frontheight, backheight; @@ -641,6 +644,8 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) pslope_t *ceilingslope = opentopslope; pslope_t *floorslope = openbottomslope; #endif + ffloor_t *floorrover = NULL; + ffloor_t *ceilingrover = NULL; // Check for frontsector's fake floors for (rover = front->ffloors; rover; rover = rover->next) @@ -668,6 +673,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) #ifdef ESLOPE ceilingslope = *rover->b_slope; #endif + ceilingrover = rover; } else if (bottomheight < highestceiling) highestceiling = bottomheight; @@ -680,6 +686,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) #ifdef ESLOPE floorslope = *rover->t_slope; #endif + floorrover = rover; } else if (topheight > lowestfloor) lowestfloor = topheight; @@ -712,6 +719,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) #ifdef ESLOPE ceilingslope = *rover->b_slope; #endif + ceilingrover = rover; } else if (bottomheight < highestceiling) highestceiling = bottomheight; @@ -724,6 +732,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) #ifdef ESLOPE floorslope = *rover->t_slope; #endif + floorrover = rover; } else if (topheight > lowestfloor) lowestfloor = topheight; @@ -743,6 +752,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) #ifdef ESLOPE ceilingslope = NULL; #endif + ceilingrover = NULL; } else if (polysec->floorheight < highestceiling && delta1 >= delta2) highestceiling = polysec->floorheight; @@ -752,6 +762,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) #ifdef ESLOPE floorslope = NULL; #endif + floorrover = NULL; } else if (polysec->ceilingheight > lowestfloor && delta1 < delta2) lowestfloor = polysec->ceilingheight; @@ -765,6 +776,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) #ifdef ESLOPE openbottomslope = floorslope; #endif + openfloorrover = floorrover; } if (lowestceiling < opentop) { @@ -772,6 +784,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) #ifdef ESLOPE opentopslope = ceilingslope; #endif + openceilingrover = floorrover; } if (lowestfloor > lowfloor) diff --git a/src/p_maputl.h b/src/p_maputl.h index 1fcb68d4c..5042817c5 100644 --- a/src/p_maputl.h +++ b/src/p_maputl.h @@ -58,6 +58,7 @@ extern fixed_t opentop, openbottom, openrange, lowfloor, highceiling; #ifdef ESLOPE extern pslope_t *opentopslope, *openbottomslope; #endif +extern ffloor_t *openfloorrover, *openceilingrover; void P_LineOpening(line_t *plinedef, mobj_t *mobj); From 55a738d2be778535a12818004224f207ba6e463a Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 1 Aug 2019 20:17:15 +0100 Subject: [PATCH 2/5] Whoops, forgot this part --- src/p_map.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index e78dd1e84..f7e1d72c8 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1808,7 +1808,7 @@ static boolean PIT_CheckLine(line_t *ld) { tmceilingz = opentop; ceilingline = ld; - tmceilingrover = NULL; + tmceilingrover = openceilingrover; #ifdef ESLOPE tmceilingslope = opentopslope; #endif @@ -1817,7 +1817,7 @@ static boolean PIT_CheckLine(line_t *ld) if (openbottom > tmfloorz) { tmfloorz = openbottom; - tmfloorrover = NULL; + tmfloorrover = openfloorrover; #ifdef ESLOPE tmfloorslope = openbottomslope; #endif From 925735bfaa3248ffb13b42b74db5032045ede067 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 1 Aug 2019 20:48:24 +0100 Subject: [PATCH 3/5] Whoops the second --- src/p_maputl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_maputl.c b/src/p_maputl.c index 4dafbcc7f..740797fb0 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -784,7 +784,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) #ifdef ESLOPE opentopslope = ceilingslope; #endif - openceilingrover = floorrover; + openceilingrover = ceilingrover; } if (lowestfloor > lowfloor) From c88f02675eb1de7fb359b0d5392de8c9ca9b449b Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 2 Aug 2019 16:51:44 +0100 Subject: [PATCH 4/5] 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)); } } From eb477ee78499bb6b7aca5be7bb4f27d6b59b374a Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 3 Aug 2019 19:06:45 +0100 Subject: [PATCH 5/5] Remove commented out P_CheckSector calls and add extra comments explaining the situation --- src/p_polyobj.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/p_polyobj.c b/src/p_polyobj.c index 857e6f3d1..040bdca2a 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -1873,7 +1873,8 @@ 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)); + // Monster Iestyn: we only need to bother with the back sector, now that P_CheckSector automatically checks the blockmap + // updating objects in the front one too just added teleporting to ground bugs P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage)); // Apply action to mirroring polyobjects as well start = 0; @@ -1887,7 +1888,8 @@ 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)); + // Monster Iestyn: we only need to bother with the back sector, now that P_CheckSector automatically checks the blockmap + // updating objects in the front one too just added teleporting to ground bugs P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage)); } @@ -2050,8 +2052,9 @@ 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]->backsector, (boolean)(po->damage)); // backsector may not be necessary, but just in case + // Monster Iestyn: we only need to bother with the back sector, now that P_CheckSector automatically checks the blockmap + // updating objects in the front one too just added teleporting to ground bugs + P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage)); // Apply action to mirroring polyobjects as well start = 0; @@ -2065,7 +2068,8 @@ 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)); + // Monster Iestyn: we only need to bother with the back sector, now that P_CheckSector automatically checks the blockmap + // updating objects in the front one too just added teleporting to ground bugs P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage)); } }