- refinement of aiming fix.

This commit is contained in:
Christoph Oelckers 2023-05-01 23:44:33 +02:00
parent fa1e667140
commit bab432ed72
7 changed files with 43 additions and 25 deletions

View file

@ -110,8 +110,8 @@ void playerLookUp(int snum, ESyncBits actions);
void playerLookDown(int snum, ESyncBits actions);
void playerAimUp(int snum, ESyncBits actions);
void playerAimDown(int snum, ESyncBits actions);
DDukeActor* aim(DDukeActor* s, int aang, bool force = true);
DDukeActor* aim_(DDukeActor* actor, DDukeActor* weapon, double aimangle);
DDukeActor* aim(DDukeActor* s, int aang, bool force = true, bool* b = nullptr);
DDukeActor* aim_(DDukeActor* actor, DDukeActor* weapon, double aimangle, bool* b = nullptr);
void shoot(DDukeActor* actor, PClass* cls);
void checkweapons(player_struct* const p);
int findotherplayer(int p, double* d);

View file

@ -191,7 +191,7 @@ double hitawall(player_struct* p, walltype** hitw)
//
//---------------------------------------------------------------------------
DDukeActor* aim(DDukeActor* actor, int abase, bool force)
DDukeActor* aim(DDukeActor* actor, int abase, bool force, bool* b)
{
DAngle aang = mapangle(abase);
@ -205,24 +205,29 @@ DDukeActor* aim(DDukeActor* actor, int abase, bool force)
{
auto* plr = &ps[actor->PlayerIndex()];
int autoaim = force? 1 : Autoaim(actor->PlayerIndex());
if (!autoaim)
// Some fudging to avoid aim randomization when autoaim is off.
// This is a reimplementation of how it was solved in RedNukem.
if (plr->curr_weapon == PISTOL_WEAPON && !isWW2GI())
{
// Some fudging to avoid aim randomization when autoaim is off.
// This is a reimplementation of how it was solved in RedNukem.
if (plr->curr_weapon == PISTOL_WEAPON && !isWW2GI() && 0)
double vel = 1024, zvel = 0;
setFreeAimVelocity(vel, zvel, plr->Angles.getPitchWithView(), 16.);
HitInfo hit{};
hitscan(plr->GetActor()->getPosWithOffsetZ().plusZ(4), actor->sector(), DVector3(actor->spr.Angles.Yaw.ToVector() * vel, zvel * 64), hit, CLIPMASK1);
if (hit.actor() != nullptr)
{
double vel = 1024, zvel = 0;
setFreeAimVelocity(vel, zvel, plr->Angles.getPitchWithView(), 16.);
HitInfo hit{};
hitscan(plr->GetActor()->getPosWithOffsetZ().plusZ(4), actor->sector(), DVector3(actor->spr.Angles.Yaw.ToVector() * vel, zvel * 64), hit, CLIPMASK1);
if (hit.actor() != nullptr)
if (isIn(hit.actor()->spr.statnum, { STAT_PLAYER, STAT_DUMMYPLAYER, STAT_ACTOR, STAT_ZOMBIEACTOR }))
{
if (isIn(hit.actor()->spr.statnum, { STAT_PLAYER, STAT_DUMMYPLAYER, STAT_ACTOR, STAT_ZOMBIEACTOR }))
return hit.actor();
if (b) *b = true;
return hit.actor();
}
}
}
if (!autoaim)
{
// The chickens in RRRA are homing and must always autoaim.
if (!isRRRA() || plr->curr_weapon != CHICKEN_WEAPON)
return nullptr;
@ -332,10 +337,10 @@ DDukeActor* aim(DDukeActor* actor, int abase, bool force)
}
// This is what aim should be.
DDukeActor* aim_(DDukeActor* actor, DDukeActor* weapon, double aimangle)
DDukeActor* aim_(DDukeActor* actor, DDukeActor* weapon, double aimangle, bool* b)
{
if (!weapon || (weapon->flags1 & SFLAG_NOAUTOAIM)) return nullptr;
return aim(actor, int((aimangle > 0 ? aimangle : weapon->FloatVar(NAME_autoaimangle)) * (512 / 90.)), (weapon->flags1 & SFLAG_FORCEAUTOAIM));
return aim(actor, int((aimangle > 0 ? aimangle : weapon->FloatVar(NAME_autoaimangle)) * (512 / 90.)), (weapon->flags1 & SFLAG_FORCEAUTOAIM), b);
}
//---------------------------------------------------------------------------

View file

@ -716,8 +716,12 @@ DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, aim, aim_)
{
PARAM_SELF_PROLOGUE(DDukeActor);
PARAM_POINTER(weapon, DDukeActor);
PARAM_FLOAT(aimangle)
ACTION_RETURN_POINTER(aim_(self, weapon, aimangle));
PARAM_FLOAT(aimangle);
bool b = false;
auto result = aim_(self, weapon, aimangle, &b);
if (numret > 0) ret[0].SetPointer(result);
if (numret > 1) ret[1].SetInt(b);
return min(numret, 2);
}
void Duke_SetAction(DDukeActor* self, int intname)

View file

@ -9,7 +9,7 @@ class DukeGreenSlime : DukeActor
+FORCESECTORSHADE;
+SHRINKAUTOAIM;
+NOHITJIBS;
sparkoffset -8;
sparkoffset -3;
}
override void Initialize()

View file

@ -17,7 +17,7 @@ class DukeRotateGun : DukeActor
+NOHITJIBS;
+NOSHOTGUNBLOOD;
sparkoffset -8;
sparkoffset -3;
aimoffset 32;
shootzoffset 0;
}

View file

@ -45,10 +45,17 @@ extend class DukeActor
if (p != null)
{
let aimed = actor.aim(self, aimangle);
let [aimed, direct] = actor.aim(self, aimangle);
if (aimed)
{
[vel, zvel] = Raze.setFreeAimVelocity(vel, zvel, p.getPitchWithView(), 16.);
// if we already aim directly at the target, use the shooter's actual pitch for the hitscan instead of re-aiming.
if (direct) [vel, zvel] = Raze.setFreeAimVelocity(vel, zvel, p.getPitchWithView(), 16.);
else
{
double dal = ((aimed.scale.X * aimed.spriteHeight()) * 0.5) + aimed.sparkoffset;
double dist = (p.actor.pos.XY - aimed.pos.XY).Length();
zvel = ((aimed.pos.Z - pos.Z - dal) * 16) / dist;
}
ang = (aimed.pos - pos).Angle();
}

View file

@ -125,6 +125,8 @@ class DukeActor : CoreActor native
landmovefactor 1;
watermovefactor 1;
gravityfactor 1;
sparkoffset 5;
move "SHRUNKVELS", 32;
move "RESPAWN_ACTOR_FLAG";
action "ANULLACTION", 0;
}
@ -338,7 +340,7 @@ class DukeActor : CoreActor native
native void operatesectors(sectortype sec);
native int SpriteWidth();
native int SpriteHeight();
native DukeActor aim(readonly<DukeActor> weapon, double aimangle = -1);
native DukeActor, bool aim(readonly<DukeActor> weapon, double aimangle = -1);
// CON simulation
native void SetAction(Name act);