diff --git a/src/actor.h b/src/actor.h index 8f0a8e9f3..912194f62 100644 --- a/src/actor.h +++ b/src/actor.h @@ -488,6 +488,7 @@ enum ActorBounceFlag BOUNCE_UseBounceState = 1<<14, // Use Bounce[.*] states BOUNCE_NotOnShootables = 1<<15, // do not bounce off shootable actors if we are a projectile. Explode instead. BOUNCE_BounceOnUnrips = 1<<16, // projectile bounces on actors with DONTRIP + BOUNCE_NotOnSky = 1<<17, // Don't bounce on sky floors / ceilings / walls BOUNCE_TypeMask = BOUNCE_Walls | BOUNCE_Floors | BOUNCE_Ceilings | BOUNCE_Actors | BOUNCE_AutoOff | BOUNCE_HereticType | BOUNCE_MBF, @@ -1376,7 +1377,7 @@ public: DVector3 PosRelative(int grp) const; DVector3 PosRelative(const AActor *other) const; DVector3 PosRelative(sector_t *sec) const; - DVector3 PosRelative(line_t *line) const; + DVector3 PosRelative(const line_t *line) const; FVector3 SoundPos() const { diff --git a/src/actorinlines.h b/src/actorinlines.h index 10c0ad615..f78163eef 100644 --- a/src/actorinlines.h +++ b/src/actorinlines.h @@ -20,7 +20,7 @@ inline DVector3 AActor::PosRelative(sector_t *sec) const return Pos() + level.Displacements.getOffset(Sector->PortalGroup, sec->PortalGroup); } -inline DVector3 AActor::PosRelative(line_t *line) const +inline DVector3 AActor::PosRelative(const line_t *line) const { return Pos() + level.Displacements.getOffset(Sector->PortalGroup, line->frontsector->PortalGroup); } diff --git a/src/g_levellocals.h b/src/g_levellocals.h index 1e3aed96f..fdd9beb15 100644 --- a/src/g_levellocals.h +++ b/src/g_levellocals.h @@ -38,6 +38,7 @@ #include "doomdata.h" #include "g_level.h" #include "r_defs.h" +#include "r_sky.h" #include "portal.h" #include "p_blockmap.h" #include "p_local.h" @@ -318,3 +319,10 @@ inline int line_t::getPortalAlignment() const { return portalindex >= level.linePortals.Size() ? 0 : level.linePortals[portalindex].mAlign; } + +inline bool line_t::hitSkyWall(AActor* mo) const +{ + return backsector && + backsector->GetTexture(sector_t::ceiling) == skyflatnum && + mo->Z() >= backsector->ceilingplane.ZatPoint(mo->PosRelative(this)); +} diff --git a/src/p_map.cpp b/src/p_map.cpp index 5d248d2db..f463e86c1 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -3551,9 +3551,9 @@ bool FSlide::BounceWall(AActor *mo) } line = bestslideline; - if (line->special == Line_Horizon) + if (line->special == Line_Horizon || (mo->BounceFlags & BOUNCE_NotOnSky) && line->hitSkyWall(mo)) { - mo->SeeSound = 0; // it might make a sound otherwise + mo->SeeSound = mo->BounceSound = 0; // it might make a sound otherwise mo->Destroy(); return true; } diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 67290a08e..d9f488725 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -2178,15 +2178,27 @@ bool AActor::FloorBounceMissile (secplane_t &plane) } } + bool onsky; + if (plane.fC() < 0) { // on ceiling if (!(BounceFlags & BOUNCE_Ceilings)) return true; + + onsky = ceilingpic == skyflatnum; } else { // on floor if (!(BounceFlags & BOUNCE_Floors)) return true; + + onsky = floorpic == skyflatnum; + } + + if (onsky && (BounceFlags & BOUNCE_NotOnSky)) + { + Destroy(); + return true; } // The amount of bounces is limited @@ -2751,10 +2763,7 @@ double P_XYMovement (AActor *mo, DVector2 scroll) explode: // explode a missile bool onsky = false; - if (tm.ceilingline && - tm.ceilingline->backsector && - tm.ceilingline->backsector->GetTexture(sector_t::ceiling) == skyflatnum && - mo->Z() >= tm.ceilingline->backsector->ceilingplane.ZatPoint(mo->PosRelative(tm.ceilingline))) + if (tm.ceilingline && tm.ceilingline->hitSkyWall(mo)) { if (!(mo->flags3 & MF3_SKYEXPLODE)) { diff --git a/src/r_defs.h b/src/r_defs.h index ad128c4dc..74a2d4942 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -1393,6 +1393,7 @@ struct line_t inline bool isVisualPortal() const; inline line_t *getPortalDestination() const; inline int getPortalAlignment() const; + inline bool hitSkyWall(AActor* mo) const; int Index() const; }; diff --git a/src/scripting/thingdef_data.cpp b/src/scripting/thingdef_data.cpp index 60200e765..0c572ba3f 100644 --- a/src/scripting/thingdef_data.cpp +++ b/src/scripting/thingdef_data.cpp @@ -360,6 +360,7 @@ static FFlagDef ActorFlagDefs[]= DEFINE_FLAG2(BOUNCE_UseBounceState, USEBOUNCESTATE, AActor, BounceFlags), DEFINE_FLAG2(BOUNCE_NotOnShootables, DONTBOUNCEONSHOOTABLES, AActor, BounceFlags), DEFINE_FLAG2(BOUNCE_BounceOnUnrips, BOUNCEONUNRIPPABLES, AActor, BounceFlags), + DEFINE_FLAG2(BOUNCE_NotOnSky, DONTBOUNCEONSKY, AActor, BounceFlags), }; // These won't be accessible through bitfield variables