]> icculus.org git repositories - taylor/freespace2.git/blob - src/fred2/asteroideditordlg.cpp
fix issue with looping audio streams
[taylor/freespace2.git] / src / fred2 / asteroideditordlg.cpp
1 /*
2  * Copyright (C) Volition, Inc. 1999.  All rights reserved.
3  *
4  * All source code herein is the property of Volition, Inc. You may not sell 
5  * or otherwise commercially exploit the source or things you created based on
6  * the source.
7  */
8
9 // AsteroidEditorDlg.cpp : implementation file
10 //
11
12 #include "stdafx.h"
13 #include "fred.h"
14 #include "asteroideditordlg.h"
15 #include "starfield.h"
16 #include "freddoc.h"
17 #include "debris.h"     //      Asteroid stuff.
18
19 #ifdef _DEBUG
20 #define new DEBUG_NEW
21 #undef THIS_FILE
22 static char THIS_FILE[] = __FILE__;
23 #endif
24
25 #define ID_FIELD_MENU 9000
26
27 // helps in looping over combo boxes
28 int Dlg_id[3] = {IDC_SHIP_DEBRIS1, IDC_SHIP_DEBRIS2, IDC_SHIP_DEBRIS3};
29
30
31 /////////////////////////////////////////////////////////////////////////////
32 // asteroid_editor dialog
33
34 asteroid_editor::asteroid_editor(CWnd* pParent /*=NULL*/)
35         : CDialog(asteroid_editor::IDD, pParent)
36 {
37         int i;
38
39         //{{AFX_DATA_INIT(asteroid_editor)
40         m_avg_speed = 0;
41         m_density = 0;
42         m_enable_asteroids = FALSE;
43         m_max_x = _T("");
44         m_max_y = _T("");
45         m_max_z = _T("");
46         m_min_x = _T("");
47         m_min_y = _T("");
48         m_min_z = _T("");
49         m_enable_inner_bounds = FALSE;
50         m_field_type = FT_ACTIVE;
51         m_box_max_x = _T("");
52         m_box_max_y = _T("");
53         m_box_max_z = _T("");
54         m_box_min_x = _T("");
55         m_box_min_y = _T("");
56         m_box_min_z = _T("");
57         //}}AFX_DATA_INIT
58
59         last_field = -1;
60         i=0;
61 //      for (i=0; i<MAX_ASTEROID_FIELDS; i++)
62                 a_field[i] = Asteroid_field;    //      Only supporting one field per mission.
63 }
64
65 void asteroid_editor::DoDataExchange(CDataExchange* pDX)
66 {
67         CDialog::DoDataExchange(pDX);
68         //{{AFX_DATA_MAP(asteroid_editor)
69         DDX_Control(pDX, IDC_DENSITY_SPIN, m_density_spin);
70         DDX_Text(pDX, IDC_AVG_SPEED, m_avg_speed);
71         DDX_Text(pDX, IDC_DENSITY, m_density);
72         DDX_Check(pDX, IDC_ENABLE_ASTEROIDS, m_enable_asteroids);
73         DDX_Text(pDX, IDC_MAX_X, m_max_x);
74         DDX_Text(pDX, IDC_MAX_Y, m_max_y);
75         DDX_Text(pDX, IDC_MAX_Z, m_max_z);
76         DDX_Text(pDX, IDC_MIN_X, m_min_x);
77         DDX_Text(pDX, IDC_MIN_Y, m_min_y);
78         DDX_Text(pDX, IDC_MIN_Z, m_min_z);
79         DDX_Check(pDX, IDC_ENABLE_INNER_BOX, m_enable_inner_bounds);
80         DDX_Text(pDX, IDC_INNER_MAX_X, m_box_max_x);
81         DDX_Text(pDX, IDC_INNER_MAX_Y, m_box_max_y);
82         DDX_Text(pDX, IDC_INNER_MAX_Z, m_box_max_z);
83         DDX_Text(pDX, IDC_INNER_MIN_X, m_box_min_x);
84         DDX_Text(pDX, IDC_INNER_MIN_Y, m_box_min_y);
85         DDX_Text(pDX, IDC_INNER_MIN_Z, m_box_min_z);
86         //}}AFX_DATA_MAP
87 }
88
89 BEGIN_MESSAGE_MAP(asteroid_editor, CDialog)
90         //{{AFX_MSG_MAP(asteroid_editor)
91         ON_WM_INITMENU()
92         ON_BN_CLICKED(IDC_ENABLE_ASTEROIDS, OnEnableAsteroids)
93         ON_WM_CLOSE()
94         ON_BN_CLICKED(IDC_ENABLE_INNER_BOX, OnEnableInnerBox)
95         ON_BN_CLICKED(IDC_PASSIVE_FIELD, OnPassiveField)
96         ON_BN_CLICKED(IDC_FIELD_SHIP, OnFieldShip)
97         ON_BN_CLICKED(IDC_ACTIVE_FIELD, OnActiveField)
98         ON_BN_CLICKED(IDC_FIELD_ASTEROID, OnFieldAsteroid)
99         //}}AFX_MSG_MAP
100 END_MESSAGE_MAP()
101
102 /////////////////////////////////////////////////////////////////////////////
103 // asteroid_editor message handlers
104
105 void asteroid_editor::OnInitMenu(CMenu* pMenu)
106 {
107         int i;
108         CString str;
109         CMenu *m;
110
111         m = pMenu->GetSubMenu(0);
112         clear_menu(m);
113         i = 0; //for (i=0; i<MAX_ASTEROID_FIELDS; i++) {
114                 str.Format("Asteroid Field %d", i);
115                 m->AppendMenu(MF_ENABLED | MF_STRING, ID_FIELD_MENU + i, str);
116         //}
117
118         m->DeleteMenu(ID_PLACEHOLDER, MF_BYCOMMAND);
119         if (cur_field != -1)
120                 m->CheckMenuItem(ID_FIELD_MENU + cur_field, MF_BYCOMMAND | MF_CHECKED);
121
122         CDialog::OnInitMenu(pMenu);
123 }
124
125 BOOL asteroid_editor::OnCommand(WPARAM wParam, LPARAM lParam) 
126 {
127         int id;
128
129         id = LOWORD(wParam);
130         if (id >= ID_FIELD_MENU && id < ID_FIELD_MENU + 1) { //MAX_ASTEROID_FIELDS) {
131                 cur_field = id - ID_FIELD_MENU;
132                 update_init();
133         }
134
135         return CDialog::OnCommand(wParam, lParam);
136 }
137
138 int asteroid_editor::query_modified()
139 {
140         int i;
141
142         for (i=0; i<1 /*MAX_ASTEROID_FIELDS*/; i++) {
143                 if (a_field[i].num_initial_asteroids != Asteroid_field.num_initial_asteroids)
144                         return 1;
145                 if (vm_vec_dist_quick(&a_field[i].vel, &Asteroid_field.vel) == 0.0f)
146                         return 1;
147                 if (a_field[i].min_bound.x != Asteroid_field.min_bound.x)
148                         return 1;
149                 if (a_field[i].min_bound.y != Asteroid_field.min_bound.y)
150                         return 1;
151                 if (a_field[i].min_bound.z != Asteroid_field.min_bound.z)
152                         return 1;
153                 if (a_field[i].max_bound.x != Asteroid_field.max_bound.x)
154                         return 1;
155                 if (a_field[i].max_bound.y != Asteroid_field.max_bound.y)
156                         return 1;
157                 if (a_field[i].max_bound.z != Asteroid_field.max_bound.z)
158                         return 1;
159
160
161                 if (a_field[i].has_inner_bound != Asteroid_field.has_inner_bound)
162                         return 1;
163
164                 if (a_field[i].field_type != Asteroid_field.field_type)
165                         return 1;
166
167                 if (a_field[i].has_inner_bound) {
168                         if (a_field[i].inner_max_bound.x != Asteroid_field.inner_max_bound.x)
169                                 return 1;
170
171                         if (a_field[i].inner_max_bound.y != Asteroid_field.inner_max_bound.y)
172                                 return 1;
173
174                         if (a_field[i].inner_max_bound.z != Asteroid_field.inner_max_bound.z)
175                                 return 1;
176
177                         if (a_field[i].inner_min_bound.x != Asteroid_field.inner_min_bound.x)
178                                 return 1;
179
180                         if (a_field[i].inner_min_bound.y != Asteroid_field.inner_min_bound.y)
181                                 return 1;
182
183                         if (a_field[i].inner_min_bound.z != Asteroid_field.inner_min_bound.z)
184                                 return 1;
185                 }
186
187         }
188
189         return 0;
190 }
191
192 #define MIN_BOX_THICKNESS 400
193 int asteroid_editor::validate_data()
194 {
195         if (!m_enable_asteroids) {
196                 return 1;
197         } else {
198                 // check x
199                 if (a_field[0].max_bound.x < a_field[0].min_bound.x) {
200                         MessageBox("Asteroid x min is greater than max");
201                         return 0;
202                 }
203
204                 // check y
205                 if (a_field[0].max_bound.y < a_field[0].min_bound.y) {
206                         MessageBox("Asteroid y min is greater than max");
207                         return 0;
208                 }
209
210                 // check z
211                 if (a_field[0].max_bound.z < a_field[0].min_bound.z) {
212                         MessageBox("Asteroid z min is greater than max");
213                         return 0;
214                 }
215
216                 // check if inner bounds enabled
217                 if (a_field[0].has_inner_bound) {
218                         if (a_field[0].inner_max_bound.x < a_field[0].inner_min_bound.x) {
219                                 MessageBox("Asteroid x inner min is greater than inner max");
220                                 return 0;
221                         }
222
223                         if (a_field[0].inner_max_bound.y < a_field[0].inner_min_bound.y) {
224                                 MessageBox("Asteroid y inner min is greater than inner max");
225                                 return 0;
226                         }
227
228                         if (a_field[0].inner_max_bound.z < a_field[0].inner_min_bound.z) {
229                                 MessageBox("Asteroid z inner min is greater than inner max");
230                                 return 0;
231                         }
232
233                         // check x thickness
234                         if (a_field[0].inner_min_bound.x - MIN_BOX_THICKNESS < a_field[0].min_bound.x) {
235                                 MessageBox("Asteroid x thickness from outer box to inner box must be > 400");
236                                 return 0;
237                         }
238
239                         if (a_field[0].inner_max_bound.x + MIN_BOX_THICKNESS > a_field[0].max_bound.x) {
240                                 MessageBox("Asteroid x thickness from outer box to inner box must be > 400");
241                                 return 0;
242                         }
243
244                         // check y thickness
245                         if (a_field[0].inner_min_bound.y - MIN_BOX_THICKNESS < a_field[0].min_bound.y) {
246                                 MessageBox("Asteroid y thickness from outer box to inner box must be > 400");
247                                 return 0;
248                         }
249
250                         if (a_field[0].inner_max_bound.y + MIN_BOX_THICKNESS > a_field[0].max_bound.y) {
251                                 MessageBox("Asteroid y thickness from outer box to inner box must be > 400");
252                                 return 0;
253                         }
254
255                         // check z thickness
256                         if (a_field[0].inner_min_bound.z - MIN_BOX_THICKNESS < a_field[0].min_bound.z) {
257                                 MessageBox("Asteroid z thickness from outer box to inner box must be > 400");
258                                 return 0;
259                         }
260
261                         if (a_field[0].inner_max_bound.z + MIN_BOX_THICKNESS > a_field[0].max_bound.z) {
262                                 MessageBox("Asteroid z thickness from outer box to inner box must be > 400");
263                                 return 0;
264                         }
265                 }
266
267                 // check if passive, ship debris field, at least one speceis selected
268                 if (a_field[0].field_type == FT_PASSIVE) {
269                         if (a_field[0].debris_genre == DG_SHIP) {
270                                 if ( (a_field[0].field_debris_type[0] == -1) && (a_field[0].field_debris_type[1] == -1) && (a_field[0].field_debris_type[2] == -1) ) {
271                                         MessageBox("You must choose one or more types of ship debris");
272                                         return 0;
273                                 }
274                         }
275                 }
276
277                 // check at least one asteroid subtype is selected
278                 if (a_field[0].debris_genre == DG_ASTEROID) {
279                         if ( (a_field[0].field_debris_type[0] == -1) && (a_field[0].field_debris_type[1] == -1) && (a_field[0].field_debris_type[2] == -1) ) {
280                                 MessageBox("You must choose one or more asteroid subtypes");
281                                 return 0;
282                         }
283                 }
284
285         }
286
287         return 1;
288 }
289
290
291
292
293 void asteroid_editor::OnOK()
294 {
295         int i;
296
297         update_init();
298         if (!validate_data()) {
299                 return;
300         }
301         for (i=0; i<1 /*MAX_ASTEROID_FIELDS*/; i++)
302                 Asteroid_field = a_field[i];
303
304         update_map_window();
305         theApp.record_window_data(&Asteroid_wnd_data, this);
306         CDialog::OnOK();
307 }
308
309 BOOL asteroid_editor::OnInitDialog() 
310 {
311         cur_field = 0;
312         CDialog::OnInitDialog();
313         update_init();
314         theApp.init_window(&Asteroid_wnd_data, this);
315
316         m_density_spin.SetRange(1, MAX_ASTEROIDS);
317         return TRUE;
318 }
319
320 void asteroid_editor::update_init()
321 {
322         int num_asteroids, idx, cur_choice;
323
324         UpdateData(TRUE);
325         if (last_field >= 0) {
326                 // store into temp asteroid field
327                 num_asteroids = a_field[last_field].num_initial_asteroids;
328                 a_field[last_field].num_initial_asteroids = m_enable_asteroids ? m_density : 0;
329                 if (a_field[last_field].num_initial_asteroids < 0)
330                         a_field[last_field].num_initial_asteroids = 0;
331
332                 if (a_field[last_field].num_initial_asteroids > MAX_ASTEROIDS)
333                         a_field[last_field].num_initial_asteroids = MAX_ASTEROIDS;
334
335                 if (num_asteroids != a_field[last_field].num_initial_asteroids)
336                         set_modified();
337
338                 vector  vel_vec = {1.0f, 0.0f, 0.0f};
339                 vm_vec_scale(&vel_vec, (float) m_avg_speed);
340
341                 MODIFY(a_field[last_field].vel.x, vel_vec.x);
342                 MODIFY(a_field[last_field].vel.y, vel_vec.y);
343                 MODIFY(a_field[last_field].vel.z, vel_vec.z);
344
345                 MODIFY(a_field[last_field].min_bound.x, (float) atof(m_min_x));
346                 MODIFY(a_field[last_field].min_bound.y, (float) atof(m_min_y));
347                 MODIFY(a_field[last_field].min_bound.z, (float) atof(m_min_z));
348                 MODIFY(a_field[last_field].max_bound.x, (float) atof(m_max_x));
349                 MODIFY(a_field[last_field].max_bound.y, (float) atof(m_max_y));
350                 MODIFY(a_field[last_field].max_bound.z, (float) atof(m_max_z));
351
352                 // type of field
353                 MODIFY(a_field[last_field].field_type, m_field_type);
354                 MODIFY(a_field[last_field].debris_genre, m_debris_genre);
355                 if ( (m_field_type == FT_PASSIVE) && (m_debris_genre == DG_SHIP) ) {
356                         // we should have ship debris
357                         for (idx=0; idx<3; idx++) {
358                                 // loop over combo boxes, store the item data of the cur selection, -1 in no cur selection
359                                 int cur_sel = ((CComboBox*)GetDlgItem(Dlg_id[idx]))->GetCurSel();
360                                 if (cur_sel != CB_ERR) {
361                                         cur_choice = ((CComboBox*)GetDlgItem(Dlg_id[idx]))->GetItemData(cur_sel);
362                                 } else {
363                                         cur_choice = -1;
364                                 }
365                                 MODIFY(a_field[cur_field].field_debris_type[idx], cur_choice);
366                         }
367                 }
368
369                 if ( m_debris_genre == DG_ASTEROID ) {
370                         if ( ((CButton *)GetDlgItem(IDC_SUBTYPE1))->GetCheck() == 1) {
371                                 cur_choice = 1;
372                         } else {
373                                 cur_choice = -1;
374                         }
375                         MODIFY(a_field[cur_field].field_debris_type[0], cur_choice);
376
377
378                         if ( ((CButton *)GetDlgItem(IDC_SUBTYPE2))->GetCheck() == 1) {
379                                 cur_choice = 1;
380                         } else {
381                                 cur_choice = -1;
382                         }
383                         MODIFY(a_field[cur_field].field_debris_type[1], cur_choice);
384
385
386                         if ( ((CButton *)GetDlgItem(IDC_SUBTYPE3))->GetCheck() == 1) {
387                                 cur_choice = 1;
388                         } else {
389                                 cur_choice = -1;
390                         }
391                         MODIFY(a_field[cur_field].field_debris_type[2], cur_choice);
392                 }
393
394                 MODIFY(a_field[last_field].has_inner_bound, m_enable_inner_bounds);
395
396                 MODIFY(a_field[last_field].inner_min_bound.x, (float) atof(m_box_min_x));
397                 MODIFY(a_field[last_field].inner_min_bound.y, (float) atof(m_box_min_y));
398                 MODIFY(a_field[last_field].inner_min_bound.z, (float) atof(m_box_min_z));
399                 MODIFY(a_field[last_field].inner_max_bound.x, (float) atof(m_box_max_x));
400                 MODIFY(a_field[last_field].inner_max_bound.y, (float) atof(m_box_max_y));
401                 MODIFY(a_field[last_field].inner_max_bound.z, (float) atof(m_box_max_z));
402         }
403
404         SDL_assert(cur_field >= 0);
405         // get from temp asteroid field into class
406         m_enable_asteroids = a_field[cur_field].num_initial_asteroids ? TRUE : FALSE;
407         m_enable_inner_bounds = a_field[cur_field].has_inner_bound ? TRUE : FALSE;
408         m_density = a_field[cur_field].num_initial_asteroids;
409         if (!m_enable_asteroids)
410                 m_density = 10;
411
412         // set field type
413         m_field_type = a_field[cur_field].field_type;
414         m_debris_genre = a_field[cur_field].debris_genre;
415 //      m_debris_species = a_field[cur_field].debris_species;
416
417         m_avg_speed = (int) vm_vec_mag(&a_field[cur_field].vel);
418         m_min_x.Format("%.1f", a_field[cur_field].min_bound.x);
419         m_min_y.Format("%.1f", a_field[cur_field].min_bound.y);
420         m_min_z.Format("%.1f", a_field[cur_field].min_bound.z);
421         m_max_x.Format("%.1f", a_field[cur_field].max_bound.x);
422         m_max_y.Format("%.1f", a_field[cur_field].max_bound.y);
423         m_max_z.Format("%.1f", a_field[cur_field].max_bound.z);
424
425         m_box_min_x.Format("%.1f", a_field[cur_field].inner_min_bound.x);
426         m_box_min_y.Format("%.1f", a_field[cur_field].inner_min_bound.y);
427         m_box_min_z.Format("%.1f", a_field[cur_field].inner_min_bound.z);
428         m_box_max_x.Format("%.1f", a_field[cur_field].inner_max_bound.x);
429         m_box_max_y.Format("%.1f", a_field[cur_field].inner_max_bound.y);
430         m_box_max_z.Format("%.1f", a_field[cur_field].inner_max_bound.z);
431
432         // set up combo boxes
433         int box_index;
434         int num_field_debris_info = MAX_DEBRIS_TYPES + 1;
435
436         for (idx=0; idx<num_field_debris_info; idx++) {
437                 box_index = ((CComboBox*)GetDlgItem(IDC_SHIP_DEBRIS1))->AddString(Field_debris_info[idx].name);
438                 ((CComboBox*)GetDlgItem(IDC_SHIP_DEBRIS1))->SetItemData(box_index, Field_debris_info[idx].index);
439
440                 box_index = ((CComboBox*)GetDlgItem(IDC_SHIP_DEBRIS2))->AddString(Field_debris_info[idx].name);
441                 ((CComboBox*)GetDlgItem(IDC_SHIP_DEBRIS2))->SetItemData(box_index, Field_debris_info[idx].index);
442
443                 box_index = ((CComboBox*)GetDlgItem(IDC_SHIP_DEBRIS3))->AddString(Field_debris_info[idx].name);
444                 ((CComboBox*)GetDlgItem(IDC_SHIP_DEBRIS3))->SetItemData(box_index, Field_debris_info[idx].index);
445         }
446
447         // now delete asteroid data
448         // search by string Field_debris_info[1-3].name
449
450         for (idx=0; idx<3; idx++) {
451                 box_index = ((CComboBox*)GetDlgItem(Dlg_id[idx]))->FindStringExact(0, Field_debris_info[1].name);       // "Asteroid Small"
452                 if (box_index > 0) {
453                         ((CComboBox*)GetDlgItem(Dlg_id[idx]))->DeleteString(box_index);
454                 }
455
456                 box_index = ((CComboBox*)GetDlgItem(Dlg_id[idx]))->FindStringExact(0, Field_debris_info[2].name);       // "Asteroid Medium"
457                 if (box_index > 0) {
458                         ((CComboBox*)GetDlgItem(Dlg_id[idx]))->DeleteString(box_index);
459                 }
460
461                 box_index = ((CComboBox*)GetDlgItem(Dlg_id[idx]))->FindStringExact(0, Field_debris_info[3].name);       // "Asteroid Big"
462                 if (box_index > 0) {
463                         ((CComboBox*)GetDlgItem(Dlg_id[idx]))->DeleteString(box_index);
464                 }
465         }
466
467         // set active debris type for each combo box
468         int box_count, cur_box_data;
469         for (idx=0;idx<3; idx++) {
470                 // Only set selection if not "None"
471                 if (a_field[cur_field].field_debris_type[idx] != -1) {
472                         box_count = ((CComboBox*)GetDlgItem(Dlg_id[idx]))->GetCount();
473                         for (box_index=0; box_index<box_count; box_index++) {
474                                 cur_box_data = ((CComboBox*)GetDlgItem(Dlg_id[idx]))->GetItemData(box_index);
475                                 if (cur_box_data == a_field[cur_field].field_debris_type[idx]) {
476                                         // set cur sel
477                                         ((CComboBox*)GetDlgItem(Dlg_id[idx]))->SetCurSel(box_index);
478                                         break;
479                                 }
480                         }
481                 }
482         }
483
484         // set up asteroid subtype checkboxes
485         ((CButton*)GetDlgItem(IDC_SUBTYPE1))->SetCheck(a_field[cur_field].field_debris_type[0] == 1);
486         ((CButton*)GetDlgItem(IDC_SUBTYPE2))->SetCheck(a_field[cur_field].field_debris_type[1] == 1);
487         ((CButton*)GetDlgItem(IDC_SUBTYPE3))->SetCheck(a_field[cur_field].field_debris_type[2] == 1);
488
489
490         UpdateData(FALSE);
491         OnEnableAsteroids();
492
493         last_field = cur_field;
494 }
495
496 void asteroid_editor::OnEnableAsteroids() 
497 {
498         UpdateData(TRUE);
499         GetDlgItem(IDC_DENSITY)->EnableWindow(m_enable_asteroids);
500         GetDlgItem(IDC_DENSITY_SPIN)->EnableWindow(m_enable_asteroids);
501         GetDlgItem(IDC_AVG_SPEED)->EnableWindow(m_enable_asteroids);
502         GetDlgItem(IDC_MIN_X)->EnableWindow(m_enable_asteroids);
503         GetDlgItem(IDC_MIN_Y)->EnableWindow(m_enable_asteroids);
504         GetDlgItem(IDC_MIN_Z)->EnableWindow(m_enable_asteroids);
505         GetDlgItem(IDC_MAX_X)->EnableWindow(m_enable_asteroids);
506         GetDlgItem(IDC_MAX_Y)->EnableWindow(m_enable_asteroids);
507         GetDlgItem(IDC_MAX_Z)->EnableWindow(m_enable_asteroids);
508
509         GetDlgItem(IDC_ENABLE_INNER_BOX)->EnableWindow(m_enable_asteroids);
510         GetDlgItem(IDC_PASSIVE_FIELD)->EnableWindow(m_enable_asteroids);
511         GetDlgItem(IDC_ACTIVE_FIELD)->EnableWindow(m_enable_asteroids);
512
513         GetDlgItem(IDC_FIELD_SHIP)->EnableWindow(m_enable_asteroids);
514         GetDlgItem(IDC_FIELD_ASTEROID)->EnableWindow(m_enable_asteroids);
515         GetDlgItem(IDC_SHIP_DEBRIS1)->EnableWindow(m_enable_asteroids && (Asteroid_field.debris_genre == DG_SHIP));
516         GetDlgItem(IDC_SHIP_DEBRIS2)->EnableWindow(m_enable_asteroids && (Asteroid_field.debris_genre == DG_SHIP));
517         GetDlgItem(IDC_SHIP_DEBRIS3)->EnableWindow(m_enable_asteroids && (Asteroid_field.debris_genre == DG_SHIP));
518         GetDlgItem(IDC_SUBTYPE1)->EnableWindow(m_enable_asteroids && (Asteroid_field.debris_genre == DG_ASTEROID));
519         GetDlgItem(IDC_SUBTYPE2)->EnableWindow(m_enable_asteroids && (Asteroid_field.debris_genre == DG_ASTEROID));
520         GetDlgItem(IDC_SUBTYPE3)->EnableWindow(m_enable_asteroids && (Asteroid_field.debris_genre == DG_ASTEROID));
521
522         OnEnableInnerBox();
523         OnEnableField();
524 }
525
526 void asteroid_editor::OnCancel()
527 {
528         theApp.record_window_data(&Asteroid_wnd_data, this);
529         CDialog::OnCancel();
530 }
531
532 void asteroid_editor::OnClose() 
533 {
534         int z;
535
536         update_init();
537         if (query_modified()) {
538                 z = MessageBox("Do you want to keep your changes?", "Close", MB_ICONQUESTION | MB_YESNOCANCEL);
539                 if (z == IDCANCEL)
540                         return;
541
542                 if (z == IDYES) {
543                         OnOK();
544                         return;
545                 }
546         }
547         
548         CDialog::OnClose();
549 }
550
551 // enable inner box (asteroid free zone)
552 // only allowed for active debris field
553 void asteroid_editor::OnEnableInnerBox() 
554 {
555         UpdateData(TRUE);
556
557         GetDlgItem(IDC_INNER_MIN_X)->EnableWindow(m_enable_inner_bounds && m_enable_asteroids);
558         GetDlgItem(IDC_INNER_MAX_X)->EnableWindow(m_enable_inner_bounds && m_enable_asteroids);
559         GetDlgItem(IDC_INNER_MIN_Y)->EnableWindow(m_enable_inner_bounds && m_enable_asteroids);
560         GetDlgItem(IDC_INNER_MAX_Y)->EnableWindow(m_enable_inner_bounds && m_enable_asteroids);
561         GetDlgItem(IDC_INNER_MIN_Z)->EnableWindow(m_enable_inner_bounds && m_enable_asteroids);
562         GetDlgItem(IDC_INNER_MAX_Z)->EnableWindow(m_enable_inner_bounds && m_enable_asteroids);
563 }
564
565 // 
566 void asteroid_editor::OnEnableField() 
567 {
568         // set check in active
569         if (m_enable_asteroids) {
570                 if (m_field_type == FT_ACTIVE) {
571                         OnActiveField();
572                 } else {
573                         OnPassiveField();
574                 }
575         }
576
577         // maybe enable species
578         if ( m_enable_asteroids && (m_field_type == FT_PASSIVE) && (m_debris_genre == DG_SHIP) ) {
579                 OnFieldShip();
580         }
581 }
582
583
584 void asteroid_editor::OnActiveField()
585 {
586         // set field type
587         m_field_type = FT_ACTIVE;
588         m_debris_genre = DG_ASTEROID;
589
590         // gray out ship and species
591         GetDlgItem(IDC_FIELD_SHIP)->EnableWindow(FALSE);
592         GetDlgItem(IDC_SHIP_DEBRIS1)->EnableWindow(FALSE);
593         GetDlgItem(IDC_SHIP_DEBRIS2)->EnableWindow(FALSE);
594         GetDlgItem(IDC_SHIP_DEBRIS3)->EnableWindow(FALSE);
595         GetDlgItem(IDC_SUBTYPE1)->EnableWindow(TRUE);
596         GetDlgItem(IDC_SUBTYPE2)->EnableWindow(TRUE);
597         GetDlgItem(IDC_SUBTYPE3)->EnableWindow(TRUE);
598
599         // force check of asteroid
600         ((CButton*)GetDlgItem(IDC_FIELD_ASTEROID))->SetCheck(1);
601         ((CButton*)GetDlgItem(IDC_FIELD_SHIP))->SetCheck(0);
602
603         // force check of active field
604         ((CButton*)GetDlgItem(IDC_ACTIVE_FIELD))->SetCheck(1);
605         ((CButton*)GetDlgItem(IDC_PASSIVE_FIELD))->SetCheck(0);
606
607         // enable inner box
608         GetDlgItem(IDC_ENABLE_INNER_BOX)->EnableWindow(TRUE);
609 }
610
611 void asteroid_editor::OnPassiveField()
612 {
613         // set field type
614         m_field_type = FT_PASSIVE;
615
616         // acivate ship
617         GetDlgItem(IDC_FIELD_SHIP)->EnableWindow(TRUE);
618
619         // maybe activate species
620         GetDlgItem(IDC_SHIP_DEBRIS1)->EnableWindow(m_debris_genre == DG_SHIP);
621         GetDlgItem(IDC_SHIP_DEBRIS2)->EnableWindow(m_debris_genre == DG_SHIP);
622         GetDlgItem(IDC_SHIP_DEBRIS3)->EnableWindow(m_debris_genre == DG_SHIP);
623
624         // maybe activate asteroid subtype
625         GetDlgItem(IDC_SUBTYPE1)->EnableWindow(m_debris_genre == DG_ASTEROID);
626         GetDlgItem(IDC_SUBTYPE2)->EnableWindow(m_debris_genre == DG_ASTEROID);
627         GetDlgItem(IDC_SUBTYPE3)->EnableWindow(m_debris_genre == DG_ASTEROID);
628
629
630         // force check of current debris type
631         ((CButton*)GetDlgItem(IDC_FIELD_ASTEROID))->SetCheck(m_debris_genre == DG_ASTEROID);
632         ((CButton*)GetDlgItem(IDC_FIELD_SHIP))->SetCheck(m_debris_genre == DG_SHIP);
633
634         // force check of passive field
635         ((CButton*)GetDlgItem(IDC_ACTIVE_FIELD))->SetCheck(0);
636         ((CButton*)GetDlgItem(IDC_PASSIVE_FIELD))->SetCheck(1);
637
638         // disable inner box
639         GetDlgItem(IDC_ENABLE_INNER_BOX)->EnableWindow(FALSE);
640 }
641
642 void asteroid_editor::OnFieldShip()
643 {
644         // set debris type 
645         m_debris_genre = DG_SHIP;
646
647         GetDlgItem(IDC_SHIP_DEBRIS1)->EnableWindow(TRUE);
648         GetDlgItem(IDC_SHIP_DEBRIS2)->EnableWindow(TRUE);
649         GetDlgItem(IDC_SHIP_DEBRIS3)->EnableWindow(TRUE);
650
651         GetDlgItem(IDC_SUBTYPE1)->EnableWindow(FALSE);
652         GetDlgItem(IDC_SUBTYPE2)->EnableWindow(FALSE);
653         GetDlgItem(IDC_SUBTYPE3)->EnableWindow(FALSE);
654
655         // force check of ship
656         ((CButton*)GetDlgItem(IDC_FIELD_ASTEROID))->SetCheck(0);
657         ((CButton*)GetDlgItem(IDC_FIELD_SHIP))->SetCheck(1);
658
659 }
660
661 void asteroid_editor::OnFieldAsteroid()
662 {
663         // set debris type 
664         m_debris_genre = DG_ASTEROID;
665
666         GetDlgItem(IDC_SHIP_DEBRIS1)->EnableWindow(FALSE);
667         GetDlgItem(IDC_SHIP_DEBRIS2)->EnableWindow(FALSE);
668         GetDlgItem(IDC_SHIP_DEBRIS3)->EnableWindow(FALSE);
669
670
671         GetDlgItem(IDC_SUBTYPE1)->EnableWindow(TRUE);
672         GetDlgItem(IDC_SUBTYPE2)->EnableWindow(TRUE);
673         GetDlgItem(IDC_SUBTYPE3)->EnableWindow(TRUE);
674
675         // force check of asteroid
676         ((CButton*)GetDlgItem(IDC_FIELD_ASTEROID))->SetCheck(1);
677         ((CButton*)GetDlgItem(IDC_FIELD_SHIP))->SetCheck(0);
678 }
679