diff --git a/doomsday/apps/client/include/client/clskyplane.h b/doomsday/apps/client/include/client/clskyplane.h new file mode 100644 index 0000000000..62a837010d --- /dev/null +++ b/doomsday/apps/client/include/client/clskyplane.h @@ -0,0 +1,70 @@ +/** @file clskyplane.h Client-side world map sky plane. + * @ingroup world + * + * @authors Copyright © 2016 Daniel Swanson + * + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#ifndef DENG_CLIENT_WORLD_CLSKYPLANE_H +#define DENG_CLIENT_WORLD_CLSKYPLANE_H + +#include + +namespace world { + +/** + * + */ +class ClSkyPlane +{ +public: + /// Notified whenever a @em height change occurs. + DENG2_DEFINE_AUDIENCE2(HeightChange, void clSkyPlaneHeightChanged(ClSkyPlane &skyPlane)) + + ClSkyPlane(bool isCeiling = false, de::ddouble defaultHeight = 0); + + /** + * Returns @c true if this sky plane is configured as the "ceiling". + * + * @see isFloor() + */ + bool isCeiling() const; + + /** + * Returns @c true if this sky plane is configured as the "ceiling". + * + * @see isCeiling() + */ + bool isFloor() const; + + /** + * Returns the current height of the sky plane. + */ + de::ddouble height() const; + + /** + * Change the height of the sky plane to @a newHeight. The HeightChange audience will + * be notified if a change occurs. + */ + void setHeight(de::ddouble newHeight); + +private: + DENG2_PRIVATE(d) +}; + +} // namespace world + +#endif // DENG_CLIENT_WORLD_CLSKYPLANE_H diff --git a/doomsday/apps/client/include/world/map.h b/doomsday/apps/client/include/world/map.h index f2a02a7eec..2270502d73 100644 --- a/doomsday/apps/client/include/world/map.h +++ b/doomsday/apps/client/include/world/map.h @@ -71,6 +71,9 @@ class LineBlockmap; class Subsector; class Sky; class Thinkers; +#ifdef __CLIENT__ +class ClSkyPlane; +#endif /** * World map. @@ -554,19 +557,17 @@ class Map : public world::BaseMap SkyDrawable::Animator &skyAnimator() const; - de::ddouble skyFix(bool ceiling) const; + ClSkyPlane &skyFloor(); + ClSkyPlane const &skyFloor() const; - inline de::ddouble skyFixFloor () const { return skyFix(false /*the floor*/); } - inline de::ddouble skyFixCeiling() const { return skyFix(true /*the ceiling*/); } + ClSkyPlane &skyCeiling(); + ClSkyPlane const &skyCeiling() const; - void setSkyFix(bool ceiling, de::ddouble newHeight); - - inline void setSkyFixFloor(de::ddouble newHeight) { - setSkyFix(false /*the floor*/, newHeight); + inline ClSkyPlane &skyPlane(bool ceiling) { + return ceiling ? skyCeiling() : skyFloor(); } - - inline void setSkyFixCeiling(de::ddouble newHeight) { - setSkyFix(true /*the ceiling*/, newHeight); + inline ClSkyPlane const &skyPlane(bool ceiling) const { + return ceiling ? skyCeiling() : skyFloor(); } #endif diff --git a/doomsday/apps/client/include/world/sky.h b/doomsday/apps/client/include/world/sky.h index 8b7fcbaabf..3d39d750e9 100644 --- a/doomsday/apps/client/include/world/sky.h +++ b/doomsday/apps/client/include/world/sky.h @@ -23,7 +23,6 @@ #define DENG_WORLD_SKY_H #include -#include #include #include #include diff --git a/doomsday/apps/client/src/client/clientsubsector.cpp b/doomsday/apps/client/src/client/clientsubsector.cpp index fb32b3b07a..4a0f67c93d 100644 --- a/doomsday/apps/client/src/client/clientsubsector.cpp +++ b/doomsday/apps/client/src/client/clientsubsector.cpp @@ -26,6 +26,7 @@ #include "world/p_object.h" #include "world/p_players.h" #include "world/surface.h" +#include "client/clskyplane.h" #include "render/rend_main.h" // Rend_SkyLightColor(), useBias #include "BiasIllum" @@ -1522,8 +1523,8 @@ bool ClientSubsector::isHeightInVoid(ddouble height) const // Check the mapped planes. if (visCeiling().surface().hasSkyMaskedMaterial()) { - ddouble const skyCeil = sector().map().skyFixCeiling(); - if (skyCeil < DDMAXFLOAT && height > skyCeil) + ClSkyPlane const &skyCeil = sector().map().skyCeiling(); + if (skyCeil.height() < DDMAXFLOAT && height > skyCeil.height()) return true; } else if (height > visCeiling().heightSmoothed()) @@ -1533,8 +1534,8 @@ bool ClientSubsector::isHeightInVoid(ddouble height) const if (visFloor().surface().hasSkyMaskedMaterial()) { - ddouble const skyFloor = sector().map().skyFixFloor(); - if (skyFloor > DDMINFLOAT && height < skyFloor) + ClSkyPlane const &skyFloor = sector().map().skyFloor(); + if (skyFloor.height() > DDMINFLOAT && height < skyFloor.height()) return true; } else if (height < visFloor().heightSmoothed()) diff --git a/doomsday/apps/client/src/client/clskyplane.cpp b/doomsday/apps/client/src/client/clskyplane.cpp new file mode 100644 index 0000000000..de3d75c351 --- /dev/null +++ b/doomsday/apps/client/src/client/clskyplane.cpp @@ -0,0 +1,68 @@ +/** @file clskyplane.cpp Client-side world map sky plane. + * + * @authors Copyright © 2016 Daniel Swanson + * + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include "client/clskyplane.h" + +using namespace de; + +namespace world { + +DENG2_PIMPL_NOREF(ClSkyPlane) +{ + bool isCeiling = false; ///< @c true if this is the ceiling; otherwise the floor. + ddouble height = 0; + + Impl(bool ceiling, ddouble defaultHeight) + : isCeiling(ceiling), height(defaultHeight) + {} + + DENG2_PIMPL_AUDIENCE(HeightChange) +}; + +DENG2_AUDIENCE_METHOD(ClSkyPlane, HeightChange) + +ClSkyPlane::ClSkyPlane(bool isCeiling, ddouble defaultHeight) + : d(new Impl(isCeiling, defaultHeight)) +{} + +bool ClSkyPlane::isCeiling() const +{ + return d->isCeiling; +} + +bool ClSkyPlane::isFloor() const +{ + return !d->isCeiling; +} + +ddouble ClSkyPlane::height() const +{ + return d->height; +} + +void ClSkyPlane::setHeight(ddouble newHeight) +{ + if (d->height != newHeight) + { + d->height = newHeight; + DENG2_FOR_AUDIENCE2(HeightChange, i) i->clSkyPlaneHeightChanged(*this); + } +} + +} // namespace world diff --git a/doomsday/apps/client/src/render/rend_main.cpp b/doomsday/apps/client/src/render/rend_main.cpp index 901008bbf7..828770475f 100644 --- a/doomsday/apps/client/src/render/rend_main.cpp +++ b/doomsday/apps/client/src/render/rend_main.cpp @@ -39,6 +39,7 @@ #include "ConvexSubspace" #include "Hand" #include "client/clientsubsector.h" +#include "client/clskyplane.h" #include "BiasIllum" #include "HueCircleVisual" #include "LightDecoration" @@ -3066,13 +3067,13 @@ static void writeSubspaceSkyMaskStrips(SkyFixEdge::FixType fixType) static ddouble skyPlaneZ(dint skyCap) { - auto const &subsec = curSubspace->subsector().as(); - dint const relPlane = (skyCap & SKYCAP_UPPER) ? Sector::Ceiling : Sector::Floor; + auto const &subsec = curSubspace->subsector().as(); + dint const planeIndex = (skyCap & SKYCAP_UPPER) ? Sector::Ceiling : Sector::Floor; if (!P_IsInVoid(viewPlayer)) { - return subsec.sector().map().skyFix(relPlane == Sector::Ceiling); + return subsec.sector().map().skyPlane(planeIndex == Sector::Ceiling).height(); } - return subsec.visPlane(relPlane).heightSmoothed(); + return subsec.visPlane(planeIndex).heightSmoothed(); } static DrawList::Indices makeFlatSkyMaskGeometry(Store &verts, gl::Primitive &primitive, @@ -3563,11 +3564,12 @@ static void projectSubspaceSprites() && mob.origin[2] <= subsec.visCeiling().heightSmoothed() && mob.origin[2] >= subsec.visFloor ().heightSmoothed()) { - coord_t visibleTop = mob.origin[2] + material->height(); - if(visibleTop > subsec.sector().map().skyFixCeiling()) + world::ClSkyPlane &skyCeiling = subsec.sector().map().skyCeiling(); + ddouble visibleTop = mob.origin[2] + material->height(); + if(visibleTop > skyCeiling.height()) { - // Raise the skyfix ceiling. - subsec.sector().map().setSkyFixCeiling(visibleTop + 16/*leeway*/); + // Raise the ceiling! + skyCeiling.setHeight(visibleTop + 16/*leeway*/); } } } @@ -5464,11 +5466,10 @@ static void drawSurfaceTangentVectors(Subsector &subsec) { Plane const &plane = subsec.as().visPlane(i); ddouble height = 0; - if (plane.surface().hasSkyMaskedMaterial() && (plane.isSectorFloor() || plane.isSectorCeiling())) { - height = plane.map().skyFix(plane.isSectorCeiling()); + height = plane.map().skyPlane(plane.isSectorCeiling()).height(); } else { diff --git a/doomsday/apps/client/src/render/skyfixedge.cpp b/doomsday/apps/client/src/render/skyfixedge.cpp index 75526da676..efb151c841 100644 --- a/doomsday/apps/client/src/render/skyfixedge.cpp +++ b/doomsday/apps/client/src/render/skyfixedge.cpp @@ -32,40 +32,40 @@ #include "render/rend_main.h" #include "client/clientsubsector.h" +#include "client/clskyplane.h" using namespace world; namespace de { -static coord_t skyFixFloorZ(Plane const *frontFloor, Plane const *backFloor) +static ddouble skyFixFloorZ(Plane const *frontFloor, Plane const *backFloor) { DENG_UNUSED(backFloor); if(devRendSkyMode || P_IsInVoid(viewPlayer)) return frontFloor->heightSmoothed(); - return frontFloor->map().skyFixFloor(); + return frontFloor->map().skyFloor().height(); } -static coord_t skyFixCeilZ(Plane const *frontCeil, Plane const *backCeil) +static ddouble skyFixCeilZ(Plane const *frontCeil, Plane const *backCeil) { DENG_UNUSED(backCeil); if(devRendSkyMode || P_IsInVoid(viewPlayer)) return frontCeil->heightSmoothed(); - return frontCeil->map().skyFixCeiling(); + return frontCeil->map().skyCeiling().height(); } DENG2_PIMPL_NOREF(SkyFixEdge::Event) { SkyFixEdge &owner; - double distance; - - Impl(SkyFixEdge &owner, double distance) + ddouble distance; + Impl(SkyFixEdge &owner, ddouble distance) : owner(owner), distance(distance) {} }; -SkyFixEdge::Event::Event(SkyFixEdge &owner, double distance) - : WorldEdge::Event(), - d(new Impl(owner, distance)) +SkyFixEdge::Event::Event(SkyFixEdge &owner, ddouble distance) + : WorldEdge::Event() + , d(new Impl(owner, distance)) {} bool SkyFixEdge::Event::operator < (Event const &other) const @@ -73,7 +73,7 @@ bool SkyFixEdge::Event::operator < (Event const &other) const return d->distance < other.distance(); } -double SkyFixEdge::Event::distance() const +ddouble SkyFixEdge::Event::distance() const { return d->distance; } @@ -87,7 +87,7 @@ DENG2_PIMPL(SkyFixEdge) { HEdge *hedge; FixType fixType; - int edge; + dint edge; Vector3d pOrigin; Vector3d pDirection; diff --git a/doomsday/apps/client/src/world/base/map.cpp b/doomsday/apps/client/src/world/base/map.cpp index 5f64072121..8f40134e3d 100644 --- a/doomsday/apps/client/src/world/base/map.cpp +++ b/doomsday/apps/client/src/world/base/map.cpp @@ -55,6 +55,7 @@ #include "Vertex" #ifdef __CLIENT__ # include "client/clientsubsector.h" +# include "client/clskyplane.h" #endif #ifdef __CLIENT__ @@ -152,87 +153,7 @@ DENG2_PIMPL(Map) } }; - bool editingEnabled = true; - EditableElements editable; - - AABoxd bounds; ///< Boundary points which encompass the entire map - - Mesh mesh; ///< All map geometries. - - QList sectors; - QList lines; - QList polyobjs; - - Bsp bsp; - QList subspaces; ///< All player-traversable subspaces. - QHash subsectorsById; ///< Not owned. - - // - // Map entities and element properties (things, line specials, etc...). - // - std::unique_ptr thinkers; - Sky sky; - - std::unique_ptr mobjBlockmap; - std::unique_ptr polyobjBlockmap; - std::unique_ptr lineBlockmap; - std::unique_ptr subspaceBlockmap; - -#ifdef __CLIENT__ - struct ContactBlockmap : public Blockmap - { - QBitArray spreadBlocks; ///< Used to prevent repeat processing. - - /** - * Construct a new contact blockmap. - * - * @param bounds Map space boundary. - * @param cellSize Width and height of a cell in map space units. - */ - ContactBlockmap(AABoxd const &bounds, duint cellSize = 128) - : Blockmap(bounds, cellSize) - , spreadBlocks(width() * height()) - {} - - void clear() - { - spreadBlocks.fill(false); - unlinkAll(); - } - - /** - * @param contact Contact to be linked. Note that if the object's origin - * lies outside the blockmap it will not be linked! - */ - void link(Contact &contact) - { - bool outside; - BlockmapCell cell = toCell(contact.objectOrigin(), &outside); - if (!outside) - { - Blockmap::link(cell, &contact); - } - } - - void spread(AABoxd const ®ion) - { - spreadContacts(*this, region, &spreadBlocks); - } - }; - std::unique_ptr mobjContactBlockmap; /// @todo Redundant? - std::unique_ptr lumobjContactBlockmap; -#endif - - nodepile_t mobjNodes; - nodepile_t lineNodes; - nodeindex_t *lineLinks = nullptr; ///< Indices to roots. - #ifdef __CLIENT__ - PlaneSet trackedPlanes; - SurfaceSet scrollingSurfaces; - - SkyDrawable::Animator skyAnimator; - /** * All (particle) generators. */ @@ -292,28 +213,112 @@ DENG2_PIMPL(Map) return nullptr; } }; - std::unique_ptr generators; - std::unique_ptr lightGrid; + struct ContactBlockmap : public Blockmap + { + QBitArray spreadBlocks; ///< Used to prevent repeat processing. + + /** + * Construct a new contact blockmap. + * + * @param bounds Map space boundary. + * @param cellSize Width and height of a cell in map space units. + */ + ContactBlockmap(AABoxd const &bounds, duint cellSize = 128) + : Blockmap(bounds, cellSize) + , spreadBlocks(width() * height()) + {} + + void clear() + { + spreadBlocks.fill(false); + unlinkAll(); + } - /// Shadow Bias data. - struct Bias + /** + * @param contact Contact to be linked. Note that if the object's origin + * lies outside the blockmap it will not be linked! + */ + void link(Contact &contact) + { + bool outside; + BlockmapCell cell = toCell(contact.objectOrigin(), &outside); + if (!outside) + { + Blockmap::link(cell, &contact); + } + } + + void spread(AABoxd const ®ion) + { + spreadContacts(*this, region, &spreadBlocks); + } + }; + + struct BiasData { duint currentTime = 0; ///< The "current" frame in milliseconds. duint lastChangeOnFrame = 0; - QList sources; ///< All bias light sources (owned). - } bias; + }; + +#endif // __CLIENT__ + + bool editingEnabled = true; + EditableElements editable; + + AABoxd bounds; ///< Boundary points which encompass the entire map + + Mesh mesh; ///< All map geometries. + QList sectors; + QList lines; + QList polyobjs; + + Bsp bsp; + QList subspaces; ///< All player-traversable subspaces. + QHash subsectorsById; ///< Not owned. + + // + // Map entities and element properties (things, line specials, etc...). + // + std::unique_ptr thinkers; + Sky sky; + std::unique_ptr mobjBlockmap; + std::unique_ptr polyobjBlockmap; + std::unique_ptr lineBlockmap; + std::unique_ptr subspaceBlockmap; +#ifdef __CLIENT__ + std::unique_ptr mobjContactBlockmap; /// @todo Redundant? + std::unique_ptr lumobjContactBlockmap; +#endif + + nodepile_t mobjNodes; + nodepile_t lineNodes; + nodeindex_t *lineLinks = nullptr; ///< Indices to roots. + +#ifdef __CLIENT__ + PlaneSet trackedPlanes; + SurfaceSet scrollingSurfaces; + SkyDrawable::Animator skyAnimator; + std::unique_ptr generators; + std::unique_ptr lightGrid; + + BiasData bias; ///< Map wide "global" data for Bias lighting. QList lumobjs; ///< All lumobjs (owned). - coord_t skyFloorHeight = DDMAXFLOAT; - coord_t skyCeilingHeight = DDMINFLOAT; + ClSkyPlane skyFloor; + ClSkyPlane skyCeiling; ClMobjHash clMobjHash; #endif - Impl(Public *i) : Base(i) + Impl(Public *i) + : Base(i) +#ifdef __CLIENT__ + , skyFloor (Sector::Floor , DDMAXFLOAT) + , skyCeiling(Sector::Ceiling, DDMINFLOAT) +#endif { sky.setMap(thisPublic); sky.setIndexInMap(0); @@ -2720,8 +2725,8 @@ void Map::initSkyFix() LOG_AS("Map::initSkyFix"); - d->skyFloorHeight = DDMAXFLOAT; - d->skyCeilingHeight = DDMINFLOAT; + d->skyFloor .setHeight(DDMAXFLOAT); + d->skyCeiling.setHeight(DDMINFLOAT); // Update for sector plane heights and mobjs which intersect the ceiling. /// @todo Can't we defer this? @@ -2737,20 +2742,20 @@ void Map::initSkyFix() if (skyCeil) { // Adjust for the plane height. - if (sector->ceiling().heightSmoothed() > d->skyCeilingHeight) + if (sector->ceiling().heightSmoothed() > d->skyCeiling.height()) { // Must raise the skyfix ceiling. - d->skyCeilingHeight = sector->ceiling().heightSmoothed(); + d->skyCeiling.setHeight(sector->ceiling().heightSmoothed()); } // Check that all the mobjs in the sector fit in. for (mobj_t *mob = sector->firstMobj(); mob; mob = mob->sNext) { ddouble extent = mob->origin[2] + mob->height; - if (extent > d->skyCeilingHeight) + if (extent > d->skyCeiling.height()) { // Must raise the skyfix ceiling. - d->skyCeilingHeight = extent; + d->skyCeiling.setHeight(extent); } } } @@ -2758,10 +2763,10 @@ void Map::initSkyFix() if (skyFloor) { // Adjust for the plane height. - if (sector->floor().heightSmoothed() < d->skyFloorHeight) + if (sector->floor().heightSmoothed() < d->skyFloor.height()) { // Must lower the skyfix floor. - d->skyFloorHeight = sector->floor().heightSmoothed(); + d->skyFloor.setHeight(sector->floor().heightSmoothed()); } } @@ -2784,16 +2789,16 @@ void Map::initSkyFix() if (edge.isValid() && edge.top().z() > edge.bottom().z()) { - if (skyCeil && edge.top().z() + edge.origin().y > d->skyCeilingHeight) + if (skyCeil && edge.top().z() + edge.origin().y > d->skyCeiling.height()) { // Must raise the skyfix ceiling. - d->skyCeilingHeight = edge.top().z() + edge.origin().y; + d->skyCeiling.setHeight(edge.top().z() + edge.origin().y); } - if (skyFloor && edge.bottom().z() + edge.origin().y < d->skyFloorHeight) + if (skyFloor && edge.bottom().z() + edge.origin().y < d->skyFloor.height()) { // Must lower the skyfix floor. - d->skyFloorHeight = edge.bottom().z() + edge.origin().y; + d->skyFloor.setHeight(edge.bottom().z() + edge.origin().y); } } return LoopContinue; @@ -2803,15 +2808,24 @@ void Map::initSkyFix() LOGDEV_MAP_VERBOSE("Completed in %.2f seconds") << begunAt.since(); } -coord_t Map::skyFix(bool ceiling) const +ClSkyPlane &Map::skyFloor() +{ + return d->skyFloor; +} + +ClSkyPlane const &Map::skyFloor() const +{ + return d->skyFloor; +} + +ClSkyPlane &Map::skyCeiling() { - return ceiling ? d->skyCeilingHeight : d->skyFloorHeight; + return d->skyCeiling; } -void Map::setSkyFix(bool ceiling, coord_t newHeight) +ClSkyPlane const &Map::skyCeiling() const { - if (ceiling) d->skyCeilingHeight = newHeight; - else d->skyFloorHeight = newHeight; + return d->skyCeiling; } Generator *Map::newGenerator() diff --git a/doomsday/apps/client/src/world/base/p_players.cpp b/doomsday/apps/client/src/world/base/p_players.cpp index 4793237d90..52f0f4c814 100644 --- a/doomsday/apps/client/src/world/base/p_players.cpp +++ b/doomsday/apps/client/src/world/base/p_players.cpp @@ -33,6 +33,7 @@ # include "ui/inputdevice.h" # include "client/clientsubsector.h" +# include "client/clskyplane.h" # include "clientapp.h" #endif @@ -163,43 +164,42 @@ int P_GetDDPlayerIdx(ddplayer_t *ddpl) bool P_IsInVoid(player_t *player) { - if(!player) return false; + if (!player) return false; ddplayer_t const *ddpl = &player->publicData(); // Cameras are allowed to move completely freely (so check z height // above/below ceiling/floor). - if(ddpl->flags & DDPF_CAMERA) + if (ddpl->flags & DDPF_CAMERA) { - if(player->inVoid || !ddpl->mo) + if (player->inVoid || !ddpl->mo) return true; mobj_t const *mob = ddpl->mo; - if(!Mobj_HasSubsector(*mob)) + if (!Mobj_HasSubsector(*mob)) return true; auto const &subsec = Mobj_Subsector(*mob).as(); - if(subsec.visCeiling().surface().hasSkyMaskedMaterial()) + if (subsec.visCeiling().surface().hasSkyMaskedMaterial()) { - ddouble const skyCeil = subsec.sector().map().skyFixCeiling(); - if(skyCeil < DDMAXFLOAT && mob->origin[2] > skyCeil - 4) + world::ClSkyPlane const &skyCeiling = subsec.sector().map().skyCeiling(); + if (skyCeiling.height() < DDMAXFLOAT && mob->origin[2] > skyCeiling.height() - 4) return true; } - else if(mob->origin[2] > subsec.visCeiling().heightSmoothed() - 4) + else if (mob->origin[2] > subsec.visCeiling().heightSmoothed() - 4) { return true; } - if(subsec.visFloor().surface().hasSkyMaskedMaterial()) + if (subsec.visFloor().surface().hasSkyMaskedMaterial()) { - ddouble const skyFloor = subsec.sector().map().skyFixFloor(); - if(skyFloor > DDMINFLOAT && mob->origin[2] < skyFloor + 4) + world::ClSkyPlane const &skyFloor = subsec.sector().map().skyFloor(); + if (skyFloor.height() > DDMINFLOAT && mob->origin[2] < skyFloor.height() + 4) return true; } - else if(mob->origin[2] < subsec.visFloor().heightSmoothed() + 4) + else if (mob->origin[2] < subsec.visFloor().heightSmoothed() + 4) { return true; } } - return false; }