DynamicGeometryInfoUpdate.cpp 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  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: DynamicGeometryInfoUpdate.cpp //////////////////////////////////////////////////////////////////////////
  24. // Author: Graham Smallwood, April 2002
  25. // Desc: Update module that changes the object's GeometryInfo
  26. ///////////////////////////////////////////////////////////////////////////////////////////////////
  27. // INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
  28. #include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
  29. #include "Common/Xfer.h"
  30. #include "GameLogic/Module/DynamicGeometryInfoUpdate.h"
  31. #include "GameLogic/Object.h"
  32. //-------------------------------------------------------------------------------------------------
  33. //-------------------------------------------------------------------------------------------------
  34. DynamicGeometryInfoUpdateModuleData::DynamicGeometryInfoUpdateModuleData()
  35. {
  36. m_initialDelay = 0;
  37. m_initialHeight = 0;
  38. m_initialMajorRadius = 0;
  39. m_initialMinorRadius = 0;
  40. m_finalHeight = 0;
  41. m_finalMajorRadius = 0;
  42. m_finalMinorRadius = 0;
  43. m_transitionTime = 1;
  44. m_reverseAtTransitionTime = FALSE;
  45. }
  46. //-------------------------------------------------------------------------------------------------
  47. /*static*/ void DynamicGeometryInfoUpdateModuleData::buildFieldParse(MultiIniFieldParse& p)
  48. {
  49. ModuleData::buildFieldParse(p);
  50. static const FieldParse dataFieldParse[] =
  51. {
  52. { "InitialDelay", INI::parseDurationUnsignedInt, NULL, offsetof(DynamicGeometryInfoUpdateModuleData, m_initialDelay) },
  53. { "InitialHeight", INI::parseReal, NULL, offsetof(DynamicGeometryInfoUpdateModuleData, m_initialHeight) },
  54. { "InitialMajorRadius", INI::parseReal, NULL, offsetof(DynamicGeometryInfoUpdateModuleData, m_initialMajorRadius) },
  55. { "InitialMinorRadius", INI::parseReal, NULL, offsetof(DynamicGeometryInfoUpdateModuleData, m_initialMinorRadius) },
  56. { "FinalHeight", INI::parseReal, NULL, offsetof(DynamicGeometryInfoUpdateModuleData, m_finalHeight) },
  57. { "FinalMajorRadius", INI::parseReal, NULL, offsetof(DynamicGeometryInfoUpdateModuleData, m_finalMajorRadius) },
  58. { "FinalMinorRadius", INI::parseReal, NULL, offsetof(DynamicGeometryInfoUpdateModuleData, m_finalMinorRadius) },
  59. { "TransitionTime", INI::parseDurationUnsignedInt, NULL, offsetof(DynamicGeometryInfoUpdateModuleData, m_transitionTime) },
  60. { "ReverseAtTransitionTime", INI::parseBool, NULL, offsetof( DynamicGeometryInfoUpdateModuleData, m_reverseAtTransitionTime ) },
  61. { 0, 0, 0, 0 }
  62. };
  63. p.add(dataFieldParse);
  64. }
  65. //-------------------------------------------------------------------------------------------------
  66. DynamicGeometryInfoUpdate::DynamicGeometryInfoUpdate( Thing *thing, const ModuleData* moduleData ) : UpdateModule( thing, moduleData )
  67. {
  68. DynamicGeometryInfoUpdateModuleData *modData = (DynamicGeometryInfoUpdateModuleData *)moduleData;
  69. m_startingDelayCountdown = modData->m_initialDelay;
  70. m_startingDelayCountdown = max( m_startingDelayCountdown, 1u );
  71. m_timeActive = 0;
  72. m_started = FALSE;
  73. m_finished = FALSE;
  74. m_reverseAtTransitionTime = modData->m_reverseAtTransitionTime;
  75. m_switchedDirections = FALSE;
  76. // record in our instance what initial and final height are
  77. m_initialHeight = modData->m_initialHeight;
  78. m_initialMajorRadius = modData->m_initialMajorRadius;
  79. m_initialMinorRadius = modData->m_initialMinorRadius;
  80. m_finalHeight = modData->m_finalHeight;
  81. m_finalMajorRadius = modData->m_finalMajorRadius;
  82. m_finalMinorRadius = modData->m_finalMinorRadius;
  83. }
  84. //-------------------------------------------------------------------------------------------------
  85. //-------------------------------------------------------------------------------------------------
  86. DynamicGeometryInfoUpdate::~DynamicGeometryInfoUpdate( void )
  87. {
  88. }
  89. //-------------------------------------------------------------------------------------------------
  90. /** The update callback. */
  91. //-------------------------------------------------------------------------------------------------
  92. UpdateSleepTime DynamicGeometryInfoUpdate::update( void )
  93. {
  94. /// @todo srj use SLEEPY_UPDATE here
  95. if( m_finished )
  96. return UPDATE_SLEEP_NONE;
  97. if( !m_started )
  98. {
  99. m_startingDelayCountdown--;
  100. if( m_startingDelayCountdown > 0 )
  101. return UPDATE_SLEEP_NONE;
  102. m_started = TRUE;
  103. } // end if
  104. // Either we've been running, or we just started right now. Doesn't matter.
  105. const DynamicGeometryInfoUpdateModuleData *data = getDynamicGeometryInfoUpdateModuleData();
  106. Object *me = getObject();
  107. Real newHeight, newMajor, newMinor;
  108. Real ratio = (float)m_timeActive / (float)data->m_transitionTime;
  109. newHeight = m_initialHeight + (ratio * (m_finalHeight - m_initialHeight));
  110. newMajor = m_initialMajorRadius + (ratio * (m_finalMajorRadius - m_initialMajorRadius));
  111. newMinor = m_initialMinorRadius + (ratio * (m_finalMinorRadius - m_initialMinorRadius));
  112. // make a new geometry info with the new values
  113. const GeometryInfo oldGeom = me->getGeometryInfo();
  114. GeometryInfo newGeom( oldGeom.getGeomType(), oldGeom.getIsSmall(), newHeight, newMajor, newMinor );
  115. me->setGeometryInfo( newGeom );
  116. // we've not been active another frame .. increment out counter
  117. m_timeActive++;
  118. // greater, so an update that is exactly right will be done
  119. if( m_timeActive > data->m_transitionTime )
  120. {
  121. // if we're supposed to reverse at transition time do so now if we haven't already
  122. if( m_reverseAtTransitionTime == TRUE )
  123. {
  124. // switch directions, reset time active, and turn off the switch at transition time
  125. m_switchedDirections = TRUE;
  126. m_timeActive = 0;
  127. m_reverseAtTransitionTime = FALSE;
  128. // swap the initial and final values
  129. m_initialHeight = data->m_finalHeight;
  130. m_initialMajorRadius = data->m_finalMajorRadius;
  131. m_initialMinorRadius = data->m_finalMinorRadius;
  132. m_finalHeight = data->m_initialHeight;
  133. m_finalMajorRadius = data->m_initialMajorRadius;
  134. m_finalMinorRadius = data->m_initialMinorRadius;
  135. } // end if
  136. else
  137. {
  138. // no switch needed ... we're all done
  139. m_finished = TRUE;
  140. } // end else
  141. } // end if, time active is longer than transition time
  142. return UPDATE_SLEEP_NONE;
  143. }
  144. // ------------------------------------------------------------------------------------------------
  145. /** CRC */
  146. // ------------------------------------------------------------------------------------------------
  147. void DynamicGeometryInfoUpdate::crc( Xfer *xfer )
  148. {
  149. // extend base class
  150. UpdateModule::crc( xfer );
  151. } // end crc
  152. // ------------------------------------------------------------------------------------------------
  153. /** Xfer method
  154. * Version Info:
  155. * 1: Initial version */
  156. // ------------------------------------------------------------------------------------------------
  157. void DynamicGeometryInfoUpdate::xfer( Xfer *xfer )
  158. {
  159. // version
  160. XferVersion currentVersion = 1;
  161. XferVersion version = currentVersion;
  162. xfer->xferVersion( &version, currentVersion );
  163. // extend base class
  164. UpdateModule::xfer( xfer );
  165. // starting delay countdown
  166. xfer->xferUnsignedInt( &m_startingDelayCountdown );
  167. // time active
  168. xfer->xferUnsignedInt( &m_timeActive );
  169. // started
  170. xfer->xferBool( &m_started );
  171. // finished
  172. xfer->xferBool( &m_finished );
  173. // reverse at transition time
  174. xfer->xferBool( &m_reverseAtTransitionTime );
  175. // direction
  176. xfer->xferUser( &m_direction, sizeof( DynamicGeometryDirection ) );
  177. // switched directions
  178. xfer->xferBool( &m_switchedDirections );
  179. // initial height
  180. xfer->xferReal( &m_initialHeight );
  181. // initial major radius
  182. xfer->xferReal( &m_initialMajorRadius );
  183. // initial minor radius
  184. xfer->xferReal( &m_initialMinorRadius );
  185. // final height
  186. xfer->xferReal( &m_finalHeight );
  187. // final major radius
  188. xfer->xferReal( &m_finalMajorRadius );
  189. // final minor radius
  190. xfer->xferReal( &m_finalMinorRadius );
  191. } // end xfer
  192. // ------------------------------------------------------------------------------------------------
  193. /** Load post process */
  194. // ------------------------------------------------------------------------------------------------
  195. void DynamicGeometryInfoUpdate::loadPostProcess( void )
  196. {
  197. // extend base class
  198. UpdateModule::loadPostProcess();
  199. } // end loadPostProcess