Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fix bungee-jumping turrets.

Turrets would use the exact muzzle position when firing, but use the base position when getting ready to fire. This
would result in a HMG tower pointing in the wrong direction half the time, bouncing up and down, if the target was
close. The turret would correctly point down when firing, and revert to pointing horizontally between shots.

Not using the exact muzzle position for direction, only for pitch, in case other code checks the direction too, and
depends on the result being the same.

Fixes ticket:2789.
  • Loading branch information...
commit d608f37fadfa969c225fef8149eaa700cc878a46 1 parent 4f85a5e
@Cyp Cyp authored
Showing with 15 additions and 14 deletions.
  1. +15 −14 src/action.cpp
View
29 src/action.cpp
@@ -363,12 +363,10 @@ bool actionTargetTurret(BASE_OBJECT *psAttacker, BASE_OBJECT *psTarget, WEAPON *
WEAPON_STATS *psWeapStats = asWeaponStats + psWeapon->nStat;
uint16_t tRotation, tPitch;
int32_t rotRate, pitchRate;
- uint16_t targetRotation, targetPitch;
- int32_t pitchError;
- int32_t rotationError, dx, dy, dz;
+ uint16_t targetRotation;
+ int32_t rotationError;
int32_t rotationTolerance = 0;
bool onTarget;
- int32_t dxy;
int32_t pitchLowerLimit, pitchUpperLimit;
bool bRepair;
@@ -397,14 +395,20 @@ bool actionTargetTurret(BASE_OBJECT *psAttacker, BASE_OBJECT *psTarget, WEAPON *
//set the pitch limits based on the weapon stats of the attacker
pitchLowerLimit = pitchUpperLimit = 0;
+ Vector3i attackerMuzzlePos = psAttacker->pos; // Using for calculating the pitch, but not the direction, in case using the exact direction causes bugs somewhere.
if (psAttacker->type == OBJ_STRUCTURE)
{
+ STRUCTURE *psStructure = (STRUCTURE *)psAttacker;
+ int weapon_slot = psWeapon - psStructure->asWeaps; // Should probably be passed weapon_slot instead of psWeapon.
+ calcStructureMuzzleLocation(psStructure, &attackerMuzzlePos, weapon_slot);
pitchLowerLimit = DEG(psWeapStats->minElevation);
pitchUpperLimit = DEG(psWeapStats->maxElevation);
}
else if (psAttacker->type == OBJ_DROID)
{
DROID *psDroid = (DROID *)psAttacker;
+ int weapon_slot = psWeapon - psDroid->asWeaps; // Should probably be passed weapon_slot instead of psWeapon.
+ calcDroidMuzzleLocation(psDroid, &attackerMuzzlePos, weapon_slot);
if (psDroid->droidType == DROID_WEAPON || psDroid->droidType == DROID_TRANSPORTER || psDroid->droidType == DROID_SUPERTRANSPORTER
|| psDroid->droidType == DROID_COMMAND || psDroid->droidType == DROID_CYBORG
@@ -447,20 +451,17 @@ bool actionTargetTurret(BASE_OBJECT *psAttacker, BASE_OBJECT *psTarget, WEAPON *
onTarget = abs(angleDelta(targetRotation - (tRotation + psAttacker->rot.direction))) <= rotationTolerance;
/* set muzzle pitch if direct fire */
- if (!bRepair && (proj_Direct(psWeapStats) || ((psAttacker->type == OBJ_DROID)
- && !proj_Direct(psWeapStats)
- && actionInsideMinRange((DROID *)psAttacker, psTarget, psWeapStats))))
+ if (!bRepair && (proj_Direct(psWeapStats)
+ || (psAttacker->type == OBJ_DROID && !proj_Direct(psWeapStats)
+ && actionInsideMinRange((DROID *)psAttacker, psTarget, psWeapStats))))
{
- dx = psTarget->pos.x - psAttacker->pos.x;
- dy = psTarget->pos.y - psAttacker->pos.y;
- dz = psTarget->pos.z - psAttacker->pos.z;
-
/* get target distance */
- dxy = iHypot(dx, dy);
+ Vector3i delta = psTarget->pos - attackerMuzzlePos;
+ int32_t dxy = iHypot(delta.x, delta.y);
- targetPitch = iAtan2(dz, dxy);
+ uint16_t targetPitch = iAtan2(delta.z, dxy);
targetPitch = (uint16_t)clip(angleDelta(targetPitch), pitchLowerLimit, pitchUpperLimit); // Cast wrapping intended.
- pitchError = angleDelta(targetPitch - tPitch);
+ int pitchError = angleDelta(targetPitch - tPitch);
tPitch += clip(pitchError, -pitchRate, pitchRate); // Addition wrapping intended.
onTarget = onTarget && targetPitch == tPitch;

0 comments on commit d608f37

Please sign in to comment.
Something went wrong with that request. Please try again.