diff --git a/src/p_spec.cpp b/src/p_spec.cpp index 0ba2f01d8..bdd6820f4 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -888,6 +888,72 @@ static void SetupCeilingPortal (AStackPoint *point) } } +static bool SpreadCeilingPortal(AStackPoint *pt, fixed_t alpha, sector_t *sector) +{ + bool fail = false; + sector->validcount = validcount; + for(int i=0; ilinecount; i++) + { + line_t *line = sector->lines[i]; + sector_t *backsector = sector == line->frontsector? line->backsector : line->frontsector; + if (line->backsector == line->frontsector) continue; + if (backsector == NULL) { fail = true; continue; } + if (backsector->validcount == validcount) continue; + if (backsector->CeilingSkyBox == pt) continue; + + // Check if the backside would map to the same visplane + if (backsector->CeilingSkyBox != NULL) { fail = true; continue; } + if (backsector->ceilingplane != sector->ceilingplane) { fail = true; continue; } + if (backsector->lightlevel != sector->lightlevel) { fail = true; continue; } + if (backsector->GetTexture(sector_t::ceiling) != sector->GetTexture(sector_t::ceiling)) { fail = true; continue; } + if (backsector->GetXOffset(sector_t::ceiling) != sector->GetXOffset(sector_t::ceiling)) { fail = true; continue; } + if (backsector->GetYOffset(sector_t::ceiling) != sector->GetYOffset(sector_t::ceiling)) { fail = true; continue; } + if (backsector->GetXScale(sector_t::ceiling) != sector->GetXScale(sector_t::ceiling)) { fail = true; continue; } + if (backsector->GetYScale(sector_t::ceiling) != sector->GetYScale(sector_t::ceiling)) { fail = true; continue; } + if (backsector->GetAngle(sector_t::ceiling) != sector->GetAngle(sector_t::ceiling)) { fail = true; continue; } + if (SpreadCeilingPortal(pt, alpha, backsector)) { fail = true; continue; } + } + if (!fail) + { + sector->CeilingSkyBox = pt; + sector->SetAlpha(sector_t::ceiling, alpha); + } + return fail; +} + +static bool SpreadFloorPortal(AStackPoint *pt, fixed_t alpha, sector_t *sector) +{ + bool fail = false; + sector->validcount = validcount; + for(int i=0; ilinecount; i++) + { + line_t *line = sector->lines[i]; + sector_t *backsector = sector == line->frontsector? line->backsector : line->frontsector; + if (line->backsector == line->frontsector) continue; + if (backsector == NULL) { fail = true; continue; } + if (backsector->validcount == validcount) continue; + if (backsector->FloorSkyBox == pt) continue; + + // Check if the backside would map to the same visplane + if (backsector->FloorSkyBox != NULL) { fail = true; continue; } + if (backsector->floorplane != sector->ceilingplane) { fail = true; continue; } + if (backsector->lightlevel != sector->lightlevel) { fail = true; continue; } + if (backsector->GetTexture(sector_t::floor) != sector->GetTexture(sector_t::floor)) { fail = true; continue; } + if (backsector->GetXOffset(sector_t::floor) != sector->GetXOffset(sector_t::floor)) { fail = true; continue; } + if (backsector->GetYOffset(sector_t::floor) != sector->GetYOffset(sector_t::floor)) { fail = true; continue; } + if (backsector->GetXScale(sector_t::floor) != sector->GetXScale(sector_t::floor)) { fail = true; continue; } + if (backsector->GetYScale(sector_t::floor) != sector->GetYScale(sector_t::floor)) { fail = true; continue; } + if (backsector->GetAngle(sector_t::floor) != sector->GetAngle(sector_t::floor)) { fail = true; continue; } + if (SpreadFloorPortal(pt, alpha, backsector)) { fail = true; continue; } + } + if (!fail) + { + sector->FloorSkyBox = pt; + sector->SetAlpha(sector_t::floor, alpha); + } + return fail; +} + void P_SetupPortals() { TThinkerIterator it; @@ -936,6 +1002,20 @@ void P_SetupPortals() } } } + validcount++; + // Some fudging to preserve an unintended 'portal bleeding' effect caused by incomplete checks in the rendering code. + // Due to the addition of linedef-based portals this effect no longer works. + for(int i=0;ibAlways && sectors[i].validcount != validcount) + { + SpreadCeilingPortal(barrier_cast(sectors[i].CeilingSkyBox), sectors[i].GetAlpha(sector_t::ceiling), §ors[i]); + } + if (sectors[i].FloorSkyBox != NULL && sectors[i].FloorSkyBox->bAlways && sectors[i].validcount != validcount) + { + SpreadFloorPortal(barrier_cast(sectors[i].FloorSkyBox), sectors[i].GetAlpha(sector_t::floor), §ors[i]); + } + } } inline void SetPortal(sector_t *sector, int plane, AStackPoint *portal, fixed_t alpha)