staticnetworkobject.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913
  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/staticnetworkobject.cpp $*
  25. * *
  26. * $Author:: Steve_t $*
  27. * *
  28. * $Modtime:: 1/15/02 1:02p $*
  29. * *
  30. * $Revision:: 15 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #include "staticnetworkobject.h"
  36. #include "staticanimphys.h"
  37. #include "doors.h"
  38. #include "elevator.h"
  39. #include "bitpackids.h"
  40. #include "combat.h"
  41. #include "damageablestaticphys.h"
  42. #include "explosion.h"
  43. #include "vistable.h"
  44. #include "networkobjectmgr.h"
  45. #include "apppackettypes.h"
  46. ////////////////////////////////////////////////////////////////
  47. // Forward declarations
  48. ////////////////////////////////////////////////////////////////
  49. DynamicVectorClass<StaticNetworkObjectClass *> StaticNetworkObjectClass::StaticNetworkObjectList;
  50. ////////////////////////////////////////////////////////////////
  51. //
  52. // StaticNetworkObjectClass
  53. //
  54. ////////////////////////////////////////////////////////////////
  55. StaticNetworkObjectClass::StaticNetworkObjectClass (void) :
  56. PhysObj (NULL),
  57. AnimationMode (0),
  58. LoopStart (0),
  59. LoopEnd (0),
  60. CurrFrame (0),
  61. TargetFrame (0)
  62. {
  63. //
  64. // Add ourselves to the master list
  65. //
  66. StaticNetworkObjectList.Add (this);
  67. //
  68. // Make sure we don't try to create the object on the client
  69. //
  70. //TSS2001d Clear_Object_Dirty_Bits ();
  71. Set_Object_Dirty_Bit (BIT_RARE, true);
  72. Set_App_Packet_Type(APPPACKETTYPE_STATIC);
  73. }
  74. ////////////////////////////////////////////////////////////////
  75. //
  76. // ~StaticNetworkObjectClass
  77. //
  78. ////////////////////////////////////////////////////////////////
  79. StaticNetworkObjectClass::~StaticNetworkObjectClass (void)
  80. {
  81. REF_PTR_RELEASE (PhysObj);
  82. //
  83. // Remove ourselves from the master list
  84. //
  85. int index = StaticNetworkObjectList.ID (this);
  86. if (index != -1) {
  87. StaticNetworkObjectList.Delete (index);
  88. }
  89. return ;
  90. }
  91. ////////////////////////////////////////////////////////////////
  92. //
  93. // Get_World_Position
  94. //
  95. ////////////////////////////////////////////////////////////////
  96. bool
  97. StaticNetworkObjectClass::Get_World_Position (Vector3 &pos) const
  98. {
  99. bool retval = false;
  100. //
  101. // Return the physic object's position
  102. //
  103. if (PhysObj != NULL) {
  104. PhysObj->Get_Position (&pos);
  105. retval = true;
  106. }
  107. return retval;
  108. }
  109. ////////////////////////////////////////////////////////////////
  110. //
  111. // Get_Vis_ID - return the vis ID for this object
  112. //
  113. ////////////////////////////////////////////////////////////////
  114. int
  115. StaticNetworkObjectClass::Get_Vis_ID (void)
  116. {
  117. if (PhysObj != NULL) {
  118. return PhysObj->Get_Vis_Object_ID ();
  119. }
  120. return -1;
  121. }
  122. ////////////////////////////////////////////////////////////////
  123. //
  124. // Initialize
  125. //
  126. ////////////////////////////////////////////////////////////////
  127. void
  128. StaticNetworkObjectClass::Initialize (StaticAnimPhysClass *phys_obj)
  129. {
  130. REF_PTR_SET (PhysObj, phys_obj);
  131. //
  132. // Update the network ID
  133. //
  134. int network_id = 0;
  135. if (PhysObj != NULL) {
  136. network_id = PhysObj->Get_ID ();
  137. //
  138. // Copy the object's state
  139. //
  140. AnimCollisionManagerClass &anim_mgr = PhysObj->Get_Animation_Manager ();
  141. AnimationMode = anim_mgr.Get_Animation_Mode ();
  142. CurrFrame = anim_mgr.Get_Current_Frame ();
  143. TargetFrame = anim_mgr.Get_Target_Frame ();
  144. LoopStart = anim_mgr.Get_Loop_Start ();
  145. LoopEnd = anim_mgr.Get_Loop_End ();
  146. }
  147. //WWASSERT(network_id >= NETID_STATIC_OBJECT_MIN && network_id <= NETID_STATIC_OBJECT_MAX);
  148. Set_Network_ID (network_id);
  149. return ;
  150. }
  151. ////////////////////////////////////////////////////////////////
  152. //
  153. // Network_Think
  154. //
  155. ////////////////////////////////////////////////////////////////
  156. void
  157. StaticNetworkObjectClass::Network_Think (void)
  158. {
  159. NetworkObjectClass::Network_Think ();
  160. if (PhysObj != NULL) {
  161. AnimCollisionManagerClass &anim_mgr = PhysObj->Get_Animation_Manager ();
  162. //
  163. // Set the dirty bit if the state has changed
  164. //
  165. if ( AnimationMode != anim_mgr.Get_Animation_Mode () ||
  166. TargetFrame != anim_mgr.Get_Target_Frame () ||
  167. LoopStart != anim_mgr.Get_Loop_Start () ||
  168. LoopEnd != anim_mgr.Get_Loop_End ())
  169. {
  170. AnimationMode = anim_mgr.Get_Animation_Mode ();
  171. CurrFrame = anim_mgr.Get_Current_Frame ();
  172. TargetFrame = anim_mgr.Get_Target_Frame ();
  173. LoopStart = anim_mgr.Get_Loop_Start ();
  174. LoopEnd = anim_mgr.Get_Loop_End ();
  175. Set_Object_Dirty_Bit (BIT_RARE, true);
  176. }
  177. }
  178. return ;
  179. }
  180. /*
  181. ////////////////////////////////////////////////////////////////////////////
  182. //
  183. // Compute_Object_Priority - TSS092201
  184. //
  185. /////////////////////////////////////////////////////////////////////////////
  186. float
  187. StaticNetworkObjectClass::Compute_Object_Priority (int client_id, const Vector3 &client_pos)
  188. {
  189. float priority = 1.0F;
  190. if (Get_Object_Dirty_Bit (client_id, BIT_RARE) == false) {
  191. priority = NetworkObjectClass::Compute_Object_Priority (client_id, client_pos);
  192. }
  193. //
  194. // Priority value is cached, update the cached value.
  195. //
  196. Set_Cached_Priority(priority);
  197. return priority;
  198. }
  199. */
  200. ////////////////////////////////////////////////////////////////
  201. //
  202. // Generate_Static_Network_Objects
  203. //
  204. ////////////////////////////////////////////////////////////////
  205. void
  206. StaticNetworkObjectClass::Generate_Static_Network_Objects (void)
  207. {
  208. RefPhysListIterator iterator = COMBAT_SCENE->Get_Static_Anim_Object_Iterator ();
  209. //
  210. // Loop over all the static anim objects in the world
  211. //
  212. for (iterator.First (); iterator.Is_Done () == false; iterator.Next ()) {
  213. StaticAnimPhysClass *phys_obj = (StaticAnimPhysClass *)iterator.Peek_Obj ();
  214. if (phys_obj != NULL) {
  215. //
  216. // Make a new network object for this phys obj
  217. //
  218. StaticNetworkObjectClass *network_obj = NULL;
  219. if (phys_obj->As_ElevatorPhysClass () != NULL) {
  220. network_obj = new ElevatorNetworkObjectClass;
  221. } else if (phys_obj->As_DoorPhysClass () != NULL) {
  222. network_obj = new DoorNetworkObjectClass;
  223. } else if (phys_obj->As_DamageableStaticPhysClass () != NULL) {
  224. network_obj = new DSAPONetworkObjectClass;
  225. } else {
  226. network_obj = new StaticNetworkObjectClass;
  227. }
  228. //
  229. // Initialize the network object
  230. //
  231. network_obj->Initialize (phys_obj);
  232. }
  233. }
  234. return ;
  235. }
  236. ////////////////////////////////////////////////////////////////
  237. //
  238. // Free_Static_Network_Objects
  239. //
  240. ////////////////////////////////////////////////////////////////
  241. void
  242. StaticNetworkObjectClass::Free_Static_Network_Objects (void)
  243. {
  244. DynamicVectorClass<StaticNetworkObjectClass *> temp_list = StaticNetworkObjectList;
  245. //
  246. // Loop over and free all the entries
  247. //
  248. for (int index = temp_list.Count () - 1; index >= 0; index --) {
  249. StaticNetworkObjectClass *object = temp_list[index];
  250. if (object != NULL) {
  251. delete object;
  252. }
  253. }
  254. //
  255. // Make sure the list has been completely cleared
  256. //
  257. WWASSERT (StaticNetworkObjectList.Count () == 0);
  258. return ;
  259. }
  260. ////////////////////////////////////////////////////////////////
  261. //
  262. // Import_Rare
  263. //
  264. ////////////////////////////////////////////////////////////////
  265. void
  266. StaticNetworkObjectClass::Import_Rare (BitStreamClass &packet)
  267. {
  268. NetworkObjectClass::Import_Rare (packet);
  269. //
  270. // Read the data
  271. //
  272. packet.Get (AnimationMode);
  273. packet.Get (LoopStart);
  274. packet.Get (LoopEnd);
  275. packet.Get (CurrFrame);
  276. packet.Get (TargetFrame);
  277. if (PhysObj != NULL) {
  278. AnimCollisionManagerClass &anim_mgr = PhysObj->Get_Animation_Manager ();
  279. //
  280. // Set the data
  281. //
  282. anim_mgr.Set_Target_Frame (TargetFrame);
  283. anim_mgr.Set_Current_Frame (CurrFrame);
  284. anim_mgr.Set_Loop_Start (LoopStart);
  285. anim_mgr.Set_Loop_End (LoopEnd);
  286. anim_mgr.Set_Animation_Mode ((AnimCollisionManagerClass::AnimModeType)AnimationMode);
  287. }
  288. return ;
  289. }
  290. ////////////////////////////////////////////////////////////////
  291. //
  292. // Export_Rare
  293. //
  294. ////////////////////////////////////////////////////////////////
  295. void
  296. StaticNetworkObjectClass::Export_Rare (BitStreamClass &packet)
  297. {
  298. NetworkObjectClass::Export_Rare (packet);
  299. //
  300. // Export information about the animation
  301. //
  302. packet.Add (AnimationMode);
  303. packet.Add (LoopStart);
  304. packet.Add (LoopEnd);
  305. packet.Add (CurrFrame);
  306. packet.Add (TargetFrame);
  307. return ;
  308. }
  309. ////////////////////////////////////////////////////////////////
  310. //
  311. // DoorNetworkObjectClass
  312. //
  313. ////////////////////////////////////////////////////////////////
  314. DoorNetworkObjectClass::DoorNetworkObjectClass (void) :
  315. DoorState (0)
  316. {
  317. Set_App_Packet_Type(APPPACKETTYPE_DOOR);
  318. }
  319. ////////////////////////////////////////////////////////////////
  320. //
  321. // Initialize
  322. //
  323. ////////////////////////////////////////////////////////////////
  324. void
  325. DoorNetworkObjectClass::Initialize (StaticAnimPhysClass *phys_obj)
  326. {
  327. StaticNetworkObjectClass::Initialize (phys_obj);
  328. //
  329. // Get a pointer to the door
  330. //
  331. if (PhysObj != NULL) {
  332. DoorPhysClass *door = PhysObj->As_DoorPhysClass ();
  333. if (door != NULL) {
  334. //
  335. // Copy the object's state
  336. //
  337. DoorState = door->State;
  338. Set_Object_Dirty_Bit (BIT_RARE, true);
  339. }
  340. }
  341. return ;
  342. }
  343. ////////////////////////////////////////////////////////////////
  344. //
  345. // Network_Think
  346. //
  347. ////////////////////////////////////////////////////////////////
  348. void
  349. DoorNetworkObjectClass::Network_Think (void)
  350. {
  351. NetworkObjectClass::Network_Think ();
  352. //
  353. // Get a pointer to the door
  354. //
  355. if (PhysObj != NULL) {
  356. DoorPhysClass *door = PhysObj->As_DoorPhysClass ();
  357. if (door != NULL) {
  358. //
  359. // Set the dirty bit if the state has changed
  360. //
  361. if (DoorState != door->State) {
  362. DoorState = door->State;
  363. if (DoorState == STATE_OPENING_DOOR || DoorState == STATE_CLOSING_DOOR || DoorState == STATE_ACCESS_DENIED) {
  364. Set_Object_Dirty_Bit (BIT_RARE, true);
  365. }
  366. }
  367. }
  368. }
  369. return ;
  370. }
  371. ////////////////////////////////////////////////////////////////
  372. //
  373. // Import_Rare
  374. //
  375. ////////////////////////////////////////////////////////////////
  376. void
  377. DoorNetworkObjectClass::Import_Rare (BitStreamClass &packet)
  378. {
  379. //
  380. // Note: As a network optimization, we don't call the base
  381. // class. Doors are now state based and don't need to
  382. // transmit frame numbers.
  383. //
  384. //
  385. // Read the new state
  386. //
  387. packet.Get (DoorState, BITPACK_DOOR_STATE);
  388. //
  389. // Get a pointer to the door
  390. //
  391. if (PhysObj != NULL) {
  392. DoorPhysClass *door = PhysObj->As_DoorPhysClass ();
  393. if (door != NULL) {
  394. //
  395. // Set the new state
  396. //
  397. bool success = door->Set_State (DoorState);
  398. if (!success) {
  399. WWDEBUG_SAY(("DoorNetworkObjectClass::Import_Rare -- Door state changed failed to apply\n"));
  400. }
  401. }
  402. }
  403. return ;
  404. }
  405. ////////////////////////////////////////////////////////////////
  406. //
  407. // Export_Rare
  408. //
  409. ////////////////////////////////////////////////////////////////
  410. void
  411. DoorNetworkObjectClass::Export_Rare (BitStreamClass &packet)
  412. {
  413. //
  414. // Note: As a network optimization, we don't call the base
  415. // class. Doors are now state based and don't need to
  416. // transmit frame numbers.
  417. //
  418. //
  419. // Send the state
  420. //
  421. packet.Add (DoorState, BITPACK_DOOR_STATE);
  422. return ;
  423. }
  424. ////////////////////////////////////////////////////////////////
  425. //
  426. // Get_Description
  427. //
  428. ////////////////////////////////////////////////////////////////
  429. void
  430. DoorNetworkObjectClass::Get_Description (StringClass & description)
  431. {
  432. StringClass line;
  433. StringClass state_string;
  434. switch (DoorState) {
  435. case STATE_CLOSED_DOOR: state_string = "STATE_CLOSED_DOOR"; break;
  436. case STATE_OPENED_DOOR: state_string = "STATE_OPENED_DOOR"; break;
  437. case STATE_OPENING_DOOR: state_string = "STATE_OPENING_DOOR"; break;
  438. case STATE_CLOSING_DOOR: state_string = "STATE_CLOSING_DOOR"; break;
  439. case STATE_ACCESS_DENIED: state_string = "STATE_ACCESS_DENIED"; break;
  440. default: DIE;
  441. }
  442. line.Format("DoorState: %d (%s)\n", DoorState, state_string);
  443. description += line;
  444. if (PhysObj != NULL) {
  445. DoorPhysClass *door = PhysObj->As_DoorPhysClass ();
  446. if (door != NULL) {
  447. line.Format("Timer: %-5.2f\n", door->Timer);
  448. description += line;
  449. line.Format("CheckTimer: %-5.2f\n", door->CheckTimer);
  450. description += line;
  451. line.Format("State: %d\n", door->State);
  452. description += line;
  453. line.Format("ORP: %d\n", door->OpenRequestPending);
  454. description += line;
  455. line.Format("LockState: %d\n", door->LockState);
  456. description += line;
  457. }
  458. }
  459. }
  460. ////////////////////////////////////////////////////////////////
  461. //
  462. // ElevatorNetworkObjectClass
  463. //
  464. ////////////////////////////////////////////////////////////////
  465. ElevatorNetworkObjectClass::ElevatorNetworkObjectClass (void) :
  466. State (0),
  467. DoorStateTop (0),
  468. DoorStateBottom (0)
  469. {
  470. Set_App_Packet_Type(APPPACKETTYPE_ELEVATOR);
  471. }
  472. ////////////////////////////////////////////////////////////////
  473. //
  474. // Initialize
  475. //
  476. ////////////////////////////////////////////////////////////////
  477. void
  478. ElevatorNetworkObjectClass::Initialize (StaticAnimPhysClass *phys_obj)
  479. {
  480. //bug NetworkObjectClass::Network_Think ();
  481. StaticNetworkObjectClass::Initialize (phys_obj);
  482. //
  483. // Get a pointer to the elevator
  484. //
  485. if (PhysObj != NULL) {
  486. ElevatorPhysClass *elevator = PhysObj->As_ElevatorPhysClass ();
  487. if (elevator != NULL) {
  488. //
  489. // Copy the object's state
  490. //
  491. State = elevator->State;
  492. DoorStateTop = elevator->DoorStates[ElevatorPhysClass::TOP];
  493. DoorStateBottom = elevator->DoorStates[ElevatorPhysClass::BOTTOM];
  494. }
  495. }
  496. return ;
  497. }
  498. ////////////////////////////////////////////////////////////////
  499. //
  500. // Network_Think
  501. //
  502. ////////////////////////////////////////////////////////////////
  503. void
  504. ElevatorNetworkObjectClass::Network_Think (void)
  505. {
  506. NetworkObjectClass::Network_Think ();
  507. //StaticNetworkObjectClass::Network_Think ();
  508. //
  509. // Get a pointer to the elevator
  510. //
  511. if (PhysObj != NULL) {
  512. ElevatorPhysClass *elevator = PhysObj->As_ElevatorPhysClass ();
  513. if (elevator != NULL) {
  514. //
  515. // Set the dirty bit if the state has changed
  516. //
  517. if ( State != elevator->State ||
  518. DoorStateTop != elevator->DoorStates[ElevatorPhysClass::TOP] ||
  519. DoorStateBottom != elevator->DoorStates[ElevatorPhysClass::BOTTOM])
  520. {
  521. State = elevator->State;
  522. DoorStateTop = elevator->DoorStates[ElevatorPhysClass::TOP];
  523. DoorStateBottom = elevator->DoorStates[ElevatorPhysClass::BOTTOM];
  524. Set_Object_Dirty_Bit (BIT_RARE, true);
  525. }
  526. }
  527. }
  528. return ;
  529. }
  530. ////////////////////////////////////////////////////////////////
  531. //
  532. // Import_Rare
  533. //
  534. ////////////////////////////////////////////////////////////////
  535. void
  536. ElevatorNetworkObjectClass::Import_Rare (BitStreamClass &packet)
  537. {
  538. //
  539. // Note: As a network optimization, we don't call the base
  540. // class. Doors are now state based and don't need to
  541. // transmit frame numbers.
  542. //
  543. //StaticNetworkObjectClass::Import_Rare (packet);
  544. //
  545. // Read the new state data
  546. //
  547. packet.Get (State);
  548. packet.Get (DoorStateTop);
  549. packet.Get (DoorStateBottom);
  550. //
  551. // Get a pointer to the elevator
  552. //
  553. if (PhysObj != NULL) {
  554. ElevatorPhysClass *elevator = PhysObj->As_ElevatorPhysClass ();
  555. if (elevator != NULL) {
  556. //
  557. // Switch to the new states
  558. //
  559. elevator->Set_State (State);
  560. elevator->Set_Door_State (ElevatorPhysClass::TOP, DoorStateTop);
  561. elevator->Set_Door_State (ElevatorPhysClass::BOTTOM, DoorStateBottom);
  562. }
  563. }
  564. return ;
  565. }
  566. ////////////////////////////////////////////////////////////////
  567. //
  568. // Export_Rare
  569. //
  570. ////////////////////////////////////////////////////////////////
  571. void
  572. ElevatorNetworkObjectClass::Export_Rare (BitStreamClass &packet)
  573. {
  574. //
  575. // Note: As a network optimization, we don't call the base
  576. // class. Doors are now state based and don't need to
  577. // transmit frame numbers.
  578. //
  579. //StaticNetworkObjectClass::Export_Rare (packet);
  580. //
  581. // Transmit the state information
  582. //
  583. packet.Add (State);
  584. packet.Add (DoorStateTop);
  585. packet.Add (DoorStateBottom);
  586. return ;
  587. }
  588. ////////////////////////////////////////////////////////////////
  589. //
  590. // Get_Description
  591. //
  592. ////////////////////////////////////////////////////////////////
  593. void
  594. ElevatorNetworkObjectClass::Get_Description (StringClass & description)
  595. {
  596. StringClass line;
  597. StringClass state_string;
  598. //
  599. // State
  600. //
  601. switch (State) {
  602. case ElevatorPhysClass::STATE_DOWN: state_string = "STATE_DOWN"; break;
  603. case ElevatorPhysClass::STATE_MOVING_UP: state_string = "STATE_MOVING_UP"; break;
  604. case ElevatorPhysClass::STATE_UP: state_string = "STATE_UP"; break;
  605. case ElevatorPhysClass::STATE_MOVING_DOWN: state_string = "STATE_MOVING_DOWN"; break;
  606. default: DIE;
  607. }
  608. line.Format("State: %d (%s)\n", State, state_string);
  609. description += line;
  610. //
  611. // DoorStateTop
  612. //
  613. switch (DoorStateTop) {
  614. case ElevatorPhysClass::DOOR_STATE_NORMAL: state_string = "DOOR_STATE_NORMAL"; break;
  615. case ElevatorPhysClass::DOOR_STATE_UNLOCKED: state_string = "DOOR_STATE_UNLOCKED"; break;
  616. case ElevatorPhysClass::DOOR_STATE_ACCESS_DENIED: state_string = "DOOR_STATE_ACCESS_DENIED"; break;
  617. default: DIE;
  618. }
  619. line.Format("DoorStateTop: %d (%s)\n", DoorStateTop, state_string);
  620. description += line;
  621. //
  622. // DoorStateBottom
  623. //
  624. switch (DoorStateBottom) {
  625. case ElevatorPhysClass::DOOR_STATE_NORMAL: state_string = "DOOR_STATE_NORMAL"; break;
  626. case ElevatorPhysClass::DOOR_STATE_UNLOCKED: state_string = "DOOR_STATE_UNLOCKED"; break;
  627. case ElevatorPhysClass::DOOR_STATE_ACCESS_DENIED: state_string = "DOOR_STATE_ACCESS_DENIED"; break;
  628. default: DIE;
  629. }
  630. line.Format("DoorStateBottom: %d (%s)\n", DoorStateBottom, state_string);
  631. description += line;
  632. if (PhysObj != NULL) {
  633. ElevatorPhysClass *elevator = PhysObj->As_ElevatorPhysClass ();
  634. if (elevator != NULL) {
  635. line.Format("State: %d\n", elevator->State);
  636. description += line;
  637. line.Format("DoorStates[0]: %d\n", elevator->DoorStates[0]);
  638. description += line;
  639. line.Format("DoorStates[1]: %d\n", elevator->DoorStates[1]);
  640. description += line;
  641. line.Format("CheckTimer: %-5.2f\n", elevator->CheckTimer);
  642. description += line;
  643. line.Format("PrevFrame: %-5.2f\n", elevator->PrevFrame);
  644. description += line;
  645. line.Format("IsCallTimerSet: %d\n", elevator->IsCallTimerSet);
  646. description += line;
  647. line.Format("CallTimer: %-5.2f\n", elevator->CallTimer);
  648. description += line;
  649. line.Format("TriggerRequest: %d\n", elevator->TriggerRequest);
  650. description += line;
  651. }
  652. }
  653. }
  654. ////////////////////////////////////////////////////////////////
  655. //
  656. // DSAPONetworkObjectClass
  657. //
  658. ////////////////////////////////////////////////////////////////
  659. DSAPONetworkObjectClass::DSAPONetworkObjectClass (void) :
  660. Health (0)
  661. {
  662. Set_App_Packet_Type(APPPACKETTYPE_DSAPO);
  663. }
  664. ////////////////////////////////////////////////////////////////
  665. //
  666. // Initialize
  667. //
  668. ////////////////////////////////////////////////////////////////
  669. void
  670. DSAPONetworkObjectClass::Initialize (StaticAnimPhysClass *phys_obj)
  671. {
  672. StaticNetworkObjectClass::Initialize (phys_obj);
  673. //
  674. // Get a pointer to the object
  675. //
  676. if (PhysObj != NULL) {
  677. DamageableStaticPhysClass *phys_obj = PhysObj->As_DamageableStaticPhysClass ();
  678. if (phys_obj != NULL) {
  679. //
  680. // Copy the object's state
  681. //
  682. Health = phys_obj->DefenseObject.Get_Health ();
  683. }
  684. }
  685. return ;
  686. }
  687. ////////////////////////////////////////////////////////////////
  688. //
  689. // Network_Think
  690. //
  691. ////////////////////////////////////////////////////////////////
  692. void
  693. DSAPONetworkObjectClass::Network_Think (void)
  694. {
  695. StaticNetworkObjectClass::Network_Think ();
  696. //
  697. // Get a pointer to the object
  698. //
  699. if (PhysObj != NULL) {
  700. DamageableStaticPhysClass *phys_obj = PhysObj->As_DamageableStaticPhysClass ();
  701. if (phys_obj != NULL) {
  702. //
  703. // Set the dirty bit if the state has changed
  704. //
  705. if (Health > 0 && phys_obj->DefenseObject.Get_Health () <= 0) {
  706. Health = phys_obj->DefenseObject.Get_Health ();
  707. Set_Object_Dirty_Bit (BIT_RARE, true);
  708. }
  709. }
  710. }
  711. return ;
  712. }
  713. ////////////////////////////////////////////////////////////////
  714. //
  715. // Import_Rare
  716. //
  717. ////////////////////////////////////////////////////////////////
  718. void
  719. DSAPONetworkObjectClass::Import_Rare (BitStreamClass &packet)
  720. {
  721. DamageableStaticPhysClass *phys_obj = PhysObj->As_DamageableStaticPhysClass ();
  722. if (phys_obj == NULL) {
  723. return ;
  724. }
  725. //
  726. // Get the health BEFORE we import the data
  727. //
  728. float old_health = phys_obj->DefenseObject.Get_Health();
  729. //
  730. // Import the data
  731. //
  732. StaticNetworkObjectClass::Import_Rare (packet);
  733. phys_obj->DefenseObject.Import (packet);
  734. //
  735. // Did the health drop below 0?
  736. //
  737. if ((old_health > 0) && (phys_obj->DefenseObject.Get_Health () <= 0)) {
  738. //
  739. // Anim data should already been sent
  740. //
  741. phys_obj->Get_Animation_Manager().Set_Animation_Mode (AnimCollisionManagerClass::ANIMATE_TARGET);
  742. //
  743. // Play the explosion
  744. //
  745. const DamageableStaticPhysDefClass *definition = phys_obj->Get_DamageableStaticPhysDef ();
  746. if (definition->KilledExplosion != 0) {
  747. ExplosionManager::Create_Explosion_At (definition->KilledExplosion, phys_obj->Get_Transform (), NULL);
  748. }
  749. }
  750. return ;
  751. }
  752. ////////////////////////////////////////////////////////////////
  753. //
  754. // Export_Rare
  755. //
  756. ////////////////////////////////////////////////////////////////
  757. void
  758. DSAPONetworkObjectClass::Export_Rare (BitStreamClass &packet)
  759. {
  760. DamageableStaticPhysClass *phys_obj = PhysObj->As_DamageableStaticPhysClass ();
  761. if (phys_obj == NULL) {
  762. return ;
  763. }
  764. //
  765. // Just export the defense object's settings
  766. //
  767. StaticNetworkObjectClass::Export_Rare (packet);
  768. phys_obj->DefenseObject.Export (packet);
  769. return ;
  770. }