Skip to content

Commit

Permalink
ZScriptify a detection check in P_LookForPlayers
Browse files Browse the repository at this point in the history
  • Loading branch information
mykola-ambar committed Sep 29, 2024
1 parent 2c25cc1 commit ad1b6ea
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 30 deletions.
8 changes: 8 additions & 0 deletions src/playsim/actor.h
Original file line number Diff line number Diff line change
Expand Up @@ -949,6 +949,14 @@ class AActor final : public DThinker
// Do I hate the other actor?
bool IsHostile (AActor *other);

// Can I detect the other actor?
bool CanDetect(AActor *other);
bool CallCanDetect(AActor *other);

// Can I be detected by the other actor?
bool CanBeDetectedBy(AActor *other);
bool CallCanBeDetectedBy(AActor *other);

inline bool IsNoClip2() const;
void CheckPortalTransition(bool islinked);
DVector3 GetPortalTransition(double byoffset, sector_t **pSec = NULL);
Expand Down
19 changes: 3 additions & 16 deletions src/playsim/p_enemy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ static FRandom pr_opendoor ("OpenDoor");
static FRandom pr_trywalk ("TryWalk");
static FRandom pr_newchasedir ("NewChaseDir");
static FRandom pr_lookformonsters ("LookForMonsters");
static FRandom pr_lookforplayers ("LookForPlayers");
static FRandom pr_scaredycat ("Anubis");
FRandom pr_chase ("Chase");
FRandom pr_facetarget ("FaceTarget");
Expand Down Expand Up @@ -1835,22 +1834,10 @@ int P_LookForPlayers (AActor *actor, INTBOOL allaround, FLookExParams *params)
if (!P_IsVisible (actor, player->mo, allaround, params))
continue; // out of sight

// [RC] Well, let's let special monsters with this flag active be able to see
// the player then, eh?
if(!(actor->flags6 & MF6_SEEINVISIBLE))

if ( !actor->CallCanDetect(player->mo) || !player->mo->CallCanBeDetectedBy(actor) )
{
if ((player->mo->flags & MF_SHADOW && !(actor->Level->i_compatflags & COMPATF_INVISIBILITY)) ||
player->mo->flags3 & MF3_GHOST)
{
if (player->mo->Distance2D (actor) > 128 && player->mo->Vel.XY().LengthSquared() < 5*5)
{ // Player is sneaking - can't detect
continue;
}
if (pr_lookforplayers() < 225)
{ // Player isn't sneaking, but still didn't detect
continue;
}
}
continue;
}

// [RH] Need to be sure the reactiontime is 0 if the monster is
Expand Down
2 changes: 2 additions & 0 deletions src/playsim/p_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ struct FRenderViewpoint;
#define USERANGE (64.)

#define DEFMELEERANGE (64.)
#define DEFMELEEDELTA (20.)

#define MISSILERANGE (32*64.)
#define PLAYERMISSILERANGE (8192.) // [RH] New MISSILERANGE for players

Expand Down
99 changes: 99 additions & 0 deletions src/playsim/p_mobj.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ static FRandom pr_missiledamage ("MissileDamage");
static FRandom pr_multiclasschoice ("MultiClassChoice");
static FRandom pr_rockettrail("RocketTrail");
static FRandom pr_uniquetid("UniqueTID");
static FRandom pr_canbedetectedby("CanBeDetectedBy");

// PUBLIC DATA DEFINITIONS -------------------------------------------------

Expand Down Expand Up @@ -7532,6 +7533,104 @@ bool AActor::IsHostile (AActor *other)
return true;
}

//==========================================================================
//
// AActor :: CanBeDetectedBy
//
// Override this if you want to customize the conditions in which another
// actor can detect this one with A_Look
//
//==========================================================================

bool AActor::CanBeDetectedBy(AActor *other)
{
static FName SneakSpeed = FName("SneakSpeed");
static FName NonSneakDetectionChance = FName("NonSneakDetectionChance");
if (this->player)
{
if (!(other->flags6 & MF6_SEEINVISIBLE))
{
if (((this->flags & MF_SHADOW) && !(this->Level->i_compatflags & COMPATF_INVISIBILITY)) || (this->flags3 & MF3_GHOST))
{
double distancesquared = this->Distance2DSquared(other);
double velsquared = this->Vel.LengthSquared();
double meleerange = other->meleerange + DEFMELEEDELTA;
double sneakspeedsquared = this->FloatVar(SneakSpeed);
sneakspeedsquared = sneakspeedsquared * sneakspeedsquared;

if (distancesquared > (2 * meleerange * 2 * meleerange) && velsquared < sneakspeedsquared)
{
// Player is sneaking - can't detect
return false;
}
double nonsneakdetectionchance = this->FloatVar(NonSneakDetectionChance);
if (pr_canbedetectedby.GenRand_Real1() < nonsneakdetectionchance)
{
// Player isn't sneaking, but still didn't detect
return false;
}
}
}
}
return true;
}

DEFINE_ACTION_FUNCTION(AActor, CanBeDetectedBy)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_OBJECT(other, AActor);
ACTION_RETURN_BOOL(self->CanBeDetectedBy(other));
}

bool AActor::CallCanBeDetectedBy(AActor *other)
{
IFVIRTUAL(AActor, CanBeDetectedBy)
{
VMValue params[] = { (DObject*)this, other };
int retv;
VMReturn ret(&retv);
VMCall(func, params, 2, &ret, 1);
return !!retv;
}
return CanBeDetectedBy(other);
}

//==========================================================================
//
// AActor :: CanDetect
//
// Customize this if you want to customize the conditions under which this
// actor can detect another one with A_Look
//
//==========================================================================

bool AActor::CanDetect(AActor *other)
{
return true;
}

DEFINE_ACTION_FUNCTION(AActor, CanDetect)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_OBJECT(other, AActor);
ACTION_RETURN_BOOL(self->CanDetect(other));
}

bool AActor::CallCanDetect(AActor *other)
{
IFVIRTUAL(AActor, CanDetect)
{
VMValue params[] = { (DObject*)this, other };
int retv;
VMReturn ret(&retv);
VMCall(func, params, 2, &ret, 1);
return !!retv;
}
return CanDetect(other);
}



//==========================================================================
//
// AActor :: DoSpecialDamage
Expand Down
4 changes: 2 additions & 2 deletions wadsrc/static/zscript/actors/actor.zs
Original file line number Diff line number Diff line change
Expand Up @@ -861,6 +861,8 @@ class Actor : Thinker native
native bool BouncePlane(readonly<SecPlane> plane);
native void PlayBounceSound(bool onFloor);
native bool ReflectOffActor(Actor blocking);
native virtual bool CanDetect(Actor actor);
native virtual bool CanBeDetectedBy(Actor actor);

clearscope double PitchTo(Actor target, double zOfs = 0, double targZOfs = 0, bool absolute = false) const
{
Expand Down Expand Up @@ -1482,8 +1484,6 @@ class Actor : Thinker native
{
if (player == NULL) Destroy();
}



States(Actor, Overlay, Weapon, Item)
{
Expand Down
18 changes: 6 additions & 12 deletions wadsrc/static/zscript/actors/player/player.zs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ class PlayerPawn : Actor
double FullHeight;
double curBob;
double prevBob;
double SneakSpeed; // Speed at which the player is considered to be sneaking (used for non-vanilla blursphere and heretic ghostsphere)
double NonSneakDetectionChance; // Chance to detect the player while they're sneaking and invisible

meta Name HealingRadiusType;
meta Name InvulMode;
Expand Down Expand Up @@ -82,6 +84,8 @@ class PlayerPawn : Actor
property ViewBob: ViewBob;
property ViewBobSpeed: ViewBobSpeed;
property WaterClimbSpeed : WaterClimbSpeed;
property SneakSpeed : SneakSpeed;
property NonSneakDetectionChance : NonSneakDetectionChance;

flagdef NoThrustWhenInvul: PlayerFlags, 0;
flagdef CanSuperMorph: PlayerFlags, 1;
Expand Down Expand Up @@ -133,6 +137,8 @@ class PlayerPawn : Actor
Player.ViewBobSpeed 20;
Player.WaterClimbSpeed 3.5;
Player.TeleportFreezeTime 18;
Player.SneakSpeed 5.0;
Player.NonSneakDetectionChance 225.0 / 255.0;
Obituary "$OB_MPDEFAULT";
}

Expand Down Expand Up @@ -256,12 +262,6 @@ class PlayerPawn : Actor
virtual void MorphPlayerThink()
{
}

//----------------------------------------------------------------------------
//
//
//
//----------------------------------------------------------------------------

virtual void OnRespawn()
{
Expand All @@ -279,12 +279,6 @@ class PlayerPawn : Actor
bRespawnInvul = true; // [RH] special effect
}
}

//----------------------------------------------------------------------------
//
//
//
//----------------------------------------------------------------------------

override String GetObituary(Actor victim, Actor inflictor, Name mod, bool playerattack)
{
Expand Down

0 comments on commit ad1b6ea

Please sign in to comment.