]> icculus.org git repositories - taylor/freespace2.git/blob - src/fred2/reinforcementeditordlg.cpp
Initial revision
[taylor/freespace2.git] / src / fred2 / reinforcementeditordlg.cpp
1 /*
2  * $Logfile: /Freespace2/code/fred2/ReinforcementEditorDlg.cpp $
3  * $Revision$
4  * $Date$
5  * $Author$
6  *
7  * Reinforcements editor dialog handling code
8  *
9  * $Log$
10  * Revision 1.1  2002/05/03 03:28:08  root
11  * Initial revision
12  *
13  * 
14  * 3     3/30/99 5:40p Dave
15  * Fixed reinforcements for TvT in multiplayer.
16  * 
17  * 2     10/07/98 6:28p Dave
18  * Initial checkin. Renamed all relevant stuff to be Fred2 instead of
19  * Fred. Globalized mission and campaign file extensions. Removed Silent
20  * Threat specific code.
21  * 
22  * 1     10/07/98 3:01p Dave
23  * 
24  * 1     10/07/98 3:00p Dave
25  * 
26  * 17    5/23/98 3:33p Hoffoss
27  * Removed unused code in reinforcements editor and make ships.tbl button
28  * in ship editor disappear in release build.
29  * 
30  * 16    1/02/98 12:45p Allender
31  * remove bogus assert
32  * 
33  * 15    7/17/97 10:17a Allender
34  * more reinforcement messaging stuff -- now working within Freespace.
35  * Fixed a couple of Fred bugs relating to not setting reinforcement flag
36  * properly
37  * 
38  * 14    7/16/97 11:02p Allender
39  * added messaging for reinforcements.  One (or one of several) can now
40  * play if reinforcement are not yet available, or when they are arriving
41  * 
42  * 13    7/08/97 10:15a Allender
43  * making ships/wings reinforcements now do not set the arrival cue to
44  * false.  A reinforcement may only be available after it's arrival cue is
45  * true
46  * 
47  * 12    5/20/97 2:29p Hoffoss
48  * Added message box queries for close window operation on all modal
49  * dialog boxes.
50  * 
51  * 11    5/14/97 4:08p Lawrance
52  * removing my_index from game arrays
53  * 
54  * 10    4/29/97 3:02p Hoffoss
55  * Reinforcement type is now automatically handled by Fred.
56  * 
57  * 9     4/17/97 2:01p Hoffoss
58  * All dialog box window states are saved between sessions now.
59  * 
60  * 8     3/20/97 3:55p Hoffoss
61  * Major changes to how dialog boxes initialize (load) and update (save)
62  * their internal data.  This should simplify things and create less
63  * problems.
64  * 
65  * 7     2/27/97 3:09p Allender
66  * major wing structure enhancement.  simplified wing code.  All around
67  * better wing support
68  * 
69  * 6     2/21/97 5:34p Hoffoss
70  * Added extensive modification detection and fixed a bug in initial
71  * orders editor.
72  * 
73  * 5     2/20/97 4:03p Hoffoss
74  * Several ToDo items: new reinforcement clears arrival cue, reinforcement
75  * control from ship and wing dialogs, show grid toggle.
76  * 
77  * 4     2/17/97 5:28p Hoffoss
78  * Checked RCS headers, added them were missing, changing description to
79  * something better, etc where needed.
80  * 
81  * 3     2/04/97 3:10p Hoffoss
82  * Reinforcements editor fully implemented.
83  * 
84  * 2     2/03/97 1:32p Hoffoss
85  * Reinforcement editor functional, but still missing a few options.
86  * Checking in good code now prior to experimenting, so I can revert if
87  * needed.
88  *
89  * $NoKeywords: $
90  */
91
92 #include "stdafx.h"
93 #include "fred.h"
94 #include "reinforcementeditordlg.h"
95 #include "missionparse.h"
96 #include "linklist.h"
97 #include "ship.h"
98 #include "freddoc.h"
99 #include "management.h"
100 #include "missionmessage.h"
101
102 #define ID_WING_DATA 9000
103
104 #ifdef _DEBUG
105 #define new DEBUG_NEW
106 #undef THIS_FILE
107 static char THIS_FILE[] = __FILE__;
108 #endif
109
110 /////////////////////////////////////////////////////////////////////////////
111 // reinforcement_editor_dlg dialog
112
113 reinforcement_editor_dlg::reinforcement_editor_dlg(CWnd* pParent /*=NULL*/)
114         : CDialog(reinforcement_editor_dlg::IDD, pParent)
115 {
116         //{{AFX_DATA_INIT(reinforcement_editor_dlg)
117         m_uses = 0;
118         m_delay = 0;
119         //}}AFX_DATA_INIT
120         cur = -1;
121 }
122
123 void reinforcement_editor_dlg::DoDataExchange(CDataExchange* pDX)
124 {
125         CDialog::DoDataExchange(pDX);
126         //{{AFX_DATA_MAP(reinforcement_editor_dlg)
127         DDX_Control(pDX, IDC_DELAY_SPIN, m_delay_spin);
128         DDX_Control(pDX, IDC_USES_SPIN, m_uses_spin);
129         DDX_Text(pDX, IDC_USES, m_uses);
130         DDX_Text(pDX, IDC_DELAY, m_delay);
131         //}}AFX_DATA_MAP
132 }
133
134 BEGIN_MESSAGE_MAP(reinforcement_editor_dlg, CDialog)
135         //{{AFX_MSG_MAP(reinforcement_editor_dlg)
136         ON_LBN_SELCHANGE(IDC_LIST, OnSelchangeList)
137         ON_BN_CLICKED(IDC_ADD, OnAdd)
138         ON_BN_CLICKED(IDC_DELETE, OnDelete)
139         ON_WM_CLOSE()
140         //}}AFX_MSG_MAP
141 END_MESSAGE_MAP()
142
143 /////////////////////////////////////////////////////////////////////////////
144 // reinforcement_editor_dlg message handlers
145
146 BOOL reinforcement_editor_dlg::OnInitDialog() 
147 {
148         int i;
149         CListBox        *box;
150
151         CDialog::OnInitDialog();
152         theApp.init_window(&Reinforcement_wnd_data, this);
153         box = (CListBox *) GetDlgItem(IDC_LIST);
154         for (i=0; i<Num_reinforcements; i++) {
155                 m_reinforcements[i] = Reinforcements[i];
156                 box->AddString(Reinforcements[i].name);
157         }
158
159         m_num_reinforcements = Num_reinforcements;
160         m_uses_spin.SetRange(1, 99);
161         m_delay_spin.SetRange(0, 1000);
162         update_data();
163         if (Num_reinforcements == MAX_REINFORCEMENTS)
164                 GetDlgItem(IDC_ADD) -> EnableWindow(FALSE);
165
166         return TRUE;
167 }
168
169 void reinforcement_editor_dlg::update_data()
170 {
171         object *objp;
172         int enable = TRUE;
173
174         if (cur < 0) {
175                 m_uses = 0;
176                 m_delay = 0;
177                 enable = FALSE;
178
179         } else {
180                 m_uses = m_reinforcements[cur].uses;
181                 m_delay = m_reinforcements[cur].arrival_delay;
182         }
183
184         UpdateData(FALSE);
185
186         GetDlgItem(IDC_USES)->EnableWindow(enable);
187         GetDlgItem(IDC_USES_SPIN)->EnableWindow(enable);
188         GetDlgItem(IDC_DELAY)->EnableWindow(enable);
189         GetDlgItem(IDC_DELAY_SPIN)->EnableWindow(enable);
190
191         if (cur < 0)
192                 return;
193
194         // disable the uses entries if the reinforcement is a ship
195         objp = GET_FIRST(&obj_used_list);
196         while (objp != END_OF_LIST(&obj_used_list)) {
197                 if (objp->type == OBJ_SHIP) {
198                         if ( !stricmp( Ships[objp->instance].ship_name, m_reinforcements[cur].name) ) {
199                                 GetDlgItem(IDC_USES)->EnableWindow(FALSE);
200                                 GetDlgItem(IDC_USES_SPIN)->EnableWindow(FALSE);
201                                 break;
202                         }
203                 }
204                 objp = GET_NEXT(objp);
205         }
206 }
207
208 void reinforcement_editor_dlg::OnSelchangeList() 
209 {
210         save_data();
211         cur = ((CListBox *) GetDlgItem(IDC_LIST))->GetCurSel();
212         GetDlgItem(IDC_DELETE) -> EnableWindow(cur != -1);
213         update_data();
214 }
215
216 void reinforcement_editor_dlg::save_data()
217 {
218         UpdateData(TRUE);
219         UpdateData(TRUE);
220         if (cur >= 0) {
221                 Assert(cur < m_num_reinforcements);
222                 m_reinforcements[cur].uses = m_uses;
223                 m_reinforcements[cur].arrival_delay = m_delay;
224
225                 // save the message information to the reinforcement structure.  First clear out the string
226                 // entires in the Reinforcement structure
227                 memset( m_reinforcements[cur].no_messages, 0, MAX_REINFORCEMENT_MESSAGES * NAME_LENGTH );
228                 memset( m_reinforcements[cur].yes_messages, 0, MAX_REINFORCEMENT_MESSAGES * NAME_LENGTH );
229         }
230 }
231
232 int reinforcement_editor_dlg::query_modified()
233 {
234         int i, j;
235
236         save_data();
237         if (Num_reinforcements != m_num_reinforcements)
238                 return 1;
239
240         for (i=0; i<Num_reinforcements; i++) {
241                 if (stricmp(m_reinforcements[i].name, Reinforcements[i].name))
242                         return 1;
243                 if (m_reinforcements[i].uses != Reinforcements[i].uses)
244                         return 1;
245                 if ( m_reinforcements[i].arrival_delay != Reinforcements[i].arrival_delay )
246                         return 1;
247
248                 // determine if the message content has changed
249                 for ( j = 0; j < MAX_REINFORCEMENT_MESSAGES; j++ ) {
250                         if ( stricmp(m_reinforcements[i].no_messages[j], Reinforcements[i].no_messages[j]) )
251                                 return 1;
252                 }
253                 for ( j = 0; j < MAX_REINFORCEMENT_MESSAGES; j++ ) {
254                         if ( stricmp(m_reinforcements[i].yes_messages[j], Reinforcements[i].yes_messages[j]) )
255                                 return 1;
256                 }
257         }
258
259         return 0;
260 }
261
262 void reinforcement_editor_dlg::OnOK()
263 {
264         int i, j;
265
266         save_data();
267         // clear arrival cues for any new reinforcements to the list
268         for (i=0; i<m_num_reinforcements; i++) {
269                 for (j=0; j<Num_reinforcements; j++)
270                         if (!stricmp(m_reinforcements[i].name, Reinforcements[j].name))
271                                 break;
272
273                 if (j == Num_reinforcements) {
274                         for (j=0; j<MAX_SHIPS; j++)
275                                 if ((Ships[j].objnum != -1) && !stricmp(m_reinforcements[i].name, Ships[j].ship_name)) {
276                                         //free_sexp2(Ships[j].arrival_cue);
277                                         //Ships[j].arrival_cue = Locked_sexp_false;
278                                         break;
279                                 }
280
281                         if (j == MAX_SHIPS) {
282                                 for (j=0; j<MAX_WINGS; j++)
283                                         if (Wings[j].wave_count && !stricmp(m_reinforcements[i].name, Wings[j].name)) {
284                                                 //free_sexp2(Wings[j].arrival_cue);
285                                                 //Wings[j].arrival_cue = Locked_sexp_false;
286                                                 break;
287                                         }
288
289                                 Assert(j < MAX_WINGS);
290                         }
291                 }
292         }
293
294         if (Num_reinforcements != m_num_reinforcements)
295                 set_modified();
296
297         Num_reinforcements = m_num_reinforcements;
298         for (i=0; i<m_num_reinforcements; i++) {
299                 if (memcmp((void *) &Reinforcements[i], (void *) &m_reinforcements[i], sizeof(reinforcements)))
300                         set_modified();
301
302                 Reinforcements[i] = m_reinforcements[i];
303                 set_reinforcement( Reinforcements[i].name, 1 );         // this call should
304         }
305
306         Update_ship = Update_wing = 1;
307         theApp.record_window_data(&Reinforcement_wnd_data, this);
308         CDialog::OnOK();
309 }
310
311 void reinforcement_editor_dlg::OnCancel()
312 {
313         theApp.record_window_data(&Reinforcement_wnd_data, this);
314         CDialog::OnCancel();
315 }
316
317 /////////////////////////////////////////////////////////////////////////////
318 // reinforcement_select dialog
319
320 reinforcement_select::reinforcement_select(CWnd* pParent /*=NULL*/)
321         : CDialog(reinforcement_select::IDD, pParent)
322 {
323         //{{AFX_DATA_INIT(reinforcement_select)
324                 // NOTE: the ClassWizard will add member initialization here
325         //}}AFX_DATA_INIT
326         cur = -1;
327 }
328
329 void reinforcement_select::DoDataExchange(CDataExchange* pDX)
330 {
331         CDialog::DoDataExchange(pDX);
332         //{{AFX_DATA_MAP(reinforcement_select)
333                 // NOTE: the ClassWizard will add DDX and DDV calls here
334         //}}AFX_DATA_MAP
335 }
336
337 BEGIN_MESSAGE_MAP(reinforcement_select, CDialog)
338         //{{AFX_MSG_MAP(reinforcement_select)
339         ON_LBN_SELCHANGE(IDC_LIST, OnSelchangeList)
340         //}}AFX_MSG_MAP
341 END_MESSAGE_MAP()
342
343 /////////////////////////////////////////////////////////////////////////////
344 // reinforcement_select message handlers
345
346 BOOL reinforcement_select::OnInitDialog()
347 {
348         int i, z;
349         CListBox *box;
350         object *ptr;
351
352         CDialog::OnInitDialog();
353         box = (CListBox *) GetDlgItem(IDC_LIST);
354         ptr = GET_FIRST(&obj_used_list);
355         while (ptr != END_OF_LIST(&obj_used_list)) {
356                 if (ptr->type == OBJ_SHIP) {
357                         z = box->AddString(Ships[ptr->instance].ship_name);
358                         box->SetItemData(z, OBJ_INDEX(ptr));
359                 }
360
361                 ptr = GET_NEXT(ptr);
362         }
363
364         for (i=0; i<num_wings; i++) {
365                 z = box->AddString(Wings[i].name);
366                 box->SetItemData(z, ID_WING_DATA + i);
367         }
368
369         return TRUE;  // return TRUE unless you set the focus to a control
370                       // EXCEPTION: OCX Property Pages should return FALSE
371 }
372
373 void reinforcement_select::OnSelchangeList() 
374 {
375         cur = ((CListBox *) GetDlgItem(IDC_LIST))->GetCurSel();
376         GetDlgItem(IDOK)->EnableWindow(cur != -1);
377 }
378
379 void reinforcement_select::OnOK()
380 {
381         cur = ((CListBox *) GetDlgItem(IDC_LIST))->GetCurSel();
382         Assert(cur != -1);
383         ((CListBox *) GetDlgItem(IDC_LIST)) -> GetText(cur, name);
384         CDialog::OnOK();
385 }
386
387 void reinforcement_select::OnCancel()
388 {
389         cur = -1;
390         CDialog::OnCancel();
391 }
392
393 void reinforcement_editor_dlg::OnAdd()
394 {
395         int i, wing_index;
396         reinforcement_select dlg;
397         CString name_check;
398
399         dlg.DoModal();
400         if (dlg.cur != -1) {
401                 // if we've run out of reinforcement slots
402                 if (m_num_reinforcements == MAX_REINFORCEMENTS) {
403                         MessageBox("Reached limit on reinforcements.  Can't add more!");
404                         return;
405                 }
406
407                 // if this is a wing, make sure its a valid wing (no mixed ship teams)
408                 wing_index = wing_lookup((char*)dlg.name);
409                 if(wing_index >= 0){
410                         if(wing_has_conflicting_teams(wing_index)){
411                                 MessageBox("Cannot have a reinforcement wing with mixed teams, sucka!");
412                                 return;
413                         }
414                 }
415
416                 i = m_num_reinforcements++;
417                 strcpy(m_reinforcements[i].name, dlg.name);
418                 ((CListBox *) GetDlgItem(IDC_LIST)) -> AddString(dlg.name);
419                 m_reinforcements[i].type = 0;
420                 m_reinforcements[i].uses = 1;
421                 m_reinforcements[i].arrival_delay = 0;
422                 memset( m_reinforcements[i].no_messages, 0, MAX_REINFORCEMENT_MESSAGES * NAME_LENGTH );
423                 memset( m_reinforcements[i].yes_messages, 0, MAX_REINFORCEMENT_MESSAGES * NAME_LENGTH );
424                 if (m_num_reinforcements == MAX_REINFORCEMENTS){
425                         GetDlgItem(IDC_ADD) -> EnableWindow(FALSE);
426                 }
427         }
428 }
429
430 void reinforcement_editor_dlg::OnDelete()
431 {
432         int i;
433
434         if (cur != -1) {
435                 ((CListBox *) GetDlgItem(IDC_LIST)) -> DeleteString(cur);
436                 for (i=cur; i<m_num_reinforcements-1; i++)
437                         m_reinforcements[i] = m_reinforcements[i + 1];
438         }
439
440         m_num_reinforcements--;
441         cur = -1;
442         if (!m_reinforcements)
443                 GetDlgItem(IDC_DELETE) -> EnableWindow(FALSE);
444 }
445
446 void reinforcement_editor_dlg::OnClose() 
447 {
448         int z;
449
450         if (query_modified()) {
451                 z = MessageBox("Do you want to keep your changes?", "Close", MB_ICONQUESTION | MB_YESNOCANCEL);
452                 if (z == IDCANCEL)
453                         return;
454
455                 if (z == IDYES) {
456                         OnOK();
457                         return;
458                 }
459         }
460         
461         CDialog::OnClose();
462 }