mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-04-14 22:11:10 +00:00
Merged https://github.com/ZDoom/gzdoom/pull/1949 (Shadow Aiming)
This commit is contained in:
parent
35ef7daf56
commit
afea6ff51f
10 changed files with 295 additions and 48 deletions
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
233
src/playsim/shadowinlines.h
Normal 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));
|
||||
}
|
|
@ -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),
|
||||
|
|
|
@ -988,6 +988,7 @@ DEFINE_PROPERTY(clearflags, 0, Actor)
|
|||
defaults->flags6 = 0;
|
||||
defaults->flags7 = 0;
|
||||
defaults->flags8 = 0;
|
||||
defaults->flags9 = 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue