Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

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 authored September 21, 2012

Showing 1 changed file with 15 additions and 14 deletions. Show diff stats Hide diff stats

  1. 29  src/action.cpp
29  src/action.cpp
@@ -363,12 +363,10 @@ bool actionTargetTurret(BASE_OBJECT *psAttacker, BASE_OBJECT *psTarget, WEAPON *
363 363
 	WEAPON_STATS *psWeapStats = asWeaponStats + psWeapon->nStat;
364 364
 	uint16_t tRotation, tPitch;
365 365
 	int32_t  rotRate, pitchRate;
366  
-	uint16_t targetRotation, targetPitch;
367  
-	int32_t  pitchError;
368  
-	int32_t  rotationError, dx, dy, dz;
  366
+	uint16_t targetRotation;
  367
+	int32_t  rotationError;
369 368
 	int32_t  rotationTolerance = 0;
370 369
 	bool     onTarget;
371  
-	int32_t  dxy;
372 370
 	int32_t  pitchLowerLimit, pitchUpperLimit;
373 371
 	bool     bRepair;
374 372
 
@@ -397,14 +395,20 @@ bool actionTargetTurret(BASE_OBJECT *psAttacker, BASE_OBJECT *psTarget, WEAPON *
397 395
 
398 396
 	//set the pitch limits based on the weapon stats of the attacker
399 397
 	pitchLowerLimit = pitchUpperLimit = 0;
  398
+	Vector3i attackerMuzzlePos = psAttacker->pos;  // Using for calculating the pitch, but not the direction, in case using the exact direction causes bugs somewhere.
400 399
 	if (psAttacker->type == OBJ_STRUCTURE)
401 400
 	{
  401
+		STRUCTURE *psStructure = (STRUCTURE *)psAttacker;
  402
+		int weapon_slot = psWeapon - psStructure->asWeaps;  // Should probably be passed weapon_slot instead of psWeapon.
  403
+		calcStructureMuzzleLocation(psStructure, &attackerMuzzlePos, weapon_slot);
402 404
 		pitchLowerLimit = DEG(psWeapStats->minElevation);
403 405
 		pitchUpperLimit = DEG(psWeapStats->maxElevation);
404 406
 	}
405 407
 	else if (psAttacker->type == OBJ_DROID)
406 408
 	{
407 409
 		DROID *psDroid = (DROID *)psAttacker;
  410
+		int weapon_slot = psWeapon - psDroid->asWeaps;  // Should probably be passed weapon_slot instead of psWeapon.
  411
+		calcDroidMuzzleLocation(psDroid, &attackerMuzzlePos, weapon_slot);
408 412
 
409 413
 		if (psDroid->droidType == DROID_WEAPON || psDroid->droidType == DROID_TRANSPORTER || psDroid->droidType == DROID_SUPERTRANSPORTER
410 414
 			|| psDroid->droidType == DROID_COMMAND || psDroid->droidType == DROID_CYBORG
@@ -447,20 +451,17 @@ bool actionTargetTurret(BASE_OBJECT *psAttacker, BASE_OBJECT *psTarget, WEAPON *
447 451
 	onTarget = abs(angleDelta(targetRotation - (tRotation + psAttacker->rot.direction))) <= rotationTolerance;
448 452
 
449 453
 	/* set muzzle pitch if direct fire */
450  
-	if (!bRepair && (proj_Direct(psWeapStats) || ((psAttacker->type == OBJ_DROID)
451  
-													  && !proj_Direct(psWeapStats)
452  
-												  && actionInsideMinRange((DROID *)psAttacker, psTarget, psWeapStats))))
  454
+	if (!bRepair && (proj_Direct(psWeapStats)
  455
+	                 || (psAttacker->type == OBJ_DROID && !proj_Direct(psWeapStats)
  456
+	                                                   && actionInsideMinRange((DROID *)psAttacker, psTarget, psWeapStats))))
453 457
 	{
454  
-		dx = psTarget->pos.x - psAttacker->pos.x;
455  
-		dy = psTarget->pos.y - psAttacker->pos.y;
456  
-		dz = psTarget->pos.z - psAttacker->pos.z;
457  
-
458 458
 		/* get target distance */
459  
-		dxy = iHypot(dx, dy);
  459
+		Vector3i delta = psTarget->pos - attackerMuzzlePos;
  460
+		int32_t dxy = iHypot(delta.x, delta.y);
460 461
 
461  
-		targetPitch = iAtan2(dz, dxy);
  462
+		uint16_t targetPitch = iAtan2(delta.z, dxy);
462 463
 		targetPitch = (uint16_t)clip(angleDelta(targetPitch), pitchLowerLimit, pitchUpperLimit);  // Cast wrapping intended.
463  
-		pitchError = angleDelta(targetPitch - tPitch);
  464
+		int pitchError = angleDelta(targetPitch - tPitch);
464 465
 
465 466
 		tPitch += clip(pitchError, -pitchRate, pitchRate);  // Addition wrapping intended.
466 467
 		onTarget = onTarget && targetPitch == tPitch;

0 notes on commit d608f37

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