From 730145d1fc429cea73824e0606ba768921b1a43f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 21 Feb 2016 23:08:51 +0100 Subject: [PATCH] - more transition to FMultiBlock* iterators: * removed all code for dealing with z-displacing portals in the iterator loops. This would cause too many problems so I decided to scrap any provisions for allowing interactive portals with z-displacement. They will remain restricted to pure teleporter portals. * changed spechit to carry a position along with the special line. If something is activated through an interactive portal this is needed to calculate movement. * pass the abovementioned position to CheckForPushSpecial. * collect touched portal lines in a second array analogous to spechit. * use FMultiBlockThingsIterator in P_TestMobjZ. --- src/b_move.cpp | 4 ++- src/p_enemy.cpp | 10 +++--- src/p_local.h | 9 ++++- src/p_map.cpp | 85 ++++++++++++++++++++++++++---------------------- src/p_maputl.cpp | 6 ++-- src/p_maputl.h | 6 ++-- 6 files changed, 67 insertions(+), 53 deletions(-) diff --git a/src/b_move.cpp b/src/b_move.cpp index 1fcf207ed9..dbecd2a48d 100644 --- a/src/b_move.cpp +++ b/src/b_move.cpp @@ -83,10 +83,12 @@ bool DBot::Move (ticcmd_t *cmd) player->mo->movedir = DI_NODIR; good = 0; + spechit_t spechit1; line_t *ld; - while (spechit.Pop (ld)) + while (spechit.Pop (spechit1)) { + ld = spechit1.line; bool tryit = true; if (ld->special == Door_LockedRaise && !P_CheckKeys (player->mo, ld->args[3], false)) diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index 47ac85d1f7..2049d5f229 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -612,18 +612,18 @@ bool P_Move (AActor *actor) // Do NOT simply return false 1/4th of the time (causes monsters to // back out when they shouldn't, and creates secondary stickiness). - line_t *ld; + spechit_t spec; int good = 0; if (!(actor->flags6 & MF6_NOTRIGGER)) { - while (spechit.Pop (ld)) + while (spechit.Pop (spec)) { // [RH] let monsters push lines, as well as use them - if (((actor->flags4 & MF4_CANUSEWALLS) && P_ActivateLine (ld, actor, 0, SPAC_Use)) || - ((actor->flags2 & MF2_PUSHWALL) && P_ActivateLine (ld, actor, 0, SPAC_Push))) + if (((actor->flags4 & MF4_CANUSEWALLS) && P_ActivateLine (spec.line, actor, 0, SPAC_Use)) || + ((actor->flags2 & MF2_PUSHWALL) && P_ActivateLine (spec.line, actor, 0, SPAC_Push))) { - good |= ld == actor->BlockingLine ? 1 : 2; + good |= spec.line == actor->BlockingLine ? 1 : 2; } } } diff --git a/src/p_local.h b/src/p_local.h index 26eb72bd2a..35dbb8b226 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -240,7 +240,14 @@ AActor *P_RoughMonsterSearch (AActor *mo, int distance, bool onlyseekable=false) // if within "tmfloorz - tmceilingz". extern msecnode_t *sector_list; // phares 3/16/98 -extern TArray spechit; +struct spechit_t +{ + line_t *line; + fixedvec2 refpos; +}; + +extern TArray spechit; +extern TArray portalhit; bool P_TestMobjLocation (AActor *mobj); diff --git a/src/p_map.cpp b/src/p_map.cpp index dc3ca76441..70043d815a 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -63,7 +63,7 @@ CVAR(Bool, cl_bloodsplats, true, CVAR_ARCHIVE) CVAR(Int, sv_smartaim, 0, CVAR_ARCHIVE | CVAR_SERVERINFO) CVAR(Bool, cl_doautoaim, false, CVAR_ARCHIVE) -static void CheckForPushSpecial(line_t *line, int side, AActor *mobj, bool windowcheck); +static void CheckForPushSpecial(line_t *line, int side, AActor *mobj, fixedvec2 * posforwindowcheck = NULL); static void SpawnShootDecal(AActor *t1, const FTraceResults &trace); static void SpawnDeepSplash(AActor *t1, const FTraceResults &trace, AActor *puff, fixed_t vx, fixed_t vy, fixed_t vz, fixed_t shootz, bool ffloor = false); @@ -75,8 +75,8 @@ static FRandom pr_crunch("DoCrunch"); // keep track of special lines as they are hit, // but don't process them until the move is proven valid -TArray spechit; -TArray portalhit; +TArray spechit; +TArray portalhit; // Temporary holder for thing_sectorlist threads msecnode_t* sector_list = NULL; // phares 3/16/98 @@ -465,8 +465,8 @@ bool P_TeleportMove(AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefra { if (!(th->flags3 & thing->flags3 & MF3_DONTOVERLAP)) { - if (z > cres.position.z + th->height || // overhead - z + thing->height < cres.position.z) // underneath + if (z > th->Top() || // overhead + z + thing->height < th->Z()) // underneath continue; } } @@ -560,9 +560,9 @@ void P_PlayerStartStomp(AActor *actor, bool mononly) if (th->player != NULL && mononly) continue; - if (actor->Z() > cres.position.z + th->height) + if (actor->Z() > th->Top()) continue; // overhead - if (actor->Top() < cres.position.z) + if (actor->Top() < th->Z()) continue; // underneath P_DamageMobj(th, actor, actor, TELEFRAG_DAMAGE, NAME_Telefrag); @@ -793,7 +793,7 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec P_DamageMobj(tm.thing, NULL, NULL, tm.thing->Mass >> 5, NAME_Melee); } tm.thing->BlockingLine = ld; - CheckForPushSpecial(ld, 0, tm.thing, false); + CheckForPushSpecial(ld, 0, tm.thing); return false; } @@ -824,7 +824,7 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec } tm.thing->BlockingLine = ld; // Calculate line side based on the actor's original position, not the new one. - CheckForPushSpecial(ld, P_PointOnLineSide(cres.position.x, cres.position.y, ld), tm.thing, false); + CheckForPushSpecial(ld, P_PointOnLineSide(cres.position.x, cres.position.y, ld), tm.thing); return false; } } @@ -896,13 +896,18 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec tm.dropoffz = open.lowfloor; // if contacted a special line, add it to the list + spechit_t spec; if (ld->special) { - spechit.Push(ld); + spec.line = ld; + spec.refpos = cres.position; + spechit.Push(spec); } if (ld->portalindex >= 0) { - portalhit.Push(ld); + spec.line = ld; + spec.refpos = cres.position; + portalhit.Push(spec); } return true; @@ -1038,8 +1043,8 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch (thing->flags & MF_SOLID) && (thing->flags4 & MF4_ACTLIKEBRIDGE)) { // [RH] Let monsters walk on actors as well as floors - if (cres.zdiff != 0 && (tm.thing->flags3 & MF3_ISMONSTER) && - topz >= tm.floorz && topz <= cres.position.z + tm.thing->MaxStepHeight) + if ((tm.thing->flags3 & MF3_ISMONSTER) && + topz >= tm.floorz && topz <= tm.thing->Z() + tm.thing->MaxStepHeight) { // The commented-out if is an attempt to prevent monsters from walking off a // thing further than they would walk off a ledge. I can't think of an easy @@ -1074,7 +1079,7 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch if (newdist > olddist) { // unblock only if there's already a vertical overlap (or both actors are flagged not to overlap) - unblocking = (cres.position.z + tm.thing->height > thing->Z() && cres.position.z < topz) || (tm.thing->flags3 & thing->flags3 & MF3_DONTOVERLAP); + unblocking = (tm.thing->Top() > thing->Z() && tm.thing->Z() < topz) || (tm.thing->flags3 & thing->flags3 & MF3_DONTOVERLAP); } } } @@ -1093,7 +1098,7 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch { // Some things prefer not to overlap each other, if possible return unblocking; } - if ((cres.position.z >= topz) || (cres.position.z + tm.thing->height <= thing->Z())) + if ((tm.thing->Z() >= topz) || (tm.thing->Top() <= thing->Z())) return true; } } @@ -1109,7 +1114,7 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch // or different species if DONTHARMSPECIES (!(thing->flags6 & MF6_DONTHARMSPECIES) || thing->GetSpecies() != tm.thing->GetSpecies()) && // touches vertically - topz >= cres.position.z && cres.position.z + tm.thing->height >= thing->Z() && + topz >= tm.thing->Z() && tm.thing->Top() >= thing->Z() && // prevents lost souls from exploding when fired by pain elementals (thing->master != tm.thing && tm.thing->master != thing)) // Difference with MBF: MBF hardcodes the LS/PE check and lets actors of the same species @@ -1212,11 +1217,11 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch } // Check if it went over / under - if (cres.position.z > thing->Z() + clipheight) + if (tm.thing->Z() > thing->Z() + clipheight) { // Over thing return true; } - if (cres.position.z + tm.thing->height < thing->Z()) + if (tm.thing->Top() < thing->Z()) { // Under thing return true; } @@ -1367,7 +1372,7 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch // [RH] The next condition is to compensate for the extra height // that gets added by P_CheckPosition() so that you cannot pick // up things that are above your true height. - && thing->Z() < cres.position.z + tm.thing->height - tm.thing->MaxStepHeight) + && thing->Z() < tm.thing->Top() - tm.thing->MaxStepHeight) { // Can be picked up by tmthing P_TouchSpecialThing(thing, tm.thing); // can remove thing } @@ -1641,12 +1646,16 @@ bool P_TestMobjZ(AActor *actor, bool quick, AActor **pOnmobj) return true; } - FBlockThingsIterator it(FBoundingBox(actor->X(), actor->Y(), actor->radius)); - AActor *thing; + FPortalGroupArray check; + FMultiBlockThingsIterator it(check, actor, -1, true); + FMultiBlockThingsIterator::CheckResult cres; - while ((thing = it.Next())) + while (it.Next(&cres)) { - if (!thing->intersects(actor)) + AActor *thing = cres.thing; + + fixed_t blockdist = thing->radius + actor->radius; + if (abs(thing->X() - cres.position.x) >= blockdist || abs(thing->Y() - cres.position.y) >= blockdist) { continue; } @@ -1753,18 +1762,18 @@ void P_FakeZMovement(AActor *mo) // //=========================================================================== -static void CheckForPushSpecial(line_t *line, int side, AActor *mobj, bool windowcheck) +static void CheckForPushSpecial(line_t *line, int side, AActor *mobj, fixedvec2 *posforwindowcheck) { if (line->special && !(mobj->flags6 & MF6_NOTRIGGER)) { - if (windowcheck && !(ib_compatflags & BCOMPATF_NOWINDOWCHECK) && line->backsector != NULL) + if (posforwindowcheck && !(ib_compatflags & BCOMPATF_NOWINDOWCHECK) && line->backsector != NULL) { // Make sure this line actually blocks us and is not a window // or similar construct we are standing inside of. fixedvec3 pos = mobj->PosRelative(line); - fixed_t fzt = line->frontsector->ceilingplane.ZatPoint(pos); - fixed_t fzb = line->frontsector->floorplane.ZatPoint(pos); - fixed_t bzt = line->backsector->ceilingplane.ZatPoint(pos); - fixed_t bzb = line->backsector->floorplane.ZatPoint(pos); + fixed_t fzt = line->frontsector->ceilingplane.ZatPoint(*posforwindowcheck); + fixed_t fzb = line->frontsector->floorplane.ZatPoint(*posforwindowcheck); + fixed_t bzt = line->backsector->ceilingplane.ZatPoint(*posforwindowcheck); + fixed_t bzb = line->backsector->floorplane.ZatPoint(*posforwindowcheck); if (fzt >= mobj->Top() && bzt >= mobj->Top() && fzb <= mobj->Z() && bzb <= mobj->Z()) { @@ -1775,8 +1784,8 @@ static void CheckForPushSpecial(line_t *line, int side, AActor *mobj, bool windo if (!(rover->flags & FF_SOLID) || !(rover->flags & FF_EXISTS)) continue; - fixed_t ff_bottom = rover->bottom.plane->ZatPoint(pos); - fixed_t ff_top = rover->top.plane->ZatPoint(pos); + fixed_t ff_bottom = rover->bottom.plane->ZatPoint(*posforwindowcheck); + fixed_t ff_top = rover->top.plane->ZatPoint(*posforwindowcheck); if (ff_bottom < mobj->Top() && ff_top > mobj->Z()) { @@ -2081,12 +2090,13 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, // if any special lines were hit, do the effect if (!(thing->flags & (MF_TELEPORT | MF_NOCLIP))) { - while (spechit.Pop(ld)) + spechit_t spec; + while (spechit.Pop(spec)) { - fixedvec3 thingpos = thing->PosRelative(ld); + line_t *ld = spec.line; fixedvec3 oldrelpos = PosRelative(oldpos, ld, oldsector); // see if the line was crossed - side = P_PointOnLineSide(thingpos.x, thingpos.y, ld); + side = P_PointOnLineSide(spec.refpos.x, spec.refpos.y, ld); oldside = P_PointOnLineSide(oldrelpos.x, oldrelpos.y, ld); if (side != oldside && ld->special && !(thing->flags6 & MF6_NOTRIGGER)) { @@ -2185,10 +2195,9 @@ pushline: while (numSpecHitTemp > 0) { // see which lines were pushed - ld = spechit[--numSpecHitTemp]; - fixedvec3 pos = thing->PosRelative(ld); - side = P_PointOnLineSide(pos.x, pos.y, ld); - CheckForPushSpecial(ld, side, thing, true); + spechit_t &spec = spechit[--numSpecHitTemp]; + side = P_PointOnLineSide(spec.refpos.x, spec.refpos.y, spec.line); + CheckForPushSpecial(spec.line, side, thing, &spec.refpos); } } return false; diff --git a/src/p_maputl.cpp b/src/p_maputl.cpp index 0e82bf1120..60d94e4b45 100644 --- a/src/p_maputl.cpp +++ b/src/p_maputl.cpp @@ -802,7 +802,6 @@ bool FMultiBlockLinesIterator::Next(FMultiBlockLinesIterator::CheckResult *item) item->position.x = offset.x; item->position.y = offset.y; item->position.z = checkpoint.z; - item->zdiff = 0; item->portalflags = portalflags; return true; } @@ -1055,7 +1054,7 @@ AActor *FBlockThingsIterator::Next(bool centeronly) // //=========================================================================== -FMultiBlockThingsIterator::FMultiBlockThingsIterator(FPortalGroupArray &check, AActor *origin, fixed_t checkradius) +FMultiBlockThingsIterator::FMultiBlockThingsIterator(FPortalGroupArray &check, AActor *origin, fixed_t checkradius, bool ignorerestricted) : checklist(check) { checkpoint = origin->Pos(); @@ -1065,7 +1064,7 @@ FMultiBlockThingsIterator::FMultiBlockThingsIterator(FPortalGroupArray &check, A Reset(); } -FMultiBlockThingsIterator::FMultiBlockThingsIterator(FPortalGroupArray &check, fixed_t checkx, fixed_t checky, fixed_t checkz, fixed_t checkh, fixed_t checkradius) +FMultiBlockThingsIterator::FMultiBlockThingsIterator(FPortalGroupArray &check, fixed_t checkx, fixed_t checky, fixed_t checkz, fixed_t checkh, fixed_t checkradius, bool ignorerestricted) : checklist(check) { checkpoint.x = checkx; @@ -1090,7 +1089,6 @@ bool FMultiBlockThingsIterator::Next(FMultiBlockThingsIterator::CheckResult *ite { item->thing = thing; item->position = checkpoint + Displacements(basegroup, thing->Sector->PortalGroup); - item->zdiff = 0; item->portalflags = portalflags; return true; } diff --git a/src/p_maputl.h b/src/p_maputl.h index 3027df3d49..452f99b3d0 100644 --- a/src/p_maputl.h +++ b/src/p_maputl.h @@ -223,7 +223,6 @@ public: { line_t *line; fixedvec3 position; - fixed_t zdiff; int portalflags; }; @@ -309,12 +308,11 @@ public: { AActor *thing; fixedvec3 position; - fixed_t zdiff; int portalflags; }; - FMultiBlockThingsIterator(FPortalGroupArray &check, AActor *origin, fixed_t checkradius = -1); - FMultiBlockThingsIterator(FPortalGroupArray &check, fixed_t checkx, fixed_t checky, fixed_t checkz, fixed_t checkh, fixed_t checkradius); + FMultiBlockThingsIterator(FPortalGroupArray &check, AActor *origin, fixed_t checkradius = -1, bool ignorerestricted = false); + FMultiBlockThingsIterator(FPortalGroupArray &check, fixed_t checkx, fixed_t checky, fixed_t checkz, fixed_t checkh, fixed_t checkradius, bool ignorerestricted = false); bool Next(CheckResult *item); void Reset(); const FBoundingBox &Box() const