ParameterInheritanceDialog.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868
  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. // ParameterInheritanceDialog.cpp : implementation file
  19. //
  20. #include "stdafx.h"
  21. #include "leveledit.h"
  22. #include "ParameterInheritanceDialog.h"
  23. #include "definition.h"
  24. #include "presetmgr.h"
  25. #include "preset.h"
  26. #include "parameter.h"
  27. #include "definitionparameter.h"
  28. #include "combatchunkid.h"
  29. #include "soldier.h"
  30. #ifdef _DEBUG
  31. #define new DEBUG_NEW
  32. #undef THIS_FILE
  33. static char THIS_FILE[] = __FILE__;
  34. #endif
  35. /////////////////////////////////////////////////////////////////////////////
  36. // Local macros
  37. /////////////////////////////////////////////////////////////////////////////
  38. #ifndef ListView_SetCheckState
  39. #define ListView_SetCheckState(hwndLV, i, fCheck) \
  40. ListView_SetItemState(hwndLV, i, \
  41. INDEXTOSTATEIMAGEMASK((fCheck)+1), LVIS_STATEIMAGEMASK)
  42. #endif
  43. /////////////////////////////////////////////////////////////////////////////
  44. // Local constants
  45. /////////////////////////////////////////////////////////////////////////////
  46. static const int ICON_GAME_SETTING = 0;
  47. static const int ICON_PHYS_SETTING = 1;
  48. /////////////////////////////////////////////////////////////////////////////
  49. // Local prototypes
  50. /////////////////////////////////////////////////////////////////////////////
  51. static LRESULT CALLBACK CheckBoxSubclassProc (HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);
  52. static BOOL TreeView_SetCheckState (HWND hwndTreeView, HTREEITEM hItem, BOOL fCheck);
  53. static bool Find_Parameter_In_List (DynamicVectorClass<DefinitionParameterClass *> &parameter_list, ParameterClass *parameter);
  54. /////////////////////////////////////////////////////////////////////////////
  55. //
  56. // ParameterInheritanceDialogClass
  57. //
  58. /////////////////////////////////////////////////////////////////////////////
  59. ParameterInheritanceDialogClass::ParameterInheritanceDialogClass(CWnd* pParent /*=NULL*/)
  60. : m_Preset (NULL),
  61. CDialog(ParameterInheritanceDialogClass::IDD, pParent)
  62. {
  63. //{{AFX_DATA_INIT(ParameterInheritanceDialogClass)
  64. // NOTE: the ClassWizard will add member initialization here
  65. //}}AFX_DATA_INIT
  66. return ;
  67. }
  68. /////////////////////////////////////////////////////////////////////////////
  69. //
  70. // DoDataExchange
  71. //
  72. /////////////////////////////////////////////////////////////////////////////
  73. void
  74. ParameterInheritanceDialogClass::DoDataExchange(CDataExchange* pDX)
  75. {
  76. CDialog::DoDataExchange(pDX);
  77. //{{AFX_DATA_MAP(ParameterInheritanceDialogClass)
  78. DDX_Control(pDX, IDC_PARAMETER_LIST, m_ListCtrl);
  79. DDX_Control(pDX, IDC_CHILD_TREE, m_TreeCtrl);
  80. //}}AFX_DATA_MAP
  81. return ;
  82. }
  83. BEGIN_MESSAGE_MAP(ParameterInheritanceDialogClass, CDialog)
  84. //{{AFX_MSG_MAP(ParameterInheritanceDialogClass)
  85. ON_WM_DESTROY()
  86. ON_NOTIFY(LVN_DELETEITEM, IDC_PARAMETER_LIST, OnDeleteitemParameterList)
  87. //}}AFX_MSG_MAP
  88. END_MESSAGE_MAP()
  89. /////////////////////////////////////////////////////////////////////////////
  90. //
  91. // OnInitDialog
  92. //
  93. /////////////////////////////////////////////////////////////////////////////
  94. BOOL
  95. ParameterInheritanceDialogClass::OnInitDialog (void)
  96. {
  97. CDialog::OnInitDialog ();
  98. //
  99. // Configure the list control
  100. //
  101. CRect rect;
  102. m_ListCtrl.GetClientRect (&rect);
  103. m_ListCtrl.InsertColumn (0, "Name");
  104. m_ListCtrl.SetColumnWidth (0, rect.Width () - ::GetSystemMetrics (SM_CXVSCROLL) - 1);
  105. //
  106. // Create a small imagelist for the list control to use
  107. //
  108. CImageList *imagelist = new CImageList;
  109. imagelist->Create (16, 16, ILC_COLOR | ILC_MASK, 2, 0);
  110. HICON icon1 = (HICON)::LoadImage (::AfxGetInstanceHandle (), MAKEINTRESOURCE(IDI_PARAM), IMAGE_ICON, 16, 16, LR_SHARED | LR_DEFAULTCOLOR);
  111. HICON icon2 = (HICON)::LoadImage (::AfxGetInstanceHandle (), MAKEINTRESOURCE(IDI_PHYS), IMAGE_ICON, 16, 16, LR_SHARED | LR_DEFAULTCOLOR);
  112. imagelist->Add (icon1);
  113. imagelist->Add (icon2);
  114. m_ListCtrl.SetImageList (imagelist, LVSIL_SMALL);
  115. //
  116. // Create a state imagelist for the list control to use for checkboxes
  117. //
  118. imagelist = new CImageList;
  119. imagelist->Create (MAKEINTRESOURCE (IDB_CHECKBOX_STATES1), 13, 0, RGB (255, 0, 255));
  120. m_ListCtrl.SetImageList (imagelist, LVSIL_STATE);
  121. //
  122. // Create a state imagelist for the tree control to use for checkboxes
  123. //
  124. imagelist = new CImageList;
  125. imagelist->Create (MAKEINTRESOURCE (IDB_CHECKBOX_STATES), 13, 0, RGB (255, 0, 255));
  126. m_TreeCtrl.SetImageList (imagelist, TVSIL_STATE);
  127. //
  128. // Fill in the parameter list and preset list
  129. //
  130. Populate_List_Ctrl ();
  131. Populate_Tree_Ctrl ();
  132. //
  133. // Subclass the list and tree controls so we can handle the checkstates
  134. //
  135. LONG oldproc1 = ::SetWindowLong (m_ListCtrl, GWL_WNDPROC, (LONG)CheckBoxSubclassProc);
  136. LONG oldproc2 = ::SetWindowLong (m_TreeCtrl, GWL_WNDPROC, (LONG)CheckBoxSubclassProc);
  137. ::SetProp (m_ListCtrl, "OLDPROC", (HANDLE)oldproc1);
  138. ::SetProp (m_TreeCtrl, "OLDPROC", (HANDLE)oldproc2);
  139. ::SetProp (m_ListCtrl, "IS_LIST_CTRL", (HANDLE)TRUE);
  140. ::SetProp (m_TreeCtrl, "IS_LIST_CTRL", (HANDLE)FALSE);
  141. //
  142. // Determine whether or not to enable the dialogue propogation controls
  143. //
  144. bool enable_dialogue_ctrls = false;
  145. if (m_Preset != NULL && m_Preset->Is_Soldier_Preset ()) {
  146. enable_dialogue_ctrls = true;
  147. }
  148. ::EnableWindow (::GetDlgItem (m_hWnd, IDC_PROPOGATE_DIALOGUE), enable_dialogue_ctrls);
  149. return TRUE;
  150. }
  151. /////////////////////////////////////////////////////////////////////////////
  152. //
  153. // Populate_List_Ctrl
  154. //
  155. /////////////////////////////////////////////////////////////////////////////
  156. void
  157. ParameterInheritanceDialogClass::Populate_List_Ctrl (void)
  158. {
  159. ASSERT (m_Preset != NULL);
  160. //
  161. // Get the definition this preset sits on
  162. //
  163. DefinitionClass *definition = m_Preset->Get_Definition ();
  164. ASSERT (definition != NULL);
  165. if (definition != NULL) {
  166. //
  167. // Recursively add paramters from this definition to the list control
  168. //
  169. Add_Parameters_To_List (definition, NULL, ICON_GAME_SETTING);
  170. }
  171. return ;
  172. }
  173. /////////////////////////////////////////////////////////////////////////////
  174. //
  175. // Add_Parameters_To_List
  176. //
  177. /////////////////////////////////////////////////////////////////////////////
  178. void
  179. ParameterInheritanceDialogClass::Add_Parameters_To_List
  180. (
  181. DefinitionClass * definition,
  182. DefinitionParameterClass * parent,
  183. int icon
  184. )
  185. {
  186. ASSERT (definition != NULL);
  187. //
  188. // Add these parameters to the list control
  189. //
  190. int count = definition->Get_Parameter_Count ();
  191. for (int index = 0; index < count; index ++) {
  192. ParameterClass *parameter = definition->Lock_Parameter (index);
  193. if (parameter != NULL) {
  194. //
  195. // Is this parameter one we need to recurse into?
  196. //
  197. if (parameter->Get_Type () == ParameterClass::TYPE_MODELDEFINITIONID) {
  198. //
  199. // Lookup the definition that this parameter points to
  200. //
  201. int def_id = ((ModelDefParameterClass *)parameter)->Get_Value ();
  202. DefinitionClass *model_def = DefinitionMgrClass::Find_Definition (def_id, false);
  203. if (model_def != NULL) {
  204. DefinitionParameterClass *def_param = new DefinitionParameterClass;
  205. def_param->Set_Definition (definition);
  206. def_param->Set_Parameter (parameter);
  207. def_param->Set_Index (index);
  208. def_param->Set_Parent (parent);
  209. //
  210. // Recurse into this model definition
  211. //
  212. Add_Parameters_To_List (model_def, def_param, ICON_PHYS_SETTING);
  213. MEMBER_RELEASE (def_param);
  214. }
  215. } else {
  216. //
  217. // Insert this preset into the list control
  218. //
  219. int item_index = m_ListCtrl.InsertItem (0xFFFF, parameter->Get_Name (), icon);
  220. if (item_index >= 0) {
  221. DefinitionParameterClass *def_param = new DefinitionParameterClass;
  222. def_param->Set_Definition (definition);
  223. def_param->Set_Parameter (parameter);
  224. def_param->Set_Index (index);
  225. def_param->Set_Parent (parent);
  226. m_ListCtrl.SetItemData (item_index, (LONG)def_param);
  227. ListView_SetCheckState (m_ListCtrl, item_index, false);
  228. }
  229. }
  230. }
  231. definition->Unlock_Parameter (index);
  232. }
  233. return ;
  234. }
  235. /////////////////////////////////////////////////////////////////////////////
  236. //
  237. // Populate_Tree_Ctrl
  238. //
  239. /////////////////////////////////////////////////////////////////////////////
  240. void
  241. ParameterInheritanceDialogClass::Populate_Tree_Ctrl (void)
  242. {
  243. ASSERT (m_Preset != NULL);
  244. int parent_id = m_Preset->Get_ID ();
  245. //
  246. // Add all the presets that 'inherit' from this preset
  247. //
  248. Add_Children_To_Tree (TVI_ROOT, parent_id);
  249. return ;
  250. }
  251. /////////////////////////////////////////////////////////////////////////////
  252. //
  253. // Add_Children_To_Tree
  254. //
  255. /////////////////////////////////////////////////////////////////////////////
  256. void
  257. ParameterInheritanceDialogClass::Add_Children_To_Tree (HTREEITEM parent_item, int parent_id)
  258. {
  259. //
  260. // Lookup the parent preset
  261. //
  262. PresetClass *parent_preset = PresetMgrClass::Find_Preset (parent_id);
  263. if (parent_preset != NULL) {
  264. //
  265. // Loop over all the children of this preset
  266. //
  267. int count = parent_preset->Get_Child_Preset_Count ();
  268. for (int index = 0; index < count; index ++) {
  269. PresetClass *child_preset = parent_preset->Get_Child_Preset (index);
  270. if (child_preset != NULL) {
  271. //
  272. // Add this preset to the tree
  273. //
  274. HTREEITEM new_item = m_TreeCtrl.InsertItem (child_preset->Get_Name (), parent_item);
  275. if (new_item != NULL) {
  276. //
  277. // Associate the preset pointer with this tree item
  278. //
  279. m_TreeCtrl.SetItemData (new_item, (LONG)child_preset);
  280. //
  281. // Check this preset by default
  282. //
  283. TreeView_SetCheckState (m_TreeCtrl, new_item, true);
  284. //
  285. // Recursively fill in this presets's children
  286. //
  287. Add_Children_To_Tree (new_item, child_preset->Get_ID ());
  288. }
  289. }
  290. }
  291. }
  292. //
  293. // Ensure this leaf is sorted
  294. //
  295. m_TreeCtrl.SortChildren (parent_item);
  296. m_TreeCtrl.Expand (parent_item, TVE_EXPAND);
  297. return ;
  298. }
  299. /////////////////////////////////////////////////////////////////////////////
  300. //
  301. // OnDestroy
  302. //
  303. /////////////////////////////////////////////////////////////////////////////
  304. void
  305. ParameterInheritanceDialogClass::OnDestroy (void)
  306. {
  307. //
  308. // Free the small image list we associated with the list control
  309. //
  310. CImageList *imagelist = m_ListCtrl.GetImageList (LVSIL_SMALL);
  311. m_ListCtrl.SetImageList (NULL, LVSIL_SMALL);
  312. SAFE_DELETE (imagelist);
  313. //
  314. // Free the state image list we associated with the list control
  315. //
  316. imagelist = m_ListCtrl.GetImageList (LVSIL_STATE);
  317. m_ListCtrl.SetImageList (NULL, LVSIL_STATE);
  318. SAFE_DELETE (imagelist);
  319. //
  320. // Free the state image list we associated with the tree control
  321. //
  322. imagelist = m_TreeCtrl.GetImageList (TVSIL_STATE);
  323. m_TreeCtrl.SetImageList (NULL, TVSIL_STATE);
  324. SAFE_DELETE (imagelist);
  325. CDialog::OnDestroy ();
  326. return ;
  327. }
  328. ////////////////////////////////////////////////////////////////////////////
  329. //
  330. // CheckBoxSubclassProc
  331. //
  332. ////////////////////////////////////////////////////////////////////////////
  333. LRESULT CALLBACK
  334. CheckBoxSubclassProc
  335. (
  336. HWND hwnd,
  337. UINT message,
  338. WPARAM wparam,
  339. LPARAM lparam
  340. )
  341. {
  342. WNDPROC old_proc = (WNDPROC)::GetProp (hwnd, "OLDPROC");
  343. if (message == WM_LBUTTONUP) {
  344. //
  345. // Is this the list control or the tree control?
  346. //
  347. BOOL is_list_ctrl = (BOOL)::GetProp (hwnd, "IS_LIST_CTRL");
  348. if (is_list_ctrl) {
  349. //
  350. // Find out where the user clicked
  351. //
  352. LVHITTESTINFO hittest = { 0 };
  353. hittest.pt.x = LOWORD (lparam);
  354. hittest.pt.y = HIWORD (lparam);
  355. ::SendMessage (hwnd, LVM_HITTEST, 0, (LPARAM)&hittest);
  356. //
  357. // Did the user click one of the checkboxes?
  358. //
  359. if (hittest.flags & LVHT_ONITEMSTATEICON) {
  360. //
  361. // Notify the dialog that the user wants to toggle the checkbox
  362. //
  363. ::PostMessage (::GetParent (hwnd), WM_USER+102, 0, (LPARAM)hittest.iItem);
  364. }
  365. } else {
  366. //
  367. // Find out where the user clicked
  368. //
  369. TVHITTESTINFO hittest = { 0 };
  370. hittest.pt.x = LOWORD (lparam);
  371. hittest.pt.y = HIWORD (lparam);
  372. ::SendMessage (hwnd, TVM_HITTEST, 0, (LPARAM)&hittest);
  373. //
  374. // Did the user click one of the checkboxes?
  375. //
  376. if (hittest.flags & TVHT_ONITEMSTATEICON) {
  377. //
  378. // Notify the dialog that the user wants to toggle the checkbox
  379. //
  380. ::PostMessage (::GetParent (hwnd), WM_USER+103, 0, (LPARAM)hittest.hItem);
  381. }
  382. }
  383. } else if (message == WM_DESTROY) {
  384. ::SetWindowLong (hwnd, GWL_WNDPROC, (LONG)old_proc);
  385. ::RemoveProp (hwnd, "OLDPROC");
  386. ::RemoveProp (hwnd, "IS_LIST_CTRL");
  387. }
  388. //
  389. // Allow the default message processing to occur
  390. //
  391. LRESULT result = 0L;
  392. if (old_proc != NULL) {
  393. result = ::CallWindowProc (old_proc, hwnd, message, wparam, lparam);
  394. } else {
  395. result = ::DefWindowProc (hwnd, message, wparam, lparam);
  396. }
  397. return result;
  398. }
  399. /////////////////////////////////////////////////////////////////////////////
  400. //
  401. // WindowProc
  402. //
  403. /////////////////////////////////////////////////////////////////////////////
  404. LRESULT
  405. ParameterInheritanceDialogClass::WindowProc
  406. (
  407. UINT message,
  408. WPARAM wParam,
  409. LPARAM lParam
  410. )
  411. {
  412. if (message == WM_USER + 102) {
  413. //
  414. // Invert the checked state of this entry
  415. //
  416. int index = (int)lParam;
  417. BOOL checked = ListView_GetCheckState (m_ListCtrl, index);
  418. Update_List_Entry_Check (index, (bool)(checked != 1));
  419. } else if (message == WM_USER + 103) {
  420. //
  421. // Invert the checked state of this entry
  422. //
  423. HTREEITEM tree_item = (HTREEITEM)lParam;
  424. BOOL checked = m_TreeCtrl.GetCheck (tree_item);
  425. Update_Tree_Entry_Check (tree_item, (bool)(checked != 1));
  426. }
  427. return CDialog::WindowProc (message, wParam, lParam);
  428. }
  429. /////////////////////////////////////////////////////////////////////////////
  430. //
  431. // Update_Tree_Entry_Check
  432. //
  433. /////////////////////////////////////////////////////////////////////////////
  434. void
  435. ParameterInheritanceDialogClass::Update_Tree_Entry_Check (HTREEITEM parent_item, bool checked)
  436. {
  437. //
  438. // Update this entry's check-state
  439. //
  440. TreeView_SetCheckState (m_TreeCtrl, parent_item, checked);
  441. //
  442. // Recurse through all the children
  443. //
  444. for ( HTREEITEM item = m_TreeCtrl.GetChildItem (parent_item);
  445. item != NULL;
  446. item = m_TreeCtrl.GetNextSiblingItem (item))
  447. {
  448. Update_Tree_Entry_Check (item, checked);
  449. }
  450. return ;
  451. }
  452. /////////////////////////////////////////////////////////////////////////////
  453. //
  454. // Update_List_Entry_Check
  455. //
  456. /////////////////////////////////////////////////////////////////////////////
  457. void
  458. ParameterInheritanceDialogClass::Update_List_Entry_Check (int index, bool checked)
  459. {
  460. //
  461. // Is this entry part of a selection?
  462. //
  463. if (m_ListCtrl.GetItemState (index, LVIS_SELECTED) == LVIS_SELECTED) {
  464. //
  465. // Apply the new check state to all the selected entries
  466. //
  467. int sel_index = -1;
  468. while ((sel_index = m_ListCtrl.GetNextItem (sel_index, LVNI_ALL | LVNI_SELECTED)) >= 0) {
  469. ListView_SetCheckState (m_ListCtrl, sel_index, checked);
  470. }
  471. } else {
  472. //
  473. // Simply change the check state of this entry
  474. //
  475. ListView_SetCheckState (m_ListCtrl, index, checked);
  476. }
  477. return ;
  478. }
  479. /////////////////////////////////////////////////////////////////////////////
  480. //
  481. // TreeView_SetCheckState
  482. //
  483. /////////////////////////////////////////////////////////////////////////////
  484. BOOL
  485. TreeView_SetCheckState (HWND hwndTreeView, HTREEITEM hItem, BOOL fCheck)
  486. {
  487. TVITEM tvItem;
  488. tvItem.mask = TVIF_HANDLE | TVIF_STATE;
  489. tvItem.hItem = hItem;
  490. tvItem.stateMask = TVIS_STATEIMAGEMASK;
  491. /*
  492. Since state images are one-based, 1 in this macro turns the check off, and
  493. 2 turns it on.
  494. */
  495. tvItem.state = INDEXTOSTATEIMAGEMASK((fCheck ? 2 : 1));
  496. return TreeView_SetItem(hwndTreeView, &tvItem);
  497. }
  498. /////////////////////////////////////////////////////////////////////////////
  499. //
  500. // OnOK
  501. //
  502. /////////////////////////////////////////////////////////////////////////////
  503. void
  504. ParameterInheritanceDialogClass::OnOK (void)
  505. {
  506. DynamicVectorClass<PresetClass *> preset_list;
  507. DynamicVectorClass<DefinitionParameterClass *> parameter_list;
  508. //
  509. // Build a list of selected parameters and presets
  510. //
  511. Build_Parameter_List (parameter_list);
  512. Build_Preset_List (TVI_ROOT, preset_list);
  513. //
  514. // Does the user want to propogate the dialogue settings?
  515. //
  516. bool propogate_dialogue_settings = false;
  517. if (SendDlgItemMessage (IDC_PROPOGATE_DIALOGUE, BM_GETCHECK) == 1) {
  518. propogate_dialogue_settings = true;
  519. }
  520. //
  521. // Loop over all the selected presets and propagate the changes
  522. //
  523. DefinitionClass *base_def = m_Preset->Get_Definition ();
  524. for (int index = 0; index < preset_list.Count (); index ++) {
  525. PresetClass *preset = preset_list[index];
  526. DefinitionClass *derived_def = preset->Get_Definition ();
  527. if (base_def != NULL) {
  528. Propagate_Changes (base_def, derived_def, parameter_list);
  529. //
  530. // Propogate the dialogue settings if necessary
  531. //
  532. if ( propogate_dialogue_settings &&
  533. base_def->Get_Class_ID () == CLASSID_GAME_OBJECT_DEF_SOLDIER &&
  534. derived_def->Get_Class_ID () == CLASSID_GAME_OBJECT_DEF_SOLDIER)
  535. {
  536. SoldierGameObjDef *base_soldier = reinterpret_cast<SoldierGameObjDef *> (base_def);
  537. SoldierGameObjDef *derived_soldier = reinterpret_cast<SoldierGameObjDef *> (derived_def);
  538. DialogueClass *src_list = base_soldier->Get_Dialog_List ();
  539. DialogueClass *dest_list = derived_soldier->Get_Dialog_List ();
  540. //
  541. // Copy the settings from the base to the derived...
  542. //
  543. for (int index = 0; index < DIALOG_MAX; index ++) {
  544. dest_list[index] = src_list[index];
  545. }
  546. }
  547. }
  548. }
  549. CDialog::OnOK ();
  550. return ;
  551. }
  552. /////////////////////////////////////////////////////////////////////////////
  553. //
  554. // Find_Parameter_In_List
  555. //
  556. /////////////////////////////////////////////////////////////////////////////
  557. bool
  558. Find_Parameter_In_List
  559. (
  560. DynamicVectorClass<DefinitionParameterClass *> &parameter_list,
  561. ParameterClass * parameter
  562. )
  563. {
  564. bool retval = false;
  565. //
  566. // Loop over all the parameters in the list
  567. //
  568. for (int index = 0; index < parameter_list.Count (); index ++) {
  569. DefinitionParameterClass *def_param = parameter_list[index];
  570. //
  571. // Is this the parameter we were looking for?
  572. //
  573. if (def_param != NULL && def_param->Get_Parameter () == parameter) {
  574. retval = true;
  575. break;
  576. }
  577. }
  578. return retval;
  579. }
  580. /////////////////////////////////////////////////////////////////////////////
  581. //
  582. // Propagate_Changes
  583. //
  584. /////////////////////////////////////////////////////////////////////////////
  585. void
  586. ParameterInheritanceDialogClass::Propagate_Changes
  587. (
  588. DefinitionClass * base_def,
  589. DefinitionClass * derived_def,
  590. DynamicVectorClass<DefinitionParameterClass *> &parameter_list
  591. )
  592. {
  593. bool is_valid = true;
  594. //
  595. // Compare all the parameters with this derived definition to
  596. // find any that are not overridden.
  597. //
  598. int param_count = base_def->Get_Parameter_Count ();
  599. for (int param_index = 0; is_valid && param_index < param_count; param_index ++) {
  600. ParameterClass *parameter = base_def->Lock_Parameter (param_index);
  601. ParameterClass *curr_parameter = derived_def->Lock_Parameter (param_index);
  602. ASSERT (parameter != NULL);
  603. ASSERT (curr_parameter != NULL);
  604. //
  605. // Are we comparing the same parameter? (We better be).
  606. //
  607. if ( parameter->Get_Type () == curr_parameter->Get_Type () &&
  608. ::lstrcmpi (parameter->Get_Name (), curr_parameter->Get_Name ()) == 0)
  609. {
  610. //
  611. // Do we need to recurse into this parameter?
  612. //
  613. if (parameter->Get_Type () == ParameterClass::TYPE_MODELDEFINITIONID) {
  614. //
  615. // Lookup the definitions that these parameters reference
  616. //
  617. int base_id = ((ModelDefParameterClass *)parameter)->Get_Value ();
  618. int derived_id = ((ModelDefParameterClass *)curr_parameter)->Get_Value ();
  619. DefinitionClass *base_model_def = DefinitionMgrClass::Find_Definition (base_id, false);
  620. DefinitionClass *derived_model_def = DefinitionMgrClass::Find_Definition (derived_id, false);
  621. //
  622. // Recurse into these definitions
  623. //
  624. if ( base_model_def != NULL && derived_model_def != NULL &&
  625. base_model_def->Get_Class_ID () == derived_model_def->Get_Class_ID ())
  626. {
  627. Propagate_Changes (base_model_def, derived_model_def, parameter_list);
  628. }
  629. } else {
  630. //
  631. // Should we propagate this parameter's value?
  632. //
  633. if (::Find_Parameter_In_List (parameter_list, parameter)) {
  634. //
  635. // Copy the parameter value from the parent.
  636. //
  637. curr_parameter->Copy_Value (*parameter);
  638. }
  639. }
  640. } else {
  641. is_valid = false;
  642. }
  643. //
  644. // Release the parameter pointers
  645. //
  646. base_def->Unlock_Parameter (param_index);
  647. derived_def->Unlock_Parameter (param_index);
  648. }
  649. return ;
  650. }
  651. /////////////////////////////////////////////////////////////////////////////
  652. //
  653. // Build_Parameter_List
  654. //
  655. /////////////////////////////////////////////////////////////////////////////
  656. void
  657. ParameterInheritanceDialogClass::Build_Parameter_List (DynamicVectorClass<DefinitionParameterClass *> &parameter_list)
  658. {
  659. //
  660. // Loop over all the parameters
  661. //
  662. for (int index = 0; index < m_ListCtrl.GetItemCount (); index ++) {
  663. DefinitionParameterClass *parameter = NULL;
  664. parameter = (DefinitionParameterClass *)m_ListCtrl.GetItemData (index);
  665. //
  666. // Add this parameter to the list if the user checked it
  667. //
  668. if (parameter != NULL && ListView_GetCheckState (m_ListCtrl, index)) {
  669. parameter_list.Add (parameter);
  670. }
  671. }
  672. return ;
  673. }
  674. /////////////////////////////////////////////////////////////////////////////
  675. //
  676. // Build_Preset_List
  677. //
  678. /////////////////////////////////////////////////////////////////////////////
  679. void
  680. ParameterInheritanceDialogClass::Build_Preset_List
  681. (
  682. HTREEITEM parent_item,
  683. DynamicVectorClass<PresetClass *> & preset_list
  684. )
  685. {
  686. //
  687. // Loop over all the immediate children
  688. //
  689. for ( HTREEITEM item = m_TreeCtrl.GetChildItem (parent_item);
  690. item != NULL;
  691. item = m_TreeCtrl.GetNextSiblingItem (item))
  692. {
  693. PresetClass *preset = (PresetClass *)m_TreeCtrl.GetItemData (item);
  694. if (preset != NULL) {
  695. //
  696. // Add this preset to the list if necessary
  697. //
  698. if (m_TreeCtrl.GetCheck (item)) {
  699. preset_list.Add (preset);
  700. }
  701. //
  702. // Recurse down the tree
  703. //
  704. Build_Preset_List (item, preset_list);
  705. }
  706. }
  707. return ;
  708. }
  709. /////////////////////////////////////////////////////////////////////////////
  710. //
  711. // OnDeleteitemParameterList
  712. //
  713. /////////////////////////////////////////////////////////////////////////////
  714. void
  715. ParameterInheritanceDialogClass::OnDeleteitemParameterList
  716. (
  717. NMHDR * pNMHDR,
  718. LRESULT* pResult
  719. )
  720. {
  721. NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
  722. (*pResult) = 0;
  723. //
  724. // Free the object we associted with this entry
  725. //
  726. DefinitionParameterClass *def_param = NULL;
  727. def_param = (DefinitionParameterClass *)m_ListCtrl.GetItemData (pNMListView->iItem);
  728. MEMBER_RELEASE (def_param);
  729. m_ListCtrl.SetItemData (pNMListView->iItem, 0);
  730. return ;
  731. }