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