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 the
6 * source.
7 *
8 */
9
10
11
12 #include "stdafx.h"
13 #include "FRED.h"
14 #include "WaypointPathDlg.h"
15 #include "Management.h"
16 #include "MainFrm.h"
17 #include "object/object.h"
18 #include "object/waypoint.h"
19 #include "globalincs/linklist.h"
20 #include "ship/ship.h"
21 #include "ai/aigoals.h"
22 #include "starfield/starfield.h"
23 #include "jumpnode/jumpnode.h"
24 #include "iff_defs/iff_defs.h"
25
26 #define ID_JUMP_NODE_MENU 8000
27 #define ID_WAYPOINT_MENU 9000
28
29 #ifdef _DEBUG
30 #undef THIS_FILE
31 static char THIS_FILE[] = __FILE__;
32 #endif
33
34 /////////////////////////////////////////////////////////////////////////////
35 // waypoint_path_dlg dialog
36
waypoint_path_dlg(CWnd * pParent)37 waypoint_path_dlg::waypoint_path_dlg(CWnd* pParent /*=NULL*/)
38 : CDialog(waypoint_path_dlg::IDD, pParent)
39 {
40 //{{AFX_DATA_INIT(waypoint_path_dlg)
41 m_name = _T("");
42 //}}AFX_DATA_INIT
43 bypass_errors = 0;
44 }
45
DoDataExchange(CDataExchange * pDX)46 void waypoint_path_dlg::DoDataExchange(CDataExchange* pDX)
47 {
48 CDialog::DoDataExchange(pDX);
49 //{{AFX_DATA_MAP(waypoint_path_dlg)
50 DDX_Text(pDX, IDC_NAME, m_name);
51 //}}AFX_DATA_MAP
52 }
53
BEGIN_MESSAGE_MAP(waypoint_path_dlg,CDialog)54 BEGIN_MESSAGE_MAP(waypoint_path_dlg, CDialog)
55 //{{AFX_MSG_MAP(waypoint_path_dlg)
56 ON_WM_CLOSE()
57 ON_WM_INITMENU()
58 //}}AFX_MSG_MAP
59 END_MESSAGE_MAP()
60
61 /////////////////////////////////////////////////////////////////////////////
62 // waypoint_path_dlg message handlers
63
64 BOOL waypoint_path_dlg::Create()
65 {
66 BOOL r;
67 r = CDialog::Create(IDD, Fred_main_wnd);
68 initialize_data(1);
69 return r;
70 }
71
OnInitMenu(CMenu * pMenu)72 void waypoint_path_dlg::OnInitMenu(CMenu* pMenu)
73 {
74 int i;
75 SCP_list<waypoint_list>::iterator ii;
76 SCP_list<CJumpNode>::iterator jnp;
77 CMenu *m;
78
79 m = pMenu->GetSubMenu(0);
80 clear_menu(m);
81
82 for (i = 0, ii = Waypoint_lists.begin(); ii != Waypoint_lists.end(); ++i, ++ii) {
83 m->AppendMenu(MF_ENABLED | MF_STRING, ID_WAYPOINT_MENU + i, ii->get_name());
84 }
85
86 i = 0;
87 for (jnp = Jump_nodes.begin(); jnp != Jump_nodes.end(); ++jnp) {
88 m->AppendMenu(MF_ENABLED | MF_STRING, ID_JUMP_NODE_MENU + i, jnp->GetName());
89 if (jnp->GetSCPObjectNumber() == cur_object_index) {
90 m->CheckMenuItem(ID_JUMP_NODE_MENU + i, MF_BYCOMMAND | MF_CHECKED);
91 }
92 i++;
93
94 }
95
96 m->DeleteMenu(ID_PLACEHOLDER, MF_BYCOMMAND);
97 if (cur_waypoint_list != NULL)
98 {
99 int index = find_index_of_waypoint_list(cur_waypoint_list);
100 Assert(index >= 0);
101 m->CheckMenuItem(ID_WAYPOINT_MENU + index, MF_BYCOMMAND | MF_CHECKED);
102 }
103
104 CDialog::OnInitMenu(pMenu);
105 }
106
OnOK()107 void waypoint_path_dlg::OnOK()
108 {
109 }
110
OnClose()111 void waypoint_path_dlg::OnClose()
112 {
113 if (update_data()) {
114 SetWindowPos(&wndTop, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
115 bypass_errors = 0;
116 return;
117 }
118
119 SetWindowPos(Fred_main_wnd, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_HIDEWINDOW);
120 Fred_main_wnd->SetWindowPos(&wndTop, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
121 }
122
initialize_data(int full_update)123 void waypoint_path_dlg::initialize_data(int full_update)
124 {
125 int enable = TRUE;
126 SCP_list<CJumpNode>::iterator jnp;
127
128 if (!GetSafeHwnd())
129 return;
130
131 if (query_valid_object() && Objects[cur_object_index].type == OBJ_WAYPOINT)
132 {
133 Assert(cur_waypoint_list == find_waypoint_list_with_instance(Objects[cur_object_index].instance));
134 }
135
136 if (cur_waypoint_list != NULL) {
137 m_name = _T(cur_waypoint_list->get_name());
138
139 } else if (Objects[cur_object_index].type == OBJ_JUMP_NODE) {
140 for (jnp = Jump_nodes.begin(); jnp != Jump_nodes.end(); ++jnp) {
141 if(jnp->GetSCPObject() == &Objects[cur_object_index])
142 break;
143 }
144
145 m_name = _T(jnp->GetName());
146
147 } else {
148 m_name = _T("");
149 enable = FALSE;
150 }
151
152 if (full_update)
153 UpdateData(FALSE);
154
155 GetDlgItem(IDC_NAME)->EnableWindow(enable);
156 }
157
update_data(int redraw)158 int waypoint_path_dlg::update_data(int redraw)
159 {
160 const char *str;
161 char old_name[255];
162 int i, z;
163 object *ptr;
164 SCP_list<CJumpNode>::iterator jnp;
165
166 if (!GetSafeHwnd())
167 return 0;
168
169 UpdateData(TRUE);
170 UpdateData(TRUE);
171
172 if (query_valid_object() && Objects[cur_object_index].type == OBJ_WAYPOINT)
173 {
174 Assert(cur_waypoint_list == find_waypoint_list_with_instance(Objects[cur_object_index].instance));
175 }
176
177 if (cur_waypoint_list != NULL) {
178 for (i=0; i<MAX_WINGS; i++)
179 {
180 if (!stricmp(Wings[i].name, m_name)) {
181 if (bypass_errors)
182 return 1;
183
184 bypass_errors = 1;
185 z = MessageBox("This waypoint path name is already being used by a wing\n"
186 "Press OK to restore old name", "Error", MB_ICONEXCLAMATION | MB_OKCANCEL);
187
188 if (z == IDCANCEL)
189 return -1;
190
191 m_name = _T(cur_waypoint_list->get_name());
192 UpdateData(FALSE);
193 }
194 }
195
196 ptr = GET_FIRST(&obj_used_list);
197 while (ptr != END_OF_LIST(&obj_used_list)) {
198 if ((ptr->type == OBJ_SHIP) || (ptr->type == OBJ_START)) {
199 if (!stricmp(m_name, Ships[ptr->instance].ship_name)) {
200 if (bypass_errors)
201 return 1;
202
203 bypass_errors = 1;
204 z = MessageBox("This waypoint path name is already being used by a ship\n"
205 "Press OK to restore old name", "Error", MB_ICONEXCLAMATION | MB_OKCANCEL);
206
207 if (z == IDCANCEL)
208 return -1;
209
210 m_name = _T(cur_waypoint_list->get_name());
211 UpdateData(FALSE);
212 }
213 }
214
215 ptr = GET_NEXT(ptr);
216 }
217
218 // We don't need to check teams. "Unknown" is a valid name and also an IFF.
219
220 for ( i=0; i < (int)Ai_tp_list.size(); i++) {
221 if (!stricmp(m_name, Ai_tp_list[i].name)) {
222 if (bypass_errors)
223 return 1;
224
225 bypass_errors = 1;
226 z = MessageBox("This waypoint path name is already being used by a target priority group.\n"
227 "Press OK to restore old name", "Error", MB_ICONEXCLAMATION | MB_OKCANCEL);
228
229 if (z == IDCANCEL)
230 return -1;
231
232 m_name = _T(cur_waypoint_list->get_name());
233 UpdateData(FALSE);
234 }
235 }
236
237 SCP_list<waypoint_list>::iterator ii;
238 for (ii = Waypoint_lists.begin(); ii != Waypoint_lists.end(); ++ii)
239 {
240 if (!stricmp(ii->get_name(), m_name) && (&(*ii) != cur_waypoint_list)) {
241 if (bypass_errors)
242 return 1;
243
244 bypass_errors = 1;
245 z = MessageBox("This waypoint path name is already being used by another waypoint path\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(cur_waypoint_list->get_name());
252 UpdateData(FALSE);
253 }
254 }
255
256 if(jumpnode_get_by_name(m_name) != NULL)
257 {
258 if (bypass_errors)
259 return 1;
260
261 bypass_errors = 1;
262 z = MessageBox("This waypoint path name is already being used by a jump node\n"
263 "Press OK to restore old name", "Error", MB_ICONEXCLAMATION | MB_OKCANCEL);
264
265 if (z == IDCANCEL)
266 return -1;
267
268 m_name = _T(cur_waypoint_list->get_name());
269 UpdateData(FALSE);
270 }
271
272 if (!stricmp(m_name.Left(1), "<")) {
273 if (bypass_errors)
274 return 1;
275
276 bypass_errors = 1;
277 z = MessageBox("Waypoint names not allowed to begin with <\n"
278 "Press OK to restore old name", "Error", MB_ICONEXCLAMATION | MB_OKCANCEL);
279
280 if (z == IDCANCEL)
281 return -1;
282
283 m_name = _T(cur_waypoint_list->get_name());
284 UpdateData(FALSE);
285 }
286
287
288 strcpy_s(old_name, cur_waypoint_list->get_name());
289 string_copy(cur_waypoint_list->get_name(), m_name, NAME_LENGTH, 1);
290
291 str = (char *) (LPCTSTR) m_name;
292 if (strcmp(old_name, str)) {
293 update_sexp_references(old_name, str);
294 ai_update_goal_references(REF_TYPE_WAYPOINT, old_name, str);
295 update_texture_replacements(old_name, str);
296 }
297
298 } else if (Objects[cur_object_index].type == OBJ_JUMP_NODE) {
299 for (jnp = Jump_nodes.begin(); jnp != Jump_nodes.end(); ++jnp) {
300 if(jnp->GetSCPObject() == &Objects[cur_object_index])
301 break;
302 }
303
304 for (i=0; i<MAX_WINGS; i++)
305 {
306 if (!stricmp(Wings[i].name, m_name)) {
307 if (bypass_errors)
308 return 1;
309
310 bypass_errors = 1;
311 z = MessageBox("This jump node name is already being used by a wing\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(jnp->GetName());
318 UpdateData(FALSE);
319 }
320 }
321
322 ptr = GET_FIRST(&obj_used_list);
323 while (ptr != END_OF_LIST(&obj_used_list)) {
324 if ((ptr->type == OBJ_SHIP) || (ptr->type == OBJ_START)) {
325 if (!stricmp(m_name, Ships[ptr->instance].ship_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 ship\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(jnp->GetName());
337 UpdateData(FALSE);
338 }
339 }
340
341 ptr = GET_NEXT(ptr);
342 }
343
344 // We don't need to check teams. "Unknown" is a valid name and also an IFF.
345
346 for ( i=0; i < (int)Ai_tp_list.size(); i++) {
347 if (!stricmp(m_name, Ai_tp_list[i].name)) {
348 if (bypass_errors)
349 return 1;
350
351 bypass_errors = 1;
352 z = MessageBox("This jump node name is already being used by a target priority group.\n"
353 "Press OK to restore old name", "Error", MB_ICONEXCLAMATION | MB_OKCANCEL);
354
355 if (z == IDCANCEL)
356 return -1;
357
358 m_name = _T(jnp->GetName());
359 UpdateData(FALSE);
360 }
361 }
362
363 if (find_matching_waypoint_list((LPCSTR) m_name) != NULL)
364 {
365 if (bypass_errors)
366 return 1;
367
368 bypass_errors = 1;
369 z = MessageBox("This jump node name is already being used by a waypoint path\n"
370 "Press OK to restore old name", "Error", MB_ICONEXCLAMATION | MB_OKCANCEL);
371
372 if (z == IDCANCEL)
373 return -1;
374
375 m_name = _T(jnp->GetName());
376 UpdateData(FALSE);
377 }
378
379 if (!stricmp(m_name.Left(1), "<")) {
380 if (bypass_errors)
381 return 1;
382
383 bypass_errors = 1;
384 z = MessageBox("Jump node names not allowed to begin with <\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(jnp->GetName());
391 UpdateData(FALSE);
392 }
393
394 CJumpNode* found = jumpnode_get_by_name(m_name);
395 if(found != NULL && &(*jnp) != found)
396 {
397 if (bypass_errors)
398 return 1;
399
400 bypass_errors = 1;
401 z = MessageBox("This jump node name is already being used by another jump node\n"
402 "Press OK to restore old name", "Error", MB_ICONEXCLAMATION | MB_OKCANCEL);
403
404 if (z == IDCANCEL)
405 return -1;
406
407 m_name = _T(jnp->GetName());
408 UpdateData(FALSE);
409 }
410
411 strcpy_s(old_name, jnp->GetName());
412 jnp->SetName((LPCSTR) m_name);
413
414 str = (LPCTSTR) m_name;
415 if (strcmp(old_name, str)) {
416 update_sexp_references(old_name, str);
417 }
418
419 }
420
421 if (redraw)
422 update_map_window();
423
424 return 0;
425 }
426
OnCommand(WPARAM wParam,LPARAM lParam)427 BOOL waypoint_path_dlg::OnCommand(WPARAM wParam, LPARAM lParam)
428 {
429 int id, point;
430 object *ptr;
431
432 id = LOWORD(wParam);
433 if ((id >= ID_WAYPOINT_MENU) && (id < ID_WAYPOINT_MENU + (int) Waypoint_lists.size())) {
434 if (!update_data()) {
435 point = id - ID_WAYPOINT_MENU;
436 unmark_all();
437 ptr = GET_FIRST(&obj_used_list);
438 while (ptr != END_OF_LIST(&obj_used_list)) {
439 if (ptr->type == OBJ_WAYPOINT)
440 if (calc_waypoint_list_index(ptr->instance) == point)
441 mark_object(OBJ_INDEX(ptr));
442
443 ptr = GET_NEXT(ptr);
444 }
445
446 return 1;
447 }
448 }
449
450 if ((id >= ID_JUMP_NODE_MENU) && (id < ID_JUMP_NODE_MENU + (int) Jump_nodes.size())) {
451 if (!update_data()) {
452 point = id - ID_JUMP_NODE_MENU;
453 unmark_all();
454 ptr = GET_FIRST(&obj_used_list);
455 while ((ptr != END_OF_LIST(&obj_used_list)) && (point > -1)) {
456 if (ptr->type == OBJ_JUMP_NODE) {
457 if (point == 0) {
458 mark_object(OBJ_INDEX(ptr));
459 }
460 point--;
461 }
462
463 ptr = GET_NEXT(ptr);
464 }
465
466 return 1;
467 }
468 }
469
470 return CDialog::OnCommand(wParam, lParam);
471 }
472