refinerygameobj.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871
  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/refinerygameobj.cpp $*
  25. * *
  26. * $Author:: Greg_h $*
  27. * *
  28. * $Modtime:: 1/18/02 11:17p $*
  29. * *
  30. * $Revision:: 24 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #include "refinerygameobj.h"
  36. #include "harvester.h"
  37. #include "basecontroller.h"
  38. #include "vehicle.h"
  39. #include "wwhack.h"
  40. #include "simpledefinitionfactory.h"
  41. #include "persistfactory.h"
  42. #include "definitionmgr.h"
  43. #include "combatchunkid.h"
  44. #include "debug.h"
  45. #include "scriptzone.h"
  46. #include "wwprofile.h"
  47. #include "combat.h"
  48. #include "wwaudio.h"
  49. #include "audiblesound.h"
  50. #include "soldier.h"
  51. #include "playertype.h"
  52. //#include "building.h"
  53. ////////////////////////////////////////////////////////////////
  54. // Hacks
  55. ////////////////////////////////////////////////////////////////
  56. DECLARE_FORCE_LINK (Refinery)
  57. ////////////////////////////////////////////////////////////////
  58. // Editable and persist factories
  59. ////////////////////////////////////////////////////////////////
  60. SimplePersistFactoryClass <RefineryGameObjDef, CHUNKID_GAME_OBJECT_DEF_REFINERY> _RefineryGameObjDefPersistFactory;
  61. SimplePersistFactoryClass <RefineryGameObj, CHUNKID_GAME_OBJECT_REFINERY> _RefineryGameObjPersistFactory;
  62. DECLARE_DEFINITION_FACTORY (RefineryGameObjDef, CLASSID_GAME_OBJECT_DEF_REFINERY, "Refinery") _RefineryGameObjDefDefFactory;
  63. ////////////////////////////////////////////////////////////////
  64. // Save/Load constants
  65. ////////////////////////////////////////////////////////////////
  66. enum
  67. {
  68. CHUNKID_DEF_PARENT = 0x02200638,
  69. CHUNKID_DEF_VARIABLES,
  70. MICROCHUNKID_DEF_UNLOAD_TIME = 1,
  71. MICROCHUNKID_DEF_FUNDS_GATHERED,
  72. MICROCHUNKID_DEF_HARVESTER_DEFID,
  73. MICROCHUNKID_DEF_FUNDS_PER_SEC
  74. };
  75. enum
  76. {
  77. CHUNKID_PARENT = 0x0219043,
  78. CHUNKID_VARIABLES,
  79. MICROCHUNKID_TIBERIUM_FIELD = 1,
  80. MICROCHUNKID_HARVESTER,
  81. MICROCHUNKID_IS_HARVESTER_DOCKED,
  82. MICROCHUNKID_UNLOAD_TIMER,
  83. XXXMICROCHUNKID_UNLOAD_DOOR_ID,
  84. MICROCHUNKID_DOCK_TM
  85. };
  86. ////////////////////////////////////////////////////////////////
  87. //
  88. // RefineryGameObjDef
  89. //
  90. ////////////////////////////////////////////////////////////////
  91. RefineryGameObjDef::RefineryGameObjDef (void) :
  92. UnloadTime (0),
  93. FundsGathered (0),
  94. FundsDistributedPerSec (0),
  95. HarvesterDefID (0)
  96. {
  97. //
  98. // Editable support
  99. //
  100. EDITABLE_PARAM (RefineryGameObjDef, ParameterClass::TYPE_FLOAT, UnloadTime);
  101. EDITABLE_PARAM (RefineryGameObjDef, ParameterClass::TYPE_FLOAT, FundsGathered);
  102. EDITABLE_PARAM (RefineryGameObjDef, ParameterClass::TYPE_FLOAT, FundsDistributedPerSec);
  103. #ifdef PARAM_EDITING_ON
  104. GenericDefParameterClass *param = new GenericDefParameterClass (&HarvesterDefID);
  105. param->Set_Class_ID (CLASSID_GAME_OBJECT_DEF_VEHICLE);
  106. param->Set_Name ("Harvester");
  107. GENERIC_EDITABLE_PARAM (RefineryGameObjDef, param)
  108. #endif //PARAM_EDITING_ON
  109. return ;
  110. }
  111. ////////////////////////////////////////////////////////////////
  112. //
  113. // ~RefineryGameObjDef
  114. //
  115. ////////////////////////////////////////////////////////////////
  116. RefineryGameObjDef::~RefineryGameObjDef (void)
  117. {
  118. return ;
  119. }
  120. ////////////////////////////////////////////////////////////////
  121. //
  122. // Get_Class_ID
  123. //
  124. ////////////////////////////////////////////////////////////////
  125. uint32
  126. RefineryGameObjDef::Get_Class_ID (void) const
  127. {
  128. return CLASSID_GAME_OBJECT_DEF_REFINERY;
  129. }
  130. ////////////////////////////////////////////////////////////////
  131. //
  132. // Create
  133. //
  134. ////////////////////////////////////////////////////////////////
  135. PersistClass *
  136. RefineryGameObjDef::Create (void) const
  137. {
  138. RefineryGameObj *building = new RefineryGameObj;
  139. building->Init (*this);
  140. return building;
  141. }
  142. ////////////////////////////////////////////////////////////////
  143. //
  144. // Create
  145. //
  146. ////////////////////////////////////////////////////////////////
  147. bool
  148. RefineryGameObjDef::Save (ChunkSaveClass &csave)
  149. {
  150. csave.Begin_Chunk (CHUNKID_DEF_PARENT);
  151. BuildingGameObjDef::Save (csave);
  152. csave.End_Chunk ();
  153. csave.Begin_Chunk (CHUNKID_DEF_VARIABLES);
  154. WRITE_MICRO_CHUNK (csave, MICROCHUNKID_DEF_UNLOAD_TIME, UnloadTime);
  155. WRITE_MICRO_CHUNK (csave, MICROCHUNKID_DEF_FUNDS_GATHERED, FundsGathered);
  156. WRITE_MICRO_CHUNK (csave, MICROCHUNKID_DEF_FUNDS_PER_SEC, FundsDistributedPerSec);
  157. WRITE_MICRO_CHUNK (csave, MICROCHUNKID_DEF_HARVESTER_DEFID, HarvesterDefID);
  158. csave.End_Chunk ();
  159. return true;
  160. }
  161. ////////////////////////////////////////////////////////////////
  162. //
  163. // Load
  164. //
  165. ////////////////////////////////////////////////////////////////
  166. bool
  167. RefineryGameObjDef::Load (ChunkLoadClass &cload)
  168. {
  169. while (cload.Open_Chunk ())
  170. {
  171. switch (cload.Cur_Chunk_ID ())
  172. {
  173. case CHUNKID_DEF_PARENT:
  174. BuildingGameObjDef::Load (cload);
  175. break;
  176. case CHUNKID_DEF_VARIABLES:
  177. Load_Variables (cload);
  178. break;
  179. default:
  180. Debug_Say (("Unrecognized Refinery Def chunkID\n"));
  181. break;
  182. }
  183. cload.Close_Chunk ();
  184. }
  185. return true;
  186. }
  187. ////////////////////////////////////////////////////////////////
  188. //
  189. // Load_Variables
  190. //
  191. ////////////////////////////////////////////////////////////////
  192. void
  193. RefineryGameObjDef::Load_Variables (ChunkLoadClass &cload)
  194. {
  195. while (cload.Open_Micro_Chunk ()) {
  196. switch (cload.Cur_Micro_Chunk_ID ())
  197. {
  198. READ_MICRO_CHUNK (cload, MICROCHUNKID_DEF_UNLOAD_TIME, UnloadTime);
  199. READ_MICRO_CHUNK (cload, MICROCHUNKID_DEF_FUNDS_GATHERED, FundsGathered);
  200. READ_MICRO_CHUNK (cload, MICROCHUNKID_DEF_FUNDS_PER_SEC, FundsDistributedPerSec);
  201. READ_MICRO_CHUNK (cload, MICROCHUNKID_DEF_HARVESTER_DEFID, HarvesterDefID);
  202. default:
  203. Debug_Say (("Unrecognized Refinery Def Variable chunkID\n"));
  204. break;
  205. }
  206. cload.Close_Micro_Chunk();
  207. }
  208. return ;
  209. }
  210. ////////////////////////////////////////////////////////////////
  211. //
  212. // Get_Factory
  213. //
  214. ////////////////////////////////////////////////////////////////
  215. const PersistFactoryClass &
  216. RefineryGameObjDef::Get_Factory (void) const
  217. {
  218. return _RefineryGameObjDefPersistFactory;
  219. }
  220. ////////////////////////////////////////////////////////////////
  221. //
  222. // RefineryGameObj
  223. //
  224. ////////////////////////////////////////////////////////////////
  225. RefineryGameObj::RefineryGameObj (void) :
  226. IsHarvesterDocked (false),
  227. Harvester (NULL),
  228. UnloadAnimationID (0),
  229. UnloadTimer (0),
  230. DistributionTimer (0),
  231. FundsPerSecond (0),
  232. TotalFunds (0),
  233. DockTM (1),
  234. TiberiumField (Vector3 (0, 0, 0), Vector3 (0, 0, 0))
  235. {
  236. WWASSERT(WWAudioClass::Get_Instance() != NULL);
  237. MoneyTrickleSound = WWAudioClass::Get_Instance()->Create_Sound("Money_Trickle");
  238. return ;
  239. }
  240. ////////////////////////////////////////////////////////////////
  241. //
  242. // ~RefineryGameObj
  243. //
  244. ////////////////////////////////////////////////////////////////
  245. RefineryGameObj::~RefineryGameObj (void)
  246. {
  247. if (MoneyTrickleSound != NULL) {
  248. MoneyTrickleSound->Stop();
  249. REF_PTR_RELEASE(MoneyTrickleSound);
  250. }
  251. return ;
  252. }
  253. ////////////////////////////////////////////////////////////////
  254. //
  255. // Get_Factory
  256. //
  257. ////////////////////////////////////////////////////////////////
  258. const PersistFactoryClass &
  259. RefineryGameObj::Get_Factory (void) const
  260. {
  261. return _RefineryGameObjPersistFactory;
  262. }
  263. ////////////////////////////////////////////////////////////////
  264. //
  265. // Init
  266. //
  267. ////////////////////////////////////////////////////////////////
  268. void
  269. RefineryGameObj::Init (void)
  270. {
  271. Init (Get_Definition ());
  272. return ;
  273. }
  274. ////////////////////////////////////////////////////////////////
  275. //
  276. // Init
  277. //
  278. ////////////////////////////////////////////////////////////////
  279. void
  280. RefineryGameObj::Init (const RefineryGameObjDef &definition)
  281. {
  282. BuildingGameObj::Init (definition);
  283. return ;
  284. }
  285. ////////////////////////////////////////////////////////////////
  286. //
  287. // Get_Definition
  288. //
  289. ////////////////////////////////////////////////////////////////
  290. const RefineryGameObjDef &
  291. RefineryGameObj::Get_Definition (void) const
  292. {
  293. return (const RefineryGameObjDef &)BaseGameObj::Get_Definition ();
  294. }
  295. ////////////////////////////////////////////////////////////////
  296. //
  297. // Save
  298. //
  299. ////////////////////////////////////////////////////////////////
  300. bool
  301. RefineryGameObj::Save (ChunkSaveClass &csave)
  302. {
  303. csave.Begin_Chunk (CHUNKID_PARENT);
  304. BuildingGameObj::Save (csave);
  305. csave.End_Chunk ();
  306. csave.Begin_Chunk (CHUNKID_VARIABLES);
  307. WRITE_MICRO_CHUNK (csave, MICROCHUNKID_TIBERIUM_FIELD, TiberiumField);
  308. WRITE_MICRO_CHUNK (csave, MICROCHUNKID_IS_HARVESTER_DOCKED, IsHarvesterDocked);
  309. WRITE_MICRO_CHUNK (csave, MICROCHUNKID_UNLOAD_TIMER, UnloadTimer);
  310. WRITE_MICRO_CHUNK (csave, MICROCHUNKID_DOCK_TM, DockTM);
  311. csave.End_Chunk ();
  312. return true;
  313. }
  314. ////////////////////////////////////////////////////////////////
  315. //
  316. // Load
  317. //
  318. ////////////////////////////////////////////////////////////////
  319. bool
  320. RefineryGameObj::Load (ChunkLoadClass &cload)
  321. {
  322. while (cload.Open_Chunk ()) {
  323. switch (cload.Cur_Chunk_ID ()) {
  324. case CHUNKID_PARENT:
  325. BuildingGameObj::Load (cload);
  326. break;
  327. case CHUNKID_VARIABLES:
  328. Load_Variables (cload);
  329. break;
  330. default:
  331. Debug_Say (("Unrecognized Refinery chunkID\n"));
  332. break;
  333. }
  334. cload.Close_Chunk();
  335. }
  336. return true;
  337. }
  338. ////////////////////////////////////////////////////////////////
  339. //
  340. // Load_Variables
  341. //
  342. ////////////////////////////////////////////////////////////////
  343. void
  344. RefineryGameObj::Load_Variables (ChunkLoadClass &cload)
  345. {
  346. while (cload.Open_Micro_Chunk ()) {
  347. switch (cload.Cur_Micro_Chunk_ID ())
  348. {
  349. READ_MICRO_CHUNK (cload, MICROCHUNKID_TIBERIUM_FIELD, TiberiumField);
  350. READ_MICRO_CHUNK (cload, MICROCHUNKID_IS_HARVESTER_DOCKED, IsHarvesterDocked);
  351. READ_MICRO_CHUNK (cload, MICROCHUNKID_UNLOAD_TIMER, UnloadTimer);
  352. READ_MICRO_CHUNK (cload, MICROCHUNKID_DOCK_TM, DockTM);
  353. default:
  354. Debug_Say (("Unrecognized Refinery Variable chunkID\n"));
  355. break;
  356. }
  357. cload.Close_Micro_Chunk();
  358. }
  359. return ;
  360. }
  361. ////////////////////////////////////////////////////////////////
  362. //
  363. // CnC_Initialize
  364. //
  365. ////////////////////////////////////////////////////////////////
  366. void
  367. RefineryGameObj::CnC_Initialize (BaseControllerClass *base)
  368. {
  369. BuildingGameObj::CnC_Initialize (base);
  370. //
  371. // Get the building's "position"
  372. //
  373. Vector3 pos;
  374. Get_Position (&pos);
  375. //
  376. // Try to find the appropriate zone for the team
  377. //
  378. ScriptZoneGameObj *zone = NULL;
  379. if (Get_Player_Type () == PLAYERTYPE_GDI) {
  380. zone = ScriptZoneGameObj::Find_Closest_Zone (pos, ZoneConstants::TYPE_GDI_TIB_FIELD);
  381. } else {
  382. zone = ScriptZoneGameObj::Find_Closest_Zone (pos, ZoneConstants::TYPE_NOD_TIB_FIELD);
  383. }
  384. //
  385. // If we can't find a "team" tiberium field, then just find the closest.
  386. //
  387. if (zone == NULL) {
  388. zone = ScriptZoneGameObj::Find_Closest_Zone (pos, ZoneConstants::TYPE_TIBERIUM_FIELD);
  389. }
  390. if (zone != NULL) {
  391. TiberiumField = zone->Get_Bounding_Box ();
  392. //
  393. // Get rid of the zone (if the game doesn't need it anymore)
  394. //
  395. if (zone->Get_Observers ().Count () == 0) {
  396. zone->Set_Delete_Pending();
  397. }
  398. }
  399. //
  400. // Find the closest unloading static anim phys
  401. //
  402. float closest2 = 99999.0F;
  403. RefPhysListIterator iterator = PhysicsSceneClass::Get_Instance()->Get_Static_Object_Iterator ();
  404. for (iterator.First (); !iterator.Is_Done (); iterator.Next ()) {
  405. StaticAnimPhysClass *anim_phys_obj = iterator.Peek_Obj ()->As_StaticAnimPhysClass ();
  406. //
  407. // Is this an unloading static anim phys?
  408. //
  409. if (anim_phys_obj != NULL && anim_phys_obj->Peek_Model () != NULL) {
  410. StringClass name = anim_phys_obj->Peek_Model ()->Get_Name ();
  411. ::strupr (name.Peek_Buffer ());
  412. if (::strstr (name, "REF_TIB_DUMP") != NULL) {
  413. //
  414. // Is this the closest one we've found so far?
  415. //
  416. Vector3 anim_pos;
  417. anim_phys_obj->Get_Position (&anim_pos);
  418. float dist2 = (anim_pos - pos).Length2 ();
  419. if (dist2 < closest2) {
  420. closest2 = dist2;
  421. UnloadAnimationID = anim_phys_obj->Get_ID ();
  422. }
  423. }
  424. }
  425. }
  426. return ;
  427. }
  428. ////////////////////////////////////////////////////////////////
  429. //
  430. // Think
  431. //
  432. ////////////////////////////////////////////////////////////////
  433. void
  434. RefineryGameObj::Think (void)
  435. {
  436. WWPROFILE ("Refinery Think");
  437. Manage_Money_Trickle_Sound();
  438. if (IsDestroyed == false && CombatManager::I_Am_Server ()) {
  439. //
  440. // Create a new harvester (if necessary)
  441. //
  442. if ( (Harvester == NULL) &&
  443. (DefenseObject.Get_Health() > 0.0f) &&
  444. (CombatManager::Is_Gameplay_Permitted()) )
  445. {
  446. Set_Is_Harvester_Docked(false);
  447. BaseController->Request_Harvester (Get_Definition ().HarvesterDefID);
  448. } else if (IsHarvesterDocked) {
  449. //
  450. // Calculate how long the building was operating during the last frame
  451. //
  452. float logical_seconds = TimeManager::Get_Frame_Seconds ();
  453. logical_seconds /= BaseController->Get_Operation_Time_Factor ();
  454. //
  455. // Deposit the money in each team-member's account
  456. //
  457. int funds = int(logical_seconds * FundsPerSecond);
  458. funds = min (funds, (int)TotalFunds);
  459. if (funds > 0) {
  460. TotalFunds -= (float)funds;
  461. //
  462. // TSS100401
  463. // Requested to give the Total Funds to all players, no division .
  464. //
  465. //BaseController->Deposit_Funds (funds);
  466. BaseController->Distribute_Funds_To_Each_Teammate (funds);
  467. }
  468. //
  469. // Is it time to send the harvester off again?
  470. //
  471. UnloadTimer -= logical_seconds;
  472. if (UnloadTimer <= 0) {
  473. //
  474. // Deposit any remaining cash
  475. //
  476. if (TotalFunds > 0) {
  477. //
  478. // TSS100401
  479. // Requested to give the Total Funds to all players, no division .
  480. //
  481. //BaseController->Deposit_Funds (TotalFunds);
  482. BaseController->Distribute_Funds_To_Each_Teammate (TotalFunds);
  483. TotalFunds = 0;
  484. }
  485. //
  486. // Send the harvester off to the tiberium field
  487. //
  488. Harvester->Go_Harvest ();
  489. Set_Is_Harvester_Docked(false);
  490. Play_Unloading_Animation (false);
  491. }
  492. }
  493. //
  494. // Distrubute a little money to each player
  495. //
  496. if (CombatManager::Is_Gameplay_Permitted() && IsHarvesterDocked == false) {
  497. //
  498. // Only do this once per second
  499. //
  500. DistributionTimer -= TimeManager::Get_Frame_Seconds ();
  501. if (DistributionTimer <= 0) {
  502. DistributionTimer = 1.0F;
  503. //
  504. // Calculate how much money to give each player on the team...
  505. //
  506. float funds = Get_Definition ().FundsDistributedPerSec;
  507. funds = funds / BaseController->Get_Operation_Time_Factor ();
  508. //
  509. // Deposit this money in their account
  510. //
  511. BaseController->Distribute_Funds_To_Each_Teammate ((int)funds);
  512. }
  513. }
  514. //
  515. // Allow the harvester to do some per-frame processing
  516. //
  517. if (Harvester != NULL) {
  518. Harvester->Think ();
  519. }
  520. }
  521. BuildingGameObj::Think ();
  522. return ;
  523. }
  524. ////////////////////////////////////////////////////////////////
  525. //
  526. // Manage_Money_Trickle_Sound
  527. //
  528. ////////////////////////////////////////////////////////////////
  529. void
  530. RefineryGameObj::Manage_Money_Trickle_Sound (void)
  531. {
  532. if (MoneyTrickleSound != NULL) {
  533. bool same_team = false;
  534. if (COMBAT_STAR != NULL && BaseController != NULL) {
  535. same_team = (COMBAT_STAR->Get_Player_Type() == BaseController->Get_Player_Type());
  536. }
  537. if (same_team) {
  538. bool play_sound =
  539. !IsDestroyed &&
  540. (DefenseObject.Get_Health() > 0.0f) &&
  541. IsHarvesterDocked;
  542. if (play_sound) {
  543. if (!MoneyTrickleSound->Is_Playing()) {
  544. MoneyTrickleSound->Play();
  545. }
  546. } else {
  547. if (MoneyTrickleSound->Is_Playing()) {
  548. MoneyTrickleSound->Stop();
  549. }
  550. }
  551. }
  552. }
  553. /*
  554. if (MoneyTrickleSound != NULL && MoneyTrickleSound->Is_Playing()) {
  555. Debug_Say(("MoneyTrickleSound Playing\n"));
  556. }
  557. /**/
  558. }
  559. ////////////////////////////////////////////////////////////////
  560. //
  561. // Play_Unloading_Animation
  562. //
  563. ////////////////////////////////////////////////////////////////
  564. void
  565. RefineryGameObj::Play_Unloading_Animation (bool onoff)
  566. {
  567. //
  568. // Lookup the static animation object we need to play
  569. //
  570. StaticPhysClass *static_phys_obj = PhysicsSceneClass::Get_Instance ()->Find_Static_Object (UnloadAnimationID);
  571. if (static_phys_obj != NULL) {
  572. StaticAnimPhysClass *anim_phys_obj = static_phys_obj->As_StaticAnimPhysClass ();
  573. if (anim_phys_obj != NULL) {
  574. //
  575. // Configure the animation
  576. //
  577. AnimCollisionManagerClass &anim_mgr = anim_phys_obj->Get_Animation_Manager ();
  578. anim_mgr.Set_Animation_Mode (AnimCollisionManagerClass::ANIMATE_TARGET);
  579. //
  580. // Either play the animation forward or backward
  581. //
  582. if (onoff) {
  583. anim_mgr.Set_Target_Frame_End ();
  584. } else {
  585. anim_mgr.Set_Target_Frame (0);
  586. }
  587. }
  588. }
  589. return ;
  590. }
  591. ////////////////////////////////////////////////////////////////
  592. //
  593. // On_Destroyed
  594. //
  595. ////////////////////////////////////////////////////////////////
  596. void
  597. RefineryGameObj::On_Destroyed (void)
  598. {
  599. BuildingGameObj::On_Destroyed ();
  600. //
  601. // Kill the harvester
  602. //
  603. if (Harvester != NULL) {
  604. VehicleGameObj * harvy = Get_Harvester_Vehicle();
  605. if (harvy != NULL) {
  606. OffenseObjectClass default_damager;
  607. harvy->Completely_Damaged(default_damager);
  608. }
  609. }
  610. //
  611. // Make sure we shut off the tiberium docking animation
  612. //
  613. Play_Unloading_Animation (false);
  614. return ;
  615. }
  616. ////////////////////////////////////////////////////////////////
  617. //
  618. // Set_Harvester_Vehicle
  619. //
  620. ////////////////////////////////////////////////////////////////
  621. void
  622. RefineryGameObj::Set_Harvester_Vehicle (VehicleGameObj *harvester)
  623. {
  624. //
  625. // Calculate what the dock location and entrance should be
  626. //
  627. Vector3 dock_location = DockTM.Get_Translation ();
  628. Vector3 dock_entrance = dock_location + (DockTM.Get_X_Vector () * 10.0F);
  629. //
  630. // Add some "harvesting" logic to the vehicle
  631. //
  632. Harvester = new HarvesterClass;
  633. Harvester->Set_Refinery (this);
  634. Harvester->Set_Dock_Location (dock_location);
  635. Harvester->Set_Dock_Entrance (dock_entrance);
  636. Harvester->Set_Tiberium_Region (TiberiumField);
  637. Harvester->Set_Harvest_Anim ("V_NOD_HARVESTER.V_NOD_HARVESTER");
  638. harvester->Add_Observer (Harvester);
  639. Harvester->Initialize ();
  640. return ;
  641. }
  642. ////////////////////////////////////////////////////////////////
  643. //
  644. // Get_Harvester_Vehicle
  645. //
  646. ////////////////////////////////////////////////////////////////
  647. VehicleGameObj *
  648. RefineryGameObj::Get_Harvester_Vehicle (void)
  649. {
  650. VehicleGameObj *vehicle = NULL;
  651. //
  652. // Dig the vehicle game object out of the harvester
  653. //
  654. if (Harvester != NULL) {
  655. vehicle = Harvester->Get_Vehicle ();
  656. }
  657. return vehicle;
  658. }
  659. void RefineryGameObj::On_Harvester_Damaged(VehicleGameObj* harvester)
  660. {
  661. if (BaseController) {
  662. BaseController->On_Vehicle_Damaged(harvester);
  663. }
  664. }
  665. void RefineryGameObj::On_Harvester_Destroyed(VehicleGameObj* harvester)
  666. {
  667. if (BaseController) {
  668. BaseController->On_Vehicle_Destroyed(harvester);
  669. }
  670. }
  671. ////////////////////////////////////////////////////////////////
  672. //
  673. // On_Harvester_Docked
  674. //
  675. ////////////////////////////////////////////////////////////////
  676. void
  677. RefineryGameObj::On_Harvester_Docked (void)
  678. {
  679. //
  680. // Initialize the unload settings from the definition
  681. //
  682. UnloadTimer = Get_Definition ().UnloadTime;
  683. TotalFunds = Get_Definition ().FundsGathered;
  684. FundsPerSecond = TotalFunds / UnloadTimer;
  685. Set_Is_Harvester_Docked(true);
  686. return ;
  687. }
  688. /////////////////////////////////////////////////////////////////////////////
  689. //
  690. // Set_Is_Harvester_Docked
  691. //
  692. /////////////////////////////////////////////////////////////////////////////
  693. void
  694. RefineryGameObj::Set_Is_Harvester_Docked (bool flag)
  695. {
  696. IsHarvesterDocked = flag;
  697. //
  698. // Mark the object as dirty so it's state will be mirrored on the client
  699. //
  700. if (CombatManager::I_Am_Server ()) {
  701. Set_Object_Dirty_Bit (NetworkObjectClass::BIT_RARE, true);
  702. }
  703. }
  704. /////////////////////////////////////////////////////////////////////////////
  705. //
  706. // Export_Rare
  707. //
  708. /////////////////////////////////////////////////////////////////////////////
  709. void
  710. RefineryGameObj::Export_Rare (BitStreamClass &packet)
  711. {
  712. BuildingGameObj::Export_Rare (packet);
  713. //
  714. // Transmit the state information
  715. //
  716. packet.Add (IsHarvesterDocked);
  717. }
  718. /////////////////////////////////////////////////////////////////////////////
  719. //
  720. // Import_Rare
  721. //
  722. /////////////////////////////////////////////////////////////////////////////
  723. void
  724. RefineryGameObj::Import_Rare (BitStreamClass &packet)
  725. {
  726. BuildingGameObj::Import_Rare (packet);
  727. packet.Get (IsHarvesterDocked);
  728. }