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