diff --git a/Include/TSEDeviceClassesImpl.h b/Include/TSEDeviceClassesImpl.h index a9ef35c..e92c4b7 100644 --- a/Include/TSEDeviceClassesImpl.h +++ b/Include/TSEDeviceClassesImpl.h @@ -802,6 +802,7 @@ class CWeaponClass : public CDeviceClass int m_iRecoil; // 0-7 (as per momentum damage) int m_iFailureChance; // Chance of failure + bool m_bBurstTracksTargets; // If the weapon is continuous, whether or not to track the target during the entire burst bool m_bContinuousConsumePerShot; // If a continuous weapon, consume ammunition for every shot in burst int m_iCounterPerShot; // How much to increment the ship's counter by per shot bool m_bOmnidirectional; // Omnidirectional diff --git a/Include/TSEDevices.h b/Include/TSEDevices.h index 677d8ef..0c524e5 100644 --- a/Include/TSEDevices.h +++ b/Include/TSEDevices.h @@ -478,6 +478,7 @@ class CInstalledDevice int GetHitPointsPercent (CSpaceObject *pSource); inline const CString &GetID (void) const { return m_sID; } inline CItem *GetItem (void) const { return m_pItem; } + inline CSpaceObject *GetLastTarget(void) const { return m_pLastTarget; } DWORD GetLinkedFireOptions (void) const; inline int GetLevel (void) const { return (m_pItem ? m_pItem->GetLevel() : GetClass()->GetLevel()); } inline int GetMinFireArc (void) const { return m_iMinFireArc; } @@ -518,6 +519,7 @@ class CInstalledDevice inline void SetFireArc (int iMinFireArc, int iMaxFireArc) { m_iMinFireArc = iMinFireArc; m_iMaxFireArc = iMaxFireArc; } inline void SetID (const CString &sID) { m_sID = sID; } inline void SetLastActivateSuccessful (bool bSuccessful) { m_fLastActivateSuccessful = bSuccessful; } + inline void SetLastTarget(CSpaceObject *pTarget) { m_pLastTarget = pTarget; } void SetLinkedFireOptions (DWORD dwOptions); inline void SetOmniDirectional (bool bOmnidirectional = true) { m_fOmniDirectional = bOmnidirectional; } inline void SetOptimized (bool bOptimized) { m_fOptimized = bOptimized; } @@ -670,4 +672,6 @@ class CInstalledDevice DWORD m_fSpare8:1; DWORD m_dwSpare:8; + + CSpaceObject *m_pLastTarget; }; diff --git a/TSE/CInstalledDevice.cpp b/TSE/CInstalledDevice.cpp index 1d45b42..cbd3083 100644 --- a/TSE/CInstalledDevice.cpp +++ b/TSE/CInstalledDevice.cpp @@ -25,6 +25,7 @@ CInstalledDevice::CInstalledDevice (void) : m_pItem(NULL), m_pOverlay(NULL), + m_pLastTarget(NULL), m_dwTargetID(0), m_iDeviceSlot(-1), m_iPosAngle(0), diff --git a/TSE/CWeaponClass.cpp b/TSE/CWeaponClass.cpp index ee1566f..9774416 100644 --- a/TSE/CWeaponClass.cpp +++ b/TSE/CWeaponClass.cpp @@ -14,6 +14,7 @@ #define ALTERNATING_ATTRIB CONSTLIT("alternating") #define AMMO_ID_ATTRIB CONSTLIT("ammoID") #define ANGLE_ATTRIB CONSTLIT("angle") +#define BURST_TRACKS_TARGETS_ATTRIB CONSTLIT("burstTracksTargets") #define CHARGES_ATTRIB CONSTLIT("charges") #define CONFIGURATION_ATTRIB CONSTLIT("configuration") #define CONTINUOUS_CONSUME_PERSHOT_ATTRIB CONSTLIT("consumeAmmoPerRepeatingShot") @@ -272,6 +273,12 @@ bool CWeaponClass::Activate (CInstalledDevice *pDevice, bool bSuccess = FireWeapon(pDevice, pShot, pSource, pTarget, 0, &bSourceDestroyed, retbConsumedItems); + // Store the target object if we need to + if (m_bBurstTracksTargets) + { + pDevice->SetLastTarget(pTarget); + } + // If firing the weapon destroyed the ship, then we bail out if (bSourceDestroyed) @@ -1439,6 +1446,7 @@ ALERROR CWeaponClass::CreateFromXML (SDesignLoadCtx &Ctx, CXMLElement *pDesc, CI pWeapon->m_bTargetStationsOnly = pDesc->GetAttributeBool(TARGET_STATIONS_ONLY_ATTRIB); pWeapon->m_bContinuousConsumePerShot = pDesc->GetAttributeBool(CONTINUOUS_CONSUME_PERSHOT_ATTRIB); pWeapon->m_iCounterPerShot = pDesc->GetAttributeIntegerBounded(SHIP_COUNTER_PER_SHOT_ATTRIB, 0, -1, 0); + pWeapon->m_bBurstTracksTargets = pDesc->GetAttributeBool(BURST_TRACKS_TARGETS_ATTRIB); // Configuration @@ -1971,10 +1979,15 @@ bool CWeaponClass::FireWeapon (CInstalledDevice *pDevice, int iFireAngle = pDevice->GetFireAngle(); // If the fire angle is -1 then we need to calc it ourselves + // If we need to recalculate for all shots in a repeating burst, + // then do so (since the AI only sets firing angle on first shot in burst). - if (iFireAngle == -1) + if (iFireAngle == -1 || (iRepeatingCount != 0 && m_bBurstTracksTargets)) { bool bOutOfArc; + CSpaceObject *pStoredTarget = pDevice->GetLastTarget(); + if (iRepeatingCount != 0 && m_bBurstTracksTargets && pTarget == NULL && pStoredTarget != NULL) + pTarget = pStoredTarget; iFireAngle = CalcFireAngle(ItemCtx, rSpeed, pTarget, &bOutOfArc); }