InstantDeathBehavior.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  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: InstantDeathBehavior.cpp ///////////////////////////////////////////////////////////////////////
  24. // Author:
  25. // Desc:
  26. ///////////////////////////////////////////////////////////////////////////////////////////////////
  27. // INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
  28. #include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
  29. #define DEFINE_SLOWDEATHPHASE_NAMES
  30. #include "Common/Thing.h"
  31. #include "Common/ThingTemplate.h"
  32. #include "Common/INI.h"
  33. #include "Common/RandomValue.h"
  34. #include "Common/GameLOD.h"
  35. #include "Common/Xfer.h"
  36. #include "GameClient/Drawable.h"
  37. #include "GameClient/FXList.h"
  38. #include "GameClient/InGameUI.h"
  39. #include "GameLogic/GameLogic.h"
  40. #include "GameLogic/Module/BodyModule.h"
  41. #include "GameLogic/Module/InstantDeathBehavior.h"
  42. #include "GameLogic/Module/AIUpdate.h"
  43. #include "GameLogic/Object.h"
  44. #include "GameLogic/ObjectCreationList.h"
  45. #include "GameLogic/Weapon.h"
  46. #include "GameClient/Drawable.h"
  47. //-------------------------------------------------------------------------------------------------
  48. InstantDeathBehaviorModuleData::InstantDeathBehaviorModuleData()
  49. {
  50. // redundant.
  51. //m_fx.clear();
  52. //m_ocls.clear();
  53. //m_weapons.clear();
  54. }
  55. //-------------------------------------------------------------------------------------------------
  56. static void parseFX( INI* ini, void *instance, void * /*store*/, const void* /*userData*/ )
  57. {
  58. InstantDeathBehaviorModuleData* self = (InstantDeathBehaviorModuleData*)instance;
  59. for (const char* token = ini->getNextToken(); token != NULL; token = ini->getNextTokenOrNull())
  60. {
  61. const FXList *fxl = TheFXListStore->findFXList((token)); // could be null! this is OK!
  62. self->m_fx.push_back(fxl);
  63. }
  64. }
  65. //-------------------------------------------------------------------------------------------------
  66. static void parseOCL( INI* ini, void *instance, void * /*store*/, const void* /*userData*/ )
  67. {
  68. InstantDeathBehaviorModuleData* self = (InstantDeathBehaviorModuleData*)instance;
  69. for (const char* token = ini->getNextToken(); token != NULL; token = ini->getNextTokenOrNull())
  70. {
  71. const ObjectCreationList *ocl = TheObjectCreationListStore->findObjectCreationList(token); // could be null! this is OK!
  72. self->m_ocls.push_back(ocl);
  73. }
  74. }
  75. //-------------------------------------------------------------------------------------------------
  76. static void parseWeapon( INI* ini, void *instance, void * /*store*/, const void* /*userData*/ )
  77. {
  78. InstantDeathBehaviorModuleData* self = (InstantDeathBehaviorModuleData*)instance;
  79. for (const char* token = ini->getNextToken(); token != NULL; token = ini->getNextTokenOrNull())
  80. {
  81. const WeaponTemplate *wt = TheWeaponStore->findWeaponTemplate(token); // could be null! this is OK!
  82. self->m_weapons.push_back(wt);
  83. }
  84. }
  85. //-------------------------------------------------------------------------------------------------
  86. /*static*/ void InstantDeathBehaviorModuleData::buildFieldParse(MultiIniFieldParse& p)
  87. {
  88. DieModuleData::buildFieldParse(p);
  89. static const FieldParse dataFieldParse[] =
  90. {
  91. { "FX", parseFX, NULL, 0 },
  92. { "OCL", parseOCL, NULL, 0 },
  93. { "Weapon", parseWeapon, NULL, 0 },
  94. { 0, 0, 0, 0 }
  95. };
  96. p.add(dataFieldParse);
  97. }
  98. //-------------------------------------------------------------------------------------------------
  99. //-------------------------------------------------------------------------------------------------
  100. InstantDeathBehavior::InstantDeathBehavior( Thing *thing, const ModuleData* moduleData ) : DieModule( thing, moduleData )
  101. {
  102. }
  103. //-------------------------------------------------------------------------------------------------
  104. //-------------------------------------------------------------------------------------------------
  105. InstantDeathBehavior::~InstantDeathBehavior( void )
  106. {
  107. }
  108. //-------------------------------------------------------------------------------------------------
  109. void InstantDeathBehavior::onDie( const DamageInfo *damageInfo )
  110. {
  111. if (!isDieApplicable(damageInfo))
  112. return;
  113. AIUpdateInterface* ai = getObject()->getAIUpdateInterface();
  114. if (ai)
  115. {
  116. // has another AI already handled us. (hopefully another InstantDeathBehavior)
  117. if (ai->isAiInDeadState())
  118. return;
  119. ai->markAsDead();
  120. }
  121. const InstantDeathBehaviorModuleData* d = getInstantDeathBehaviorModuleData();
  122. Int idx, listSize;
  123. listSize = d->m_fx.size();
  124. if (listSize > 0)
  125. {
  126. idx = GameLogicRandomValue(0, listSize-1);
  127. const FXListVec& v = d->m_fx;
  128. DEBUG_ASSERTCRASH(idx>=0&&idx<v.size(),("bad idx"));
  129. const FXList* fxl = v[idx];
  130. FXList::doFXObj(fxl, getObject(), NULL);
  131. }
  132. listSize = d->m_ocls.size();
  133. if (listSize > 0)
  134. {
  135. idx = GameLogicRandomValue(0, listSize-1);
  136. const OCLVec& v = d->m_ocls;
  137. DEBUG_ASSERTCRASH(idx>=0&&idx<v.size(),("bad idx"));
  138. const ObjectCreationList* ocl = v[idx];
  139. ObjectCreationList::create(ocl, getObject(), NULL);
  140. }
  141. listSize = d->m_weapons.size();
  142. if (listSize > 0)
  143. {
  144. idx = GameLogicRandomValue(0, listSize-1);
  145. const WeaponTemplateVec& v = d->m_weapons;
  146. DEBUG_ASSERTCRASH(idx>=0&&idx<v.size(),("bad idx"));
  147. const WeaponTemplate* wt = v[idx];
  148. if (wt)
  149. {
  150. TheWeaponStore->createAndFireTempWeapon(wt, getObject(), getObject()->getPosition());
  151. }
  152. }
  153. TheGameLogic->destroyObject(getObject());
  154. }
  155. // ------------------------------------------------------------------------------------------------
  156. /** CRC */
  157. // ------------------------------------------------------------------------------------------------
  158. void InstantDeathBehavior::crc( Xfer *xfer )
  159. {
  160. // extend base class
  161. DieModule::crc( xfer );
  162. } // end crc
  163. // ------------------------------------------------------------------------------------------------
  164. /** Xfer method
  165. * Version Info:
  166. * 1: Initial version */
  167. // ------------------------------------------------------------------------------------------------
  168. void InstantDeathBehavior::xfer( Xfer *xfer )
  169. {
  170. // version
  171. XferVersion currentVersion = 1;
  172. XferVersion version = currentVersion;
  173. xfer->xferVersion( &version, currentVersion );
  174. // extend base class
  175. DieModule::xfer( xfer );
  176. } // end xfer
  177. // ------------------------------------------------------------------------------------------------
  178. /** Load post process */
  179. // ------------------------------------------------------------------------------------------------
  180. void InstantDeathBehavior::loadPostProcess( void )
  181. {
  182. // extend base class
  183. DieModule::loadPostProcess();
  184. } // end loadPostProcess