SalvageCrateCollide.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  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: SalvageCrateCollide.cpp ///////////////////////////////////////////////////////////////////////
  24. // Author: Graham Smallwood, March 2002
  25. // Desc: The Savlage system can give a Weaponset bonus, a level, or money. Salvagers create them
  26. // by killing marked units, and only WeaponSalvagers can get the WeaponSet bonus
  27. ///////////////////////////////////////////////////////////////////////////////////////////////////
  28. // INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
  29. #include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
  30. #include "GameLogic/Module/SalvageCrateCollide.h"
  31. #include "Common/AudioEventRTS.h"
  32. #include "Common/MiscAudio.h"
  33. #include "Common/Kindof.h"
  34. #include "Common/RandomValue.h"
  35. #include "Common/Player.h"
  36. #include "Common/ThingTemplate.h"
  37. #include "Common/Xfer.h"
  38. #include "GameClient/GameText.h"
  39. #include "GameClient/InGameUI.h"
  40. #include "GameLogic/ExperienceTracker.h"
  41. #include "GameLogic/Object.h"
  42. //-------------------------------------------------------------------------------------------------
  43. //-------------------------------------------------------------------------------------------------
  44. SalvageCrateCollide::SalvageCrateCollide( Thing *thing, const ModuleData* moduleData ) : CrateCollide( thing, moduleData )
  45. {
  46. }
  47. //-------------------------------------------------------------------------------------------------
  48. //-------------------------------------------------------------------------------------------------
  49. SalvageCrateCollide::~SalvageCrateCollide( void )
  50. {
  51. }
  52. //-------------------------------------------------------------------------------------------------
  53. Bool SalvageCrateCollide::isValidToExecute( const Object *other ) const
  54. {
  55. if( ! CrateCollide::isValidToExecute( other ) )
  56. return FALSE;
  57. // Only salvage units can pick up a Salvage crate
  58. if( ! other->getTemplate()->isKindOf( KINDOF_SALVAGER ) )
  59. return FALSE;
  60. return TRUE;
  61. }
  62. //-------------------------------------------------------------------------------------------------
  63. Bool SalvageCrateCollide::executeCrateBehavior( Object *other )
  64. {
  65. if( eligibleForArmorSet(other) )// No percent chance on this one, if you can get it, you get it.
  66. {
  67. doArmorSet(other);
  68. //Play the salvage installation crate pickup sound.
  69. AudioEventRTS soundToPlay = TheAudio->getMiscAudio()->m_crateSalvage;
  70. soundToPlay.setObjectID( other->getID() );
  71. TheAudio->addAudioEvent( &soundToPlay );
  72. }
  73. else if( eligibleForWeaponSet( other ) && testWeaponChance() )
  74. {
  75. doWeaponSet( other );
  76. //Play the salvage installation crate pickup sound.
  77. AudioEventRTS soundToPlay = TheAudio->getMiscAudio()->m_crateSalvage;
  78. soundToPlay.setObjectID( other->getID() );
  79. TheAudio->addAudioEvent( &soundToPlay );
  80. //Play the unit voice acknowledgement for upgrading weapons.
  81. //Already handled by the "move order"
  82. //const AudioEventRTS *soundToPlayPtr = other->getTemplate()->getPerUnitSound( "VoiceSalvage" );
  83. //soundToPlay = *soundToPlayPtr;
  84. //soundToPlay.setObjectID( other->getID() );
  85. //TheAudio->addAudioEvent( &soundToPlay );
  86. }
  87. else if( eligibleForLevel( other ) && testLevelChance() )
  88. {
  89. doLevelGain( other );
  90. //Sound will play in
  91. //soundToPlay = TheAudio->getMiscAudio()->m_unitPromoted;
  92. }
  93. else // just assume the testMoneyChance
  94. {
  95. doMoney( other );
  96. AudioEventRTS soundToPlay = TheAudio->getMiscAudio()->m_crateMoney;
  97. soundToPlay.setObjectID( other->getID() );
  98. TheAudio->addAudioEvent(&soundToPlay);
  99. }
  100. other->getControllingPlayer()->getAcademyStats()->recordSalvageCollected();
  101. return TRUE;
  102. }
  103. // ------------------------------------------------------------------------------------------------
  104. Bool SalvageCrateCollide::eligibleForWeaponSet( Object *other )
  105. {
  106. if( other == NULL )
  107. return FALSE;
  108. // A kindof marks eligibility, and you must not be fully upgraded
  109. if( !other->isKindOf(KINDOF_WEAPON_SALVAGER) )
  110. return FALSE;
  111. if( other->testWeaponSetFlag(WEAPONSET_CRATEUPGRADE_TWO) )
  112. return FALSE;
  113. return TRUE;
  114. }
  115. // ------------------------------------------------------------------------------------------------
  116. Bool SalvageCrateCollide::eligibleForArmorSet( Object *other )
  117. {
  118. if( other == NULL )
  119. return FALSE;
  120. // A kindof marks eligibility, and you must not be fully upgraded
  121. if( !other->isKindOf(KINDOF_ARMOR_SALVAGER) )
  122. return FALSE;
  123. if( other->testArmorSetFlag(ARMORSET_CRATE_UPGRADE_TWO) )
  124. return FALSE;
  125. return TRUE;
  126. }
  127. // ------------------------------------------------------------------------------------------------
  128. Bool SalvageCrateCollide::eligibleForLevel( Object *other )
  129. {
  130. if( other == NULL )
  131. return FALSE;
  132. // Sorry, you are max level
  133. if( other->getExperienceTracker()->getVeterancyLevel() == LEVEL_HEROIC )
  134. return FALSE;
  135. // Sorry, you can't gain levels
  136. if( !other->getExperienceTracker()->isTrainable() )
  137. return FALSE;
  138. return TRUE;
  139. }
  140. // ------------------------------------------------------------------------------------------------
  141. Bool SalvageCrateCollide::testWeaponChance()
  142. {
  143. const SalvageCrateCollideModuleData *md = getSalvageCrateCollideModuleData();
  144. if( md->m_weaponChance == 1.0f )
  145. return TRUE; // don't waste a random number for a 100%
  146. Real randomNumber = GameLogicRandomValueReal( 0, 1 );
  147. if( randomNumber < md->m_weaponChance )
  148. return TRUE;
  149. return FALSE;
  150. }
  151. // ------------------------------------------------------------------------------------------------
  152. Bool SalvageCrateCollide::testLevelChance()
  153. {
  154. const SalvageCrateCollideModuleData *md = getSalvageCrateCollideModuleData();
  155. if( md->m_levelChance == 1.0f )
  156. return TRUE; // don't waste a random number for a 100%
  157. Real randomNumber = GameLogicRandomValueReal( 0, 1 );
  158. if( randomNumber < md->m_levelChance )
  159. return TRUE;
  160. return FALSE;
  161. }
  162. // ------------------------------------------------------------------------------------------------
  163. void SalvageCrateCollide::doWeaponSet( Object *other )
  164. {
  165. if( other->testWeaponSetFlag( WEAPONSET_CRATEUPGRADE_ONE ) )
  166. {
  167. other->clearWeaponSetFlag( WEAPONSET_CRATEUPGRADE_ONE );
  168. other->setWeaponSetFlag( WEAPONSET_CRATEUPGRADE_TWO );
  169. }
  170. else
  171. {
  172. other->setWeaponSetFlag( WEAPONSET_CRATEUPGRADE_ONE );
  173. }
  174. }
  175. // ------------------------------------------------------------------------------------------------
  176. void SalvageCrateCollide::doArmorSet( Object *other )
  177. {
  178. if( other->testArmorSetFlag( ARMORSET_CRATE_UPGRADE_ONE ) )
  179. {
  180. other->clearArmorSetFlag( ARMORSET_CRATE_UPGRADE_ONE );
  181. other->setArmorSetFlag( ARMORSET_CRATE_UPGRADE_TWO );
  182. other->clearAndSetModelConditionState(MODELCONDITION_ARMORSET_CRATEUPGRADE_ONE, MODELCONDITION_ARMORSET_CRATEUPGRADE_TWO);
  183. }
  184. else
  185. {
  186. other->setArmorSetFlag( ARMORSET_CRATE_UPGRADE_ONE );
  187. other->setModelConditionState(MODELCONDITION_ARMORSET_CRATEUPGRADE_ONE);
  188. }
  189. }
  190. // ------------------------------------------------------------------------------------------------
  191. void SalvageCrateCollide::doLevelGain( Object *other )
  192. {
  193. other->getExperienceTracker()->gainExpForLevel( 1 );
  194. }
  195. // ------------------------------------------------------------------------------------------------
  196. void SalvageCrateCollide::doMoney( Object *other )
  197. {
  198. const SalvageCrateCollideModuleData *md = getSalvageCrateCollideModuleData();
  199. Int money;
  200. if( md->m_minimumMoney != md->m_maximumMoney )// Random value doesn't like to get a constant range
  201. money = GameLogicRandomValue( md->m_minimumMoney, md->m_maximumMoney );
  202. else
  203. money = md->m_minimumMoney;
  204. if( money > 0 )
  205. {
  206. other->getControllingPlayer()->getMoney()->deposit( money );
  207. other->getControllingPlayer()->getScoreKeeper()->addMoneyEarned( money );
  208. //Display cash income floating over the crate. Position is me, everything else is them.
  209. UnicodeString moneyString;
  210. moneyString.format( TheGameText->fetch( "GUI:AddCash" ), money );
  211. Coord3D pos;
  212. pos.set( getObject()->getPosition() );
  213. pos.z += 10.0f; //add a little z to make it show up above the unit.
  214. Color color = other->getControllingPlayer()->getPlayerColor() | GameMakeColor( 0, 0, 0, 230 );
  215. TheInGameUI->addFloatingText( moneyString, &pos, color );
  216. }
  217. }
  218. // ------------------------------------------------------------------------------------------------
  219. /** CRC */
  220. // ------------------------------------------------------------------------------------------------
  221. void SalvageCrateCollide::crc( Xfer *xfer )
  222. {
  223. // extend base class
  224. CrateCollide::crc( xfer );
  225. } // end crc
  226. // ------------------------------------------------------------------------------------------------
  227. /** Xfer method
  228. * Version Info:
  229. * 1: Initial version */
  230. // ------------------------------------------------------------------------------------------------
  231. void SalvageCrateCollide::xfer( Xfer *xfer )
  232. {
  233. // version
  234. XferVersion currentVersion = 1;
  235. XferVersion version = currentVersion;
  236. xfer->xferVersion( &version, currentVersion );
  237. // extend base class
  238. CrateCollide::xfer( xfer );
  239. } // end xfer
  240. // ------------------------------------------------------------------------------------------------
  241. /** Load post process */
  242. // ------------------------------------------------------------------------------------------------
  243. void SalvageCrateCollide::loadPostProcess( void )
  244. {
  245. // extend base class
  246. CrateCollide::loadPostProcess();
  247. } // end loadPostProcess