OCLSpecialPower.cpp 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. /*
  2. ** Command & Conquer Generals(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: OCLSpecialPower.cpp //////////////////////////////////////////////////////////////////////
  24. // Author: Colin Day, April 2002
  25. // Desc: Special powers that are driven by object creation lists
  26. ///////////////////////////////////////////////////////////////////////////////////////////////////
  27. // USER INCLUDES //////////////////////////////////////////////////////////////////////////////////
  28. #include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
  29. #include "Common/Player.h"
  30. #include "Common/RandomValue.h"
  31. #include "Common/Xfer.h"
  32. #include "GameLogic/Object.h"
  33. #include "GameLogic/ObjectCreationList.h"
  34. #include "GameLogic/PartitionManager.h"
  35. #include "GameLogic/TerrainLogic.h"
  36. #include "GameLogic/Module/OCLSpecialPower.h"
  37. ///////////////////////////////////////////////////////////////////////////////////////////////////
  38. // MODULE DATA ////////////////////////////////////////////////////////////////////////////////////
  39. ///////////////////////////////////////////////////////////////////////////////////////////////////
  40. #ifdef _INTERNAL
  41. // for occasional debugging...
  42. //#pragma optimize("", off)
  43. //#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
  44. #endif
  45. enum
  46. {
  47. CREATE_ABOVE_LOCATION_HEIGHT = 300
  48. };
  49. static const char* TheOCLCreateLocTypeNames[] =
  50. {
  51. "CREATE_AT_EDGE_NEAR_SOURCE",
  52. "CREATE_AT_EDGE_NEAR_TARGET",
  53. "CREATE_AT_LOCATION",
  54. "USE_OWNER_OBJECT",
  55. "CREATE_ABOVE_LOCATION",
  56. "CREATE_AT_EDGE_FARTHEST_FROM_TARGET",
  57. NULL
  58. };
  59. //-------------------------------------------------------------------------------------------------
  60. //-------------------------------------------------------------------------------------------------
  61. OCLSpecialPowerModuleData::OCLSpecialPowerModuleData( void )
  62. {
  63. m_defaultOCL = NULL;
  64. m_upgradeOCL.clear();
  65. m_createLoc = CREATE_AT_EDGE_NEAR_SOURCE;
  66. }
  67. //-------------------------------------------------------------------------------------------------
  68. //-------------------------------------------------------------------------------------------------
  69. static void parseOCLUpgradePair( INI* ini, void * /*instance*/, void *store, const void* /*userData*/ )
  70. {
  71. OCLSpecialPowerModuleData::Upgrades up;
  72. INI::parseScience(ini, NULL, &up.m_science, NULL);
  73. INI::parseObjectCreationList(ini, NULL, &up.m_ocl, NULL);
  74. std::vector<OCLSpecialPowerModuleData::Upgrades>* s = (std::vector<OCLSpecialPowerModuleData::Upgrades>*)store;
  75. s->push_back(up);
  76. }
  77. //-------------------------------------------------------------------------------------------------
  78. //-------------------------------------------------------------------------------------------------
  79. /* static */ void OCLSpecialPowerModuleData::buildFieldParse(MultiIniFieldParse& p)
  80. {
  81. SpecialPowerModuleData::buildFieldParse( p );
  82. static const FieldParse dataFieldParse[] =
  83. {
  84. { "UpgradeOCL", parseOCLUpgradePair, NULL, offsetof( OCLSpecialPowerModuleData, m_upgradeOCL ) },
  85. { "OCL", INI::parseObjectCreationList, NULL, offsetof( OCLSpecialPowerModuleData, m_defaultOCL ) },
  86. { "CreateLocation", INI::parseIndexList, TheOCLCreateLocTypeNames, offsetof( OCLSpecialPowerModuleData, m_createLoc ) },
  87. { 0, 0, 0, 0 }
  88. };
  89. p.add(dataFieldParse);
  90. }
  91. ///////////////////////////////////////////////////////////////////////////////////////////////////
  92. // MODULE /////////////////////////////////////////////////////////////////////////////////////////
  93. ///////////////////////////////////////////////////////////////////////////////////////////////////
  94. //-------------------------------------------------------------------------------------------------
  95. //-------------------------------------------------------------------------------------------------
  96. OCLSpecialPower::OCLSpecialPower( Thing *thing, const ModuleData *moduleData )
  97. : SpecialPowerModule( thing, moduleData )
  98. {
  99. }
  100. //-------------------------------------------------------------------------------------------------
  101. //-------------------------------------------------------------------------------------------------
  102. const ObjectCreationList* OCLSpecialPower::findOCL() const
  103. {
  104. const OCLSpecialPowerModuleData* d = getOCLSpecialPowerModuleData();
  105. const Player* controller = getObject()->getControllingPlayer();
  106. if (controller != NULL)
  107. {
  108. for (std::vector<OCLSpecialPowerModuleData::Upgrades>::const_iterator it = d->m_upgradeOCL.begin();
  109. it != d->m_upgradeOCL.end();
  110. ++it)
  111. {
  112. if (controller->hasScience(it->m_science))
  113. return it->m_ocl;
  114. }
  115. }
  116. return d->m_defaultOCL;
  117. }
  118. //-------------------------------------------------------------------------------------------------
  119. //-------------------------------------------------------------------------------------------------
  120. OCLSpecialPower::~OCLSpecialPower( void )
  121. {
  122. }
  123. //-------------------------------------------------------------------------------------------------
  124. /** Execute the power */
  125. //-------------------------------------------------------------------------------------------------
  126. void OCLSpecialPower::doSpecialPowerAtLocation( const Coord3D *loc, UnsignedInt commandOptions )
  127. {
  128. if (getObject()->isDisabled())
  129. return;
  130. // sanity
  131. if( loc == NULL )
  132. return;
  133. // call the base class action cause we are *EXTENDING* functionality
  134. SpecialPowerModule::doSpecialPowerAtLocation( loc, commandOptions );
  135. const ObjectCreationList* ocl = findOCL();
  136. // get the module data
  137. const OCLSpecialPowerModuleData *modData = getOCLSpecialPowerModuleData();
  138. // at what point will the "deliverer" come in
  139. Coord3D creationCoord;
  140. switch (modData->m_createLoc)
  141. {
  142. case CREATE_AT_EDGE_NEAR_SOURCE:
  143. creationCoord = TheTerrainLogic->findClosestEdgePoint( getObject()->getPosition() );
  144. ObjectCreationList::create( ocl, getObject(), &creationCoord, loc );
  145. break;
  146. case CREATE_AT_EDGE_NEAR_TARGET:
  147. creationCoord = TheTerrainLogic->findClosestEdgePoint(loc);
  148. ObjectCreationList::create( ocl, getObject(), &creationCoord, loc );
  149. break;
  150. case CREATE_AT_EDGE_FARTHEST_FROM_TARGET:
  151. creationCoord = TheTerrainLogic->findFarthestEdgePoint(loc);
  152. creationCoord.z += CREATE_ABOVE_LOCATION_HEIGHT;
  153. ObjectCreationList::create( ocl, getObject(), &creationCoord, loc );
  154. break;
  155. case CREATE_AT_LOCATION:
  156. // this is the case where the special power stuff originates at the location of the mouse click
  157. creationCoord = *loc;
  158. ObjectCreationList::create( ocl, getObject(), &creationCoord, loc );
  159. break;
  160. case USE_OWNER_OBJECT:
  161. creationCoord.set( loc );
  162. ObjectCreationList::create( ocl, getObject(), &creationCoord, loc, false );
  163. break;
  164. case CREATE_ABOVE_LOCATION:
  165. // this is the case where the special power stuff originates above the location of the mouse click
  166. creationCoord = *loc;
  167. creationCoord.z += CREATE_ABOVE_LOCATION_HEIGHT;
  168. ObjectCreationList::create( ocl, getObject(), &creationCoord, loc );
  169. break;
  170. }
  171. }
  172. // ------------------------------------------------------------------------------------------------
  173. // ------------------------------------------------------------------------------------------------
  174. void OCLSpecialPower::doSpecialPowerAtObject( Object *obj, UnsignedInt commandOptions )
  175. {
  176. if (getObject()->isDisabled())
  177. return;
  178. // convert to a location
  179. if( !obj )
  180. return;
  181. doSpecialPowerAtLocation( obj->getPosition(), commandOptions );
  182. }
  183. // ------------------------------------------------------------------------------------------------
  184. void OCLSpecialPower::doSpecialPower( UnsignedInt commandOptions )
  185. {
  186. if (getObject()->isDisabled())
  187. return;
  188. Coord3D creationCoord;
  189. creationCoord.set( getObject()->getPosition() );
  190. // call the base class action cause we are *EXTENDING* functionality
  191. SpecialPowerModule::doSpecialPowerAtLocation( &creationCoord, commandOptions );
  192. const ObjectCreationList* ocl = findOCL();
  193. ObjectCreationList::create( ocl, getObject(), &creationCoord, &creationCoord, false );
  194. }
  195. // ------------------------------------------------------------------------------------------------
  196. /** CRC */
  197. // ------------------------------------------------------------------------------------------------
  198. void OCLSpecialPower::crc( Xfer *xfer )
  199. {
  200. // extend base class
  201. SpecialPowerModule::crc( xfer );
  202. } // end crc
  203. // ------------------------------------------------------------------------------------------------
  204. /** Xfer method
  205. * Version Info:
  206. * 1: Initial version */
  207. // ------------------------------------------------------------------------------------------------
  208. void OCLSpecialPower::xfer( Xfer *xfer )
  209. {
  210. // version
  211. XferVersion currentVersion = 1;
  212. XferVersion version = currentVersion;
  213. xfer->xferVersion( &version, currentVersion );
  214. // extend base class
  215. SpecialPowerModule::xfer( xfer );
  216. } // end xfer
  217. // ------------------------------------------------------------------------------------------------
  218. /** Load post process */
  219. // ------------------------------------------------------------------------------------------------
  220. void OCLSpecialPower::loadPostProcess( void )
  221. {
  222. // extend base class
  223. SpecialPowerModule::loadPostProcess();
  224. } // end loadPostProcess