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