ConvertToHijackedVehicleCrateCollide.cpp 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  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. ///////////////////////////////////////////////////////////////////////////////////////////////////
  24. //
  25. // FILE: ConvertToHijackedVehicleCrateCollide.cpp
  26. // Author: Mark Lorenzen, July 2002
  27. // Desc: A crate (actually a terrorist - mobile crate) that makes the target vehicle switch
  28. // sides, and kills its driver
  29. // @todo Needs to set the science of that vehicle (dozer) so still can build same stuff as always
  30. //
  31. ///////////////////////////////////////////////////////////////////////////////////////////////////
  32. // INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
  33. #include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
  34. #include "Common/Player.h"
  35. #include "Common/PlayerList.h"
  36. #include "Common/Radar.h"
  37. #include "Common/ThingTemplate.h"
  38. #include "Common/Xfer.h"
  39. #include "GameClient/Drawable.h"
  40. #include "GameClient/Eva.h"
  41. #include "GameClient/InGameUI.h" // useful for printing quick debug strings when we need to
  42. #include "GameLogic/ExperienceTracker.h"
  43. #include "GameLogic/Module/AIUpdate.h"
  44. #include "GameLogic/Module/ConvertToHijackedVehicleCrateCollide.h"
  45. #include "GameLogic/Module/HijackerUpdate.h"
  46. #include "GameLogic/Module/ContainModule.h"
  47. #include "GameLogic/Object.h"
  48. #include "GameLogic/PartitionManager.h"
  49. #include "GameLogic/ScriptEngine.h"
  50. #include "GameLogic/Module/DozerAIUpdate.h"
  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. ConvertToHijackedVehicleCrateCollide::ConvertToHijackedVehicleCrateCollide( Thing *thing, const ModuleData* moduleData ) : CrateCollide( thing, moduleData )
  59. {
  60. }
  61. //-------------------------------------------------------------------------------------------------
  62. //-------------------------------------------------------------------------------------------------
  63. ConvertToHijackedVehicleCrateCollide::~ConvertToHijackedVehicleCrateCollide( void )
  64. {
  65. }
  66. //-------------------------------------------------------------------------------------------------
  67. //-------------------------------------------------------------------------------------------------
  68. Bool ConvertToHijackedVehicleCrateCollide::isValidToExecute( const Object *other ) const
  69. {
  70. if( !CrateCollide::isValidToExecute(other) )
  71. {
  72. return FALSE;
  73. }
  74. if( other->isEffectivelyDead() )
  75. {
  76. return FALSE;// can't hijack a dead vehicle
  77. }
  78. if( other->isKindOf( KINDOF_AIRCRAFT ) || other->isKindOf( KINDOF_BOAT ) )
  79. {
  80. //Can't hijack planes and boats!
  81. return FALSE;
  82. }
  83. if ( other->getStatusBits() & OBJECT_STATUS_HIJACKED )
  84. {
  85. return FALSE;// oops, sorry, I'll jack the next one.
  86. }
  87. Relationship r = getObject()->getRelationship( other );
  88. //Only hijack enemy objects
  89. if( r != ENEMIES )
  90. {
  91. return FALSE;
  92. }
  93. if( other->isKindOf( KINDOF_TRANSPORT ) )
  94. {
  95. //Kris: Allow empty transports to be hijacked.
  96. if( other->getContain() && other->getContain()->getContainCount() > 0 )
  97. {
  98. return FALSE;// dustin sez: do not jack vehicles that may carry hostile passengers
  99. }
  100. }
  101. //Kris: Make sure you can't hijack any aircraft (or hijack-enter).
  102. if( other->isKindOf( KINDOF_AIRCRAFT ) )
  103. {
  104. return FALSE;
  105. }
  106. //VeterancyLevel veterancyLevel = other->getVeterancyLevel();
  107. //if( veterancyLevel >= LEVEL_ELITE )
  108. //{
  109. // return FALSE;
  110. //}
  111. return TRUE;
  112. }
  113. //-------------------------------------------------------------------------------------------------
  114. //-------------------------------------------------------------------------------------------------
  115. Bool ConvertToHijackedVehicleCrateCollide::executeCrateBehavior( Object *other )
  116. {
  117. //Check to make sure that the other object is also the goal object in the AIUpdateInterface
  118. //in order to prevent an unintentional conversion simply by having the terrorist walk too close
  119. //to it.
  120. //Assume ai is valid because CrateCollide::isValidToExecute(other) checks it.
  121. Object *obj = getObject();
  122. AIUpdateInterface* ai = obj->getAIUpdateInterface();
  123. if (ai && ai->getGoalObject() != other)
  124. {
  125. return false;
  126. }
  127. TheRadar->tryInfiltrationEvent( other );
  128. //Before the actual defection takes place, play the "vehicle stolen" EVA
  129. //event if the local player is the victim!
  130. if( other->isLocallyControlled() )
  131. {
  132. TheEva->setShouldPlay( EVA_VehicleStolen );
  133. }
  134. other->setTeam( obj->getControllingPlayer()->getDefaultTeam() );
  135. other->setStatus( OBJECT_STATUS_HIJACKED );// I claim this car in the name of the GLA
  136. AIUpdateInterface* targetAI = other->getAIUpdateInterface();
  137. targetAI->aiMoveToPosition( other->getPosition(), CMD_FROM_AI );
  138. targetAI->aiIdle( CMD_FROM_AI );
  139. //Just in case this target is a dozer, lets make him stop al his dozer tasks, like building and repairing,
  140. //So the previous owner does not benefit from these tasks
  141. DozerAIInterface * dozerAI = targetAI->getDozerAIInterface();
  142. if ( dozerAI )
  143. {
  144. for (UnsignedInt task = DOZER_TASK_FIRST; task < DOZER_NUM_TASKS; ++task)
  145. {
  146. dozerAI->cancelTask( (DozerTask)task );
  147. }
  148. }
  149. AudioEventRTS hijackEvent( "HijackDriver", obj->getID() );
  150. TheAudio->addAudioEvent( &hijackEvent );
  151. //In order to make things easier for the designers, we are going to transfer the hijacker's name
  152. //to the car... so the designer can control the car with their scripts.
  153. TheScriptEngine->transferObjectName( obj->getName(), other );
  154. ExperienceTracker *targetExp = other->getExperienceTracker();
  155. ExperienceTracker *jackerExp = obj->getExperienceTracker();
  156. if ( targetExp && jackerExp )
  157. {
  158. VeterancyLevel highestLevel = MAX(targetExp->getVeterancyLevel(),jackerExp->getVeterancyLevel());
  159. jackerExp->setVeterancyLevel( highestLevel );
  160. targetExp->setVeterancyLevel( highestLevel );
  161. }
  162. Bool targetCanEject = FALSE;
  163. BehaviorModule **dmi = NULL;
  164. for( dmi = other->getBehaviorModules(); *dmi; ++dmi )
  165. {
  166. if( (*dmi)->getEjectPilotDieInterface() )
  167. {
  168. targetCanEject = TRUE;
  169. break;
  170. }
  171. } // end for dmi
  172. if ( ! targetCanEject )
  173. {
  174. TheGameLogic->destroyObject( obj );
  175. return TRUE;
  176. }
  177. // I we have made it this far, we are going to ride in this vehicle for a while
  178. // get the name of the hijackerupdate
  179. static NameKeyType key_HijackerUpdate = NAMEKEY( "HijackerUpdate" );
  180. HijackerUpdate *hijackerUpdate = (HijackerUpdate*)obj->findUpdateModule( key_HijackerUpdate );
  181. if( hijackerUpdate )
  182. {
  183. hijackerUpdate->setTargetObject( other );
  184. hijackerUpdate->setIsInVehicle( TRUE );
  185. hijackerUpdate->setUpdate( TRUE );
  186. // flag bits so hijacker won't be selectible or collideable
  187. //while within the vehicle
  188. obj->setStatus( OBJECT_STATUS_NO_COLLISIONS );
  189. obj->setStatus( OBJECT_STATUS_MASKED );
  190. obj->setStatus( OBJECT_STATUS_UNSELECTABLE );
  191. }
  192. // THIS BLOCK HIDES THE HIJACKER AND REMOVES HIM FROM PARTITION MANAGER
  193. // remove object from its group (if any)
  194. obj->leaveGroup();
  195. if( ai )
  196. {
  197. //By setting him to idle, we will prevent him from entering the target after this gets called.
  198. ai->aiIdle( CMD_FROM_AI );
  199. }
  200. //This is kinda special... we will endow our new ride with our vision and shroud range, since we are driving
  201. other->setVisionRange(getObject()->getVisionRange());
  202. other->setShroudClearingRange(getObject()->getShroudClearingRange());
  203. // remove rider from partition manager
  204. ThePartitionManager->unRegisterObject( obj );
  205. // hide the drawable associated with rider
  206. if( obj->getDrawable() )
  207. obj->getDrawable()->setDrawableHidden( true );
  208. // By returning FALSE, we will not remove the object (Hijacker)
  209. return FALSE;
  210. // return TRUE;
  211. }
  212. // ------------------------------------------------------------------------------------------------
  213. /** CRC */
  214. // ------------------------------------------------------------------------------------------------
  215. void ConvertToHijackedVehicleCrateCollide::crc( Xfer *xfer )
  216. {
  217. // extend base class
  218. CrateCollide::crc( xfer );
  219. } // end crc
  220. // ------------------------------------------------------------------------------------------------
  221. /** Xfer method
  222. * Version Info:
  223. * 1: Initial version */
  224. // ------------------------------------------------------------------------------------------------
  225. void ConvertToHijackedVehicleCrateCollide::xfer( Xfer *xfer )
  226. {
  227. // version
  228. XferVersion currentVersion = 1;
  229. XferVersion version = currentVersion;
  230. xfer->xferVersion( &version, currentVersion );
  231. // extend base class
  232. CrateCollide::xfer( xfer );
  233. } // end xfer
  234. // ------------------------------------------------------------------------------------------------
  235. /** Load post process */
  236. // ------------------------------------------------------------------------------------------------
  237. void ConvertToHijackedVehicleCrateCollide::loadPostProcess( void )
  238. {
  239. // extend base class
  240. CrateCollide::loadPostProcess();
  241. } // end loadPostProcess