Skip to content

Commit

Permalink
Fix bungee-jumping turrets.
Browse files Browse the repository at this point in the history
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
Cyp committed Sep 21, 2012
1 parent 4f85a5e commit d608f37
Showing 1 changed file with 15 additions and 14 deletions.
29 changes: 15 additions & 14 deletions src/action.cpp
Expand Up @@ -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;

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit d608f37

Please sign in to comment.