diff --git a/src/p_map.cpp b/src/p_map.cpp index 8e59d246e..8a5321cf3 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -3679,7 +3679,7 @@ struct aim_t newtrace.bottompitch = newbottompitch; newtrace.aimdir = position == sector_t::ceiling? aim_t::aim_up : aim_t::aim_down; newtrace.startpos = { startpos.x + portal->scaleX, startpos.y + portal->scaleY, startpos.z }; - newtrace.startfrac = frac + FixedDiv(FRACUNIT, attackrange); // this is to skip the transition line to the portal which will produce a bogus opening + newtrace.startfrac = frac + FixedDiv(FRACUNIT, attackrange); // this is to skip the transition line to the portal which would produce a bogus opening newtrace.lastsector = P_PointInSector(newtrace.startpos.x + FixedMul(aimtrace.x, newtrace.startfrac) , newtrace.startpos.y + FixedMul(aimtrace.y, newtrace.startfrac)); newtrace.limitz = portal->threshold; Printf("-----Entering %s portal from sector %d to sector %d\n", position ? "ceiling" : "floor", lastsector->sectornum, newtrace.lastsector->sectornum); @@ -3690,6 +3690,45 @@ struct aim_t Printf("-----Exiting %s portal\n", position ? "ceiling" : "floor"); } + //============================================================================ + // + // traverses a line portal + // simply calling PortalRelocate does not work here because more needs to be set up + // + //============================================================================ + + void EnterLinePortal(line_t *li, fixed_t frac) + { + aim_t newtrace = Clone(); + + FLinePortal *port = li->getPortal(); + line_t *dest = port->mDestination; + + newtrace.toppitch = toppitch; + newtrace.bottompitch = bottompitch; + newtrace.aimdir = aimdir; + newtrace.unlinked = (port->mType != PORTT_LINKED); + newtrace.startpos = startpos; + newtrace.aimtrace = aimtrace; + P_TranslatePortalXY(li, dest, newtrace.startpos.x, newtrace.startpos.y); + P_TranslatePortalZ(li, dest, newtrace.startpos.z); + P_TranslatePortalVXVY(li, dest, newtrace.aimtrace.x, newtrace.aimtrace.y); + + newtrace.startfrac = frac + FixedDiv(FRACUNIT, attackrange); // this is to skip the transition line to the portal which would produce a bogus opening + + fixed_t x = newtrace.startpos.x + FixedMul(newtrace.aimtrace.x, newtrace.startfrac); + fixed_t y = newtrace.startpos.y + FixedMul(newtrace.aimtrace.y, newtrace.startfrac); + + newtrace.lastsector = P_PointInSector(x, y); + P_TranslatePortalZ(li, dest, limitz); + Printf("-----Entering line portal from sector %d to sector %d\n", lastsector->sectornum, newtrace.lastsector->sectornum); + newtrace.AimTraverse(); + SetResult(linetarget, newtrace.linetarget); + SetResult(thing_friend, newtrace.thing_friend); + SetResult(thing_other, newtrace.thing_other); + } + + //============================================================================ // // PTR_AimTraverse @@ -3759,6 +3798,13 @@ struct aim_t Printf("Found line %d: toppitch = %f, bottompitch = %f\n", int(li - lines), ANGLE2DBL(toppitch), ANGLE2DBL(bottompitch)); + if (li->isLinePortal() && frontflag == 0) + { + EnterLinePortal(li, in->frac); + return; + } + + if (!(li->flags & ML_TWOSIDED) || (li->flags & ML_BLOCKEVERYTHING)) return; // stop @@ -3886,7 +3932,7 @@ struct aim_t if (crossedffloors) { // if 3D floors were in the way do an extra visibility check for safety - if (!P_CheckSight(shootthing, th, SF_IGNOREVISIBILITY | SF_IGNOREWATERBOUNDARY)) + if (!unlinked && !P_CheckSight(shootthing, th, SF_IGNOREVISIBILITY | SF_IGNOREWATERBOUNDARY)) { // the thing can't be seen so we can safely exclude its range from our aiming field if (thingtoppitch < toppitch) diff --git a/src/p_maputl.cpp b/src/p_maputl.cpp index a00bc3b87..11284a7bf 100644 --- a/src/p_maputl.cpp +++ b/src/p_maputl.cpp @@ -1616,7 +1616,7 @@ void FPathTraverse::init (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, int fl // //=========================================================================== -bool FPathTraverse::PortalRelocate(intercept_t *in, int flags, fixedvec3 *optpos) +int FPathTraverse::PortalRelocate(intercept_t *in, int flags, fixedvec3 *optpos) { if (!in->isaline || !in->d.line->isLinePortal()) return false; if (P_PointOnLineSidePrecise(trace.x, trace.y, in->d.line) == 1) return false; @@ -1636,7 +1636,7 @@ bool FPathTraverse::PortalRelocate(intercept_t *in, int flags, fixedvec3 *optpos } intercepts.Resize(intercept_index); init(hitx, hity, endx, endy, flags, in->frac); - return true; + return in->d.line->getPortal()->mType == PORTT_LINKED? 1:-1; } //=========================================================================== diff --git a/src/p_maputl.h b/src/p_maputl.h index 5b702a2d1..d8044303e 100644 --- a/src/p_maputl.h +++ b/src/p_maputl.h @@ -356,7 +356,7 @@ public: init(x1, y1, x2, y2, flags, startfrac); } void init(fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, int flags, fixed_t startfrac = 0); - bool PortalRelocate(intercept_t *in, int flags, fixedvec3 *optpos = NULL); + int PortalRelocate(intercept_t *in, int flags, fixedvec3 *optpos = NULL); virtual ~FPathTraverse(); const divline_t &Trace() const { return trace; } };