CrateCollide.cpp 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  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: CrateCollide.cpp ///////////////////////////////////////////////////////////////////////
  24. // Author: Graham Smallwood, March 2002
  25. // Desc: Abstract base Class Crate Collide
  26. ///////////////////////////////////////////////////////////////////////////////////////////////////
  27. // INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
  28. #include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
  29. #include "Common/BitFlagsIO.h"
  30. #include "Common/Player.h"
  31. #include "Common/Xfer.h"
  32. #include "GameClient/Anim2D.h"
  33. #include "GameClient/FXList.h"
  34. #include "GameClient/InGameUI.h"
  35. #include "GameLogic/GameLogic.h"
  36. #include "GameLogic/Object.h"
  37. #include "GameLogic/Module/CrateCollide.h"
  38. //-------------------------------------------------------------------------------------------------
  39. //-------------------------------------------------------------------------------------------------
  40. CrateCollideModuleData::CrateCollideModuleData()
  41. {
  42. m_isForbidOwnerPlayer = FALSE;
  43. m_executeAnimationDisplayTimeInSeconds = 0.0f;
  44. m_executeAnimationZRisePerSecond = 0.0f;
  45. m_executeAnimationFades = TRUE;
  46. m_isBuildingPickup = FALSE;
  47. m_isHumanOnlyPickup = FALSE;
  48. m_executeFX = NULL;
  49. m_pickupScience = SCIENCE_INVALID;
  50. // Added By Sadullah Nader
  51. // Initializations missing and needed
  52. m_executionAnimationTemplate = AsciiString::TheEmptyString;
  53. // End Add
  54. }
  55. //-------------------------------------------------------------------------------------------------
  56. //-------------------------------------------------------------------------------------------------
  57. void CrateCollideModuleData::buildFieldParse(MultiIniFieldParse& p)
  58. {
  59. ModuleData::buildFieldParse(p);
  60. static const FieldParse dataFieldParse[] =
  61. {
  62. { "RequiredKindOf", KindOfMaskType::parseFromINI, NULL, offsetof( CrateCollideModuleData, m_kindof ) },
  63. { "ForbiddenKindOf", KindOfMaskType::parseFromINI, NULL, offsetof( CrateCollideModuleData, m_kindofnot ) },
  64. { "ForbidOwnerPlayer", INI::parseBool, NULL, offsetof( CrateCollideModuleData, m_isForbidOwnerPlayer ) },
  65. { "BuildingPickup", INI::parseBool, NULL, offsetof( CrateCollideModuleData, m_isBuildingPickup ) },
  66. { "HumanOnly", INI::parseBool, NULL, offsetof( CrateCollideModuleData, m_isHumanOnlyPickup ) },
  67. { "PickupScience", INI::parseScience, NULL, offsetof( CrateCollideModuleData, m_pickupScience ) },
  68. { "ExecuteFX", INI::parseFXList, NULL, offsetof( CrateCollideModuleData, m_executeFX ) },
  69. { "ExecuteAnimation", INI::parseAsciiString, NULL, offsetof( CrateCollideModuleData, m_executionAnimationTemplate ) },
  70. { "ExecuteAnimationTime", INI::parseReal, NULL, offsetof( CrateCollideModuleData, m_executeAnimationDisplayTimeInSeconds ) },
  71. { "ExecuteAnimationZRise", INI::parseReal, NULL, offsetof( CrateCollideModuleData, m_executeAnimationZRisePerSecond ) },
  72. { "ExecuteAnimationFades", INI::parseBool, NULL, offsetof( CrateCollideModuleData, m_executeAnimationFades ) },
  73. { 0, 0, 0, 0 }
  74. };
  75. p.add(dataFieldParse);
  76. }
  77. //-------------------------------------------------------------------------------------------------
  78. //-------------------------------------------------------------------------------------------------
  79. CrateCollide::CrateCollide( Thing *thing, const ModuleData* moduleData ) : CollideModule( thing, moduleData )
  80. {
  81. }
  82. //-------------------------------------------------------------------------------------------------
  83. //-------------------------------------------------------------------------------------------------
  84. CrateCollide::~CrateCollide( void )
  85. {
  86. }
  87. //-------------------------------------------------------------------------------------------------
  88. /** The collide event.
  89. * Note that when other is NULL it means "collide with ground" */
  90. //-------------------------------------------------------------------------------------------------
  91. void CrateCollide::onCollide( Object *other, const Coord3D *, const Coord3D * )
  92. {
  93. const CrateCollideModuleData *modData = getCrateCollideModuleData();
  94. // If the crate can be picked up, perform the game logic and destroy the crate.
  95. if( isValidToExecute( other ) )
  96. {
  97. if( executeCrateBehavior( other ) )
  98. {
  99. if( modData->m_executeFX != NULL )
  100. {
  101. // Note: We pass in other here, because the crate is owned by the neutral player, and
  102. // we want to do things that only the other person can see.
  103. FXList::doFXObj( modData->m_executeFX, other );
  104. }
  105. TheGameLogic->destroyObject( getObject() );
  106. }
  107. // play animation in the world at this spot if there is one
  108. if( TheAnim2DCollection && modData->m_executionAnimationTemplate.isEmpty() == FALSE && TheGameLogic->getDrawIconUI() )
  109. {
  110. Anim2DTemplate *animTemplate = TheAnim2DCollection->findTemplate( modData->m_executionAnimationTemplate );
  111. TheInGameUI->addWorldAnimation( animTemplate,
  112. getObject()->getPosition(),
  113. WORLD_ANIM_FADE_ON_EXPIRE,
  114. modData->m_executeAnimationDisplayTimeInSeconds,
  115. modData->m_executeAnimationZRisePerSecond );
  116. }
  117. }
  118. }
  119. //-------------------------------------------------------------------------------------------------
  120. Bool CrateCollide::isValidToExecute( const Object *other ) const
  121. {
  122. //The ground never picks up a crate
  123. if( other == NULL )
  124. return FALSE;
  125. //Nothing Neutral can pick up any type of crate
  126. if( other->isNeutralControlled() )
  127. return FALSE;
  128. const CrateCollideModuleData* md = getCrateCollideModuleData();
  129. Bool validBuildingAttempt = md->m_isBuildingPickup && other->isKindOf( KINDOF_STRUCTURE );
  130. // Must be a "Unit" type thing. Real Game Object, not just Object
  131. if( other->getAIUpdateInterface() == NULL && !validBuildingAttempt )// Building exception flag for Drop Zone
  132. return FALSE;
  133. // must match our kindof flags (if any)
  134. if (md && !other->isKindOfMulti(md->m_kindof, md->m_kindofnot))
  135. return FALSE;
  136. if( other->isEffectivelyDead() )
  137. return FALSE;
  138. // crates cannot be claimed while in the air, except by buildings
  139. if( getObject()->isAboveTerrain() && !validBuildingAttempt )
  140. return FALSE;
  141. if( md->m_isForbidOwnerPlayer && (getObject()->getControllingPlayer() == other->getControllingPlayer()) )
  142. return FALSE; // Design has decreed this to not be picked up by the dead guy's team.
  143. if( md->m_isHumanOnlyPickup && other->getControllingPlayer() && (other->getControllingPlayer()->getPlayerType() != PLAYER_HUMAN) )
  144. return FALSE; // Human only mission crate
  145. if( (md->m_pickupScience != SCIENCE_INVALID) && other->getControllingPlayer() && !other->getControllingPlayer()->hasScience(md->m_pickupScience) )
  146. return FALSE; // Science required to pick this up
  147. return TRUE;
  148. }
  149. // ------------------------------------------------------------------------------------------------
  150. /** CRC */
  151. // ------------------------------------------------------------------------------------------------
  152. void CrateCollide::crc( Xfer *xfer )
  153. {
  154. // extend base class
  155. CollideModule::crc( xfer );
  156. } // end crc
  157. // ------------------------------------------------------------------------------------------------
  158. /** Xfer Method
  159. * Version Info:
  160. * 1: Initial version */
  161. // ------------------------------------------------------------------------------------------------
  162. void CrateCollide::xfer( Xfer *xfer )
  163. {
  164. // version
  165. XferVersion currentVersion = 1;
  166. XferVersion version = currentVersion;
  167. xfer->xferVersion( &version, currentVersion );
  168. // extend base class
  169. CollideModule::xfer( xfer );
  170. } // end xfer
  171. // ------------------------------------------------------------------------------------------------
  172. /** Load post process */
  173. // ------------------------------------------------------------------------------------------------
  174. void CrateCollide::loadPostProcess( void )
  175. {
  176. // extend base class
  177. CollideModule::loadPostProcess();
  178. } // end loadPostProcess