diff --git a/GeneralsMD/Code/GameEngine/CMakeLists.txt b/GeneralsMD/Code/GameEngine/CMakeLists.txt index 135c9bbda2..e503b61d13 100644 --- a/GeneralsMD/Code/GameEngine/CMakeLists.txt +++ b/GeneralsMD/Code/GameEngine/CMakeLists.txt @@ -415,6 +415,7 @@ set(GAMEENGINE_SRC Include/GameLogic/Module/RebuildHoleExposeDie.h Include/GameLogic/Module/RepairDockUpdate.h Include/GameLogic/Module/ReplaceObjectUpgrade.h + Include/GameLogic/Module/ResetSpecialPowerTimerWhileAliveUpdate.h Include/GameLogic/Module/RiderChangeContain.h Include/GameLogic/Module/SabotageCommandCenterCrateCollide.h Include/GameLogic/Module/SabotageFakeBuildingCrateCollide.h @@ -1055,6 +1056,7 @@ set(GAMEENGINE_SRC Source/GameLogic/Object/Update/RadarUpdate.cpp Source/GameLogic/Object/Update/RadiusDecalUpdate.cpp Source/GameLogic/Object/Update/RadiusDecalBehavior.cpp + Source/GameLogic/Object/Update/ResetSpecialPowerTimerWhileAliveUpdate.cpp Source/GameLogic/Object/Update/ScatterShotUpdate.cpp Source/GameLogic/Object/Update/SlavedUpdate.cpp Source/GameLogic/Object/Update/SmartBombTargetHomingUpdate.cpp diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/ResetSpecialPowerTimerWhileAliveUpdate.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/ResetSpecialPowerTimerWhileAliveUpdate.h new file mode 100644 index 0000000000..fd6502b094 --- /dev/null +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/ResetSpecialPowerTimerWhileAliveUpdate.h @@ -0,0 +1,59 @@ +// FILE: ResetSpecialPowerTimerWhileAliveUpdate.h ////////////////////////////////////////////////////////////////////////// +// Author: pWn3d, 2025 +// Desc: Update module to reset a player global special power timer while this object is alive +// Example use: airdrop special power that starts with the cooldown when the dropped unit is dead, add this module to the +// dropped unit +/////////////////////////////////////////////////////////////////////////////////////////////////// + + +#pragma once + +#ifndef __RESET_SPECIAL_POWER_TIMER_WHILE_ALIVE_UPDATE_H_ +#define __RESET_SPECIAL_POWER_TIMER_WHILE_ALIVE_UPDATE_H_ + +// INCLUDES /////////////////////////////////////////////////////////////////////////////////////// +#include "Common/KindOf.h" +#include "GameLogic/Module/UpdateModule.h" + +// FORWARD REFERENCES ///////////////////////////////////////////////////////////////////////////// +class ThingTemplate; +class SpecialPowerTemplate; + + +//------------------------------------------------------------------------------------------------- +//------------------------------------------------------------------------------------------------- +class ResetSpecialPowerTimerWhileAliveUpdateModuleData : public ModuleData +{ +public: + SpecialPowerTemplate* m_specialPowerTemplate; + + ResetSpecialPowerTimerWhileAliveUpdateModuleData(); + static void buildFieldParse(MultiIniFieldParse& p); + +private: + +}; + +//------------------------------------------------------------------------------------------------- +/** The default update module */ +//------------------------------------------------------------------------------------------------- +class ResetSpecialPowerTimerWhileAliveUpdate : public UpdateModule +{ + + MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(ResetSpecialPowerTimerWhileAliveUpdate, "ResetSpecialPowerTimerWhileAliveUpdate") + MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA(ResetSpecialPowerTimerWhileAliveUpdate, ResetSpecialPowerTimerWhileAliveUpdateModuleData); + +public: + + ResetSpecialPowerTimerWhileAliveUpdate(Thing* thing, const ModuleData* moduleData); + // virtual destructor prototype provided by memory pool declaration + + virtual void onObjectCreated(); + virtual UpdateSleepTime update(); + +protected: + // no members needed +}; + + +#endif \ No newline at end of file diff --git a/GeneralsMD/Code/GameEngine/Source/Common/System/MemoryInit.cpp b/GeneralsMD/Code/GameEngine/Source/Common/System/MemoryInit.cpp index a4387c1a60..104fc8a8fc 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/System/MemoryInit.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/System/MemoryInit.cpp @@ -729,6 +729,7 @@ static PoolSizeRec sizes[] = { "ThumbnailManagerClass", 32, 32}, { "SmudgeSet", 32, 32}, { "Smudge", 128, 32}, + { "ResetSpecialPowerTimerWhileAliveUpdate", 8, 8 }, { 0, 0, 0 } }; diff --git a/GeneralsMD/Code/GameEngine/Source/Common/Thing/ModuleFactory.cpp b/GeneralsMD/Code/GameEngine/Source/Common/Thing/ModuleFactory.cpp index 5b3850300d..e1d9c7c7a7 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/Thing/ModuleFactory.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/Thing/ModuleFactory.cpp @@ -197,6 +197,7 @@ #include "GameLogic/Module/PowerPlantUpdate.h" #include "GameLogic/Module/CheckpointUpdate.h" #include "GameLogic/Module/EMPUpdate.h" +#include "GameLogic/Module/ResetSpecialPowerTimerWhileAliveUpdate.h" // upgrade includes #include "GameLogic/Module/ActiveShroudUpgrade.h" @@ -486,6 +487,7 @@ void ModuleFactory::init( void ) addModule( WorkerAIUpdate ); addModule( PowerPlantUpdate ); addModule( CheckpointUpdate ); + addModule( ResetSpecialPowerTimerWhileAliveUpdate ); // upgrade modules addModule( CostModifierUpgrade ); diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ResetSpecialPowerTimerWhileAliveUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ResetSpecialPowerTimerWhileAliveUpdate.cpp new file mode 100644 index 0000000000..a3040a2cfe --- /dev/null +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ResetSpecialPowerTimerWhileAliveUpdate.cpp @@ -0,0 +1,132 @@ + +// INCLUDES /////////////////////////////////////////////////////////////////////////////////////// +#include "PreRTS.h" // This must go first in EVERY cpp file in the GameEngine + +#include "Common/BitFlagsIO.h" +#include "Common/RandomValue.h" +#include "Common/ThingTemplate.h" +#include "Common/Xfer.h" +#include "Common/SpecialPower.h" +#include "Common/Player.h" + +#include "GameClient/Drawable.h" + +#include "GameLogic/GameLogic.h" +#include "GameLogic/PartitionManager.h" +#include "GameLogic/Object.h" +#include "GameLogic/ObjectIter.h" +#include "GameLogic/Module/ResetSpecialPowerTimerWhileAliveUpdate.h" +#include "GameLogic/Module/PhysicsUpdate.h" +#include "GameLogic/Weapon.h" + + + +//------------------------------------------------------------------------------------------------- +//------------------------------------------------------------------------------------------------- +ResetSpecialPowerTimerWhileAliveUpdateModuleData::ResetSpecialPowerTimerWhileAliveUpdateModuleData() +{ + m_specialPowerTemplate = NULL; +} + +//------------------------------------------------------------------------------------------------- +/*static*/ void ResetSpecialPowerTimerWhileAliveUpdateModuleData::buildFieldParse(MultiIniFieldParse& p) +{ + ModuleData::buildFieldParse(p); + + static const FieldParse dataFieldParse[] = + { + { "SpecialPowerTemplate", INI::parseSpecialPowerTemplate, NULL, offsetof(ResetSpecialPowerTimerWhileAliveUpdateModuleData, m_specialPowerTemplate ) }, + { 0, 0, 0, 0 } + }; + p.add(dataFieldParse); +} + +//------------------------------------------------------------------------------------------------- +ResetSpecialPowerTimerWhileAliveUpdate::ResetSpecialPowerTimerWhileAliveUpdate( Thing *thing, const ModuleData* moduleData ) : UpdateModule( thing, moduleData ) +{ + setWakeFrame(getObject(), UPDATE_SLEEP_NONE);// No starting sleep, but we want to sleep later. +} + +//------------------------------------------------------------------------------------------------- +//------------------------------------------------------------------------------------------------- +ResetSpecialPowerTimerWhileAliveUpdate::~ResetSpecialPowerTimerWhileAliveUpdate( void ) +{ + +} + + +//------------------------------------------------------------------------------------------------- +void ResetSpecialPowerTimerWhileAliveUpdate::onObjectCreated() +{ + const ResetSpecialPowerTimerWhileAliveUpdateModuleData *data = getResetSpecialPowerTimerWhileAliveUpdateModuleData(); + + //Make sure we have a weapon template + if( !data->m_specialPowerTemplate ) + { + DEBUG_CRASH( ("ResetSpecialPowerTimerWhileAliveUpdateModuleData for %s doesn't have a valid Special Power Template", + getObject()->getTemplate()->getName().str() ) ); + return; + } + + //Make sure the special power template + if (!data->m_specialPowerTemplate->isSharedNSync()) { + DEBUG_CRASH(("ResetSpecialPowerTimerWhileAliveUpdateModuleData for %s only supports SpecialPowerTemplates with shared sync timers!", + getObject()->getTemplate()->getName().str())); + return; + } +} + +//------------------------------------------------------------------------------------------------- +/** The update callback. */ +//------------------------------------------------------------------------------------------------- +UpdateSleepTime ResetSpecialPowerTimerWhileAliveUpdate::update() +{ + Object *me = getObject(); + if( me->isEffectivelyDead() ) + return UPDATE_SLEEP_FOREVER; //No more resetting when dead + + const ResetSpecialPowerTimerWhileAliveUpdateModuleData *data = getResetSpecialPowerTimerWhileAliveUpdateModuleData(); + + Player* owner = me->getControllingPlayer(); + if (owner != nullptr) { + owner->resetOrStartSpecialPowerReadyFrame(data->m_specialPowerTemplate); + } + + return UPDATE_SLEEP_NONE; +} + +// ------------------------------------------------------------------------------------------------ +/** CRC */ +// ------------------------------------------------------------------------------------------------ +void ResetSpecialPowerTimerWhileAliveUpdate::crc( Xfer *xfer ) +{ + // extend base class + UpdateModule::crc( xfer ); +} // end crc + +// ------------------------------------------------------------------------------------------------ +/** Xfer method + * Version Info: + * 1: Initial version */ +// ------------------------------------------------------------------------------------------------ +void ResetSpecialPowerTimerWhileAliveUpdate::xfer( Xfer *xfer ) +{ + // version + XferVersion currentVersion = 1; + XferVersion version = currentVersion; + xfer->xferVersion( &version, currentVersion ); + + // extend base class + UpdateModule::xfer( xfer ); + +} // end xfer + +// ------------------------------------------------------------------------------------------------ +/** Load post process */ +// ------------------------------------------------------------------------------------------------ +void ResetSpecialPowerTimerWhileAliveUpdate::loadPostProcess( void ) +{ + // extend base class + UpdateModule::loadPostProcess(); + +} // end loadPostProcess