diff --git a/src/p_local.h b/src/p_local.h index e553def292..06748c76a6 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -110,7 +110,8 @@ enum EPuffFlags PF_MELEERANGE = 2, PF_TEMPORARY = 4, PF_HITTHINGBLEED = 8, - PF_NORANDOMZ = 16 + PF_NORANDOMZ = 16, + PF_HITSKY = 32 }; AActor *P_SpawnPuff(AActor *source, PClassActor *pufftype, const DVector3 &pos, DAngle hitdir, DAngle particledir, int updown, int flags = 0, AActor *vict = NULL); diff --git a/src/p_map.cpp b/src/p_map.cpp index bb7164ef7c..ed4f0d0896 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -4623,9 +4623,13 @@ AActor *P_LineAttack(AActor *t1, DAngle angle, double distance, damageType = puffDefaults->DamageType; } - int tflags; - if (nointeract || (puffDefaults && puffDefaults->flags6 & MF6_NOTRIGGER)) tflags = TRACE_NoSky; - else tflags = TRACE_NoSky | TRACE_Impact; + uint32_t tflags = TRACE_NoSky | TRACE_Impact; + if (nointeract || (puffDefaults && puffDefaults->flags6 & MF6_NOTRIGGER)) tflags &= ~TRACE_Impact; + if (spawnSky) + { + tflags &= ~TRACE_NoSky; + tflags |= TRACE_HitSky; + } // [MC] Check the flags and set the position according to what is desired. // LAF_ABSPOSITION: Treat the offset parameters as direct coordinates. @@ -4683,8 +4687,16 @@ AActor *P_LineAttack(AActor *t1, DAngle angle, double distance, { if (trace.HitType != TRACE_HitActor) { + + if (trace.HitType == TRACE_HasHitSky || (trace.HitType == TRACE_HitWall + && trace.Line->special == Line_Horizon && spawnSky)) + { + puffFlags |= PF_HITSKY; + } + P_GeometryLineAttack(trace, t1, damage, damageType); + // position a bit closer for puffs if (nointeract || trace.HitType != TRACE_HitWall || ((trace.Line->special != Line_Horizon) || spawnSky)) { diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index fe40348c16..596a9fc01a 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -6245,7 +6245,11 @@ AActor *P_SpawnPuff (AActor *source, PClassActor *pufftype, const DVector3 &pos1 // it will enter the crash state. This is used by the StrifeSpark // and BlasterPuff. FState *crashstate; - if (!(flags & PF_HITTHING) && (crashstate = puff->FindState(NAME_Crash)) != NULL) + if ((flags & PF_HITSKY) && (crashstate = puff->FindState(NAME_Death, NAME_Sky, true)) != NULL) + { + puff->SetState (crashstate); + } + else if (!(flags & PF_HITTHING) && (crashstate = puff->FindState(NAME_Crash)) != NULL) { puff->SetState (crashstate); } diff --git a/src/p_trace.cpp b/src/p_trace.cpp index 48e49dba07..d2f3e71f40 100644 --- a/src/p_trace.cpp +++ b/src/p_trace.cpp @@ -938,6 +938,27 @@ bool FTraceInfo::CheckPlane (const secplane_t &plane) static bool EditTraceResult (uint32_t flags, FTraceResults &res) { + if (flags & TRACE_HitSky) + { // Throw away sky hits + if (res.HitType == TRACE_HitFloor || res.HitType == TRACE_HitCeiling) + { + if (res.HitTexture == skyflatnum) + { + res.HitType = TRACE_HasHitSky; + return true; + } + } + else if (res.HitType == TRACE_HitWall) + { + if (res.Tier == TIER_Upper && + res.Line->frontsector->GetTexture(sector_t::ceiling) == skyflatnum && + res.Line->backsector->GetTexture(sector_t::ceiling) == skyflatnum) + { + res.HitType = TRACE_HasHitSky; + return true; + } + } + } if (flags & TRACE_NoSky) { // Throw away sky hits if (res.HitType == TRACE_HitFloor || res.HitType == TRACE_HitCeiling) diff --git a/src/p_trace.h b/src/p_trace.h index 92a0f30a53..5e733b4c4c 100644 --- a/src/p_trace.h +++ b/src/p_trace.h @@ -52,6 +52,7 @@ enum ETraceResult TRACE_HitWall, TRACE_HitActor, TRACE_CrossingPortal, + TRACE_HasHitSky, }; enum @@ -98,6 +99,7 @@ enum TRACE_PortalRestrict= 0x0008, // Cannot go through portals without a static link offset. TRACE_ReportPortals = 0x0010, // Report any portal crossing to the TraceCallback TRACE_3DCallback = 0x0020, // [ZZ] use TraceCallback to determine whether we need to go through a line to do 3D floor check, or not. without this, only line flag mask is used + TRACE_HitSky = 0x0040, // Hitting the sky returns TRACE_HasHitSky }; // return values from callback diff --git a/wadsrc/static/zscript/actor.txt b/wadsrc/static/zscript/actor.txt index 767b87e0f8..c30d6cb249 100644 --- a/wadsrc/static/zscript/actor.txt +++ b/wadsrc/static/zscript/actor.txt @@ -38,7 +38,8 @@ struct FLineTraceData TRACE_HitCeiling, TRACE_HitWall, TRACE_HitActor, - TRACE_CrossingPortal + TRACE_CrossingPortal, + TRACE_HasHitSky }; Actor HitActor; diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index 314b59b3a3..fa7a8182d5 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -503,6 +503,7 @@ enum ETraceFlags TRACE_PortalRestrict = 0x0008, // Cannot go through portals without a static link offset. TRACE_ReportPortals = 0x0010, // Report any portal crossing to the TraceCallback //TRACE_3DCallback = 0x0020, // [ZZ] use TraceCallback to determine whether we need to go through a line to do 3D floor check, or not. without this, only line flag mask is used + TRACE_HitSky = 0x0040 // Hitting the sky returns TRACE_HasHitSky } @@ -513,7 +514,8 @@ enum ETraceResult TRACE_HitCeiling, TRACE_HitWall, TRACE_HitActor, - TRACE_CrossingPortal + TRACE_CrossingPortal, + TRACE_HasHitSky } enum ELineTier diff --git a/wadsrc/static/zscript/constants.txt b/wadsrc/static/zscript/constants.txt index dc394a0d20..92f5483558 100644 --- a/wadsrc/static/zscript/constants.txt +++ b/wadsrc/static/zscript/constants.txt @@ -1122,7 +1122,8 @@ enum EPuffFlags PF_MELEERANGE = 2, PF_TEMPORARY = 4, PF_HITTHINGBLEED = 8, - PF_NORANDOMZ = 16 + PF_NORANDOMZ = 16, + PF_HITSKY = 32 }; enum EPlayerCheats