WaypointNode.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559
  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. *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : LevelEdit *
  23. * *
  24. * $Archive:: /Commando/Code/Tools/LevelEdit/WaypointNode.cpp $*
  25. * *
  26. * Author:: Patrick Smith *
  27. * *
  28. * $Modtime:: 10/10/00 11:07a $*
  29. * *
  30. * $Revision:: 6 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #include "stdafx.h"
  36. #include "waypathnode.h"
  37. #include "sceneeditor.h"
  38. #include "collisiongroups.h"
  39. #include "persistfactory.h"
  40. #include "editorchunkids.h"
  41. #include "preset.h"
  42. #include "chunkio.h"
  43. #include "nodemgr.h"
  44. #include "segline.h"
  45. #include "waypointnode.h"
  46. #include "waypathnode.h"
  47. #include "waypathinfopage.h"
  48. #include "nodeinfopage.h"
  49. #include "positionpage.h"
  50. #include "editorpropsheet.h"
  51. //////////////////////////////////////////////////////////////////////////////
  52. // Persist factory
  53. //////////////////////////////////////////////////////////////////////////////
  54. SimplePersistFactoryClass<WaypointNodeClass, CHUNKID_NODE_WAYPOINT> _WaypointNodePersistFactory;
  55. enum
  56. {
  57. CHUNKID_VARIABLES = 0x03011130,
  58. CHUNKID_BASE_CLASS
  59. };
  60. enum
  61. {
  62. VARID_WAYPATH_PTR = 0x01,
  63. VARID_OLD_PTR = 0x02,
  64. VARID_FLAGS = 0x03,
  65. };
  66. //////////////////////////////////////////////////////////////////////////////
  67. //
  68. // WaypointNodeClass
  69. //
  70. //////////////////////////////////////////////////////////////////////////////
  71. WaypointNodeClass::WaypointNodeClass (PresetClass *preset)
  72. : m_PhysObj (NULL),
  73. m_Waypath (NULL),
  74. m_Flags (NULL),
  75. m_ModelType (MODEL_MIDDLE_PT),
  76. m_Speed (0.6F),
  77. NodeClass (preset)
  78. {
  79. return ;
  80. }
  81. //////////////////////////////////////////////////////////////////////////////
  82. //
  83. // WaypointNodeClass
  84. //
  85. //////////////////////////////////////////////////////////////////////////////
  86. WaypointNodeClass::WaypointNodeClass (const WaypointNodeClass &src)
  87. : m_PhysObj (NULL),
  88. m_Waypath (NULL),
  89. m_Flags (NULL),
  90. m_ModelType (MODEL_MIDDLE_PT),
  91. m_Speed (0.6F),
  92. NodeClass (NULL)
  93. {
  94. *this = src;
  95. return ;
  96. }
  97. //////////////////////////////////////////////////////////////////////////////
  98. //
  99. // ~WaypointNodeClass
  100. //
  101. //////////////////////////////////////////////////////////////////////////////
  102. WaypointNodeClass::~WaypointNodeClass (void)
  103. {
  104. Remove_From_Scene ();
  105. MEMBER_RELEASE (m_PhysObj);
  106. return ;
  107. }
  108. //////////////////////////////////////////////////////////////////////////////
  109. //
  110. // Initialize
  111. //
  112. // Note: This may be called more than once. It is used as an 'initialize'
  113. // and a 're-initialize'.
  114. //
  115. //////////////////////////////////////////////////////////////////////////////
  116. void
  117. WaypointNodeClass::Initialize (void)
  118. {
  119. //
  120. // Refresh the model
  121. //
  122. MEMBER_RELEASE (m_PhysObj);
  123. Update_Model ();
  124. return ;
  125. }
  126. //////////////////////////////////////////////////////////////////////////////
  127. //
  128. // Set_Model
  129. //
  130. //////////////////////////////////////////////////////////////////////////////
  131. void
  132. WaypointNodeClass::Set_Model (MODEL model)
  133. {
  134. if (m_ModelType != model) {
  135. m_ModelType = model;
  136. Update_Model ();
  137. }
  138. return ;
  139. }
  140. //////////////////////////////////////////////////////////////////////////////
  141. //
  142. // Update_Model
  143. //
  144. //////////////////////////////////////////////////////////////////////////////
  145. void
  146. WaypointNodeClass::Update_Model (void)
  147. {
  148. if (m_PhysObj == NULL) {
  149. m_PhysObj = new DecorationPhysClass;
  150. }
  151. StringClass model_name;
  152. switch (m_ModelType)
  153. {
  154. case MODEL_START_PT:
  155. model_name = "WAY_G";
  156. break;
  157. case MODEL_MIDDLE_PT:
  158. model_name = "WAY_B";
  159. break;
  160. case MODEL_END_PT:
  161. model_name = "WAY_R";
  162. break;
  163. }
  164. //
  165. // Create the appropriate model
  166. //
  167. RenderObjClass *render_obj = ::Create_Render_Obj (model_name);
  168. WWASSERT (render_obj != NULL);
  169. if (render_obj != NULL) {
  170. //
  171. // Pass the model onto the physics object
  172. //
  173. m_PhysObj->Set_Model (render_obj);
  174. //
  175. // Configure the physics object
  176. //
  177. m_PhysObj->Set_Transform (Matrix3D(1));
  178. m_PhysObj->Set_Collision_Group (EDITOR_COLLISION_GROUP);
  179. m_PhysObj->Peek_Model ()->Set_User_Data ((PVOID)&m_HitTestInfo, FALSE);
  180. m_PhysObj->Peek_Model ()->Set_Collision_Type (COLLISION_TYPE_6);
  181. m_PhysObj->Set_Transform (m_Transform);
  182. MEMBER_RELEASE (render_obj);
  183. }
  184. return ;
  185. }
  186. ////////////////////////////////////////////////////////////////
  187. //
  188. // Get_Factory
  189. //
  190. ////////////////////////////////////////////////////////////////
  191. const PersistFactoryClass &
  192. WaypointNodeClass::Get_Factory (void) const
  193. {
  194. return _WaypointNodePersistFactory;
  195. }
  196. /////////////////////////////////////////////////////////////////
  197. //
  198. // Save
  199. //
  200. /////////////////////////////////////////////////////////////////
  201. bool
  202. WaypointNodeClass::Save (ChunkSaveClass &csave)
  203. {
  204. csave.Begin_Chunk (CHUNKID_BASE_CLASS);
  205. NodeClass::Save (csave);
  206. csave.End_Chunk ();
  207. csave.Begin_Chunk (CHUNKID_VARIABLES);
  208. WaypointNodeClass *this_ptr = this;
  209. WRITE_MICRO_CHUNK (csave, VARID_OLD_PTR, this_ptr);
  210. WRITE_MICRO_CHUNK (csave, VARID_WAYPATH_PTR, m_Waypath);
  211. WRITE_MICRO_CHUNK (csave, VARID_FLAGS, m_Flags);
  212. csave.End_Chunk ();
  213. return true;
  214. }
  215. /////////////////////////////////////////////////////////////////
  216. //
  217. // Load
  218. //
  219. /////////////////////////////////////////////////////////////////
  220. bool
  221. WaypointNodeClass::Load (ChunkLoadClass &cload)
  222. {
  223. while (cload.Open_Chunk ()) {
  224. switch (cload.Cur_Chunk_ID ()) {
  225. case CHUNKID_BASE_CLASS:
  226. NodeClass::Load (cload);
  227. break;
  228. case CHUNKID_VARIABLES:
  229. Load_Variables (cload);
  230. break;
  231. }
  232. cload.Close_Chunk ();
  233. }
  234. return true;
  235. }
  236. ///////////////////////////////////////////////////////////////////////
  237. //
  238. // Load_Variables
  239. //
  240. ///////////////////////////////////////////////////////////////////////
  241. bool
  242. WaypointNodeClass::Load_Variables (ChunkLoadClass &cload)
  243. {
  244. //
  245. // Loop through all the microchunks that define the variables
  246. //
  247. while (cload.Open_Micro_Chunk ()) {
  248. switch (cload.Cur_Micro_Chunk_ID ()) {
  249. READ_MICRO_CHUNK (cload, VARID_FLAGS, m_Flags);
  250. case VARID_WAYPATH_PTR:
  251. {
  252. //
  253. // Read the old pointer from the chunk and register it
  254. // for remapping.
  255. //
  256. cload.Read (&m_Waypath, sizeof (m_Waypath));
  257. REQUEST_POINTER_REMAP ((void **)&m_Waypath);
  258. }
  259. break;
  260. case VARID_OLD_PTR:
  261. {
  262. //
  263. // Read the old pointer from the chunk and submit it
  264. // to the remapping system.
  265. //
  266. WaypointNodeClass *old_ptr = NULL;
  267. cload.Read (&old_ptr, sizeof (old_ptr));
  268. SaveLoadSystemClass::Register_Pointer (old_ptr, this);
  269. }
  270. break;
  271. }
  272. cload.Close_Micro_Chunk ();
  273. }
  274. return true;
  275. }
  276. ///////////////////////////////////////////////////////////////////////
  277. //
  278. // On_Transform
  279. //
  280. ///////////////////////////////////////////////////////////////////////
  281. void
  282. WaypointNodeClass::On_Transform (void)
  283. {
  284. On_Translate ();
  285. return ;
  286. }
  287. ///////////////////////////////////////////////////////////////////////
  288. //
  289. // On_Translate
  290. //
  291. ///////////////////////////////////////////////////////////////////////
  292. void
  293. WaypointNodeClass::On_Translate (void)
  294. {
  295. if (m_Waypath != NULL) {
  296. //
  297. // Find where we are on the waypath
  298. //
  299. int index = m_Waypath->Find_Index (this);
  300. if (index != -1) {
  301. //
  302. // Notify our waypath that we have been moved
  303. //
  304. Matrix3D &tm = Get_Transform ();
  305. m_Waypath->On_Point_Moved (index, tm.Get_Translation ());
  306. }
  307. }
  308. return ;
  309. }
  310. /////////////////////////////////////////////////////////////////
  311. //
  312. // On_Delete
  313. //
  314. /////////////////////////////////////////////////////////////////
  315. void
  316. WaypointNodeClass::On_Delete (void)
  317. {
  318. if (m_Waypath != NULL) {
  319. //
  320. // Find where we are on the waypath
  321. //
  322. int index = m_Waypath->Find_Index (this);
  323. if (index != -1) {
  324. //
  325. // Detach ourselves from the waypath
  326. //
  327. m_Waypath->Delete_Point (index);
  328. }
  329. }
  330. return ;
  331. }
  332. /////////////////////////////////////////////////////////////////
  333. //
  334. // operator=
  335. //
  336. /////////////////////////////////////////////////////////////////
  337. const WaypointNodeClass &
  338. WaypointNodeClass::operator= (const WaypointNodeClass &src)
  339. {
  340. m_Speed = src.m_Speed;
  341. m_Flags = src.m_Flags;
  342. m_ModelType = src.m_ModelType;
  343. NodeClass::operator= (src);
  344. return *this;
  345. }
  346. //////////////////////////////////////////////////////////////////////
  347. //
  348. // Pre_Export
  349. //
  350. //////////////////////////////////////////////////////////////////////
  351. void
  352. WaypointNodeClass::Pre_Export (void)
  353. {
  354. //
  355. // Remove ourselves from the 'system' so we don't get accidentally
  356. // saved during the export.
  357. //
  358. Add_Ref ();
  359. if (m_PhysObj != NULL && m_IsInScene) {
  360. ::Get_Scene_Editor ()->Remove_Object (m_PhysObj);
  361. }
  362. return ;
  363. }
  364. //////////////////////////////////////////////////////////////////////
  365. //
  366. // Post_Export
  367. //
  368. //////////////////////////////////////////////////////////////////////
  369. void
  370. WaypointNodeClass::Post_Export (void)
  371. {
  372. //
  373. // Put ourselves back into the system
  374. //
  375. if (m_PhysObj != NULL && m_IsInScene) {
  376. ::Get_Scene_Editor ()->Add_Dynamic_Object (m_PhysObj);
  377. }
  378. Release_Ref ();
  379. return ;
  380. }
  381. //////////////////////////////////////////////////////////////////////////////
  382. //
  383. // Set_Flags
  384. //
  385. //////////////////////////////////////////////////////////////////////////////
  386. void
  387. WaypointNodeClass::Set_Flags (int flags)
  388. {
  389. m_Flags = flags;
  390. return ;
  391. }
  392. //////////////////////////////////////////////////////////////////////////////
  393. //
  394. // Set_Flag
  395. //
  396. //////////////////////////////////////////////////////////////////////////////
  397. void
  398. WaypointNodeClass::Set_Flag (int flag, bool onoff)
  399. {
  400. m_Flags &= ~flag;
  401. if (onoff) {
  402. m_Flags |= flag;
  403. }
  404. return ;
  405. }
  406. //////////////////////////////////////////////////////////////////////////////
  407. //
  408. // Get_Flag
  409. //
  410. //////////////////////////////////////////////////////////////////////////////
  411. bool
  412. WaypointNodeClass::Get_Flag (int flag)
  413. {
  414. return bool((m_Flags & flag) == flag);
  415. }
  416. //////////////////////////////////////////////////////////////////////////////
  417. //
  418. // Show_Settings_Dialog
  419. //
  420. //////////////////////////////////////////////////////////////////////////////
  421. bool
  422. WaypointNodeClass::Show_Settings_Dialog (void)
  423. {
  424. NodeInfoPageClass info_tab (this);
  425. PositionPageClass pos_tab (this);
  426. WaypathInfoPageClass path_tab (this);
  427. //
  428. // Add each tab to the property sheet
  429. //
  430. EditorPropSheetClass prop_sheet;
  431. prop_sheet.Add_Page (&info_tab);
  432. prop_sheet.Add_Page (&pos_tab);
  433. prop_sheet.Add_Page (&path_tab);
  434. // Show the property sheet
  435. UINT ret_code = prop_sheet.DoModal ();
  436. if (ret_code == IDOK && m_Waypath != NULL) {
  437. m_Waypath->Update_Line ();
  438. }
  439. // Return true if the user clicked OK
  440. return (ret_code == IDOK);
  441. }
  442. //////////////////////////////////////////////////////////////////////////////
  443. //
  444. // Parent_Set_Transform
  445. //
  446. //////////////////////////////////////////////////////////////////////////////
  447. void
  448. WaypointNodeClass::Parent_Set_Transform (const Matrix3D &tm)
  449. {
  450. m_Transform = tm;
  451. PhysClass *phys_obj = Peek_Physics_Obj ();
  452. if (phys_obj != NULL) {
  453. phys_obj->Set_Transform (tm);
  454. }
  455. return ;
  456. }
  457. //////////////////////////////////////////////////////////////////////////////
  458. //
  459. // Parent_Set_Position
  460. //
  461. //////////////////////////////////////////////////////////////////////////////
  462. void
  463. WaypointNodeClass::Parent_Set_Position (const Vector3 &pos)
  464. {
  465. m_Transform.Set_Translation (pos);
  466. PhysClass *phys_obj = Peek_Physics_Obj ();
  467. if (phys_obj != NULL) {
  468. phys_obj->Set_Transform (m_Transform);
  469. }
  470. return ;
  471. }