mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-24 21:21:04 +00:00
- fixed: For melee attacks with a short attack range P_AimLineAttack must check for hits from above and below.
This is necessary to be in line with P_LineAttack which does check for those.
This commit is contained in:
parent
352f93c066
commit
a851a5d151
6 changed files with 100 additions and 12 deletions
|
@ -1997,7 +1997,7 @@ DEFINE_ACTION_FUNCTION(AStateProvider, A_CustomPunch)
|
|||
|
||||
angle = self->Angles.Yaw + pr_cwpunch.Random2() * (5.625 / 256);
|
||||
if (range == 0) range = DEFMELEERANGE;
|
||||
pitch = P_AimLineAttack (self, angle, range, &t);
|
||||
pitch = P_AimLineAttack (self, angle, range, &t, 0., ALF_CHECK3D);
|
||||
|
||||
// only use ammo when actually hitting something!
|
||||
if ((flags & CPF_USEAMMO) && t.linetarget && weapon && ACTION_CALL_FROM_PSPRITE())
|
||||
|
|
|
@ -3998,6 +3998,70 @@ struct aim_t
|
|||
SetResult(thing_other, newtrace.thing_other);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// Finds where the trace exits an actor to check for hits from above/below
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
double ExitPoint(AActor *thing)
|
||||
{
|
||||
// The added check at the exit point only has some value if a 3D distance check is involved
|
||||
if (!(flags & ALF_CHECK3D)) return -1;
|
||||
|
||||
divline_t trace = { startpos.X, startpos.Y, aimtrace.X, aimtrace.Y };
|
||||
divline_t line;
|
||||
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0: // Top edge
|
||||
line.y = thing->Y() + thing->radius;
|
||||
if (trace.y > line.y) continue;
|
||||
line.x = thing->X() + thing->radius;
|
||||
line.dx = -thing->radius * 2;
|
||||
line.dy = 0;
|
||||
break;
|
||||
|
||||
case 1: // Right edge
|
||||
line.x = thing->X() + thing->radius;
|
||||
if (trace.x > line.x) continue;
|
||||
line.y = thing->Y() - thing->radius;
|
||||
line.dx = 0;
|
||||
line.dy = thing->radius * 2;
|
||||
break;
|
||||
|
||||
case 2: // Bottom edge
|
||||
line.y = thing->Y() - thing->radius;
|
||||
if (trace.y < line.y) continue;
|
||||
line.x = thing->X() - thing->radius;
|
||||
line.dx = thing->radius * 2;
|
||||
line.dy = 0;
|
||||
break;
|
||||
|
||||
case 3: // Left edge
|
||||
line.x = thing->X() - thing->radius;
|
||||
if (trace.x < line.x) continue;
|
||||
line.y = thing->Y() + thing->radius;
|
||||
line.dx = 0;
|
||||
line.dy = thing->radius * -2;
|
||||
break;
|
||||
}
|
||||
|
||||
// If it is, see if the trace crosses it
|
||||
if (P_PointOnDivlineSide(line.x, line.y, &trace) !=
|
||||
P_PointOnDivlineSide(line.x + line.dx, line.y + line.dy, &trace))
|
||||
{
|
||||
// It's a hit
|
||||
double frac = P_InterceptVector(&trace, &line);
|
||||
if (frac > 1.) frac = 1.;
|
||||
return frac;
|
||||
}
|
||||
}
|
||||
|
||||
return -1.;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
|
@ -4047,9 +4111,7 @@ struct aim_t
|
|||
intercept_t *in;
|
||||
|
||||
if (aimdebug)
|
||||
Printf("Start AimTraverse, start = %f,%f,%f, vect = %f,%f\n",
|
||||
startpos.X / 65536., startpos.Y / 65536., startpos.Z / 65536.,
|
||||
aimtrace.X / 65536., aimtrace.Y / 65536.);
|
||||
Printf("Start AimTraverse, start = %f,%f,%f, vect = %f,%f\n", startpos.X, startpos.Y, startpos.Z, aimtrace.X, aimtrace.Y);
|
||||
|
||||
while ((in = it.Next()))
|
||||
{
|
||||
|
@ -4195,12 +4257,38 @@ struct aim_t
|
|||
thingtoppitch = -VecToAngle(dist, th->Top() - shootz);
|
||||
|
||||
if (thingtoppitch > bottompitch)
|
||||
continue; // shot over the thing
|
||||
{
|
||||
// Check for a hit from above
|
||||
if (shootz > th->Top())
|
||||
{
|
||||
double exitfrac = ExitPoint(th);
|
||||
if (exitfrac > 0.)
|
||||
{
|
||||
double exitdist = attackrange * exitfrac;
|
||||
thingtoppitch = -VecToAngle(exitdist, th->Top() - shootz);
|
||||
if (thingtoppitch > bottompitch) continue;
|
||||
}
|
||||
}
|
||||
else continue; // shot over the thing
|
||||
}
|
||||
|
||||
thingbottompitch = -VecToAngle(dist, th->Z() - shootz);
|
||||
|
||||
if (thingbottompitch < toppitch)
|
||||
{
|
||||
// Check for a hit from below
|
||||
if (shootz < th->Z())
|
||||
{
|
||||
double exitfrac = ExitPoint(th);
|
||||
if (exitfrac > 0.)
|
||||
{
|
||||
double exitdist = attackrange * exitfrac;
|
||||
thingbottompitch = -VecToAngle(exitdist, th->Z() - shootz);
|
||||
if (thingbottompitch < toppitch) continue;
|
||||
}
|
||||
}
|
||||
continue; // shot under the thing
|
||||
}
|
||||
|
||||
if (crossedffloors)
|
||||
{
|
||||
|
|
|
@ -65,7 +65,7 @@ extend class Actor
|
|||
damage *= 10;
|
||||
|
||||
double ang = angle + Random2[Punch]() * (5.625 / 256);
|
||||
double pitch = AimLineAttack (ang, DEFMELEERANGE);
|
||||
double pitch = AimLineAttack (ang, DEFMELEERANGE, null, 0., ALF_CHECK3D);
|
||||
|
||||
LineAttack (ang, DEFMELEERANGE, pitch, damage, 'Melee', "BulletPuff", LAF_ISMELEEATTACK, t);
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ class CWeapMace : ClericWeapon
|
|||
for (int j = 1; j >= -1; j -= 2)
|
||||
{
|
||||
double ang = angle + j*i*(45. / 16);
|
||||
double slope = AimLineAttack(ang, 2 * DEFMELEERANGE, t);
|
||||
double slope = AimLineAttack(ang, 2 * DEFMELEERANGE, t, 0., ALF_CHECK3D);
|
||||
if (t.linetarget)
|
||||
{
|
||||
LineAttack(ang, 2 * DEFMELEERANGE, slope, damage, 'Melee', "HammerPuff", true, t);
|
||||
|
@ -81,7 +81,7 @@ class CWeapMace : ClericWeapon
|
|||
// didn't find any creatures, so try to strike any walls
|
||||
weaponspecial = 0;
|
||||
|
||||
double slope = AimLineAttack (angle, DEFMELEERANGE);
|
||||
double slope = AimLineAttack (angle, DEFMELEERANGE, null, 0., ALF_CHECK3D);
|
||||
LineAttack (angle, DEFMELEERANGE, slope, damage, 'Melee', "HammerPuff");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -245,7 +245,7 @@ class FWeapAxe : FighterWeapon
|
|||
for (int j = 1; j >= -1; j -= 2)
|
||||
{
|
||||
double ang = angle + j*i*(45. / 16);
|
||||
double slope = AimLineAttack(ang, AXERANGE, t);
|
||||
double slope = AimLineAttack(ang, AXERANGE, t, 0., ALF_CHECK3D);
|
||||
if (t.linetarget)
|
||||
{
|
||||
LineAttack(ang, AXERANGE, slope, damage, 'Melee', pufftype, true, t);
|
||||
|
@ -273,7 +273,7 @@ class FWeapAxe : FighterWeapon
|
|||
// didn't find any creatures, so try to strike any walls
|
||||
self.weaponspecial = 0;
|
||||
|
||||
double slope = AimLineAttack (angle, DEFMELEERANGE);
|
||||
double slope = AimLineAttack (angle, DEFMELEERANGE, null, 0., ALF_CHECK3D);
|
||||
LineAttack (angle, DEFMELEERANGE, slope, damage, 'Melee', pufftype, true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ class FWeapFist : FighterWeapon
|
|||
Class<Actor> pufftype;
|
||||
FTranslatedLineTarget t;
|
||||
|
||||
double slope = AimLineAttack (angle, 2*DEFMELEERANGE, t);
|
||||
double slope = AimLineAttack (angle, 2*DEFMELEERANGE, t, 0., ALF_CHECK3D);
|
||||
if (t.linetarget != null)
|
||||
{
|
||||
if (++weaponspecial >= 3)
|
||||
|
@ -117,7 +117,7 @@ class FWeapFist : FighterWeapon
|
|||
// didn't find any creatures, so try to strike any walls
|
||||
weaponspecial = 0;
|
||||
|
||||
double slope = AimLineAttack (angle, DEFMELEERANGE);
|
||||
double slope = AimLineAttack (angle, DEFMELEERANGE, null, 0., ALF_CHECK3D);
|
||||
LineAttack (angle, DEFMELEERANGE, slope, damage, 'Melee', "PunchPuff", true);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue