NeutronMissileSlowDeathUpdate.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528
  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: NeutronMissileSlowDeathBehavior.cpp ////////////////////////////////////////////////////////
  24. // Author: Colin Day, April 2002
  25. // Desc: Update module for the neutron missile superweapon object
  26. ///////////////////////////////////////////////////////////////////////////////////////////////////
  27. // INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
  28. #include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
  29. #include "Common/GameState.h"
  30. #include "Common/Player.h"
  31. #include "Common/Xfer.h"
  32. #include "GameClient/FXList.h"
  33. #include "GameClient/Drawable.h"
  34. #include "GameClient/GameClient.h"
  35. #include "GameLogic/GameLogic.h"
  36. #include "GameLogic/Object.h"
  37. #include "GameLogic/ObjectIter.h"
  38. #include "GameLogic/PartitionManager.h"
  39. #include "GameLogic/Module/FlammableUpdate.h"
  40. #include "GameLogic/Module/PhysicsUpdate.h"
  41. #include "GameLogic/Module/NeutronMissileSlowDeathUpdate.h"
  42. #include "GameLogic/Module/ToppleUpdate.h"
  43. #include "GameLogic/TerrainLogic.h"
  44. ///////////////////////////////////////////////////////////////////////////////////////////////////
  45. ///////////////////////////////////////////////////////////////////////////////////////////////////
  46. ///////////////////////////////////////////////////////////////////////////////////////////////////
  47. // ------------------------------------------------------------------------------------------------
  48. // ------------------------------------------------------------------------------------------------
  49. NeutronMissileSlowDeathBehaviorModuleData::NeutronMissileSlowDeathBehaviorModuleData( void )
  50. {
  51. for( Int i = 0; i < MAX_NEUTRON_BLASTS; ++i )
  52. {
  53. m_blastInfo[ i ].enabled = FALSE;
  54. m_blastInfo[ i ].delay = 0.0f;
  55. m_blastInfo[ i ].scorchDelay = 0.0f;
  56. m_blastInfo[ i ].innerRadius = 0.0f;
  57. m_blastInfo[ i ].outerRadius = 0.0f;
  58. m_blastInfo[ i ].maxDamage = 0.0f;
  59. m_blastInfo[ i ].minDamage = 0.0f;
  60. m_blastInfo[ i ].toppleSpeed = 0.0f;
  61. m_blastInfo[ i ].pushForceMag = 0.0f;
  62. } // end for i
  63. m_scorchSize = 0.0f;
  64. m_fxList = NULL;
  65. } // end NeutronMissileSlowDeathBehaviorModuleData
  66. // ------------------------------------------------------------------------------------------------
  67. // ------------------------------------------------------------------------------------------------
  68. /*static*/ void NeutronMissileSlowDeathBehaviorModuleData::buildFieldParse(MultiIniFieldParse& p)
  69. {
  70. SlowDeathBehaviorModuleData::buildFieldParse( p );
  71. static const FieldParse dataFieldParse[] =
  72. {
  73. { "ScorchMarkSize", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_scorchSize ) },
  74. { "FXList", INI::parseFXList, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_fxList ) },
  75. { "Blast1Enabled", INI::parseBool, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_1 ].enabled ) },
  76. { "Blast1Delay", INI::parseDurationReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_1 ].delay ) },
  77. { "Blast1ScorchDelay", INI::parseDurationReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_1 ].scorchDelay ) },
  78. { "Blast1InnerRadius", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_1 ].innerRadius ) },
  79. { "Blast1OuterRadius", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_1 ].outerRadius ) },
  80. { "Blast1MaxDamage", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_1 ].maxDamage ) },
  81. { "Blast1MinDamage", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_1 ].minDamage ) },
  82. { "Blast1ToppleSpeed", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_1 ].toppleSpeed ) },
  83. { "Blast1PushForce", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_1 ].pushForceMag ) },
  84. { "Blast2Enabled", INI::parseBool, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_2 ].enabled ) },
  85. { "Blast2Delay", INI::parseDurationReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_2 ].delay ) },
  86. { "Blast2ScorchDelay", INI::parseDurationReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_2 ].scorchDelay ) },
  87. { "Blast2InnerRadius", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_2 ].innerRadius ) },
  88. { "Blast2OuterRadius", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_2 ].outerRadius ) },
  89. { "Blast2MaxDamage", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_2 ].maxDamage ) },
  90. { "Blast2MinDamage", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_2 ].minDamage ) },
  91. { "Blast2ToppleSpeed", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_2 ].toppleSpeed ) },
  92. { "Blast2PushForce", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_2 ].pushForceMag ) },
  93. { "Blast3Enabled", INI::parseBool, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_3 ].enabled ) },
  94. { "Blast3Delay", INI::parseDurationReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_3 ].delay ) },
  95. { "Blast3ScorchDelay", INI::parseDurationReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_3 ].scorchDelay ) },
  96. { "Blast3InnerRadius", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_3 ].innerRadius ) },
  97. { "Blast3OuterRadius", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_3 ].outerRadius ) },
  98. { "Blast3MaxDamage", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_3 ].maxDamage ) },
  99. { "Blast3MinDamage", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_3 ].minDamage ) },
  100. { "Blast3ToppleSpeed", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_3 ].toppleSpeed ) },
  101. { "Blast3PushForce", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_3 ].pushForceMag ) },
  102. { "Blast4Enabled", INI::parseBool, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_4 ].enabled ) },
  103. { "Blast4Delay", INI::parseDurationReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_4 ].delay ) },
  104. { "Blast4ScorchDelay", INI::parseDurationReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_4 ].scorchDelay ) },
  105. { "Blast4InnerRadius", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_4 ].innerRadius ) },
  106. { "Blast4OuterRadius", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_4 ].outerRadius ) },
  107. { "Blast4MaxDamage", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_4 ].maxDamage ) },
  108. { "Blast4MinDamage", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_4 ].minDamage ) },
  109. { "Blast4ToppleSpeed", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_4 ].toppleSpeed ) },
  110. { "Blast4PushForce", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_4 ].pushForceMag ) },
  111. { "Blast5Enabled", INI::parseBool, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_5 ].enabled ) },
  112. { "Blast5Delay", INI::parseDurationReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_5 ].delay ) },
  113. { "Blast5ScorchDelay", INI::parseDurationReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_5 ].scorchDelay ) },
  114. { "Blast5InnerRadius", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_5 ].innerRadius ) },
  115. { "Blast5OuterRadius", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_5 ].outerRadius ) },
  116. { "Blast5MaxDamage", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_5 ].maxDamage ) },
  117. { "Blast5MinDamage", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_5 ].minDamage ) },
  118. { "Blast5ToppleSpeed", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_5 ].toppleSpeed ) },
  119. { "Blast5PushForce", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_5 ].pushForceMag ) },
  120. { "Blast6Enabled", INI::parseBool, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_6 ].enabled ) },
  121. { "Blast6Delay", INI::parseDurationReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_6 ].delay ) },
  122. { "Blast6ScorchDelay", INI::parseDurationReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_6 ].scorchDelay ) },
  123. { "Blast6InnerRadius", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_6 ].innerRadius ) },
  124. { "Blast6OuterRadius", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_6 ].outerRadius ) },
  125. { "Blast6MaxDamage", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_6 ].maxDamage ) },
  126. { "Blast6MinDamage", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_6 ].minDamage ) },
  127. { "Blast6ToppleSpeed", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_6 ].toppleSpeed ) },
  128. { "Blast6PushForce", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_6 ].pushForceMag ) },
  129. { "Blast7Enabled", INI::parseBool, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_7 ].enabled ) },
  130. { "Blast7Delay", INI::parseDurationReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_7 ].delay ) },
  131. { "Blast7ScorchDelay", INI::parseDurationReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_7 ].scorchDelay ) },
  132. { "Blast7InnerRadius", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_7 ].innerRadius ) },
  133. { "Blast7OuterRadius", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_7 ].outerRadius ) },
  134. { "Blast7MaxDamage", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_7 ].maxDamage ) },
  135. { "Blast7MinDamage", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_7 ].minDamage ) },
  136. { "Blast7ToppleSpeed", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_7 ].toppleSpeed ) },
  137. { "Blast7PushForce", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_7 ].pushForceMag ) },
  138. { "Blast8Enabled", INI::parseBool, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_8 ].enabled ) },
  139. { "Blast8Delay", INI::parseDurationReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_8 ].delay ) },
  140. { "Blast8ScorchDelay", INI::parseDurationReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_8 ].scorchDelay ) },
  141. { "Blast8InnerRadius", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_8 ].innerRadius ) },
  142. { "Blast8OuterRadius", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_8 ].outerRadius ) },
  143. { "Blast8MaxDamage", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_8 ].maxDamage ) },
  144. { "Blast8MinDamage", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_8 ].minDamage ) },
  145. { "Blast8ToppleSpeed", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_8 ].toppleSpeed ) },
  146. { "Blast8PushForce", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_8 ].pushForceMag ) },
  147. { "Blast9Enabled", INI::parseBool, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_9 ].enabled ) },
  148. { "Blast9Delay", INI::parseDurationReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_9 ].delay ) },
  149. { "Blast9ScorchDelay", INI::parseDurationReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_9 ].scorchDelay ) },
  150. { "Blast9InnerRadius", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_9 ].innerRadius ) },
  151. { "Blast9OuterRadius", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_9 ].outerRadius ) },
  152. { "Blast9MaxDamage", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_9 ].maxDamage ) },
  153. { "Blast9MinDamage", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_9 ].minDamage ) },
  154. { "Blast9ToppleSpeed", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_9 ].toppleSpeed ) },
  155. { "Blast9PushForce", INI::parseReal, NULL, offsetof( NeutronMissileSlowDeathBehaviorModuleData, m_blastInfo[ NEUTRON_BLAST_9 ].pushForceMag ) },
  156. { 0, 0, 0, 0 }
  157. };
  158. p.add(dataFieldParse);
  159. } // end buildFieldParse
  160. ///////////////////////////////////////////////////////////////////////////////////////////////////
  161. ///////////////////////////////////////////////////////////////////////////////////////////////////
  162. ///////////////////////////////////////////////////////////////////////////////////////////////////
  163. // ------------------------------------------------------------------------------------------------
  164. // ------------------------------------------------------------------------------------------------
  165. NeutronMissileSlowDeathBehavior::NeutronMissileSlowDeathBehavior( Thing *thing, const ModuleData *moduleData )
  166. : SlowDeathBehavior( thing, moduleData )
  167. {
  168. Int i;
  169. m_scorchPlaced = FALSE;
  170. m_activationFrame = 0;
  171. for( i = 0; i < MAX_NEUTRON_BLASTS; i++ )
  172. {
  173. m_completedBlasts[ i ] = FALSE;
  174. m_completedScorchBlasts[ i ] = FALSE;
  175. } // end for i
  176. } // end NeutronMissileSlowDeathBehavior
  177. // ------------------------------------------------------------------------------------------------
  178. // ------------------------------------------------------------------------------------------------
  179. NeutronMissileSlowDeathBehavior::~NeutronMissileSlowDeathBehavior( void )
  180. {
  181. } // end ~NeutronMissileSlowDeathBehavior
  182. // ------------------------------------------------------------------------------------------------
  183. // ------------------------------------------------------------------------------------------------
  184. UpdateSleepTime NeutronMissileSlowDeathBehavior::update( void )
  185. {
  186. /// @todo srj use SLEEPY_UPDATE here
  187. // get the module data
  188. const NeutronMissileSlowDeathBehaviorModuleData *modData = getNeutronMissileSlowDeathBehaviorModuleData();
  189. // call the base class cause we're extending functionality
  190. SlowDeathBehavior::update();
  191. // get out of here if we're not activated yet
  192. if( isSlowDeathActivated() == FALSE )
  193. return UPDATE_SLEEP_NONE;
  194. // get the current frame
  195. UnsignedInt currFrame = TheGameLogic->getFrame();
  196. // when we become activated we want to do a few things
  197. if( m_activationFrame == 0 )
  198. {
  199. Coord3D pos;
  200. const Coord3D *missilePos = getObject()->getPosition();
  201. // get the position to play the effect at on the ground
  202. pos.x = missilePos->x;
  203. pos.y = missilePos->y;
  204. pos.z = TheTerrainLogic->getGroundHeight( pos.x, pos.y );
  205. // record the frame
  206. m_activationFrame = currFrame;
  207. FXList::doFXPos( modData->m_fxList, &pos );
  208. } // end if
  209. // see if it's time for any explosions
  210. for( Int i = 0; i < MAX_NEUTRON_BLASTS; i++ )
  211. {
  212. // if this blast is not enabled we will not bother with it
  213. if( modData->m_blastInfo[ i ].enabled == FALSE )
  214. continue;
  215. // has the time of this blast come
  216. if( m_completedBlasts[ i ] == FALSE &&
  217. (currFrame - m_activationFrame > modData->m_blastInfo[ i ].delay) )
  218. {
  219. // do the blast
  220. doBlast( &modData->m_blastInfo[ i ] );
  221. // mark this blast as complete now
  222. m_completedBlasts[ i ] = TRUE;
  223. } // end if
  224. // has the time for a scorch blast come
  225. if( m_completedScorchBlasts[ i ] == FALSE &&
  226. (currFrame - m_activationFrame > modData->m_blastInfo[ i ].scorchDelay) )
  227. {
  228. // do the scorch blast
  229. doScorchBlast( &modData->m_blastInfo[ i ] );
  230. // mark this scorch blast as complete now
  231. m_completedScorchBlasts[ i ] = TRUE;
  232. } // end if
  233. } // end for i
  234. return UPDATE_SLEEP_NONE;
  235. } // end update
  236. // ------------------------------------------------------------------------------------------------
  237. /** Do a single blast for the bomb */
  238. // ------------------------------------------------------------------------------------------------
  239. void NeutronMissileSlowDeathBehavior::doBlast( const BlastInfo *blastInfo )
  240. {
  241. // sanity
  242. if( blastInfo == NULL )
  243. return;
  244. // get the module data
  245. const NeutronMissileSlowDeathBehaviorModuleData *modData = getNeutronMissileSlowDeathBehaviorModuleData();
  246. // get the object and position
  247. Object *missile = getObject();
  248. const Coord3D *missilePos = missile->getPosition();
  249. // setup a damage info structure to do some damage
  250. DamageInfo damageInfo;
  251. damageInfo.in.m_damageType = DAMAGE_EXPLOSION;
  252. damageInfo.in.m_deathType = DEATH_EXPLODED;
  253. damageInfo.in.m_sourceID = missile->getID();
  254. damageInfo.in.m_amount = blastInfo->minDamage;
  255. // scan objects around us and do damage to objects we have "passed over" and are behind us
  256. if( blastInfo->outerRadius )
  257. {
  258. ObjectIterator *iter = ThePartitionManager->iterateObjectsInRange( missilePos,
  259. blastInfo->outerRadius,
  260. FROM_CENTER_2D,
  261. NULL );
  262. MemoryPoolObjectHolder hold( iter );
  263. Object *other;
  264. const Coord3D *otherPos;
  265. Coord3D forceVector;
  266. Real dist;
  267. for( other = iter->first(); other; other = iter->next() )
  268. {
  269. // get other position
  270. otherPos = other->getPosition();
  271. // compute vector from the missile to other object
  272. forceVector.x = otherPos->x - missilePos->x;
  273. forceVector.y = otherPos->y - missilePos->y;
  274. forceVector.z = otherPos->z - missilePos->z;
  275. // try to topple other object
  276. other->topple( &forceVector, blastInfo->toppleSpeed, TOPPLE_OPTIONS_NO_BOUNCE |
  277. TOPPLE_OPTIONS_NO_FX );
  278. //
  279. // compute how much damage we're going to do to this object ... if the object
  280. // is inside the inner radius we do the full damage. Outside of the inner radius
  281. // we do a percentage based on how far away from the inner radius it is, but we
  282. // will always do at least blastInfo->minDamage amount of damage
  283. //
  284. dist = forceVector.length();
  285. if( dist <= blastInfo->innerRadius )
  286. damageInfo.in.m_amount = blastInfo->maxDamage;
  287. else
  288. {
  289. Real percent;
  290. percent = 1.0f - ((dist - blastInfo->innerRadius) / (blastInfo->outerRadius - blastInfo->innerRadius + 0.01f));
  291. damageInfo.in.m_amount = blastInfo->maxDamage * percent;
  292. if( damageInfo.in.m_amount < blastInfo->minDamage )
  293. damageInfo.in.m_amount = blastInfo->minDamage;
  294. } // end else
  295. // do actual damage
  296. if( damageInfo.in.m_amount )
  297. {
  298. // do damage
  299. other->attemptDamage( &damageInfo );
  300. // place a scorch mark if we haven't already
  301. if( m_scorchPlaced == FALSE )
  302. {
  303. TheGameClient->addScorch( missilePos, modData->m_scorchSize, SCORCH_1 );
  304. m_scorchPlaced = TRUE;
  305. } // end if
  306. } // end if
  307. /*
  308. // apply a small force to the object from the shockwave center
  309. PhysicsBehavior *physics = other->getPhysics();
  310. if( physics )
  311. {
  312. Coord3D physicsForce = forceVector;
  313. // normalize the physics force
  314. physicsForce.normalize();
  315. //
  316. // change the magnitude of the physics force to the force amount we want to apply from
  317. // the shockwave
  318. //
  319. physicsForce.x *= blastInfo->pushForceMag;
  320. physicsForce.y *= blastInfo->pushForceMag;
  321. physicsForce.z *= blastInfo->pushForceMag;
  322. // apply the force
  323. physics->applyForce( &physicsForce );
  324. } // end if, physics
  325. */
  326. } // end for, other
  327. } // end if, an outer radius exists
  328. } // end doBlast
  329. // ------------------------------------------------------------------------------------------------
  330. /** Do a scorch blast event ... this doesn't do actual damage, but it "scorches" things */
  331. // ------------------------------------------------------------------------------------------------
  332. void NeutronMissileSlowDeathBehavior::doScorchBlast( const BlastInfo *blastInfo )
  333. {
  334. // sanity
  335. if( blastInfo == NULL )
  336. return;
  337. // get the module data
  338. // const NeutronMissileSlowDeathBehaviorModuleData *modData = getNeutronMissileSlowDeathBehaviorModuleData();
  339. // get the object and position
  340. Object *missile = getObject();
  341. const Coord3D *missilePos = missile->getPosition();
  342. // scan objects around us and do damage to objects we have "passed over" and are behind us
  343. if( blastInfo->outerRadius )
  344. {
  345. ObjectIterator *iter = ThePartitionManager->iterateObjectsInRange( missilePos,
  346. blastInfo->outerRadius,
  347. FROM_CENTER_2D,
  348. NULL );
  349. MemoryPoolObjectHolder hold( iter );
  350. Object *other;
  351. for( other = iter->first(); other; other = iter->next() )
  352. {
  353. // set things aflame
  354. ///@todo can't to this now, flames eat too many particles
  355. // static NameKeyType flammableKey = NAMEKEY( "FlammableUpdate" );
  356. // FlammableUpdate *update = (FlammableUpdate *)other->findUpdateModule( flammableKey );
  357. // if( update )
  358. // update->tryToIgnite();
  359. // set model condition as all burnt up
  360. other->setModelConditionState( MODELCONDITION_BURNED );
  361. // remove the shadows from trees
  362. if( other->isKindOf( KINDOF_SHRUBBERY ) )
  363. {
  364. Drawable *draw = other->getDrawable();
  365. if( draw )
  366. draw->setShadowsEnabled( FALSE );
  367. } // end if
  368. } // end for, other
  369. } // end if, outer radius exists
  370. } // end doScorchBlast
  371. // ------------------------------------------------------------------------------------------------
  372. /** CRC */
  373. // ------------------------------------------------------------------------------------------------
  374. void NeutronMissileSlowDeathBehavior::crc( Xfer *xfer )
  375. {
  376. // extend base class
  377. SlowDeathBehavior::crc( xfer );
  378. } // end crc
  379. // ------------------------------------------------------------------------------------------------
  380. /** Xfer method
  381. * Version Info:
  382. * 1: Initial version */
  383. // ------------------------------------------------------------------------------------------------
  384. void NeutronMissileSlowDeathBehavior::xfer( Xfer *xfer )
  385. {
  386. // version
  387. XferVersion currentVersion = 1;
  388. XferVersion version = currentVersion;
  389. xfer->xferVersion( &version, currentVersion );
  390. // extend base class
  391. SlowDeathBehavior::xfer( xfer );
  392. // activation frame
  393. xfer->xferUnsignedInt( &m_activationFrame );
  394. // size of MAX_NEUTRON_BLASTS since we use it for two arrays here
  395. UnsignedByte maxNeutronBlasts = MAX_NEUTRON_BLASTS;
  396. xfer->xferUnsignedByte( &maxNeutronBlasts );
  397. if( maxNeutronBlasts != MAX_NEUTRON_BLASTS )
  398. {
  399. DEBUG_CRASH(( "NeutronMissileSlowDeathBehavior::xfer - Size of MAX_NEUTRON_BLASTS has changed, you must version this xfer code and then you can remove this error message\n" ));
  400. throw SC_INVALID_DATA;
  401. } // end if
  402. // completed blasts
  403. UnsignedByte i;
  404. for( i = 0; i < maxNeutronBlasts; ++i )
  405. xfer->xferBool( &m_completedBlasts[ i ] );
  406. // completed scorch blasts
  407. for( i = 0; i < maxNeutronBlasts; ++i )
  408. xfer->xferBool( &m_completedScorchBlasts[ i ] );
  409. // scorch placed
  410. xfer->xferBool( &m_scorchPlaced );
  411. } // end xfer
  412. // ------------------------------------------------------------------------------------------------
  413. /** Load post process */
  414. // ------------------------------------------------------------------------------------------------
  415. void NeutronMissileSlowDeathBehavior::loadPostProcess( void )
  416. {
  417. // extend base class
  418. SlowDeathBehavior::loadPostProcess();
  419. } // end loadPostProcess