diff --git a/src/playsim/shadowinlines.h b/src/playsim/shadowinlines.h index fce131f7bc..60caa95069 100644 --- a/src/playsim/shadowinlines.h +++ b/src/playsim/shadowinlines.h @@ -25,14 +25,14 @@ inline FRandom pr_shadowaimz("VerticalShadowAim"); // //========================================================================== -struct ShadowCheckData +struct SightCheckData { AActor* HitShadow; }; -static ETraceStatus CheckForShadowBlockers(FTraceResults& res, void* userdata) +inline ETraceStatus CheckForShadowBlockers(FTraceResults& res, void* userdata) { - ShadowCheckData* output = (ShadowCheckData*)userdata; + SightCheckData* output = (SightCheckData*)userdata; if (res.HitType == TRACE_HitActor && res.Actor && (res.Actor->flags9 & MF9_SHADOWBLOCK)) { output->HitShadow = res.Actor; @@ -48,10 +48,10 @@ static ETraceStatus CheckForShadowBlockers(FTraceResults& res, void* userdata) } // [inkoalawetrust] Check if an MF9_SHADOWBLOCK actor is standing between t1 and t2. -inline bool P_CheckForShadowBlock(AActor* t1, AActor* t2, DVector3 pos, double& penaltyFactor) +inline AActor* P_CheckForShadowBlock(AActor* t1, AActor* t2, DVector3 pos, double& penaltyFactor) { FTraceResults result; - ShadowCheckData ShadowCheck; + SightCheckData ShadowCheck; ShadowCheck.HitShadow = nullptr; DVector3 dir; double dist; @@ -78,21 +78,21 @@ inline bool P_CheckForShadowBlock(AActor* t1, AActor* t2, DVector3 pos, double& return ShadowCheck.HitShadow; } -inline bool AffectedByShadows(AActor* self, AActor* other) +inline bool AffectedByShadows(AActor* self) { return (!(self->flags6 & MF6_SEEINVISIBLE) || self->flags9 & MF9_SHADOWAIM); } -inline bool CheckForShadows(AActor* self, AActor* other, DVector3 pos, double& penaltyFactor) +inline AActor* CheckForShadows(AActor* self, AActor* other, DVector3 pos, double& penaltyFactor) { - return ((other && (other->flags & MF_SHADOW)) || (self->flags9 & MF9_DOSHADOWBLOCK) && P_CheckForShadowBlock(self, other, pos, penaltyFactor)); + return ((other && (other->flags & MF_SHADOW)) || (self->flags9 & MF9_DOSHADOWBLOCK)) ? P_CheckForShadowBlock(self, other, pos, penaltyFactor) : nullptr; } -inline bool PerformShadowChecks(AActor* self, AActor* other, DVector3 pos, double& penaltyFactor) +inline AActor* PerformShadowChecks(AActor* self, AActor* other, DVector3 pos, double& penaltyFactor) { - if (other != nullptr) penaltyFactor = other->ShadowPenaltyFactor; //Use target penalty factor by default. - else penaltyFactor = 1.0; - return (AffectedByShadows(self, other) && CheckForShadows(self, other, pos, penaltyFactor)); + if (other != nullptr) penaltyFactor = other->ShadowPenaltyFactor; //Use target penalty factor by default. + else penaltyFactor = 1.0; + return AffectedByShadows(self) ? CheckForShadows(self, other, pos, penaltyFactor) : nullptr; } //========================================================================== diff --git a/src/scripting/vmthunks_actors.cpp b/src/scripting/vmthunks_actors.cpp index e3438d6f61..34bbe6e74d 100644 --- a/src/scripting/vmthunks_actors.cpp +++ b/src/scripting/vmthunks_actors.cpp @@ -55,6 +55,7 @@ #include "actorinlines.h" #include "p_enemy.h" #include "gi.h" +#include "shadowinlines.h" DVector2 AM_GetPosition(); int Net_GetLatency(int *ld, int *ad); @@ -1227,6 +1228,23 @@ DEFINE_ACTION_FUNCTION_NATIVE(AActor, LineTrace, LineTrace) ACTION_RETURN_BOOL(P_LineTrace(self,DAngle::fromDeg(angle),distance,DAngle::fromDeg(pitch),flags,offsetz,offsetforward,offsetside,data)); } +DEFINE_ACTION_FUNCTION(AActor, PerformShadowChecks) +{ + PARAM_SELF_PROLOGUE(AActor); + PARAM_OBJECT(other, AActor); //If this pointer is null, the trace uses the facing direction instead. + PARAM_FLOAT(x); + PARAM_FLOAT(y); + PARAM_FLOAT(z); + + double penaltyFactor = 0.0; + AActor* shadow = PerformShadowChecks(self, other, DVector3(x, y, z), penaltyFactor); + if (numret > 2) ret[2].SetFloat(penaltyFactor); + if (numret > 1) ret[1].SetObject(shadow); + if (numret > 0) ret[0].SetInt(bool(shadow)); + return numret; +} + + static void TraceBleedAngle(AActor *self, int damage, double angle, double pitch) { P_TraceBleed(damage, self, DAngle::fromDeg(angle), DAngle::fromDeg(pitch)); diff --git a/wadsrc/static/zscript/actors/actor.zs b/wadsrc/static/zscript/actors/actor.zs index db83620db5..161a8d8920 100644 --- a/wadsrc/static/zscript/actors/actor.zs +++ b/wadsrc/static/zscript/actors/actor.zs @@ -769,6 +769,7 @@ class Actor : Thinker native native bool LineTrace(double angle, double distance, double pitch, int flags = 0, double offsetz = 0., double offsetforward = 0., double offsetside = 0., out FLineTraceData data = null); native bool CheckSight(Actor target, int flags = 0); native bool IsVisible(Actor other, bool allaround, LookExParams params = null); + native bool, Actor, double PerformShadowChecks (Actor other, Vector3 pos); native bool HitFriend(); native bool MonsterMove();