Skip to content

Commit

Permalink
Fixed|World|SectorCluster: Dynamic map-hacks depending on non-neighbo…
Browse files Browse the repository at this point in the history
…r planes

For example, the Red Key trap in Alien Vendetta MAP04 uses a map-hack
construct where the columns are dependent on the Planes from both the
column sector and the adjacent neighbors. Both planes must be observed
in order correctly resolve the "current" dependent plane when a move
occurs.

Also fixed a potential crash given a malformed BSP, where many nested
"selfreferencing" map-hacks might result in leafs being assigned to
the wrong Sector (which will confuse SectorClusterCirculator).
  • Loading branch information
danij-deng committed Apr 30, 2014
1 parent a39861a commit 4c5c18a
Showing 1 changed file with 70 additions and 40 deletions.
110 changes: 70 additions & 40 deletions doomsday/client/src/world/sectorcluster.cpp
Expand Up @@ -136,6 +136,9 @@ DENG2_PIMPL(SectorCluster)

~Instance()
{
observePlane(&self.sector().floor(), false);
observePlane(&self.sector().ceiling(), false);

#ifdef __CLIENT__
self.sector().audienceForLightLevelChange -= this;
self.sector().audienceForLightColorChange -= this;
Expand Down Expand Up @@ -225,13 +228,19 @@ DENG2_PIMPL(SectorCluster)
if(!clusterAdr || *clusterAdr == newCluster)
return;

if(*clusterAdr != thisPublic)
{
observePlane(mappedPlane(planeIdx), false);
}
observeCluster(*clusterAdr, false);
observePlane(mappedPlane(planeIdx), false);

*clusterAdr = newCluster;

observeCluster(*clusterAdr);
observePlane(mappedPlane(planeIdx), true, !permanent);
if(*clusterAdr != thisPublic)
{
observePlane(mappedPlane(planeIdx), true, !permanent);
}
}

void clearMapping(int planeIdx)
Expand Down Expand Up @@ -619,7 +628,10 @@ DENG2_PIMPL(SectorCluster)
SectorClusterCirculator it(base);
do
{
markAllSurfacesForDecorationUpdate(it->mapElementAs<LineSideSegment>().line());
if(it->hasMapElement()) // BSP errors may fool the circulator wrt interior edges -ds
{
markAllSurfacesForDecorationUpdate(it->mapElementAs<LineSideSegment>().line());
}
} while(&it.next() != base);

// Mark surfaces of the inner edge loop(s).
Expand All @@ -628,7 +640,10 @@ DENG2_PIMPL(SectorCluster)
SectorClusterCirculator it(base);
do
{
markAllSurfacesForDecorationUpdate(it->mapElementAs<LineSideSegment>().line());
if(it->hasMapElement()) // BSP errors may fool the circulator wrt interior edges -ds
{
markAllSurfacesForDecorationUpdate(it->mapElementAs<LineSideSegment>().line());
}
} while(&it.next() != base);
}
}
Expand Down Expand Up @@ -664,54 +679,57 @@ DENG2_PIMPL(SectorCluster)
/// Observes Plane HeightChange.
void planeHeightChanged(Plane &plane)
{
// Check if there are any camera players in this sector. If their height
// is now above the ceiling/below the floor they are now in the void.
for(int i = 0; i < DDMAXPLAYERS; ++i)
if(&plane == mappedPlane(plane.indexInSector()))
{
player_t *plr = &ddPlayers[i];
ddplayer_t *ddpl = &plr->shared;
// Check if there are any camera players in this sector. If their height
// is now above the ceiling/below the floor they are now in the void.
for(int i = 0; i < DDMAXPLAYERS; ++i)
{
player_t *plr = &ddPlayers[i];
ddplayer_t *ddpl = &plr->shared;

if(!ddpl->inGame || !ddpl->mo)
continue;
if(Mobj_ClusterPtr(*ddpl->mo) != thisPublic)
continue;
if(!ddpl->inGame || !ddpl->mo)
continue;
if(Mobj_ClusterPtr(*ddpl->mo) != thisPublic)
continue;

if((ddpl->flags & DDPF_CAMERA) &&
(ddpl->mo->origin[VZ] > self.visCeiling().height() - 4 ||
ddpl->mo->origin[VZ] < self.visFloor().height()))
{
ddpl->inVoid = true;
if((ddpl->flags & DDPF_CAMERA) &&
(ddpl->mo->origin[VZ] > self.visCeiling().height() - 4 ||
ddpl->mo->origin[VZ] < self.visFloor().height()))
{
ddpl->inVoid = true;
}
}
}

#ifdef __CLIENT__
// We'll need to recalculate environmental audio characteristics.
needReverbUpdate = true;
// We'll need to recalculate environmental audio characteristics.
needReverbUpdate = true;

if(!ddMapSetup && useBias)
{
// Inform bias surfaces of changed geometry.
foreach(BspLeaf *bspLeaf, bspLeafs)
if(!ddMapSetup && useBias)
{
self.updateBiasAfterGeometryMove(*bspLeaf, plane.indexInSector());

HEdge *base = bspLeaf->poly().hedge();
HEdge *hedge = base;
do
// Inform bias surfaces of changed geometry.
foreach(BspLeaf *bspLeaf, bspLeafs)
{
updateBiasForWallSectionsAfterGeometryMove(hedge);
} while((hedge = &hedge->next()) != base);
self.updateBiasAfterGeometryMove(*bspLeaf, plane.indexInSector());

foreach(Mesh *mesh, bspLeaf->extraMeshes())
foreach(HEdge *hedge, mesh->hedges())
{
updateBiasForWallSectionsAfterGeometryMove(hedge);
HEdge *base = bspLeaf->poly().hedge();
HEdge *hedge = base;
do
{
updateBiasForWallSectionsAfterGeometryMove(hedge);
} while((hedge = &hedge->next()) != base);

foreach(Mesh *mesh, bspLeaf->extraMeshes())
foreach(HEdge *hedge, mesh->hedges())
{
updateBiasForWallSectionsAfterGeometryMove(hedge);
}
}
}
}

markDependantSurfacesForDecorationUpdate();
markDependantSurfacesForDecorationUpdate();
#endif // __CLIENT__
}

// We may need to update one or both mapped planes.
maybeInvalidateMapping(plane.indexInSector());
Expand Down Expand Up @@ -1001,13 +1019,21 @@ DENG2_PIMPL(SectorCluster)
/// Observes Sector LightLevelChange.
void sectorLightLevelChanged(Sector &sector)
{
sector.map().lightGrid().blockLightSourceChanged(thisPublic);
DENG2_ASSERT(&sector == &self.sector());
if(sector.map().hasLightGrid())
{
sector.map().lightGrid().blockLightSourceChanged(thisPublic);
}
}

/// Observes Sector LightColorChange.
void sectorLightColorChanged(Sector &sector)
{
sector.map().lightGrid().blockLightSourceChanged(thisPublic);
DENG2_ASSERT(&sector == &self.sector());
if(sector.map().hasLightGrid())
{
sector.map().lightGrid().blockLightSourceChanged(thisPublic);
}
}
#endif // __CLIENT__
};
Expand All @@ -1022,6 +1048,10 @@ SectorCluster::SectorCluster(BspLeafs const &bspLeafs)
bspLeaf->setCluster(this);
}

// Observe changes to plane heights in "this" sector.
d->observePlane(&sector().floor());
d->observePlane(&sector().ceiling());

#ifdef __CLIENT__
// Observe changes to sector lighting properties.
sector().audienceForLightLevelChange += d;
Expand Down

0 comments on commit 4c5c18a

Please sign in to comment.