HelicopterSlowDeathUpdate.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566
  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: HelicopterSlowDeathBehavior.cpp ////////////////////////////////////////////////////////////
  24. // Author: Colin Day, March 2002
  25. // Desc: Helicoptor slow deaths
  26. ///////////////////////////////////////////////////////////////////////////////////////////////////
  27. // USER INCLUDES //////////////////////////////////////////////////////////////////////////////////
  28. #include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
  29. #include "Common/GameAudio.h"
  30. #include "Common/GlobalData.h"
  31. #include "Common/RandomValue.h"
  32. #include "Common/ThingFactory.h"
  33. #include "Common/ThingTemplate.h"
  34. #include "Common/Xfer.h"
  35. #include "GameClient/Drawable.h"
  36. #include "GameClient/FXList.h"
  37. #include "GameClient/InGameUI.h"
  38. #include "GameClient/ParticleSys.h"
  39. #include "GameLogic/GameLogic.h"
  40. #include "GameLogic/Locomotor.h"
  41. #include "GameLogic/Object.h"
  42. #include "GameLogic/ObjectCreationList.h"
  43. #include "GameLogic/Module/AIUpdate.h"
  44. #include "GameLogic/Module/BodyModule.h"
  45. #include "GameLogic/Module/EjectPilotDie.h"
  46. #include "GameLogic/Module/HelicopterSlowDeathUpdate.h"
  47. #include "GameLogic/Module/PhysicsUpdate.h"
  48. ///////////////////////////////////////////////////////////////////////////////////////////////////
  49. // Helicopter slow death update module data ///////////////////////////////////////////////////////
  50. ///////////////////////////////////////////////////////////////////////////////////////////////////
  51. #ifdef _INTERNAL
  52. // for occasional debugging...
  53. //#pragma optimize("", off)
  54. //#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
  55. #endif
  56. //-------------------------------------------------------------------------------------------------
  57. //-------------------------------------------------------------------------------------------------
  58. HelicopterSlowDeathBehaviorModuleData::HelicopterSlowDeathBehaviorModuleData( void )
  59. {
  60. //Added By Sadullah Nader
  61. //Initializations missing and needed
  62. m_attachParticleBone.clear();
  63. m_bladeBone.clear();
  64. m_bladeObjectName.clear();
  65. m_finalRubbleObject.clear();
  66. //
  67. m_spiralOrbitTurnRate = 0.0f;
  68. m_spiralOrbitForwardSpeed = 0.0f;
  69. m_spiralOrbitForwardSpeedDamping = 1.0f; // no damping
  70. m_minSelfSpin = 0.0f;
  71. m_maxSelfSpin = 0.0f;
  72. m_selfSpinUpdateDelay = 0.0f;
  73. m_selfSpinUpdateAmount = 0.0f;
  74. m_fallHowFast = 0.0f;
  75. m_minBladeFlyOffDelay = 0.0;
  76. m_maxBladeFlyOffDelay = 0.0;
  77. m_attachParticleSystem = NULL;
  78. m_attachParticleLoc.x = 0.0f;
  79. m_attachParticleLoc.y = 0.0f;
  80. m_attachParticleLoc.z = 0.0f;
  81. m_oclEjectPilot = NULL;
  82. m_fxBlade = NULL;
  83. m_oclBlade = NULL;
  84. m_fxHitGround = NULL;
  85. m_oclHitGround = NULL;
  86. m_fxFinalBlowUp = NULL;
  87. m_oclFinalBlowUp = NULL;
  88. m_delayFromGroundToFinalDeath = 0;
  89. m_maxBraking = 99999.0f;
  90. } // end HelicopterSlowDeathBehaviorModuleData
  91. // ------------------------------------------------------------------------------------------------
  92. // ------------------------------------------------------------------------------------------------
  93. /*static*/ void HelicopterSlowDeathBehaviorModuleData::buildFieldParse( MultiIniFieldParse &p )
  94. {
  95. SlowDeathBehaviorModuleData::buildFieldParse( p );
  96. static const FieldParse dataFieldParse[] =
  97. {
  98. { "SpiralOrbitTurnRate", INI::parseAngularVelocityReal, NULL, offsetof( HelicopterSlowDeathBehaviorModuleData, m_spiralOrbitTurnRate ) },
  99. { "SpiralOrbitForwardSpeed", INI::parseVelocityReal, NULL, offsetof( HelicopterSlowDeathBehaviorModuleData, m_spiralOrbitForwardSpeed ) },
  100. { "SpiralOrbitForwardSpeedDamping", INI::parseReal, NULL, offsetof( HelicopterSlowDeathBehaviorModuleData, m_spiralOrbitForwardSpeedDamping ) },
  101. { "MinSelfSpin", INI::parseAngularVelocityReal, NULL, offsetof( HelicopterSlowDeathBehaviorModuleData, m_minSelfSpin ) },
  102. { "MaxSelfSpin", INI::parseAngularVelocityReal, NULL, offsetof( HelicopterSlowDeathBehaviorModuleData, m_maxSelfSpin ) },
  103. { "SelfSpinUpdateDelay", INI::parseDurationReal, NULL, offsetof( HelicopterSlowDeathBehaviorModuleData, m_selfSpinUpdateDelay ) },
  104. { "SelfSpinUpdateAmount", INI::parseAngleReal, NULL, offsetof( HelicopterSlowDeathBehaviorModuleData, m_selfSpinUpdateAmount ) },
  105. { "FallHowFast", INI::parsePercentToReal, NULL, offsetof( HelicopterSlowDeathBehaviorModuleData, m_fallHowFast ) },
  106. { "MinBladeFlyOffDelay", INI::parseDurationReal, NULL, offsetof( HelicopterSlowDeathBehaviorModuleData, m_minBladeFlyOffDelay ) },
  107. { "MaxBladeFlyOffDelay", INI::parseDurationReal, NULL, offsetof( HelicopterSlowDeathBehaviorModuleData, m_maxBladeFlyOffDelay ) },
  108. { "AttachParticle", INI::parseParticleSystemTemplate, NULL, offsetof( HelicopterSlowDeathBehaviorModuleData, m_attachParticleSystem ) },
  109. { "AttachParticleBone", INI::parseAsciiString, NULL, offsetof( HelicopterSlowDeathBehaviorModuleData, m_attachParticleBone ) },
  110. { "AttachParticleLoc", INI::parseCoord3D, NULL, offsetof( HelicopterSlowDeathBehaviorModuleData, m_attachParticleLoc ) },
  111. { "BladeObjectName", INI::parseAsciiString, NULL, offsetof( HelicopterSlowDeathBehaviorModuleData, m_bladeObjectName ) },
  112. { "BladeBoneName", INI::parseAsciiString, NULL, offsetof( HelicopterSlowDeathBehaviorModuleData, m_bladeBone ) },
  113. { "OCLEjectPilot", INI::parseObjectCreationList, NULL, offsetof( HelicopterSlowDeathBehaviorModuleData, m_oclEjectPilot ) },
  114. { "FXBlade", INI::parseFXList, NULL, offsetof( HelicopterSlowDeathBehaviorModuleData, m_fxBlade ) },
  115. { "OCLBlade", INI::parseObjectCreationList, NULL, offsetof( HelicopterSlowDeathBehaviorModuleData, m_oclBlade ) },
  116. { "FXHitGround", INI::parseFXList, NULL, offsetof( HelicopterSlowDeathBehaviorModuleData, m_fxHitGround ) },
  117. { "OCLHitGround", INI::parseObjectCreationList, NULL, offsetof( HelicopterSlowDeathBehaviorModuleData, m_oclHitGround ) },
  118. { "FXFinalBlowUp", INI::parseFXList, NULL, offsetof( HelicopterSlowDeathBehaviorModuleData, m_fxFinalBlowUp ) },
  119. { "OCLFinalBlowUp", INI::parseObjectCreationList, NULL, offsetof( HelicopterSlowDeathBehaviorModuleData, m_oclFinalBlowUp ) },
  120. { "DelayFromGroundToFinalDeath", INI::parseDurationReal, NULL, offsetof( HelicopterSlowDeathBehaviorModuleData, m_delayFromGroundToFinalDeath ) },
  121. { "FinalRubbleObject", INI::parseAsciiString, NULL, offsetof( HelicopterSlowDeathBehaviorModuleData, m_finalRubbleObject ) },
  122. { "SoundDeathLoop", INI::parseAudioEventRTS, NULL, offsetof( HelicopterSlowDeathBehaviorModuleData, m_deathSound) },
  123. { "MaxBraking", INI::parseAccelerationReal, NULL, offsetof( HelicopterSlowDeathBehaviorModuleData, m_maxBraking) },
  124. { 0, 0, 0, 0 }
  125. };
  126. p.add(dataFieldParse);
  127. } // end buildFieldParse
  128. ///////////////////////////////////////////////////////////////////////////////////////////////////
  129. // Helicopter slow death update ///////////////////////////////////////////////////////////////////
  130. ///////////////////////////////////////////////////////////////////////////////////////////////////
  131. //
  132. // we use these to guide the direction of the circular orbit, as well as the direction the
  133. // object self spins
  134. //
  135. #define ORBIT_DIRECTION_LEFT ( 1.0f)
  136. #define ORBIT_DIRECTION_RIGHT (-1.0f)
  137. //-------------------------------------------------------------------------------------------------
  138. //-------------------------------------------------------------------------------------------------
  139. HelicopterSlowDeathBehavior::HelicopterSlowDeathBehavior( Thing *thing, const ModuleData *moduleData )
  140. : SlowDeathBehavior( thing, moduleData )
  141. {
  142. m_orbitDirection = ORBIT_DIRECTION_LEFT;
  143. m_forwardAngle = 0.0f;
  144. m_forwardSpeed = 0.0f;
  145. m_selfSpin = 0.0f;
  146. m_selfSpinTowardsMax = FALSE;
  147. m_lastSelfSpinUpdateFrame = 0;
  148. m_bladeFlyOffFrame = 0;
  149. m_hitGroundFrame = 0;
  150. } // end HelicopterSlowDeathBehavior
  151. //-------------------------------------------------------------------------------------------------
  152. //-------------------------------------------------------------------------------------------------
  153. HelicopterSlowDeathBehavior::~HelicopterSlowDeathBehavior( void )
  154. {
  155. } // end ~HelicopterSlowDeathBehavior
  156. //-------------------------------------------------------------------------------------------------
  157. //-------------------------------------------------------------------------------------------------
  158. void HelicopterSlowDeathBehavior::beginSlowDeath( const DamageInfo *damageInfo )
  159. {
  160. // extending functionality
  161. SlowDeathBehavior::beginSlowDeath( damageInfo );
  162. // stop the current movement sound
  163. if (getObject()->getDrawable())
  164. {
  165. getObject()->getDrawable()->stopAmbientSound();
  166. }
  167. // get the module data
  168. const HelicopterSlowDeathBehaviorModuleData *modData = getHelicopterSlowDeathBehaviorModuleData();
  169. m_deathSound = modData->m_deathSound;
  170. if (m_deathSound.getEventName().isEmpty() == false)
  171. {
  172. m_deathSound.setObjectID(getObject()->getID());
  173. m_deathSound.setPlayingHandle(TheAudio->addAudioEvent(&m_deathSound));
  174. }
  175. // pick a frame we will fly the blade off at
  176. m_bladeFlyOffFrame = GameLogicRandomValueReal( modData->m_minBladeFlyOffDelay,
  177. modData->m_maxBladeFlyOffDelay );
  178. // for now, make it always fall to the left
  179. m_orbitDirection = ORBIT_DIRECTION_LEFT;
  180. //
  181. // record the current forward angle of the object to be the start angle of our downward
  182. // spin circle angle
  183. //
  184. m_forwardAngle = getObject()->getOrientation();
  185. // set or forward speed in the spiral orbit speed to that specified
  186. m_forwardSpeed = modData->m_spiralOrbitForwardSpeed;
  187. // start our self spinning at the min self spin rate
  188. m_selfSpin = modData->m_minSelfSpin;
  189. // we will start off changing the self spin towards the MaxSelfSpin
  190. m_selfSpinTowardsMax = TRUE;
  191. // the fall of the helicopter
  192. if( !getObject()->getAIUpdateInterface() )
  193. {
  194. return;
  195. }
  196. Locomotor *locomotor = getObject()->getAIUpdateInterface()->getCurLocomotor();
  197. locomotor->setMaxLift( -TheGlobalData->m_gravity * (1.0f - modData->m_fallHowFast) );
  198. locomotor->setMaxBraking( modData->m_maxBraking );
  199. // attach particle system to bone if present
  200. if( modData->m_attachParticleSystem )
  201. {
  202. ParticleSystem *pSys = TheParticleSystemManager->createParticleSystem( modData->m_attachParticleSystem );
  203. if( pSys )
  204. {
  205. // where do the offset attachment to
  206. if( modData->m_attachParticleBone.isEmpty() == FALSE )
  207. {
  208. Drawable *draw = getObject()->getDrawable();
  209. if( draw )
  210. {
  211. Coord3D pos;
  212. if( draw->getPristineBonePositions( modData->m_attachParticleBone.str(), 0, &pos, NULL, 1 ) )
  213. pSys->setPosition( &pos );
  214. } // end if
  215. } // end if
  216. else
  217. {
  218. // use location coord specified ... it will be zero if not given which is center of obj anyway
  219. pSys->setPosition( &modData->m_attachParticleLoc );
  220. } // end else
  221. // attach the particle system to the object
  222. pSys->attachToObject( getObject() );
  223. } // end if
  224. } // end if
  225. } // end beginSlowDeath
  226. //-------------------------------------------------------------------------------------------------
  227. //-------------------------------------------------------------------------------------------------
  228. UpdateSleepTime HelicopterSlowDeathBehavior::update( void )
  229. {
  230. /// @todo srj use SLEEPY_UPDATE here
  231. // call the base class cause we're extending functionality
  232. SlowDeathBehavior::update();
  233. // get out of here if we're not activated yet
  234. if( isSlowDeathActivated() == FALSE )
  235. return UPDATE_SLEEP_NONE;
  236. // get the module data
  237. const HelicopterSlowDeathBehaviorModuleData *modData = getHelicopterSlowDeathBehaviorModuleData();
  238. // get the helicopter for easy access in here
  239. Object *copter = getObject();
  240. // update self spin and orbit if we haven't hit the ground yet
  241. if( m_hitGroundFrame == 0 )
  242. {
  243. //
  244. // change the angle of the helicoptor based on the spiral rate for the turning on the
  245. // large downward spin circle
  246. //
  247. //copter->setOrientation( copter->getOrientation() + m_selfSpin * m_orbitDirection );
  248. Matrix3D xfrm = *copter->getTransformMatrix();
  249. xfrm.In_Place_Pre_Rotate_Z(m_selfSpin * m_orbitDirection);
  250. copter->setTransformMatrix( &xfrm );
  251. //
  252. // over time we change the rate at which we self spin around our center of gravity ... we
  253. // will ping pong back and forth between the MinSelfSpin and MaxSelfSpin defined in INI
  254. //
  255. if( modData->m_selfSpinUpdateDelay &&
  256. TheGameLogic->getFrame() - m_lastSelfSpinUpdateFrame > modData->m_selfSpinUpdateDelay )
  257. {
  258. // update the self spin
  259. if( m_selfSpinTowardsMax == TRUE )
  260. {
  261. // we're going towards the max self spin, increase it
  262. m_selfSpin += modData->m_selfSpinUpdateAmount / LOGICFRAMES_PER_SECOND;
  263. if( m_selfSpin > modData->m_maxSelfSpin )
  264. {
  265. m_selfSpin = modData->m_maxSelfSpin; // cap at max
  266. m_selfSpinTowardsMax = FALSE; // now start changing spin towards min again
  267. } // end if
  268. } // end if
  269. else
  270. {
  271. // we're going towards the min self spin, decrease it
  272. m_selfSpin -= modData->m_selfSpinUpdateAmount / LOGICFRAMES_PER_SECOND;
  273. if( m_selfSpin < modData->m_minSelfSpin )
  274. {
  275. m_selfSpin = modData->m_minSelfSpin; // cap at min
  276. m_selfSpinTowardsMax = TRUE; // now start chaning spin towards max again
  277. } // end if
  278. } // end else
  279. // we have made a change to the self spinning
  280. m_lastSelfSpinUpdateFrame = TheGameLogic->getFrame();
  281. } // end if
  282. // get the physics update module
  283. PhysicsBehavior *physics = copter->getPhysics();
  284. DEBUG_ASSERTCRASH( physics, ("HelicopterSlowDeathBehavior: object '%s' does not have a physics module\n",
  285. copter->getTemplate()->getName().str()) );
  286. //
  287. // apply a force to the helicopter pushing it in a forward motion according to the
  288. // forward angle & speed we are keeping track of to make our downward circle (that forward angle
  289. // is *NOT* the angle the object is facing
  290. //
  291. Coord3D force;
  292. force.x = DOUBLE_TO_REAL( Cos( m_forwardAngle ) ) * m_forwardSpeed;
  293. force.y = DOUBLE_TO_REAL( Sin( m_forwardAngle ) ) * m_forwardSpeed;
  294. force.z = 0.0f;
  295. physics->applyMotiveForce( &force );
  296. // update our forward angle for travelling along the large spiral downward circle
  297. m_forwardAngle += (modData->m_spiralOrbitTurnRate * m_orbitDirection);
  298. // adjust our forward spiral orbit by the damping factor specified
  299. m_forwardSpeed *= modData->m_spiralOrbitForwardSpeedDamping;
  300. // is it time to have the blade fly off
  301. if( m_bladeFlyOffFrame > 0 )
  302. {
  303. // decrement count
  304. m_bladeFlyOffFrame--;
  305. if( m_bladeFlyOffFrame <= 0 )
  306. {
  307. Coord3D bladePos = *copter->getPosition();
  308. // get the blade position from the bone in the model
  309. Drawable *draw = copter->getDrawable();
  310. if( draw )
  311. {
  312. draw->getPristineBonePositions( modData->m_bladeBone.str(), 0, &bladePos, NULL, 1 );
  313. draw->convertBonePosToWorldPos( &bladePos, NULL, &bladePos, NULL );
  314. } // end if
  315. // create the blades flying through the air
  316. // const ObjectCreationList *ocl = TheObjectCreationListStore->findObjectCreationList( "OCL_ComancheBlades" );
  317. // ObjectCreationList::create( ocl, &bladePos );
  318. // run the fx at the blade position
  319. FXList::doFXPos( modData->m_fxBlade, &bladePos );
  320. ObjectCreationList::create( modData->m_oclBlade, copter, &bladePos, NULL );
  321. //
  322. // if we have (potentially) a pilot ejection, do it here.
  323. // note that we call EjectPilotDie::ejectPilot() rather than ObjectCreationList::create(),
  324. // because the former makes the right sounds, and also constrains to veteran-or-better status.
  325. //
  326. if( modData->m_oclEjectPilot && copter->getVeterancyLevel() > LEVEL_REGULAR )
  327. EjectPilotDie::ejectPilot( modData->m_oclEjectPilot, copter, NULL );
  328. } // end if
  329. } // endif
  330. } // end if, not on ground
  331. Bool hitATree = FALSE;
  332. // Here we want to make sure we crash if we collide with a tree on the way down
  333. PhysicsBehavior *phys = copter->getPhysics();
  334. if ( m_hitGroundFrame == 0 && phys )
  335. {
  336. ObjectID treeID = phys->getLastCollidee();
  337. Object *tree = TheGameLogic->findObjectByID( treeID );
  338. if ( tree )
  339. {
  340. if (tree->isKindOf( KINDOF_SHRUBBERY ) )
  341. hitATree = TRUE;
  342. }
  343. }
  344. // when we hit the ground
  345. const Coord3D *pos = copter->getPosition();
  346. if (m_hitGroundFrame == 0)
  347. {
  348. // srj sez: if we haven't yet hit the ground, adjust our layer properly so we crash on bridges
  349. Coord3D tmpPt = *pos;
  350. tmpPt.z = 99999.0f;
  351. PathfindLayerEnum newLayer = TheTerrainLogic->getHighestLayerForDestination(&tmpPt);
  352. copter->setLayer(newLayer);
  353. Real ground = TheTerrainLogic->getLayerHeight( tmpPt.x, tmpPt.y, newLayer );
  354. if (pos->z <= ground + 1.0f || hitATree )
  355. {
  356. // mark the frame we hit the ground on
  357. m_hitGroundFrame = TheGameLogic->getFrame();
  358. // make hit ground effect
  359. FXList::doFXObj( modData->m_fxHitGround, copter );
  360. ObjectCreationList::create( modData->m_oclHitGround, copter, NULL );
  361. // hold the copter in place now
  362. copter->setDisabled( DISABLED_HELD );
  363. // special damage state ... has the blades no on anymore
  364. Drawable *draw = copter->getDrawable();
  365. if( draw )
  366. draw->setModelConditionState( MODELCONDITION_SPECIAL_DAMAGED );
  367. // Stop the sound from playing.
  368. TheAudio->removeAudioEvent(m_deathSound.getPlayingHandle());
  369. } // end if
  370. }
  371. // if we're on the ground, see if it's time for our final boom
  372. if( m_hitGroundFrame &&
  373. TheGameLogic->getFrame() - m_hitGroundFrame > modData->m_delayFromGroundToFinalDeath )
  374. {
  375. // make effect
  376. FXList::doFXObj( modData->m_fxFinalBlowUp, copter );
  377. ObjectCreationList::create( modData->m_oclFinalBlowUp, copter, NULL );
  378. // we are now all done, destroy us and make a rubble shell copter
  379. const ThingTemplate* ttn = TheThingFactory->findTemplate(modData->m_finalRubbleObject);
  380. Object *rubble = TheThingFactory->newObject( ttn, copter->getTeam() );
  381. if( rubble )
  382. {
  383. rubble->setTransformMatrix( copter->getTransformMatrix() );
  384. } // end if
  385. // destroy the copter finally
  386. TheGameLogic->destroyObject( copter );
  387. } // end if
  388. return UPDATE_SLEEP_NONE;
  389. } // end update
  390. // ------------------------------------------------------------------------------------------------
  391. /** CRC */
  392. // ------------------------------------------------------------------------------------------------
  393. void HelicopterSlowDeathBehavior::crc( Xfer *xfer )
  394. {
  395. // extend base class
  396. SlowDeathBehavior::crc( xfer );
  397. } // end crc
  398. // ------------------------------------------------------------------------------------------------
  399. /** Xfer method
  400. * Version Info:
  401. * 1: Initial version */
  402. // ------------------------------------------------------------------------------------------------
  403. void HelicopterSlowDeathBehavior::xfer( Xfer *xfer )
  404. {
  405. // version
  406. XferVersion currentVersion = 1;
  407. XferVersion version = currentVersion;
  408. xfer->xferVersion( &version, currentVersion );
  409. // extend base class
  410. SlowDeathBehavior::xfer( xfer );
  411. // orbit direction
  412. xfer->xferInt( &m_orbitDirection );
  413. // forward angle
  414. xfer->xferReal( &m_forwardAngle );
  415. // forward speed
  416. xfer->xferReal( &m_forwardSpeed );
  417. // self spin
  418. xfer->xferReal( &m_selfSpin );
  419. // self sping towards max
  420. xfer->xferBool( &m_selfSpinTowardsMax );
  421. // last self spin update frame
  422. xfer->xferUnsignedInt( &m_lastSelfSpinUpdateFrame );
  423. // blade fly off frame
  424. xfer->xferUnsignedInt( &m_bladeFlyOffFrame );
  425. // hit ground frame
  426. xfer->xferUnsignedInt( &m_hitGroundFrame );
  427. } // end xfer
  428. // ------------------------------------------------------------------------------------------------
  429. /** Load post process */
  430. // ------------------------------------------------------------------------------------------------
  431. void HelicopterSlowDeathBehavior::loadPostProcess( void )
  432. {
  433. // extend base class
  434. SlowDeathBehavior::loadPostProcess();
  435. } // end loadPostProcess