diff --git a/Generals/Code/GameEngine/Include/GameLogic/Module/SpecialPowerModule.h b/Generals/Code/GameEngine/Include/GameLogic/Module/SpecialPowerModule.h index d6e55578b82..5b19dc02d18 100644 --- a/Generals/Code/GameEngine/Include/GameLogic/Module/SpecialPowerModule.h +++ b/Generals/Code/GameEngine/Include/GameLogic/Module/SpecialPowerModule.h @@ -66,6 +66,7 @@ class SpecialPowerModuleInterface virtual void markSpecialPowerTriggered( const Coord3D *location ) = 0; virtual void startPowerRecharge() = 0; virtual const AudioEventRTS& getInitiateSound() const = 0; + virtual Bool hasInitialReloadTime() const = 0; virtual Bool isScriptOnly() const = 0; }; @@ -83,6 +84,7 @@ class SpecialPowerModuleData : public BehaviorModuleData AudioEventRTS m_initiateSound; Bool m_updateModuleStartsAttack; ///< update module determines when the special power actually starts! If true, update module is required. Bool m_startsPaused; ///< Paused on creation, someone else will have to unpause (like upgrade module, or script) + Bool m_hasInitialReloadTime; ///< If true, the special power will have a reload time on creation, otherwise it will be ready immediately. Bool m_scriptedSpecialPowerOnly; }; @@ -154,6 +156,7 @@ class SpecialPowerModule : public BehaviorModule, virtual void startPowerRecharge() override; virtual const AudioEventRTS& getInitiateSound() const override; + virtual Bool hasInitialReloadTime() const override; virtual Bool isScriptOnly() const override; protected: diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/SpecialPower/SpecialPowerModule.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/SpecialPower/SpecialPowerModule.cpp index 24db1aab346..01cf92b600e 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/SpecialPower/SpecialPowerModule.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/SpecialPower/SpecialPowerModule.cpp @@ -63,6 +63,7 @@ SpecialPowerModuleData::SpecialPowerModuleData() m_specialPowerTemplate = nullptr; m_updateModuleStartsAttack = false; m_startsPaused = FALSE; + m_hasInitialReloadTime = TRUE; m_scriptedSpecialPowerOnly = FALSE; } @@ -78,6 +79,7 @@ SpecialPowerModuleData::SpecialPowerModuleData() { "SpecialPowerTemplate", INI::parseSpecialPowerTemplate, nullptr, offsetof( SpecialPowerModuleData, m_specialPowerTemplate ) }, { "UpdateModuleStartsAttack", INI::parseBool, nullptr, offsetof( SpecialPowerModuleData, m_updateModuleStartsAttack ) }, { "StartsPaused", INI::parseBool, nullptr, offsetof( SpecialPowerModuleData, m_startsPaused ) }, + { "HasInitialReloadTime", INI::parseBool, nullptr, offsetof( SpecialPowerModuleData, m_hasInitialReloadTime ) }, { "InitiateSound", INI::parseAudioEventRTS, nullptr, offsetof( SpecialPowerModuleData, m_initiateSound ) }, { "ScriptedSpecialPowerOnly", INI::parseBool, nullptr, offsetof( SpecialPowerModuleData, m_scriptedSpecialPowerOnly ) }, { nullptr, nullptr, nullptr, 0 } @@ -113,7 +115,11 @@ SpecialPowerModule::SpecialPowerModule( Thing *thing, const ModuleData *moduleDa //A sharedNSync special only startPowerRecharges when first scienced or when executed, //Since a new module with same SPTemplates may construct at any time. if ( getSpecialPowerTemplate()->isSharedNSync() == FALSE ) + { startPowerRecharge(); + if (!hasInitialReloadTime()) + m_availableOnFrame = TheGameLogic->getFrame(); + } } // WE USED TO DO THE POLL-EVERYBODY-AND-VOTE-ON-WHO-TO-SYNC-TO THING HERE, // BUT NO MORE, NOW IT IS HANDLED IN PLAYER @@ -345,6 +351,16 @@ Real SpecialPowerModule::getPercentReady() const return percent; } +Bool SpecialPowerModule::hasInitialReloadTime() const +{ +#if RETAIL_COMPATIBLE_CRC + return true; +#endif + + const SpecialPowerModuleData* modData = getSpecialPowerModuleData(); + return modData->m_hasInitialReloadTime; +} + //------------------------------------------------------------------------------------------------- // A special power module that is only supposed to be fired via scripts. An example of this // are the various cargo plane units we have. Scripters can launch specials from them after diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Upgrade/UnpauseSpecialPowerUpgrade.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Upgrade/UnpauseSpecialPowerUpgrade.cpp index 73a0d8f0dee..e477567f12c 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Upgrade/UnpauseSpecialPowerUpgrade.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Upgrade/UnpauseSpecialPowerUpgrade.cpp @@ -33,6 +33,7 @@ #include "PreRTS.h" #include "Common/SpecialPower.h" #include "Common/Xfer.h" +#include "GameLogic/GameLogic.h" #include "GameLogic/Object.h" #include "GameLogic/Module/SpecialPowerModule.h" #include "GameLogic/Module/UnpauseSpecialPowerUpgrade.h" @@ -89,7 +90,15 @@ void UnpauseSpecialPowerUpgrade::upgradeImplementation() continue; if( sp->getSpecialPowerTemplate() == getUnpauseSpecialPowerUpgradeModuleData()->m_specialPower ) + { sp->pauseCountdown( FALSE ); + + if (!sp->hasInitialReloadTime()) + { + UnsignedInt now = TheGameLogic->getFrame(); + sp->setReadyFrame(now); + } + } } } diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/SpecialPowerModule.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/SpecialPowerModule.h index 8e5200007fc..5d7ffdb4264 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/SpecialPowerModule.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/SpecialPowerModule.h @@ -66,6 +66,7 @@ class SpecialPowerModuleInterface virtual void markSpecialPowerTriggered( const Coord3D *location ) = 0; virtual void startPowerRecharge() = 0; virtual const AudioEventRTS& getInitiateSound() const = 0; + virtual Bool hasInitialReloadTime() const = 0; virtual Bool isScriptOnly() const = 0; //If the special power launches a construction site, we need to know the final product for placement purposes. @@ -86,6 +87,7 @@ class SpecialPowerModuleData : public BehaviorModuleData AudioEventRTS m_initiateSound; Bool m_updateModuleStartsAttack; ///< update module determines when the special power actually starts! If true, update module is required. Bool m_startsPaused; ///< Paused on creation, someone else will have to unpause (like upgrade module, or script) + Bool m_hasInitialReloadTime; ///< If true, the special power will have a reload time on creation, otherwise it will be ready immediately. Bool m_scriptedSpecialPowerOnly; }; @@ -157,6 +159,7 @@ class SpecialPowerModule : public BehaviorModule, virtual void startPowerRecharge() override; virtual const AudioEventRTS& getInitiateSound() const override; + virtual Bool hasInitialReloadTime() const override; virtual Bool isScriptOnly() const override; //If the special power launches a construction site, we need to know the final product for placement purposes. diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/SpecialPower/SpecialPowerModule.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/SpecialPower/SpecialPowerModule.cpp index 6f88eff654d..35d03c85b93 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/SpecialPower/SpecialPowerModule.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/SpecialPower/SpecialPowerModule.cpp @@ -64,6 +64,7 @@ SpecialPowerModuleData::SpecialPowerModuleData() m_specialPowerTemplate = nullptr; m_updateModuleStartsAttack = false; m_startsPaused = FALSE; + m_hasInitialReloadTime = TRUE; m_scriptedSpecialPowerOnly = FALSE; } @@ -79,6 +80,7 @@ SpecialPowerModuleData::SpecialPowerModuleData() { "SpecialPowerTemplate", INI::parseSpecialPowerTemplate, nullptr, offsetof( SpecialPowerModuleData, m_specialPowerTemplate ) }, { "UpdateModuleStartsAttack", INI::parseBool, nullptr, offsetof( SpecialPowerModuleData, m_updateModuleStartsAttack ) }, { "StartsPaused", INI::parseBool, nullptr, offsetof( SpecialPowerModuleData, m_startsPaused ) }, + { "HasInitialReloadTime", INI::parseBool, nullptr, offsetof( SpecialPowerModuleData, m_hasInitialReloadTime ) }, { "InitiateSound", INI::parseAudioEventRTS, nullptr, offsetof( SpecialPowerModuleData, m_initiateSound ) }, { "ScriptedSpecialPowerOnly", INI::parseBool, nullptr, offsetof( SpecialPowerModuleData, m_scriptedSpecialPowerOnly ) }, { nullptr, nullptr, nullptr, 0 } @@ -114,7 +116,11 @@ SpecialPowerModule::SpecialPowerModule( Thing *thing, const ModuleData *moduleDa //A sharedNSync special only startPowerRecharges when first scienced or when executed, //Since a new module with same SPTemplates may construct at any time. if ( getSpecialPowerTemplate()->isSharedNSync() == FALSE ) + { startPowerRecharge(); + if (!hasInitialReloadTime()) + m_availableOnFrame = TheGameLogic->getFrame(); + } } // WE USED TO DO THE POLL-EVERYBODY-AND-VOTE-ON-WHO-TO-SYNC-TO THING HERE, // BUT NO MORE, NOW IT IS HANDLED IN PLAYER @@ -370,6 +376,16 @@ Real SpecialPowerModule::getPercentReady() const return percent; } +Bool SpecialPowerModule::hasInitialReloadTime() const +{ +#if RETAIL_COMPATIBLE_CRC + return true; +#endif + + const SpecialPowerModuleData* modData = getSpecialPowerModuleData(); + return modData->m_hasInitialReloadTime; +} + //------------------------------------------------------------------------------------------------- // A special power module that is only supposed to be fired via scripts. An example of this // are the various cargo plane units we have. Scripters can launch specials from them after diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Upgrade/UnpauseSpecialPowerUpgrade.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Upgrade/UnpauseSpecialPowerUpgrade.cpp index 182e636bc58..ff799bc9d95 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Upgrade/UnpauseSpecialPowerUpgrade.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Upgrade/UnpauseSpecialPowerUpgrade.cpp @@ -33,6 +33,7 @@ #include "PreRTS.h" #include "Common/SpecialPower.h" #include "Common/Xfer.h" +#include "GameLogic/GameLogic.h" #include "GameLogic/Object.h" #include "GameLogic/Module/SpecialPowerModule.h" #include "GameLogic/Module/UnpauseSpecialPowerUpgrade.h" @@ -89,7 +90,15 @@ void UnpauseSpecialPowerUpgrade::upgradeImplementation() continue; if( sp->getSpecialPowerTemplate() == getUnpauseSpecialPowerUpgradeModuleData()->m_specialPower ) + { sp->pauseCountdown( FALSE ); + + if (!sp->hasInitialReloadTime()) + { + UnsignedInt now = TheGameLogic->getFrame(); + sp->setReadyFrame(now); + } + } } }