warfactorygameobj.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561
  1. /*
  2. ** Command & Conquer Renegade(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. *** Confidential - Westwood Studios ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : Commando *
  23. * *
  24. * $Archive:: /Commando/Code/Combat/warfactorygameobj.cpp $Author:: Patrick $*
  25. * *
  26. * $Modtime:: 1/07/02 4:46p $*
  27. * *
  28. * $Revision:: 15 $*
  29. * *
  30. *---------------------------------------------------------------------------------------------*
  31. * Functions: *
  32. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  33. #include "warfactorygameobj.h"
  34. #include "basecontroller.h"
  35. #include "vehicle.h"
  36. #include "wwhack.h"
  37. #include "simpledefinitionfactory.h"
  38. #include "persistfactory.h"
  39. #include "definitionmgr.h"
  40. #include "combatchunkid.h"
  41. #include "debug.h"
  42. #include "scriptzone.h"
  43. #include "wwprofile.h"
  44. #include "basecontroller.h"
  45. #include "combatchunkid.h"
  46. #include "hanim.h"
  47. #include "vehiclephys.h"
  48. ////////////////////////////////////////////////////////////////
  49. // Hacks
  50. ////////////////////////////////////////////////////////////////
  51. DECLARE_FORCE_LINK (WarFactory)
  52. ////////////////////////////////////////////////////////////////
  53. // Editable and persist factories
  54. ////////////////////////////////////////////////////////////////
  55. SimplePersistFactoryClass <WarFactoryGameObjDef, CHUNKID_GAME_OBJECT_DEF_WARFACTORY> _WarFactoryGameObjDefPersistFactory;
  56. SimplePersistFactoryClass <WarFactoryGameObj, CHUNKID_GAME_OBJECT_WARFACTORY> _WarFactoryGameObjPersistFactory;
  57. DECLARE_DEFINITION_FACTORY (WarFactoryGameObjDef, CLASSID_GAME_OBJECT_DEF_WARFACTORY, "WarFactory") _WarFactoryGameObjDefDefFactory;
  58. ////////////////////////////////////////////////////////////////
  59. // Constants
  60. ////////////////////////////////////////////////////////////////
  61. float UNITIALIZED_TIMER = -100.0F;
  62. const float WARFACTORY_LOCK_TIME = 26.0f;
  63. ////////////////////////////////////////////////////////////////
  64. // Save/Load constants
  65. ////////////////////////////////////////////////////////////////
  66. enum
  67. {
  68. CHUNKID_DEF_PARENT = 0x02200638,
  69. CHUNKID_DEF_VARIABLES,
  70. MICROCHUNKID_DEF_UNUSED = 1,
  71. };
  72. enum
  73. {
  74. CHUNKID_PARENT = 0x0219043,
  75. CHUNKID_VARIABLES,
  76. MICROCHUNKID_UNUSED = 1,
  77. };
  78. ////////////////////////////////////////////////////////////////
  79. //
  80. // WarFactoryGameObjDef
  81. //
  82. ////////////////////////////////////////////////////////////////
  83. WarFactoryGameObjDef::WarFactoryGameObjDef (void)
  84. {
  85. return ;
  86. }
  87. ////////////////////////////////////////////////////////////////
  88. //
  89. // ~WarFactoryGameObjDef
  90. //
  91. ////////////////////////////////////////////////////////////////
  92. WarFactoryGameObjDef::~WarFactoryGameObjDef (void)
  93. {
  94. return ;
  95. }
  96. ////////////////////////////////////////////////////////////////
  97. //
  98. // Get_Class_ID
  99. //
  100. ////////////////////////////////////////////////////////////////
  101. uint32
  102. WarFactoryGameObjDef::Get_Class_ID (void) const
  103. {
  104. return CLASSID_GAME_OBJECT_DEF_WARFACTORY;
  105. }
  106. ////////////////////////////////////////////////////////////////
  107. //
  108. // Create
  109. //
  110. ////////////////////////////////////////////////////////////////
  111. PersistClass *
  112. WarFactoryGameObjDef::Create (void) const
  113. {
  114. WarFactoryGameObj *building = new WarFactoryGameObj;
  115. building->Init (*this);
  116. return building;
  117. }
  118. ////////////////////////////////////////////////////////////////
  119. //
  120. // Create
  121. //
  122. ////////////////////////////////////////////////////////////////
  123. bool
  124. WarFactoryGameObjDef::Save (ChunkSaveClass &csave)
  125. {
  126. csave.Begin_Chunk (CHUNKID_DEF_PARENT);
  127. VehicleFactoryGameObjDef::Save (csave);
  128. csave.End_Chunk ();
  129. csave.Begin_Chunk (CHUNKID_DEF_VARIABLES);
  130. csave.End_Chunk ();
  131. return true;
  132. }
  133. ////////////////////////////////////////////////////////////////
  134. //
  135. // Load
  136. //
  137. ////////////////////////////////////////////////////////////////
  138. bool
  139. WarFactoryGameObjDef::Load (ChunkLoadClass &cload)
  140. {
  141. while (cload.Open_Chunk ())
  142. {
  143. switch (cload.Cur_Chunk_ID ())
  144. {
  145. case CHUNKID_DEF_PARENT:
  146. VehicleFactoryGameObjDef::Load (cload);
  147. break;
  148. case CHUNKID_DEF_VARIABLES:
  149. Load_Variables (cload);
  150. break;
  151. default:
  152. Debug_Say (("Unrecognized WarFactory Def chunkID\n"));
  153. break;
  154. }
  155. cload.Close_Chunk ();
  156. }
  157. return true;
  158. }
  159. ////////////////////////////////////////////////////////////////
  160. //
  161. // Load_Variables
  162. //
  163. ////////////////////////////////////////////////////////////////
  164. void
  165. WarFactoryGameObjDef::Load_Variables (ChunkLoadClass &cload)
  166. {
  167. while (cload.Open_Micro_Chunk ()) {
  168. /*switch (cload.Cur_Micro_Chunk_ID ())
  169. {
  170. default:
  171. Debug_Say (("Unrecognized WarFactory Def Variable chunkID\n"));
  172. break;
  173. }*/
  174. cload.Close_Micro_Chunk();
  175. }
  176. return ;
  177. }
  178. ////////////////////////////////////////////////////////////////
  179. //
  180. // Get_Factory
  181. //
  182. ////////////////////////////////////////////////////////////////
  183. const PersistFactoryClass &
  184. WarFactoryGameObjDef::Get_Factory (void) const
  185. {
  186. return _WarFactoryGameObjDefPersistFactory;
  187. }
  188. ////////////////////////////////////////////////////////////////
  189. //
  190. // WarFactoryGameObj
  191. //
  192. ////////////////////////////////////////////////////////////////
  193. WarFactoryGameObj::WarFactoryGameObj (void) :
  194. CreationAnimationID (0),
  195. CreationFinishedTimer (UNITIALIZED_TIMER)
  196. {
  197. return ;
  198. }
  199. ////////////////////////////////////////////////////////////////
  200. //
  201. // ~WarFactoryGameObj
  202. //
  203. ////////////////////////////////////////////////////////////////
  204. WarFactoryGameObj::~WarFactoryGameObj (void)
  205. {
  206. return ;
  207. }
  208. ////////////////////////////////////////////////////////////////
  209. //
  210. // Get_Factory
  211. //
  212. ////////////////////////////////////////////////////////////////
  213. const PersistFactoryClass &
  214. WarFactoryGameObj::Get_Factory (void) const
  215. {
  216. return _WarFactoryGameObjPersistFactory;
  217. }
  218. ////////////////////////////////////////////////////////////////
  219. //
  220. // Init
  221. //
  222. ////////////////////////////////////////////////////////////////
  223. void WarFactoryGameObj::Init( void )
  224. {
  225. Init( Get_Definition() );
  226. }
  227. ////////////////////////////////////////////////////////////////
  228. //
  229. // Init
  230. //
  231. ////////////////////////////////////////////////////////////////
  232. void
  233. WarFactoryGameObj::Init (const WarFactoryGameObjDef &definition)
  234. {
  235. VehicleFactoryGameObj::Init (definition);
  236. return ;
  237. }
  238. ////////////////////////////////////////////////////////////////
  239. //
  240. // Get_Definition
  241. //
  242. ////////////////////////////////////////////////////////////////
  243. const WarFactoryGameObjDef &
  244. WarFactoryGameObj::Get_Definition (void) const
  245. {
  246. return (const WarFactoryGameObjDef &)BaseGameObj::Get_Definition ();
  247. }
  248. ////////////////////////////////////////////////////////////////
  249. //
  250. // Save
  251. //
  252. ////////////////////////////////////////////////////////////////
  253. bool
  254. WarFactoryGameObj::Save (ChunkSaveClass &csave)
  255. {
  256. csave.Begin_Chunk (CHUNKID_PARENT);
  257. VehicleFactoryGameObj::Save (csave);
  258. csave.End_Chunk ();
  259. csave.Begin_Chunk (CHUNKID_VARIABLES);
  260. csave.End_Chunk ();
  261. return true;
  262. }
  263. ////////////////////////////////////////////////////////////////
  264. //
  265. // Load
  266. //
  267. ////////////////////////////////////////////////////////////////
  268. bool
  269. WarFactoryGameObj::Load (ChunkLoadClass &cload)
  270. {
  271. while (cload.Open_Chunk ()) {
  272. switch (cload.Cur_Chunk_ID ()) {
  273. case CHUNKID_PARENT:
  274. VehicleFactoryGameObj::Load (cload);
  275. break;
  276. case CHUNKID_VARIABLES:
  277. Load_Variables (cload);
  278. break;
  279. default:
  280. Debug_Say (("Unrecognized WarFactory chunkID\n"));
  281. break;
  282. }
  283. cload.Close_Chunk();
  284. }
  285. return true;
  286. }
  287. ////////////////////////////////////////////////////////////////
  288. //
  289. // Load_Variables
  290. //
  291. ////////////////////////////////////////////////////////////////
  292. void
  293. WarFactoryGameObj::Load_Variables (ChunkLoadClass &cload)
  294. {
  295. while (cload.Open_Micro_Chunk ()) {
  296. /*switch (cload.Cur_Micro_Chunk_ID ())
  297. {
  298. default:
  299. Debug_Say (("Unrecognized WarFactory Variable chunkID\n"));
  300. break;
  301. }*/
  302. cload.Close_Micro_Chunk();
  303. }
  304. return ;
  305. }
  306. ////////////////////////////////////////////////////////////////
  307. //
  308. // CnC_Initialize
  309. //
  310. ////////////////////////////////////////////////////////////////
  311. void
  312. WarFactoryGameObj::CnC_Initialize (BaseControllerClass *base)
  313. {
  314. VehicleFactoryGameObj::CnC_Initialize (base);
  315. //
  316. // Get the building's "position"
  317. //
  318. Vector3 pos;
  319. Get_Position (&pos);
  320. //
  321. // Find the closest creation static anim phys
  322. //
  323. float closest2 = 99999.0F;
  324. RefPhysListIterator iterator = PhysicsSceneClass::Get_Instance()->Get_Static_Object_Iterator ();
  325. for (iterator.First (); !iterator.Is_Done (); iterator.Next ()) {
  326. StaticAnimPhysClass *anim_phys_obj = iterator.Peek_Obj ()->As_StaticAnimPhysClass ();
  327. //
  328. // Is this a vehicle creation static anim phys?
  329. //
  330. if (anim_phys_obj != NULL && anim_phys_obj->Peek_Model () != NULL) {
  331. StringClass name = anim_phys_obj->Peek_Model ()->Get_Name ();
  332. ::strupr (name.Peek_Buffer ());
  333. if (::strstr (name, "WEP#CONSTRUCT") != NULL) {
  334. //
  335. // Is this the closest one we've found so far?
  336. //
  337. Vector3 anim_pos;
  338. anim_phys_obj->Get_Position (&anim_pos);
  339. float dist2 = (anim_pos - pos).Length2 ();
  340. if (dist2 < closest2) {
  341. closest2 = dist2;
  342. CreationAnimationID = anim_phys_obj->Get_ID ();
  343. }
  344. }
  345. }
  346. }
  347. return ;
  348. }
  349. ////////////////////////////////////////////////////////////////
  350. //
  351. // Think
  352. //
  353. ////////////////////////////////////////////////////////////////
  354. void
  355. WarFactoryGameObj::Think (void)
  356. {
  357. WWPROFILE ("WarFactory Think");
  358. //
  359. // Are we currently building a vehicle?
  360. //
  361. if (IsDestroyed == false && GeneratingVehicleID != 0) {
  362. if (CreationFinishedTimer > UNITIALIZED_TIMER) {
  363. CreationFinishedTimer -= TimeManager::Get_Frame_Seconds ();
  364. if (CreationFinishedTimer <= 0) {
  365. CreationFinishedTimer = UNITIALIZED_TIMER;
  366. //
  367. // Generate the current vehicle
  368. //
  369. VehicleGameObj *vehicle = Create_Vehicle ();
  370. if (vehicle != NULL) {
  371. Matrix3D new_tm = CreationTM;
  372. //
  373. // Adjust the vehicle's transform to ensure its
  374. // not embedded in the ground
  375. //
  376. if (vehicle->Peek_Vehicle_Phys() != NULL) {
  377. float height = vehicle->Peek_Vehicle_Phys()->Compute_Approximate_Ride_Height();
  378. new_tm.Translate(0.0f,0.0f,height);
  379. vehicle->Set_Transform(new_tm);
  380. }
  381. //
  382. // Lock the vehicle to anyone but the purchaser
  383. //
  384. if (Purchaser != NULL) {
  385. vehicle->Lock_Vehicle(Purchaser,WARFACTORY_LOCK_TIME);
  386. }
  387. //
  388. // Destroy any game object that's in our way
  389. //
  390. Destroy_Blocking_Objects ();
  391. // Tell the vehicle to drive to one of the delivery points
  392. Deliver_Vehicle();
  393. }
  394. //
  395. // Now play the creation animation backwards to restore the
  396. // state of the factory
  397. //
  398. Play_Creation_Animation (false);
  399. }
  400. }
  401. }
  402. VehicleFactoryGameObj::Think ();
  403. return ;
  404. }
  405. ////////////////////////////////////////////////////////////////
  406. //
  407. // Play_Creation_Animation
  408. //
  409. ////////////////////////////////////////////////////////////////
  410. void
  411. WarFactoryGameObj::Play_Creation_Animation (bool onoff)
  412. {
  413. //
  414. // Lookup the static animation object we need to play
  415. //
  416. StaticPhysClass *static_phys_obj = PhysicsSceneClass::Get_Instance ()->Find_Static_Object (CreationAnimationID);
  417. if (static_phys_obj != NULL) {
  418. StaticAnimPhysClass *anim_phys_obj = static_phys_obj->As_StaticAnimPhysClass ();
  419. if (anim_phys_obj != NULL) {
  420. //
  421. // Configure the animation
  422. //
  423. AnimCollisionManagerClass &anim_mgr = anim_phys_obj->Get_Animation_Manager ();
  424. anim_mgr.Set_Animation_Mode (AnimCollisionManagerClass::ANIMATE_TARGET);
  425. //
  426. // Either play the animation forward or backward
  427. //
  428. if (onoff) {
  429. anim_mgr.Set_Target_Frame_End ();
  430. } else {
  431. anim_mgr.Set_Target_Frame (0);
  432. }
  433. static_phys_obj->Enable_Is_State_Dirty(true);
  434. }
  435. }
  436. return ;
  437. }
  438. ////////////////////////////////////////////////////////////////
  439. //
  440. // Begin_Generation
  441. //
  442. ////////////////////////////////////////////////////////////////
  443. void
  444. WarFactoryGameObj::Begin_Generation (void)
  445. {
  446. Play_Creation_Animation (true);
  447. CreationFinishedTimer = 2.0F;
  448. //
  449. // Lookup the static animation object for the ending animation
  450. //
  451. StaticPhysClass *static_phys_obj = PhysicsSceneClass::Get_Instance ()->Find_Static_Object (CreationAnimationID);
  452. if (static_phys_obj != NULL) {
  453. StaticAnimPhysClass *anim_phys_obj = static_phys_obj->As_StaticAnimPhysClass ();
  454. if (anim_phys_obj != NULL) {
  455. //
  456. // Calculate how long to wait before we start playing the end animations
  457. //
  458. AnimCollisionManagerClass &anim_mgr = anim_phys_obj->Get_Animation_Manager ();
  459. CreationFinishedTimer = anim_mgr.Peek_Animation ()->Get_Total_Time () + 2.0f;
  460. }
  461. }
  462. return ;
  463. }