Added MF9_BLOCKSIGHT.

This flag allows actors with MF9_DOBLOCKSIGHT to have their vision blocked when calling P_CheckSight(), if an obstacle with the flag gets in the way.
This commit is contained in:
inkoalawetrust 2024-01-28 16:26:22 +02:00
parent 458d81cede
commit e67b8f574b
7 changed files with 69 additions and 9 deletions

View file

@ -443,6 +443,8 @@ enum ActorFlag9
MF9_SHADOWBLOCK = 0x00000004, // [inkoalawetrust] Actors in the line of fire with this flag trigger the MF_SHADOW aiming penalty. MF9_SHADOWBLOCK = 0x00000004, // [inkoalawetrust] Actors in the line of fire with this flag trigger the MF_SHADOW aiming penalty.
MF9_SHADOWAIMVERT = 0x00000008, // [inkoalawetrust] Monster aim is also offset vertically when aiming at shadow actors. MF9_SHADOWAIMVERT = 0x00000008, // [inkoalawetrust] Monster aim is also offset vertically when aiming at shadow actors.
MF9_DECOUPLEDANIMATIONS = 0x00000010, // [RL0] Decouple model animations from states MF9_DECOUPLEDANIMATIONS = 0x00000010, // [RL0] Decouple model animations from states
MF9_BLOCKSIGHT = 0X00000020, // [inkoalawetrust] This actors' hitbox blocks P_CheckSight().
MF9_DOBLOCKSIGHT = 0x00000040 // [inkoalawetrust] When calling P_CheckSight(), this actor checks for MF9_BLOCKSIGHT actors.
}; };
// --- mobj.renderflags --- // --- mobj.renderflags ---

View file

@ -271,6 +271,7 @@ bool P_BounceWall (AActor *mo);
bool P_BounceActor (AActor *mo, AActor *BlockingMobj, bool ontop); bool P_BounceActor (AActor *mo, AActor *BlockingMobj, bool ontop);
bool P_ReflectOffActor(AActor* mo, AActor* blocking); bool P_ReflectOffActor(AActor* mo, AActor* blocking);
int P_CheckSight (AActor *t1, AActor *t2, int flags=0); int P_CheckSight (AActor *t1, AActor *t2, int flags=0);
AActor* P_CheckForSightBlock(AActor* t1, AActor* t2);
enum ESightFlags enum ESightFlags
{ {

View file

@ -36,6 +36,7 @@
#include "g_levellocals.h" #include "g_levellocals.h"
#include "actorinlines.h" #include "actorinlines.h"
#include "shadowinlines.h"
static FRandom pr_botchecksight ("BotCheckSight"); static FRandom pr_botchecksight ("BotCheckSight");
static FRandom pr_checksight ("CheckSight"); static FRandom pr_checksight ("CheckSight");
@ -838,6 +839,38 @@ sightcounts[2]++;
===================== =====================
*/ */
ETraceStatus CheckForSightBlockers(FTraceResults& res, void* userdata)
{
SightCheckData* output = (SightCheckData*)userdata;
if (res.HitType == TRACE_HitActor && res.Actor && (res.Actor->flags9 & MF9_BLOCKSIGHT))
{
output->HitSightBlocker = res.Actor;
return TRACE_Stop;
}
if (res.HitType != TRACE_HitActor)
{
return TRACE_Stop;
}
return TRACE_Continue;
}
// [inkoalawetrust] Check if an MF9_BLOCKSIGHT actor is standing between t1 and t2.
AActor* P_CheckForSightBlock(AActor* t1, AActor* t2)
{
FTraceResults result;
SightCheckData SightCheck;
SightCheck.HitSightBlocker = nullptr;
DVector3 dir = t1->Vec3To(t2);
double dist = dir.Length();
DVector3 origin = t1->PosPlusZ(t1->Height * 0.75); //Standard sight checks are done at this height too.
Trace(origin, t1->Sector, dir, dist, ActorFlags::FromInt(0xFFFFFFFF), ML_BLOCKEVERYTHING, t1, result, 0, CheckForSightBlockers, &SightCheck);
return SightCheck.HitSightBlocker;
}
int P_CheckSight (AActor *t1, AActor *t2, int flags) int P_CheckSight (AActor *t1, AActor *t2, int flags)
{ {
SightCycles.Clock(); SightCycles.Clock();
@ -904,6 +937,18 @@ sightcounts[0]++;
} }
} }
// [inkoalawetrust] All trivial checks passed, now check for MF9_BLOCKSIGHT
if (t1->flags9 & MF9_DOBLOCKSIGHT)
{
AActor* blocker = P_CheckForSightBlock(t1, t2);
if (blocker != nullptr)
{
res = false;
goto done;
}
}
// An unobstructed LOS is possible. // An unobstructed LOS is possible.
// Now look from eyes of t1 to any part of t2. // Now look from eyes of t1 to any part of t2.

View file

@ -25,9 +25,11 @@ inline FRandom pr_shadowaimz("VerticalShadowAim");
// //
//========================================================================== //==========================================================================
// Generic actor sight check data.
struct SightCheckData struct SightCheckData
{ {
AActor* HitShadow; AActor* HitShadow;
AActor* HitSightBlocker;
}; };
inline ETraceStatus CheckForShadowBlockers(FTraceResults& res, void* userdata) inline ETraceStatus CheckForShadowBlockers(FTraceResults& res, void* userdata)

View file

@ -353,6 +353,8 @@ static FFlagDef ActorFlagDefs[]=
DEFINE_FLAG(MF9, SHADOWBLOCK, AActor, flags9), DEFINE_FLAG(MF9, SHADOWBLOCK, AActor, flags9),
DEFINE_FLAG(MF9, SHADOWAIMVERT, AActor, flags9), DEFINE_FLAG(MF9, SHADOWAIMVERT, AActor, flags9),
DEFINE_FLAG(MF9, DECOUPLEDANIMATIONS, AActor, flags9), DEFINE_FLAG(MF9, DECOUPLEDANIMATIONS, AActor, flags9),
DEFINE_FLAG(MF9, BLOCKSIGHT, AActor, flags9),
DEFINE_FLAG(MF9, DOBLOCKSIGHT, AActor, flags9),
// Effect flags // Effect flags
DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects), DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects),

View file

@ -1453,6 +1453,13 @@ DEFINE_ACTION_FUNCTION_NATIVE(AActor, CheckSight, P_CheckSight)
ACTION_RETURN_BOOL(P_CheckSight(self, target, flags)); ACTION_RETURN_BOOL(P_CheckSight(self, target, flags));
} }
DEFINE_ACTION_FUNCTION_NATIVE(AActor, CheckForSightBlocker, P_CheckForSightBlock)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_OBJECT_NOT_NULL(target, AActor);
ACTION_RETURN_OBJECT(P_CheckForSightBlock(self, target));
}
static void GiveSecret(AActor *self, bool printmessage, bool playsound) static void GiveSecret(AActor *self, bool printmessage, bool playsound)
{ {
P_GiveSecret(self->Level, self, printmessage, playsound, -1); P_GiveSecret(self->Level, self, printmessage, playsound, -1);

View file

@ -776,6 +776,7 @@ class Actor : Thinker native
native Actor, int LineAttack(double angle, double distance, double pitch, int damage, Name damageType, class<Actor> pufftype, int flags = 0, out FTranslatedLineTarget victim = null, double offsetz = 0., double offsetforward = 0., double offsetside = 0.); native Actor, int LineAttack(double angle, double distance, double pitch, int damage, Name damageType, class<Actor> pufftype, int flags = 0, out FTranslatedLineTarget victim = null, double offsetz = 0., double offsetforward = 0., double offsetside = 0.);
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 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 CheckSight(Actor target, int flags = 0);
native Actor CheckForSightBlocker (Actor target);
native bool IsVisible(Actor other, bool allaround, LookExParams params = null); native bool IsVisible(Actor other, bool allaround, LookExParams params = null);
native bool, Actor, double PerformShadowChecks (Actor other, Vector3 pos); native bool, Actor, double PerformShadowChecks (Actor other, Vector3 pos);
native bool HitFriend(); native bool HitFriend();