diff --git a/src/gl/dynlights/a_dynlight.cpp b/src/gl/dynlights/a_dynlight.cpp index 45e8bfb14..0ab834505 100644 --- a/src/gl/dynlights/a_dynlight.cpp +++ b/src/gl/dynlights/a_dynlight.cpp @@ -582,81 +582,107 @@ double ADynamicLight::DistToSeg(const DVector3 &pos, seg_t *seg) // to sidedefs and sector parts. // //========================================================================== +struct LightLinkEntry +{ + subsector_t *sub; + DVector3 pos; +}; +static TArray collected_ss; -void ADynamicLight::CollectWithinRadius(const DVector3 &pos, subsector_t *subSec, float radius) +void ADynamicLight::CollectWithinRadius(const DVector3 &opos, subsector_t *subSec, float radius) { if (!subSec) return; - + collected_ss.Clear(); + collected_ss.Push({ subSec, opos }); subSec->validcount = ::validcount; - touching_subsectors = AddLightNode(&subSec->lighthead, subSec, this, touching_subsectors); - if (subSec->sector->validcount != ::validcount) + for (unsigned i = 0; i < collected_ss.Size(); i++) { - touching_sector = AddLightNode(&subSec->render_sector->lighthead, subSec->sector, this, touching_sector); - subSec->sector->validcount = ::validcount; - } + subSec = collected_ss[i].sub; + auto &pos = collected_ss[i].pos; - for (unsigned int i = 0; i < subSec->numlines; i++) - { - seg_t * seg = subSec->firstline + i; - - // check distance from x/y to seg and if within radius add this seg and, if present the opposing subsector (lather/rinse/repeat) - // If out of range we do not need to bother with this seg. - if (DistToSeg(pos, seg) <= radius) + touching_subsectors = AddLightNode(&subSec->lighthead, subSec, this, touching_subsectors); + if (subSec->sector->validcount != ::validcount) { - if (seg->sidedef && seg->linedef && seg->linedef->validcount != ::validcount) + touching_sector = AddLightNode(&subSec->render_sector->lighthead, subSec->sector, this, touching_sector); + subSec->sector->validcount = ::validcount; + } + + for (unsigned int i = 0; i < subSec->numlines; i++) + { + seg_t * seg = subSec->firstline + i; + + // check distance from x/y to seg and if within radius add this seg and, if present the opposing subsector (lather/rinse/repeat) + // If out of range we do not need to bother with this seg. + if (DistToSeg(pos, seg) <= radius) { - // light is in front of the seg - if ((pos.Y - seg->v1->fY()) * (seg->v2->fX() - seg->v1->fX()) + (seg->v1->fX() - pos.X) * (seg->v2->fY() - seg->v1->fY()) <= 0) + if (seg->sidedef && seg->linedef && seg->linedef->validcount != ::validcount) { - seg->linedef->validcount = validcount; - touching_sides = AddLightNode(&seg->sidedef->lighthead, seg->sidedef, this, touching_sides); - } - } - if (seg->linedef) - { - FLinePortal *port = seg->linedef->getPortal(); - if (port && port->mType == PORTT_LINKED) - { - line_t *other = port->mDestination; - if (other->validcount != ::validcount) + // light is in front of the seg + if ((pos.Y - seg->v1->fY()) * (seg->v2->fX() - seg->v1->fX()) + (seg->v1->fX() - pos.X) * (seg->v2->fY() - seg->v1->fY()) <= 0) { - subsector_t *othersub = R_PointInSubsector(other->v1->fPos() + other->Delta() / 2); - if (othersub->validcount != ::validcount) CollectWithinRadius(PosRelative(other), othersub, radius); + seg->linedef->validcount = validcount; + touching_sides = AddLightNode(&seg->sidedef->lighthead, seg->sidedef, this, touching_sides); + } + } + if (seg->linedef) + { + FLinePortal *port = seg->linedef->getPortal(); + if (port && port->mType == PORTT_LINKED) + { + line_t *other = port->mDestination; + if (other->validcount != ::validcount) + { + subsector_t *othersub = R_PointInSubsector(other->v1->fPos() + other->Delta() / 2); + if (othersub->validcount != ::validcount) + { + othersub->validcount = ::validcount; + collected_ss.Push({ othersub, PosRelative(other) }); + } + } + } + } + + seg_t *partner = seg->PartnerSeg; + if (partner) + { + subsector_t *sub = partner->Subsector; + if (sub != NULL && sub->validcount != ::validcount) + { + sub->validcount = ::validcount; + collected_ss.Push({ sub, pos }); } } } - - seg_t *partner = seg->PartnerSeg; - if (partner) + } + sector_t *sec = subSec->sector; + if (!sec->PortalBlocksSight(sector_t::ceiling)) + { + line_t *other = subSec->firstline->linedef; + if (sec->GetPortalPlaneZ(sector_t::ceiling) < Z() + radius) { - subsector_t *sub = partner->Subsector; - if (sub != NULL && sub->validcount != ::validcount) + DVector2 refpos = other->v1->fPos() + other->Delta() / 2 + sec->GetPortalDisplacement(sector_t::ceiling); + subsector_t *othersub = R_PointInSubsector(refpos); + if (othersub->validcount != ::validcount) { - CollectWithinRadius(pos, sub, radius); + othersub->validcount = ::validcount; + collected_ss.Push({ othersub, PosRelative(othersub->sector) }); } } } - } - sector_t *sec = subSec->sector; - if (!sec->PortalBlocksSight(sector_t::ceiling)) - { - line_t *other = subSec->firstline->linedef; - if (sec->GetPortalPlaneZ(sector_t::ceiling) < Z() + radius) + if (!sec->PortalBlocksSight(sector_t::floor)) { - DVector2 refpos = other->v1->fPos() + other->Delta() / 2 + sec->GetPortalDisplacement(sector_t::ceiling); - subsector_t *othersub = R_PointInSubsector(refpos); - if (othersub->validcount != ::validcount) CollectWithinRadius(PosRelative(othersub->sector), othersub, radius); - } - } - if (!sec->PortalBlocksSight(sector_t::floor)) - { - line_t *other = subSec->firstline->linedef; - if (sec->GetPortalPlaneZ(sector_t::floor) > Z() - radius) - { - DVector2 refpos = other->v1->fPos() + other->Delta() / 2 + sec->GetPortalDisplacement(sector_t::floor); - subsector_t *othersub = R_PointInSubsector(refpos); - if (othersub->validcount != ::validcount) CollectWithinRadius(PosRelative(othersub->sector), othersub, radius); + line_t *other = subSec->firstline->linedef; + if (sec->GetPortalPlaneZ(sector_t::floor) > Z() - radius) + { + DVector2 refpos = other->v1->fPos() + other->Delta() / 2 + sec->GetPortalDisplacement(sector_t::floor); + subsector_t *othersub = R_PointInSubsector(refpos); + if (othersub->validcount != ::validcount) + { + othersub->validcount = ::validcount; + collected_ss.Push({ othersub, PosRelative(othersub->sector) }); + } + } } } } diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index 54f1dd75b..81164e434 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -102,9 +102,10 @@ void GLWall::SetupLights() Vector fn, pos; - float x = node->lightsource->X(); - float y = node->lightsource->Y(); - float z = node->lightsource->Z(); + DVector3 posrel = node->lightsource->PosRelative(seg->frontsector); + float x = posrel.X; + float y = posrel.Y; + float z = posrel.Z; float dist = fabsf(p.DistToPoint(x, z, y)); float radius = node->lightsource->GetRadius(); float scale = 1.0f / ((2.f * radius) - dist); diff --git a/src/p_map.cpp b/src/p_map.cpp index 290b84b9e..f889069f1 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -869,12 +869,6 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec if (tm.thing->Z() < portz && tm.thing->Z() + tm.thing->MaxStepHeight >= portz && tm.floorz < portz) { // Actor is stepping through a portal. - /* - tm.floorz = portz; - tm.floorsector = oppsec; - tm.floorpic = cres.line->sidedef[0]->GetTexture(side_t::mid); - tm.floorterrain = 0; - */ tm.portalstep = true; return true; } @@ -2150,7 +2144,7 @@ bool P_TryMove(AActor *thing, const DVector2 &pos, goto pushline; } else if (BlockingMobj->Top() - thing->Z() > thing->MaxStepHeight - || (BlockingMobj->Sector->ceilingplane.ZatPoint(pos) - (BlockingMobj->Top()) < thing->Height) + || ((BlockingMobj->Sector->ceilingplane.ZatPoint(pos) - (BlockingMobj->Top()) < thing->Height) && BlockingMobj->Sector->PortalBlocksMovement(sector_t::ceiling)) || (tm.ceilingz - (BlockingMobj->Top()) < thing->Height)) { goto pushline; diff --git a/src/p_sight.cpp b/src/p_sight.cpp index 21aa1bbe3..df02e2ebb 100644 --- a/src/p_sight.cpp +++ b/src/p_sight.cpp @@ -716,6 +716,7 @@ bool SightCheck::P_SightPathTraverse () // step through map blocks // Count is present to prevent a round off error from skipping the break + int itres; for (count = 0 ; count < 1000 ; count++) { // end traversing when reaching the end of the blockmap @@ -724,15 +725,15 @@ bool SightCheck::P_SightPathTraverse () { break; } - int res = P_SightBlockLinesIterator(mapx, mapy); - if (res == 0) + itres = P_SightBlockLinesIterator(mapx, mapy); + if (itres == 0) { sightcounts[1]++; return false; // early out } // either reached the end or had an early-out condition with portals left to check, - if (res == -1 || (mapxstep | mapystep) == 0) + if (itres == -1 || (mapxstep | mapystep) == 0) break; switch (((xs_FloorToInt(yintercept) == mapy) << 1) | (xs_FloorToInt(xintercept) == mapx)) @@ -787,7 +788,9 @@ sightcounts[1]++; // sightcounts[2]++; - return P_SightTraverseIntercepts ( ); + bool traverseres = P_SightTraverseIntercepts ( ); + if (itres == -1) return false; // if the iterator had an early out there was no line of sight. The traverser was only called to collect more portals. + return traverseres; } /* diff --git a/wadsrc/static/filter/hexen/sprofs.txt b/wadsrc/static/filter/hexen/sprofs.txt index a8d614ca0..4408e3b95 100644 --- a/wadsrc/static/filter/hexen/sprofs.txt +++ b/wadsrc/static/filter/hexen/sprofs.txt @@ -57,7 +57,7 @@ CLERW0, 37, 53, iwad CLERX0, 37, 43, iwad CLERY0, 38, 30, iwad CLERZ0, 38, 18, iwad -CLER[0, 38, 12, iwad +"CLER[0", 38, 12, iwad CPB1A0, 8, 7, iwad CPB2A0, 7, 6, iwad CPB3A0, 12, 4, iwad diff --git a/wadsrc/static/filter/strife/sprofs.txt b/wadsrc/static/filter/strife/sprofs.txt index d7118297b..c6dafb581 100644 --- a/wadsrc/static/filter/strife/sprofs.txt +++ b/wadsrc/static/filter/strife/sprofs.txt @@ -200,8 +200,8 @@ PGRDW0, 35, 28, iwad PGRDX0, 35, 28, iwad PGRDY0, 35, 28, iwad PGRDZ0, 35, 28, iwad -PGRD[0, 35, 28, iwad -PGRD\0, 35, 28, iwad +"PGRD[0", 35, 28, iwad +"PGRD\0", 35, 28, iwad PDEDE0, 22, 20, iwad PDEDF0, 23, 16, iwad PDEDG0, 23, 15, iwad