This commit is contained in:
Major Cooke 2023-01-21 11:25:42 -06:00
parent 35ef7daf56
commit afea6ff51f
10 changed files with 295 additions and 48 deletions

View file

@ -206,8 +206,7 @@ enum ActorFlag2
// but still considered solid
MF2_INVULNERABLE = 0x08000000, // mobj is invulnerable
MF2_DORMANT = 0x10000000, // thing is dormant
MF2_ARGSDEFINED = 0x20000000, // Internal flag used by DECORATE to signal that the
// args should not be taken from the mapthing definition
MF2_ARGSDEFINED = 0x20000000, // Internal flag used by DECORATE to signal that the args should not be taken from the mapthing definition
MF2_SEEKERMISSILE = 0x40000000, // is a seeker (for reflection)
MF2_REFLECTIVE = 0x80000000, // reflects missiles
};
@ -394,11 +393,13 @@ enum ActorFlag7
MF7_SPRITEANGLE = 0x02000000, // [MC] Utilize the SpriteAngle property and lock the rotation to the degrees specified.
MF7_SMASHABLE = 0x04000000, // dies if hitting the floor.
MF7_NOSHIELDREFLECT = 0x08000000, // will not be reflected by shields.
MF7_FORCEZERORADIUSDMG = 0x10000000, // passes zero radius damage on to P_DamageMobj, this is necessary in some cases where DoSpecialDamage gets overrideen.
MF7_FORCEZERORADIUSDMG = 0x10000000,// passes zero radius damage on to P_DamageMobj, this is necessary in some cases where DoSpecialDamage gets overrideen.
MF7_NOINFIGHTSPECIES = 0x20000000, // don't start infights with one's own species.
MF7_FORCEINFIGHTING = 0x40000000, // overrides a map setting of 'no infighting'.
MF7_INCHASE = 0x80000000, // [RH] used by A_Chase and A_Look to avoid recursion
};
// --- mobj.flags8 ---
enum ActorFlag8
{
MF8_FRIGHTENING = 0x00000001, // for those moments when halloween just won't do
@ -426,12 +427,21 @@ enum ActorFlag8
MF8_STAYONLIFT = 0x02000000, // MBF AI enhancement.
MF8_DONTFOLLOWPLAYERS = 0x04000000, // [inkoalawetrust] Friendly monster will not follow players.
MF8_SEEFRIENDLYMONSTERS = 0X08000000, // [inkoalawetrust] Hostile monster can see friendly monsters.
MF8_CROSSLINECHECK = 0x10000000, // [MC]Enables CanCrossLine virtual
MF8_CROSSLINECHECK = 0x10000000, // [MC] Enables CanCrossLine virtual
MF8_MASTERNOSEE = 0x20000000, // Don't show object in first person if their master is the current camera.
MF8_ADDLIGHTLEVEL = 0x40000000, // [MC] Actor light level is additive with sector.
MF8_ONLYSLAMSOLID = 0x80000000, // [B] Things with skullfly will ignore non-solid Actors.
};
// --- mobj.flags9 ---
enum ActorFlag9
{
MF9_SHADOWAIM = 0x00000001, // [inkoalawetrust] Monster still gets aim penalty from aiming at shadow actors even with MF6_SEEINVISIBLE on.
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.
};
// --- mobj.renderflags ---
enum ActorRenderFlag
{
@ -586,6 +596,7 @@ typedef TFlags<ActorFlag5> ActorFlags5;
typedef TFlags<ActorFlag6> ActorFlags6;
typedef TFlags<ActorFlag7> ActorFlags7;
typedef TFlags<ActorFlag8> ActorFlags8;
typedef TFlags<ActorFlag9> ActorFlags9;
typedef TFlags<ActorRenderFlag> ActorRenderFlags;
typedef TFlags<ActorRenderFlag2> ActorRenderFlags2;
typedef TFlags<ActorBounceFlag> ActorBounceFlags;
@ -598,6 +609,7 @@ DEFINE_TFLAGS_OPERATORS (ActorFlags5)
DEFINE_TFLAGS_OPERATORS (ActorFlags6)
DEFINE_TFLAGS_OPERATORS (ActorFlags7)
DEFINE_TFLAGS_OPERATORS (ActorFlags8)
DEFINE_TFLAGS_OPERATORS (ActorFlags9)
DEFINE_TFLAGS_OPERATORS (ActorRenderFlags)
DEFINE_TFLAGS_OPERATORS (ActorRenderFlags2)
DEFINE_TFLAGS_OPERATORS (ActorBounceFlags)
@ -1072,6 +1084,7 @@ public:
ActorFlags6 flags6; // Shit! Where did all the flags go?
ActorFlags7 flags7; // WHO WANTS TO BET ON 8!?
ActorFlags8 flags8; // I see your 8, and raise you a bet for 9.
ActorFlags9 flags9; // Happy ninth actor flag field GZDoom !
double Floorclip; // value to use for floor clipping
double radius, Height; // for movement checking
@ -1188,6 +1201,8 @@ public:
double Gravity; // [GRB] Gravity factor
double Friction;
double pushfactor;
double ShadowAimFactor; // [inkoalawetrust] How much the actors' aim is affected when attacking shadow actors.
double ShadowPenaltyFactor;// [inkoalawetrust] How much the shadow actor affects its' shooters' aim.
int bouncecount; // Strife's grenades only bounce twice before exploding
int FastChaseStrafeCount;
int lastpush;

View file

@ -70,20 +70,21 @@
#include "actorinlines.h"
#include "types.h"
#include "model.h"
#include "shadowinlines.h"
static FRandom pr_camissile ("CustomActorfire");
static FRandom pr_cabullet ("CustomBullet");
static FRandom pr_cwjump ("CustomWpJump");
static FRandom pr_cwpunch ("CustomWpPunch");
static FRandom pr_grenade ("ThrowGrenade");
static FRandom pr_crailgun ("CustomRailgun");
FRandom pr_crailgun ("CustomRailgun");
static FRandom pr_spawndebris ("SpawnDebris");
static FRandom pr_spawnitemex ("SpawnItemEx");
static FRandom pr_burst ("Burst");
static FRandom pr_monsterrefire ("MonsterRefire");
static FRandom pr_teleport("A_Teleport");
static FRandom pr_bfgselfdamage("BFGSelfDamage");
FRandom pr_cajump("CustomJump");
FRandom pr_cajump("CustomJump");
//==========================================================================
//
@ -1226,11 +1227,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CustomRailgun)
self->Angles.Yaw = self->AngleTo(self->target,- self->target->Vel.X * veleffect, -self->target->Vel.Y * veleffect);
}
if (self->target->flags & MF_SHADOW)
{
DAngle rnd = DAngle::fromDeg(pr_crailgun.Random2() * (45. / 256.));
self->Angles.Yaw += rnd;
}
A_CustomRailgun_ShadowHandling(self, spawnofs_xy, spawnofs_z, spread_xy, flags);
}
if (!(flags & CRF_EXPLICITANGLE))
@ -2092,6 +2089,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Respawn)
self->flags6 = defs->flags6;
self->flags7 = defs->flags7;
self->flags8 = defs->flags8;
self->flags9 = defs->flags9;
self->SetState (self->SpawnState);
self->renderflags &= ~RF_INVISIBLE;
@ -3526,7 +3524,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_WolfAttack)
hitchance -= idist * (dodge ? 16 : 8);
// While we're here, we may as well do something for this:
if (self->target->flags & MF_SHADOW)
if (A_WolfAttack_ShadowHandling(self))
{
hitchance >>= 2;
}

View file

@ -50,6 +50,7 @@
#include "vm.h"
#include "actorinlines.h"
#include "a_ceiling.h"
#include "shadowinlines.h"
#include "gi.h"
@ -61,8 +62,8 @@ static FRandom pr_lookformonsters ("LookForMonsters");
static FRandom pr_lookforplayers ("LookForPlayers");
static FRandom pr_scaredycat ("Anubis");
FRandom pr_chase ("Chase");
static FRandom pr_facetarget ("FaceTarget");
static FRandom pr_railface ("RailFace");
FRandom pr_facetarget ("FaceTarget");
FRandom pr_railface ("RailFace");
static FRandom pr_look2 ("LookyLooky");
static FRandom pr_look3 ("IGotHooky");
static FRandom pr_slook ("SlooK");
@ -3018,15 +3019,11 @@ void A_Face(AActor *self, AActor *other, DAngle max_turn, DAngle max_pitch, DAng
self->Angles.Pitch = other_pitch;
}
self->Angles.Pitch += pitch_offset;
A_Face_ShadowHandling(self, other, max_pitch, other_pitch, true);
}
// This will never work well if the turn angle is limited.
if (max_turn == nullAngle && (self->Angles.Yaw == other_angle) && other->flags & MF_SHADOW && !(self->flags6 & MF6_SEEINVISIBLE) )
{
self->Angles.Yaw += DAngle::fromDeg(pr_facetarget.Random2() * (45 / 256.));
}
A_Face_ShadowHandling(self,other,max_turn,other_angle,false);
}
void A_FaceTarget(AActor *self)
@ -3073,10 +3070,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MonsterRail)
// Let the aim trail behind the player
self->Angles.Yaw = self->AngleTo(self->target, -self->target->Vel.X * 3, -self->target->Vel.Y * 3);
if (self->target->flags & MF_SHADOW && !(self->flags6 & MF6_SEEINVISIBLE))
{
self->Angles.Yaw += DAngle::fromDeg(pr_railface.Random2() * 45./256);
}
A_MonsterRail_ShadowHandling(self);
FRailParams p;

View file

@ -92,6 +92,7 @@
#include "r_sky.h"
#include "g_levellocals.h"
#include "actorinlines.h"
#include <shadowinlines.h>
CVAR(Bool, cl_bloodsplats, true, CVAR_ARCHIVE)
CVAR(Int, sv_smartaim, 0, CVAR_ARCHIVE | CVAR_SERVERINFO)
@ -4452,6 +4453,11 @@ DAngle P_AimLineAttack(AActor *t1, DAngle angle, double distance, FTranslatedLin
{
*pLineTarget = *result;
}
DAngle newPitch = P_AimLineAttack_ShadowHandling(t1,target,result->linetarget,shootz);
if (newPitch != nullAngle)
result->pitch = newPitch;
return result->linetarget ? result->pitch : t1->Angles.Pitch;
}

View file

@ -99,6 +99,7 @@
#include "actorinlines.h"
#include "a_dynlight.h"
#include "fragglescript/t_fs.h"
#include "shadowinlines.h"
// MACROS ------------------------------------------------------------------
@ -120,7 +121,6 @@ EXTERN_CVAR (Int, cl_rockettrails)
// PRIVATE DATA DEFINITIONS ------------------------------------------------
static FRandom pr_explodemissile ("ExplodeMissile");
FRandom pr_bounce ("Bounce");
static FRandom pr_reflect ("Reflect");
static FRandom pr_nightmarerespawn ("NightmareRespawn");
static FRandom pr_botspawnmobj ("BotSpawnActor");
@ -133,7 +133,6 @@ static FRandom pr_splat ("FAxeSplatter");
static FRandom pr_ripperblood ("RipperBlood");
static FRandom pr_chunk ("Chunk");
static FRandom pr_checkmissilespawn ("CheckMissileSpawn");
static FRandom pr_spawnmissile ("SpawnMissile");
static FRandom pr_missiledamage ("MissileDamage");
static FRandom pr_multiclasschoice ("MultiClassChoice");
static FRandom pr_rockettrail("RocketTrail");
@ -142,6 +141,8 @@ static FRandom pr_uniquetid("UniqueTID");
// PUBLIC DATA DEFINITIONS -------------------------------------------------
FRandom pr_spawnmobj ("SpawnActor");
FRandom pr_bounce("Bounce");
FRandom pr_spawnmissile("SpawnMissile");
CUSTOM_CVAR (Float, sv_gravity, 800.f, CVAR_SERVERINFO|CVAR_NOSAVE|CVAR_NOINITCALL)
{
@ -233,6 +234,7 @@ void AActor::Serialize(FSerializer &arc)
A("flags6", flags6)
A("flags7", flags7)
A("flags8", flags8)
A("flags9", flags9)
A("weaponspecial", weaponspecial)
A("special1", special1)
A("special2", special2)
@ -6646,7 +6648,7 @@ AActor *P_SpawnMissileXYZ (DVector3 pos, AActor *source, AActor *dest, PClassAct
if (dest == NULL)
{
Printf ("P_SpawnMissilyXYZ: Tried to shoot %s from %s with no dest\n",
Printf ("P_SpawnMissileXYZ: Tried to shoot %s from %s with no destination\n",
type->TypeName.GetChars(), source->GetClass()->TypeName.GetChars());
return NULL;
}
@ -6685,21 +6687,8 @@ AActor *P_SpawnMissileXYZ (DVector3 pos, AActor *source, AActor *dest, PClassAct
}
th->Vel = velocity.Resized(speed);
// invisible target: rotate velocity vector in 2D
// [RC] Now monsters can aim at invisible player as if they were fully visible.
if (dest->flags & MF_SHADOW && !(source->flags6 & MF6_SEEINVISIBLE))
{
DAngle an = DAngle::fromDeg(pr_spawnmissile.Random2() * (22.5 / 256));
double c = an.Cos();
double s = an.Sin();
double newx = th->Vel.X * c - th->Vel.Y * s;
double newy = th->Vel.X * s + th->Vel.Y * c;
th->Vel.X = newx;
th->Vel.Y = newy;
}
P_SpawnMissileXYZ_ShadowHandling(source,dest,th,pos);
th->AngleFromVel();
if (th->flags4 & MF4_SPECTRAL)
@ -6820,14 +6809,11 @@ AActor *P_SpawnMissileZAimed (AActor *source, double z, AActor *dest, PClassActo
an = source->Angles.Yaw;
if (dest->flags & MF_SHADOW)
{
an += DAngle::fromDeg(pr_spawnmissile.Random2() * (16. / 360.));
}
dist = source->Distance2D (dest);
speed = GetDefaultSpeed (type);
dist /= speed;
vz = dist != 0 ? (dest->Z() - source->Z())/dist : speed;
an += P_SpawnMissileZAimed_ShadowHandling(source, dest, vz, speed, source->PosAtZ(z));
return P_SpawnMissileAngleZSpeed (source, z, type, an, vz, speed);
}
@ -7692,6 +7678,9 @@ void PrintMiscActorInfo(AActor *query)
Printf("\n flags8: %x", query->flags8.GetValue());
for (flagi = 0; flagi <= 31; flagi++)
if (query->flags8 & ActorFlags8::FromInt(1<<flagi)) Printf(" %s", FLAG_NAME(1<<flagi, flags8));
Printf("\n flags9: %x", query->flags9.GetValue());
for (flagi = 0; flagi <= 31; flagi++)
if (query->flags9 & ActorFlags9::FromInt(1 << flagi)) Printf(" %s", FLAG_NAME(1 << flagi, flags9));
Printf("\nBounce flags: %x\nBounce factors: f:%f, w:%f",
query->BounceFlags.GetValue(), query->bouncefactor,
query->wallbouncefactor);

233
src/playsim/shadowinlines.h Normal file
View file

@ -0,0 +1,233 @@
#pragma once
#include "actor.h"
#include "r_defs.h"
#include "m_random.h"
//-----------------------------------------------------------------------------
//
// DESCRIPTION:
// Handling of MF_SHADOW related code for attack and aiming functions.
//
//-----------------------------------------------------------------------------
// RNG VARIABLES ------------------------------------------------
extern FRandom pr_spawnmissile;
extern FRandom pr_facetarget;
extern FRandom pr_railface;
extern FRandom pr_crailgun;
static FRandom pr_shadowaimz("VerticalShadowAim");
//==========================================================================
//
// Generic checks
//
//==========================================================================
struct ShadowCheckData
{
AActor* HitShadow;
};
static ETraceStatus CheckForShadowBlockers(FTraceResults& res, void* userdata)
{
ShadowCheckData* output = (ShadowCheckData*)userdata;
if (res.HitType == TRACE_HitActor && res.Actor && (res.Actor->flags9 & MF9_SHADOWBLOCK))
{
output->HitShadow = res.Actor;
return TRACE_Stop;
}
if (res.HitType != TRACE_HitActor)
{
return TRACE_Stop;
}
return TRACE_Continue;
}
// [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)
{
FTraceResults result;
ShadowCheckData ShadowCheck;
ShadowCheck.HitShadow = nullptr;
DVector3 dir;
double dist;
if (t2)
{
dir = t1->Vec3To(t2);
dist = dir.Length();
}
//No second actor, fall back to shooting at facing direction.
else
{
dir = DRotator(-(t1->Angles.Pitch), t1->Angles.Yaw, t1->Angles.Yaw);
dist = 65536.0; //Arbitrary large value.
}
Trace(pos, t1->Sector, dir, dist, ActorFlags::FromInt(0xFFFFFFFF), ML_BLOCKEVERYTHING, t1, result, 0, CheckForShadowBlockers, &ShadowCheck);
//Use the penalty factor of the shadowblocker that was hit. Otherwise, use the factor passed by PerformShadowChecks().
if (ShadowCheck.HitShadow)
{
penaltyFactor = ShadowCheck.HitShadow->ShadowPenaltyFactor;
}
return ShadowCheck.HitShadow;
}
inline bool AffectedByShadows(AActor* self, AActor* other)
{
return (!(self->flags6 & MF6_SEEINVISIBLE) || self->flags9 & MF9_SHADOWAIM);
}
inline bool 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));
}
inline bool 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));
}
//==========================================================================
//
// Function-specific inlines.
//
//==========================================================================
inline void P_SpawnMissileXYZ_ShadowHandling(AActor* source, AActor* target, AActor* missile, DVector3 pos)
{
double penaltyFactor;
// invisible target: rotate velocity vector in 2D
// [RC] Now monsters can aim at invisible player as if they were fully visible.
if (PerformShadowChecks(source, target, pos, penaltyFactor))
{
DAngle an = DAngle::fromDeg(pr_spawnmissile.Random2() * (22.5 / 256)) * source->ShadowAimFactor * penaltyFactor;
double c = an.Cos();
double s = an.Sin();
double newx = missile->Vel.X * c - missile->Vel.Y * s;
double newy = missile->Vel.X * s + missile->Vel.Y * c;
missile->Vel.X = newx;
missile->Vel.Y = newy;
if (source->flags9 & MF9_SHADOWAIMVERT)
{
DAngle pitch = DAngle::fromDeg(pr_spawnmissile.Random2() * (22.5 / 256)) * source->ShadowAimFactor * penaltyFactor;
double newz = -pitch.Sin() * missile->Speed;
missile->Vel.Z = newz;
}
}
return;
}
//P_SpawnMissileZAimed uses a local variable for the angle it passes on.
inline DAngle P_SpawnMissileZAimed_ShadowHandling(AActor* source, AActor* target, double& vz, double speed, DVector3 pos)
{
double penaltyFactor;
if (PerformShadowChecks(source, target, pos, penaltyFactor))
{
if (source->flags9 & MF9_SHADOWAIMVERT)
{
DAngle pitch = DAngle::fromDeg(pr_spawnmissile.Random2() * (16. / 360.)) * source->ShadowAimFactor * penaltyFactor;
vz += -pitch.Sin() * speed; //Modify the Z velocity pointer that is then passed to P_SpawnMissileAngleZSpeed.
}
return DAngle::fromDeg(pr_spawnmissile.Random2() * (16. / 360.)) * source->ShadowAimFactor * penaltyFactor;
}
return nullAngle;
}
inline void A_Face_ShadowHandling(AActor* self, AActor* other, DAngle max_turn, DAngle other_angle, bool vertical)
{
double penaltyFactor;
if (!vertical)
{
// This will never work well if the turn angle is limited.
if (max_turn == nullAngle && (self->Angles.Yaw == other_angle) && PerformShadowChecks(self, other, self->PosAtZ(self->Center()), penaltyFactor))
{
self->Angles.Yaw += DAngle::fromDeg(pr_facetarget.Random2() * (45 / 256.)) * self->ShadowAimFactor * penaltyFactor;
}
}
else
{
//Randomly offset the pitch when looking at shadows.
if (self->flags9 & MF9_SHADOWAIMVERT && max_turn == nullAngle && (self->Angles.Pitch == other_angle) && PerformShadowChecks(self, other, self->PosAtZ(self->Center()), penaltyFactor))
{
self->Angles.Pitch += DAngle::fromDeg(pr_facetarget.Random2() * (45 / 256.)) * self->ShadowAimFactor * penaltyFactor;
}
}
return;
}
inline void A_MonsterRail_ShadowHandling(AActor* self)
{
double penaltyFactor;
double shootZ = self->Center() - self->FloatSpeed - self->Floorclip; // The formula P_RailAttack uses, minus offset_z since A_MonsterRail doesn't use it.
if (PerformShadowChecks(self, self->target, self->PosAtZ(shootZ), penaltyFactor))
{
self->Angles.Yaw += DAngle::fromDeg(pr_railface.Random2() * 45. / 256) * self->ShadowAimFactor * penaltyFactor;
if (self->flags9 & MF9_SHADOWAIMVERT)
self->Angles.Pitch += DAngle::fromDeg(pr_railface.Random2() * 45. / 256) * self->ShadowAimFactor * penaltyFactor;
}
return;
}
//Also passes parameters to determine a firing position for the SHADOWBLOCK check.
inline void A_CustomRailgun_ShadowHandling(AActor* self, double spawnofs_xy, double spawnofs_z, DAngle spread_xy, int flags)
{
double penaltyFactor;
// [inkoalawetrust] The exact formula P_RailAttack uses to determine where the railgun trace should spawn from.
DVector2 shootXY = (self->Vec2Angle(spawnofs_xy, (self->Angles.Yaw + spread_xy) - DAngle::fromDeg(90.)));
double shootZ = self->Center() - self->FloatSpeed + spawnofs_z - self->Floorclip;
if (flags & 16) shootZ += self->AttackOffset(); //16 is RGF_CENTERZ
DVector3 checkPos;
checkPos.X = shootXY.X;
checkPos.Y = shootXY.Y;
checkPos.Z = shootZ;
if (PerformShadowChecks(self, self->target, checkPos, penaltyFactor))
{
self->Angles.Yaw += DAngle::fromDeg(pr_crailgun.Random2() * (45. / 256.)) * self->ShadowAimFactor * penaltyFactor;
if (self->flags9 & MF9_SHADOWAIMVERT)
{
self->Angles.Pitch += DAngle::fromDeg(pr_crailgun.Random2() * (45. / 256.)) * self->ShadowAimFactor * penaltyFactor;
}
}
return;
}
//If anything is returned, then AimLineAttacks' result pitch is changed to that value.
inline DAngle P_AimLineAttack_ShadowHandling(AActor*source, AActor* target, AActor* linetarget, double shootZ)
{
double penaltyFactor;
AActor* mo;
if (target)
mo = target;
else
mo = linetarget;
// [inkoalawetrust] Randomly offset the vertical aim of monsters. Roughly uses the SSG vertical spread.
if (source->player == NULL && source->flags9 & MF9_SHADOWAIMVERT && PerformShadowChecks (source, mo, source->PosAtZ (shootZ), penaltyFactor))
{
if (linetarget)
return DAngle::fromDeg(pr_shadowaimz.Random2() * (28.388 / 256.)) * source->ShadowAimFactor * penaltyFactor; //Change the autoaims' pitch to this.
else
source->Angles.Pitch = DAngle::fromDeg(pr_shadowaimz.Random2() * (28.388 / 256.)) * source->ShadowAimFactor * penaltyFactor;
}
return nullAngle;
}
//A_WolfAttack directly harms the target instead of firing a hitscan or projectile. So it handles shadows by lowering the chance of harming the target.
inline bool A_WolfAttack_ShadowHandling(AActor* self)
{
double p; //Does nothing.
return (PerformShadowChecks(self, self->target, self->PosAtZ(self->Center()), p));
}

View file

@ -345,6 +345,11 @@ static FFlagDef ActorFlagDefs[]=
DEFINE_FLAG(MF8, ADDLIGHTLEVEL, AActor, flags8),
DEFINE_FLAG(MF8, ONLYSLAMSOLID, AActor, flags8),
DEFINE_FLAG(MF9, SHADOWAIM, AActor, flags9),
DEFINE_FLAG(MF9, DOSHADOWBLOCK, AActor, flags9),
DEFINE_FLAG(MF9, SHADOWBLOCK, AActor, flags9),
DEFINE_FLAG(MF9, SHADOWAIMVERT, AActor, flags9),
// Effect flags
DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects),
DEFINE_FLAG2(FX_ROCKET, ROCKETTRAIL, AActor, effects),
@ -353,8 +358,7 @@ static FFlagDef ActorFlagDefs[]=
DEFINE_FLAG(RF, FORCEYBILLBOARD, AActor, renderflags),
DEFINE_FLAG(RF, FORCEXYBILLBOARD, AActor, renderflags),
DEFINE_FLAG(RF, ROLLSPRITE, AActor, renderflags), // [marrub] roll the sprite billboard
// [fgsfds] Flat sprites
DEFINE_FLAG(RF, FLATSPRITE, AActor, renderflags),
DEFINE_FLAG(RF, FLATSPRITE, AActor, renderflags), // [fgsfds] Flat sprites
DEFINE_FLAG(RF, WALLSPRITE, AActor, renderflags),
DEFINE_FLAG(RF, DONTFLIP, AActor, renderflags),
DEFINE_FLAG(RF, ROLLCENTER, AActor, renderflags),

View file

@ -988,6 +988,7 @@ DEFINE_PROPERTY(clearflags, 0, Actor)
defaults->flags6 = 0;
defaults->flags7 = 0;
defaults->flags8 = 0;
defaults->flags9 = 0;
}
//==========================================================================

View file

@ -2109,6 +2109,8 @@ DEFINE_FIELD_NAMED(AActor, ViewAngles.Yaw, viewangle)
DEFINE_FIELD_NAMED(AActor, ViewAngles.Pitch, viewpitch)
DEFINE_FIELD_NAMED(AActor, ViewAngles.Roll, viewroll)
DEFINE_FIELD(AActor, LightLevel)
DEFINE_FIELD(AActor, ShadowAimFactor)
DEFINE_FIELD(AActor, ShadowPenaltyFactor)
DEFINE_FIELD_X(FCheckPosition, FCheckPosition, thing);
DEFINE_FIELD_X(FCheckPosition, FCheckPosition, pos);

View file

@ -248,6 +248,7 @@ class Actor : Thinker native
native double ViewAngle, ViewPitch, ViewRoll;
native double RadiusDamageFactor; // Radius damage factor
native double SelfDamageFactor;
native double ShadowAimFactor, ShadowPenaltyFactor;
native double StealthAlpha;
native int WoundHealth; // Health needed to enter wound state
native readonly color BloodColor;
@ -361,6 +362,8 @@ class Actor : Thinker native
property FriendlySeeBlocks: FriendlySeeBlocks;
property ThruBits: ThruBits;
property LightLevel: LightLevel;
property ShadowAimFactor: ShadowAimFactor;
property ShadowPenaltyFactor: ShadowPenaltyFactor;
// need some definition work first
//FRenderStyle RenderStyle;
@ -438,6 +441,8 @@ class Actor : Thinker native
FastSpeed -1;
RadiusDamageFactor 1;
SelfDamageFactor 1;
ShadowAimFactor 1;
ShadowPenaltyFactor 1;
StealthAlpha 0;
WoundHealth 6;
GibHealth int.min;