]> icculus.org git repositories - taylor/freespace2.git/blob - src/fred2/waypointpathdlg.cpp
fix issue with looping audio streams
[taylor/freespace2.git] / src / fred2 / waypointpathdlg.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/WaypointPathDlg.cpp $
11  * $Revision$
12  * $Date$
13  * $Author$
14  *
15  * Waypoint editor
16  *
17  * $Log$
18  * Revision 1.3  2002/06/09 04:41:17  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:09  root
25  * Initial import.
26  *
27  * 
28  * 2     10/07/98 6:28p Dave
29  * Initial checkin. Renamed all relevant stuff to be Fred2 instead of
30  * Fred. Globalized mission and campaign file extensions. Removed Silent
31  * Threat specific code.
32  * 
33  * 1     10/07/98 3:02p Dave
34  * 
35  * 1     10/07/98 3:00p Dave
36  * 
37  * 12    3/21/98 7:36p Lawrance
38  * Move jump nodes to own lib.
39  * 
40  * 11    3/10/98 6:11p Hoffoss
41  * Added jump node renaming abilities to Fred.
42  * 
43  * 10    8/12/97 1:55a Hoffoss
44  * Made extensive changes to object reference checking and handling for
45  * object deletion call.
46  * 
47  * 9     5/23/97 1:53p Hoffoss
48  * Fixed problems with modeless dialog updating.  It won't get caught in
49  * an infinate loop anymore, but still gives an error warning 3 times when
50  * using cancel and trying to switch window focus to main window.  Don't
51  * know if I can fix that, but it's not too critical right now.
52  * 
53  * 8     5/14/97 4:08p Lawrance
54  * removing my_index from game arrays
55  * 
56  * 7     4/28/97 4:14p Hoffoss
57  * Fixed several bugs involving waypoints.
58  * 
59  * 6     3/13/97 12:09p Hoffoss
60  * Waypoint path editor finished (apparently I didn't get around to
61  * completing it before).
62  * 
63  * 5     2/28/97 11:31a Hoffoss
64  * Implemented modeless dialog saving and restoring, and changed some
65  * variables names.
66  * 
67  * 4     2/21/97 5:34p Hoffoss
68  * Added extensive modification detection and fixed a bug in initial
69  * orders editor.
70  * 
71  * 3     2/12/97 5:50p Hoffoss
72  * Expanded on error checking.
73  * 
74  * 2     2/12/97 12:26p Hoffoss
75  * Expanded on global error checker, added initial orders conflict
76  * checking and warning, added waypoint editor dialog and code.
77  *
78  * $NoKeywords: $
79  */
80
81 #include "stdafx.h"
82 #include "fred.h"
83 #include "waypointpathdlg.h"
84 #include "management.h"
85 #include "mainfrm.h"
86 #include "object.h"
87 #include "linklist.h"
88 #include "ship.h"
89 #include "aigoals.h"
90 #include "starfield.h"
91 #include "jumpnode.h"
92
93 #define ID_JUMP_NODE_MENU       8000
94 #define ID_WAYPOINT_MENU        9000
95
96 #ifdef _DEBUG
97 #define new DEBUG_NEW
98 #undef THIS_FILE
99 static char THIS_FILE[] = __FILE__;
100 #endif
101
102 /////////////////////////////////////////////////////////////////////////////
103 // waypoint_path_dlg dialog
104
105 waypoint_path_dlg::waypoint_path_dlg(CWnd* pParent /*=NULL*/)
106         : CDialog(waypoint_path_dlg::IDD, pParent)
107 {
108         //{{AFX_DATA_INIT(waypoint_path_dlg)
109         m_name = _T("");
110         //}}AFX_DATA_INIT
111         bypass_errors = 0;
112 }
113
114 void waypoint_path_dlg::DoDataExchange(CDataExchange* pDX)
115 {
116         CDialog::DoDataExchange(pDX);
117         //{{AFX_DATA_MAP(waypoint_path_dlg)
118         DDX_Text(pDX, IDC_NAME, m_name);
119         //}}AFX_DATA_MAP
120 }
121
122 BEGIN_MESSAGE_MAP(waypoint_path_dlg, CDialog)
123         //{{AFX_MSG_MAP(waypoint_path_dlg)
124         ON_WM_CLOSE()
125         ON_WM_INITMENU()
126         //}}AFX_MSG_MAP
127 END_MESSAGE_MAP()
128
129 /////////////////////////////////////////////////////////////////////////////
130 // waypoint_path_dlg message handlers
131
132 BOOL waypoint_path_dlg::Create()
133 {
134         BOOL r;
135         r = CDialog::Create(IDD, Fred_main_wnd);
136         initialize_data(1);
137         return r;
138 }
139
140 void waypoint_path_dlg::OnInitMenu(CMenu* pMenu)
141 {
142         int i;
143         CMenu *m;
144
145         m = pMenu->GetSubMenu(0);
146         clear_menu(m);
147         for (i=0; i<Num_waypoint_lists; i++)
148                 if (Waypoint_lists[i].count)
149                         m->AppendMenu(MF_ENABLED | MF_STRING, ID_WAYPOINT_MENU + i, Waypoint_lists[i].name);
150
151         for (i=0; i<Num_jump_nodes; i++)
152                 m->AppendMenu(MF_ENABLED | MF_STRING, ID_JUMP_NODE_MENU + i, Jump_nodes[i].name);
153
154         m->DeleteMenu(ID_PLACEHOLDER, MF_BYCOMMAND);
155         if (cur_waypoint_list != -1)
156                 m->CheckMenuItem(ID_WAYPOINT_MENU + cur_waypoint_list, MF_BYCOMMAND | MF_CHECKED);
157
158         if (cur_object_index >= 0)
159                 if (Objects[cur_object_index].type == OBJ_JUMP_NODE)
160                         m->CheckMenuItem(ID_JUMP_NODE_MENU + Objects[cur_object_index].instance, MF_BYCOMMAND | MF_CHECKED);
161
162         CDialog::OnInitMenu(pMenu);
163 }
164
165 void waypoint_path_dlg::OnOK()
166 {
167 }
168
169 void waypoint_path_dlg::OnClose() 
170 {
171         if (update_data()) {
172                 SetWindowPos(&wndTop, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
173                 bypass_errors = 0;
174                 return;
175         }
176
177         SetWindowPos(Fred_main_wnd, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_HIDEWINDOW);
178         Fred_main_wnd->SetWindowPos(&wndTop, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
179 }
180
181 void waypoint_path_dlg::initialize_data(int full_update)
182 {
183         int enable = TRUE;
184
185         if (!GetSafeHwnd())
186                 return;
187
188         if (query_valid_object() && Objects[cur_object_index].type == OBJ_WAYPOINT)
189                 SDL_assert(cur_waypoint_list == (Objects[cur_object_index].instance / 65536));
190
191         if (cur_waypoint_list >= 0) {
192                 m_name = _T(Waypoint_lists[cur_waypoint_list].name);
193
194         } else if (Objects[cur_object_index].type == OBJ_JUMP_NODE) {
195                 m_name = _T(Jump_nodes[Objects[cur_object_index].instance].name);
196
197         } else {
198                 m_name = _T("");
199                 enable = FALSE;
200         }
201
202         if (full_update)
203                 UpdateData(FALSE);
204
205         GetDlgItem(IDC_NAME)->EnableWindow(enable);
206 }
207
208 int waypoint_path_dlg::update_data(int redraw)
209 {
210         char *str, old_name[255];
211         int i, z, inst;
212         object *ptr;
213
214         if (!GetSafeHwnd())
215                 return 0;
216
217         UpdateData(TRUE);
218         UpdateData(TRUE);
219
220         if (query_valid_object() && Objects[cur_object_index].type == OBJ_WAYPOINT)
221                 SDL_assert(cur_waypoint_list == (Objects[cur_object_index].instance / 65536));
222
223         if (cur_waypoint_list >= 0) {
224                 if (!strnicmp(m_name, "player ", 7)) {
225                         if (bypass_errors)
226                                 return 1;
227
228                         bypass_errors = 1;
229                         z = MessageBox("Waypoint path names can't start with the word 'player'\n"
230                                 "Press OK to restore old name", "Error", MB_ICONEXCLAMATION | MB_OKCANCEL);
231
232                         if (z == IDCANCEL)
233                                 return -1;
234
235                         m_name = _T(Waypoint_lists[cur_waypoint_list].name);
236                         UpdateData(FALSE);
237                 }
238
239                 for (i=0; i<MAX_WINGS; i++)
240                         if (!stricmp(Wings[i].name, m_name)) {
241                                 if (bypass_errors)
242                                         return 1;
243
244                                 bypass_errors = 1;
245                                 z = MessageBox("This waypoint path name is already being used by a wing\n"
246                                         "Press OK to restore old name", "Error", MB_ICONEXCLAMATION | MB_OKCANCEL);
247
248                                 if (z == IDCANCEL)
249                                         return -1;
250
251                                 m_name = _T(Waypoint_lists[cur_waypoint_list].name);
252                                 UpdateData(FALSE);
253                         }
254
255                 ptr = GET_FIRST(&obj_used_list);
256                 while (ptr != END_OF_LIST(&obj_used_list)) {
257                         if (ptr->type == OBJ_SHIP) {
258                                 if (!stricmp(m_name, Ships[ptr->instance].ship_name)) {
259                                         if (bypass_errors)
260                                                 return 1;
261
262                                         bypass_errors = 1;
263                                         z = MessageBox("This waypoint path name is already being used by a ship\n"
264                                                 "Press OK to restore old name", "Error", MB_ICONEXCLAMATION | MB_OKCANCEL);
265
266                                         if (z == IDCANCEL)
267                                                 return -1;
268
269                                         m_name = _T(Waypoint_lists[cur_waypoint_list].name);
270                                         UpdateData(FALSE);
271                                 }
272                         }
273
274                         ptr = GET_NEXT(ptr);
275                 }
276
277                 for (i=0; i<MAX_WAYPOINT_LISTS; i++)
278                         if (Waypoint_lists[i].count && !stricmp(Waypoint_lists[i].name, m_name) && (i != cur_waypoint_list)) {
279                                 if (bypass_errors)
280                                         return 1;
281
282                                 bypass_errors = 1;
283                                 z = MessageBox("This waypoint path name is already being used by another waypoint path\n"
284                                         "Press OK to restore old name", "Error", MB_ICONEXCLAMATION | MB_OKCANCEL);
285
286                                 if (z == IDCANCEL)
287                                         return -1;
288
289                                 m_name = _T(Waypoint_lists[cur_waypoint_list].name);
290                                 UpdateData(FALSE);
291                         }
292
293                 for (i=0; i<Num_jump_nodes; i++)
294                         if (!stricmp(Jump_nodes[i].name, m_name)) {
295                                 if (bypass_errors)
296                                         return 1;
297
298                                 bypass_errors = 1;
299                                 z = MessageBox("This waypoint path name is already being used by a jump node\n"
300                                         "Press OK to restore old name", "Error", MB_ICONEXCLAMATION | MB_OKCANCEL);
301
302                                 if (z == IDCANCEL)
303                                         return -1;
304
305                                 m_name = _T(Waypoint_lists[cur_waypoint_list].name);
306                                 UpdateData(FALSE);
307                         }
308
309                 strcpy(old_name, Waypoint_lists[cur_waypoint_list].name);
310                 string_copy(Waypoint_lists[cur_waypoint_list].name, m_name, NAME_LENGTH, 1);
311
312                 str = (char *) (LPCTSTR) m_name;
313                 if (stricmp(old_name, str)) {
314                         update_sexp_references(old_name, str);
315                         ai_update_goal_references(REF_TYPE_WAYPOINT, old_name, str);
316                 }
317
318         } else if (Objects[cur_object_index].type == OBJ_JUMP_NODE) {
319                 inst = Objects[cur_object_index].instance;
320                 if (!strnicmp(m_name, "player ", 7)) {
321                         if (bypass_errors)
322                                 return 1;
323
324                         bypass_errors = 1;
325                         z = MessageBox("Jump node names can't start with the word 'player'\n"
326                                 "Press OK to restore old name", "Error", MB_ICONEXCLAMATION | MB_OKCANCEL);
327
328                         if (z == IDCANCEL)
329                                 return -1;
330
331                         m_name = _T(Jump_nodes[inst].name);
332                         UpdateData(FALSE);
333                 }
334
335                 for (i=0; i<MAX_WINGS; i++)
336                         if (!stricmp(Wings[i].name, m_name)) {
337                                 if (bypass_errors)
338                                         return 1;
339
340                                 bypass_errors = 1;
341                                 z = MessageBox("This jump node name is already being used by a wing\n"
342                                         "Press OK to restore old name", "Error", MB_ICONEXCLAMATION | MB_OKCANCEL);
343
344                                 if (z == IDCANCEL)
345                                         return -1;
346
347                                 m_name = _T(Jump_nodes[inst].name);
348                                 UpdateData(FALSE);
349                         }
350
351                 ptr = GET_FIRST(&obj_used_list);
352                 while (ptr != END_OF_LIST(&obj_used_list)) {
353                         if (ptr->type == OBJ_SHIP) {
354                                 if (!stricmp(m_name, Ships[ptr->instance].ship_name)) {
355                                         if (bypass_errors)
356                                                 return 1;
357
358                                         bypass_errors = 1;
359                                         z = MessageBox("This jump node name is already being used by a ship\n"
360                                                 "Press OK to restore old name", "Error", MB_ICONEXCLAMATION | MB_OKCANCEL);
361
362                                         if (z == IDCANCEL)
363                                                 return -1;
364
365                                         m_name = _T(Jump_nodes[inst].name);
366                                         UpdateData(FALSE);
367                                 }
368                         }
369
370                         ptr = GET_NEXT(ptr);
371                 }
372
373                 for (i=0; i<MAX_WAYPOINT_LISTS; i++)
374                         if (Waypoint_lists[i].count && !stricmp(Waypoint_lists[i].name, m_name)) {
375                                 if (bypass_errors)
376                                         return 1;
377
378                                 bypass_errors = 1;
379                                 z = MessageBox("This jump node name is already being used by a waypoint path\n"
380                                         "Press OK to restore old name", "Error", MB_ICONEXCLAMATION | MB_OKCANCEL);
381
382                                 if (z == IDCANCEL)
383                                         return -1;
384
385                                 m_name = _T(Jump_nodes[inst].name);
386                                 UpdateData(FALSE);
387                         }
388
389                 for (i=0; i<Num_jump_nodes; i++)
390                         if ((i != inst) && !stricmp(Jump_nodes[i].name, m_name)) {
391                                 if (bypass_errors)
392                                         return 1;
393
394                                 bypass_errors = 1;
395                                 z = MessageBox("This jump node name is already being used by another jump node\n"
396                                         "Press OK to restore old name", "Error", MB_ICONEXCLAMATION | MB_OKCANCEL);
397
398                                 if (z == IDCANCEL)
399                                         return -1;
400
401                                 m_name = _T(Jump_nodes[inst].name);
402                                 UpdateData(FALSE);
403                         }
404
405                 strcpy(old_name, Jump_nodes[inst].name);
406                 string_copy(Jump_nodes[inst].name, m_name, NAME_LENGTH, 1);
407
408                 str = (char *) (LPCTSTR) m_name;
409                 if (stricmp(old_name, str)) {
410                         update_sexp_references(old_name, str);
411                 }
412         }
413
414         if (redraw)
415                 update_map_window();
416
417         return 0;
418 }
419
420 BOOL waypoint_path_dlg::OnCommand(WPARAM wParam, LPARAM lParam) 
421 {
422         int id, point;
423         object *ptr;
424
425         id = LOWORD(wParam);
426         if ((id >= ID_WAYPOINT_MENU) && (id < ID_WAYPOINT_MENU + MAX_WAYPOINT_LISTS)) {
427                 if (!update_data()) {
428                         point = id - ID_WAYPOINT_MENU;
429                         unmark_all();
430                         ptr = GET_FIRST(&obj_used_list);
431                         while (ptr != END_OF_LIST(&obj_used_list)) {
432                                 if (ptr->type == OBJ_WAYPOINT)
433                                         if ((ptr->instance / 65536) == point)
434                                                 mark_object(OBJ_INDEX(ptr));
435
436                                 ptr = GET_NEXT(ptr);
437                         }
438
439                         return 1;
440                 }
441         }
442
443         if ((id >= ID_JUMP_NODE_MENU) && (id < ID_JUMP_NODE_MENU + Num_jump_nodes)) {
444                 if (!update_data()) {
445                         point = id - ID_JUMP_NODE_MENU;
446                         unmark_all();
447                         ptr = GET_FIRST(&obj_used_list);
448                         while (ptr != END_OF_LIST(&obj_used_list)) {
449                                 if (ptr->type == OBJ_JUMP_NODE)
450                                         if (ptr->instance == point)
451                                                 mark_object(OBJ_INDEX(ptr));
452
453                                 ptr = GET_NEXT(ptr);
454                         }
455
456                         return 1;
457                 }
458         }
459
460         return CDialog::OnCommand(wParam, lParam);
461 }
462