UpgradeModule.h 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. /*
  2. ** Command & Conquer Generals Zero Hour(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. ////////////////////////////////////////////////////////////////////////////////
  19. // //
  20. // (c) 2001-2003 Electronic Arts Inc. //
  21. // //
  22. ////////////////////////////////////////////////////////////////////////////////
  23. // FILE: UpgradeModule.h /////////////////////////////////////////////////////////////////////////////////
  24. // Author: Graham Smallwood, March 2002
  25. // Desc: A Module that responds to PlayerUpgrade Bitsetting by executing code once and only once
  26. ///////////////////////////////////////////////////////////////////////////////////////////////////
  27. #pragma once
  28. #ifndef __UPGRADE_MODULE_H_
  29. #define __UPGRADE_MODULE_H_
  30. #include "Common/Module.h"
  31. #include "Common/STLTypedefs.h"
  32. #include "Common/Upgrade.h"
  33. #include "GameClient/Drawable.h"
  34. #include "GameClient/FXList.h"
  35. #include "GameLogic/Module/BehaviorModule.h"
  36. // FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
  37. class Player;
  38. //-------------------------------------------------------------------------------------------------
  39. /** OBJECT DIE MODULE base class */
  40. //-------------------------------------------------------------------------------------------------
  41. //-------------------------------------------------------------------------------------------------
  42. class UpgradeModuleInterface
  43. {
  44. public:
  45. virtual Bool isAlreadyUpgraded() const = 0;
  46. virtual Bool attemptUpgrade( UpgradeMaskType keyMask ) = 0;
  47. virtual Bool wouldUpgrade( UpgradeMaskType keyMask ) const = 0;
  48. virtual Bool resetUpgrade( UpgradeMaskType keyMask ) = 0;
  49. virtual Bool isSubObjectsUpgrade() = 0;
  50. virtual void forceRefreshUpgrade() = 0;
  51. virtual Bool testUpgradeConditions( UpgradeMaskType keyMask ) const = 0;
  52. };
  53. //-------------------------------------------------------------------------------------------------
  54. class UpgradeMuxData // does NOT inherit from ModuleData.
  55. {
  56. public:
  57. mutable std::vector<AsciiString> m_triggerUpgradeNames;
  58. mutable std::vector<AsciiString> m_activationUpgradeNames;
  59. mutable std::vector<AsciiString> m_conflictingUpgradeNames;
  60. mutable std::vector<AsciiString> m_removalUpgradeNames;
  61. mutable const FXList* m_fxListUpgrade;
  62. mutable UpgradeMaskType m_activationMask; ///< Activation only supports a single name currently
  63. mutable UpgradeMaskType m_conflictingMask; ///< Conflicts support multiple listings, and they are an OR
  64. mutable Bool m_requiresAllTriggers;
  65. UpgradeMuxData()
  66. {
  67. m_triggerUpgradeNames.clear();
  68. m_activationUpgradeNames.clear();
  69. m_conflictingUpgradeNames.clear();
  70. m_removalUpgradeNames.clear();
  71. m_fxListUpgrade = NULL;
  72. m_activationMask.clear();
  73. m_conflictingMask.clear();
  74. m_requiresAllTriggers = false;
  75. }
  76. static const FieldParse* getFieldParse()
  77. {
  78. static const FieldParse dataFieldParse[] =
  79. {
  80. { "TriggeredBy", INI::parseAsciiStringVector, NULL, offsetof( UpgradeMuxData, m_activationUpgradeNames ) },
  81. { "ConflictsWith", INI::parseAsciiStringVector, NULL, offsetof( UpgradeMuxData, m_conflictingUpgradeNames ) },
  82. { "RemovesUpgrades",INI::parseAsciiStringVector, NULL, offsetof( UpgradeMuxData, m_removalUpgradeNames ) },
  83. { "FXListUpgrade", INI::parseFXList, NULL, offsetof( UpgradeMuxData, m_fxListUpgrade ) },
  84. { "RequiresAllTriggers", INI::parseBool, NULL, offsetof( UpgradeMuxData, m_requiresAllTriggers ) },
  85. { 0, 0, 0, 0 }
  86. };
  87. return dataFieldParse;
  88. }
  89. Bool requiresAllActivationUpgrades() const;
  90. void getUpgradeActivationMasks(UpgradeMaskType& activation, UpgradeMaskType& conflicting) const; ///< The first time someone looks at my mask, I'll figure it out.
  91. void performUpgradeFX(Object* obj) const;
  92. void muxDataProcessUpgradeRemoval(Object* obj) const;
  93. Bool isTriggeredBy(const std::string &upgrade) const;
  94. };
  95. //-------------------------------------------------------------------------------------------------
  96. // implements some handy mix-in guts, but doesn't descend from ObjectModule... useful for Behaviors
  97. // that want to implement Upgrades
  98. class UpgradeMux : public UpgradeModuleInterface
  99. {
  100. public:
  101. UpgradeMux();
  102. virtual Bool isAlreadyUpgraded() const ;
  103. // ***DANGER! DANGER! Don't use this, unless you are forcing an already made upgrade to refresh!!
  104. virtual void forceRefreshUpgrade();
  105. virtual Bool attemptUpgrade( UpgradeMaskType keyMask );
  106. virtual Bool wouldUpgrade( UpgradeMaskType keyMask ) const;
  107. virtual Bool resetUpgrade( UpgradeMaskType keyMask );
  108. virtual Bool testUpgradeConditions( UpgradeMaskType keyMask ) const;
  109. protected:
  110. void setUpgradeExecuted(Bool e) { m_upgradeExecuted = e; }
  111. virtual void upgradeImplementation( ) = 0; ///< Here's the actual work of Upgrading
  112. virtual void getUpgradeActivationMasks(UpgradeMaskType& activation, UpgradeMaskType& conflicting) const = 0; ///< Here's the actual work of Upgrading
  113. virtual void performUpgradeFX() = 0; ///< perform the associated fx list
  114. virtual Bool requiresAllActivationUpgrades() const = 0;
  115. virtual Bool isSubObjectsUpgrade() = 0;
  116. virtual void processUpgradeRemoval() = 0;
  117. void giveSelfUpgrade();
  118. //
  119. // this is not a snapshot class itself, but it is a base class used in conjunction with
  120. // multiple inheritance for modules, so those modules need to be able to poke inside
  121. // this class and xfer the data here during a snapshot process
  122. //
  123. virtual void upgradeMuxCRC( Xfer *xfer );
  124. virtual void upgradeMuxXfer( Xfer *xfer);
  125. virtual void upgradeMuxLoadPostProcess( void );
  126. private:
  127. Bool m_upgradeExecuted; ///< Upgrade only executes once
  128. };
  129. //-------------------------------------------------------------------------------------------------
  130. struct UpgradeModuleData : public BehaviorModuleData
  131. {
  132. public:
  133. UpgradeMuxData m_upgradeMuxData;
  134. static void buildFieldParse(MultiIniFieldParse& p)
  135. {
  136. ModuleData::buildFieldParse(p);
  137. p.add(UpgradeMuxData::getFieldParse(), offsetof( UpgradeModuleData, m_upgradeMuxData ));
  138. }
  139. };
  140. //-------------------------------------------------------------------------------------------------
  141. class UpgradeModule : public BehaviorModule, public UpgradeMux
  142. {
  143. MEMORY_POOL_GLUE_ABC( UpgradeModule )
  144. MAKE_STANDARD_MODULE_MACRO_ABC( UpgradeModule )
  145. MAKE_STANDARD_MODULE_DATA_MACRO_ABC(UpgradeModule, UpgradeModuleData)
  146. public:
  147. UpgradeModule( Thing *thing, const ModuleData* moduleData );
  148. // virtual destructor prototype defined by MemoryPoolObject
  149. // module methods
  150. static Int getInterfaceMask() { return MODULEINTERFACE_UPGRADE; }
  151. // BehaviorModule
  152. virtual UpgradeModuleInterface* getUpgrade() { return this; }
  153. bool isTriggeredBy(const std::string & upgrade) const { return getUpgradeModuleData()->m_upgradeMuxData.isTriggeredBy(upgrade); }
  154. protected:
  155. virtual void processUpgradeRemoval()
  156. {
  157. // I can't take it any more. Let the record show that I think the UpgradeMux multiple inheritence is CRAP.
  158. getUpgradeModuleData()->m_upgradeMuxData.muxDataProcessUpgradeRemoval(getObject());
  159. }
  160. virtual Bool requiresAllActivationUpgrades() const
  161. {
  162. return getUpgradeModuleData()->m_upgradeMuxData.m_requiresAllTriggers;
  163. }
  164. virtual void getUpgradeActivationMasks(UpgradeMaskType& activation, UpgradeMaskType& conflicting) const
  165. {
  166. getUpgradeModuleData()->m_upgradeMuxData.getUpgradeActivationMasks(activation, conflicting);
  167. }
  168. virtual void performUpgradeFX()
  169. {
  170. getUpgradeModuleData()->m_upgradeMuxData.performUpgradeFX(getObject());
  171. }
  172. };
  173. inline UpgradeModule::UpgradeModule( Thing *thing, const ModuleData* moduleData ) : BehaviorModule( thing, moduleData ) { }
  174. inline UpgradeModule::~UpgradeModule() { }
  175. #endif