Skip to content

Commit

Permalink
Added MF9_BLOCKSIGHT.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
inkoalawetrust committed Mar 18, 2024
1 parent 458d81c commit e67b8f5
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 9 deletions.
4 changes: 3 additions & 1 deletion src/playsim/actor.h
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,9 @@ enum ActorFlag9
MF9_DOSHADOWBLOCK = 0x00000002, // [inkoalawetrust] Should the monster look for SHADOWBLOCK actors ?
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_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 ---
Expand Down
17 changes: 9 additions & 8 deletions src/playsim/p_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -249,17 +249,17 @@ extern TArray<spechit_t> spechit;
extern TArray<spechit_t> portalhit;


int P_TestMobjLocation (AActor *mobj);
int P_TestMobjZ (AActor *mobj, bool quick=true, AActor **pOnmobj = NULL);
bool P_CheckPosition(AActor *thing, const DVector2 &pos, bool actorsonly = false);
void P_DoMissileDamage(AActor* inflictor, AActor* target);
bool P_CheckPosition(AActor *thing, const DVector2 &pos, FCheckPosition &tm, bool actorsonly = false);
AActor *P_CheckOnmobj (AActor *thing);
int P_TestMobjLocation (AActor *mobj);
int P_TestMobjZ (AActor *mobj, bool quick=true, AActor **pOnmobj = NULL);
bool P_CheckPosition(AActor *thing, const DVector2 &pos, bool actorsonly = false);
void P_DoMissileDamage(AActor* inflictor, AActor* target);
bool P_CheckPosition(AActor *thing, const DVector2 &pos, FCheckPosition &tm, bool actorsonly = false);
AActor* P_CheckOnmobj (AActor *thing);
void P_FakeZMovement (AActor *mo);
bool P_TryMove(AActor* thing, const DVector2 &pos, int dropoff, const secplane_t * onfloor, FCheckPosition &tm, bool missileCheck = false);
bool P_TryMove(AActor* thing, const DVector2 &pos, int dropoff, const secplane_t * onfloor = NULL, bool missilecheck = false);

bool P_CheckMove(AActor *thing, const DVector2 &pos, FCheckPosition& tm, int flags);
bool P_CheckMove(AActor *thing, const DVector2 &pos, FCheckPosition& tm, int flags);
bool P_CheckMove(AActor *thing, const DVector2 &pos, int flags = 0);
void P_ApplyTorque(AActor *mo);

Expand All @@ -270,7 +270,8 @@ void P_SlideMove (AActor* mo, const DVector2 &pos, int numsteps);
bool P_BounceWall (AActor *mo);
bool P_BounceActor (AActor *mo, AActor *BlockingMobj, bool ontop);
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
{
Expand Down
45 changes: 45 additions & 0 deletions src/playsim/p_sight.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@

#include "g_levellocals.h"
#include "actorinlines.h"
#include "shadowinlines.h"

static FRandom pr_botchecksight ("BotCheckSight");
static FRandom pr_checksight ("CheckSight");
Expand Down Expand Up @@ -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)
{
SightCycles.Clock();
Expand Down Expand Up @@ -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.
// Now look from eyes of t1 to any part of t2.

Expand Down
2 changes: 2 additions & 0 deletions src/playsim/shadowinlines.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@ inline FRandom pr_shadowaimz("VerticalShadowAim");
//
//==========================================================================

// Generic actor sight check data.
struct SightCheckData
{
AActor* HitShadow;
AActor* HitSightBlocker;
};

inline ETraceStatus CheckForShadowBlockers(FTraceResults& res, void* userdata)
Expand Down
2 changes: 2 additions & 0 deletions src/scripting/thingdef_data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,8 @@ static FFlagDef ActorFlagDefs[]=
DEFINE_FLAG(MF9, SHADOWBLOCK, AActor, flags9),
DEFINE_FLAG(MF9, SHADOWAIMVERT, AActor, flags9),
DEFINE_FLAG(MF9, DECOUPLEDANIMATIONS, AActor, flags9),
DEFINE_FLAG(MF9, BLOCKSIGHT, AActor, flags9),
DEFINE_FLAG(MF9, DOBLOCKSIGHT, AActor, flags9),

// Effect flags
DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects),
Expand Down
7 changes: 7 additions & 0 deletions src/scripting/vmthunks_actors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1453,6 +1453,13 @@ DEFINE_ACTION_FUNCTION_NATIVE(AActor, CheckSight, P_CheckSight)
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)
{
P_GiveSecret(self->Level, self, printmessage, playsound, -1);
Expand Down
1 change: 1 addition & 0 deletions wadsrc/static/zscript/actors/actor.zs
Original file line number Diff line number Diff line change
Expand Up @@ -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 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 Actor CheckForSightBlocker (Actor target);
native bool IsVisible(Actor other, bool allaround, LookExParams params = null);
native bool, Actor, double PerformShadowChecks (Actor other, Vector3 pos);
native bool HitFriend();
Expand Down

0 comments on commit e67b8f5

Please sign in to comment.