FS2_Open
Open source remastering of the Freespace 2 engine
wing_editor.cpp
Go to the documentation of this file.
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 "MainFrm.h"
14 #include "FRED.h"
15 #include "FREDDoc.h"
16 #include "Management.h"
17 #include "wing.h"
18 #include "globalincs/linklist.h"
19 #include "ai/aigoals.h"
20 #include "FREDView.h"
21 #include "starfield/starfield.h"
22 #include "jumpnode/jumpnode.h"
23 #include "cfile/cfile.h"
24 #include "restrictpaths.h"
25 #include "iff_defs/iff_defs.h"
26 
27 #define ID_WING_MENU 9000
28 
29 #ifdef _DEBUG
30 #undef THIS_FILE
31 static char THIS_FILE[] = __FILE__;
32 #endif
33 
35 // wing_editor dialog
36 
37 wing_editor::wing_editor(CWnd* pParent /*=NULL*/)
38  : CDialog(wing_editor::IDD, pParent)
39 {
40  //{{AFX_DATA_INIT(wing_editor)
41  m_wing_name = _T("");
42  m_wing_squad_filename = _T("");
43  m_special_ship = -1;
44  m_waves = 0;
45  m_threshold = 0;
46  m_arrival_location = -1;
48  m_arrival_delay = 0;
51  m_hotkey = -1;
55  m_arrival_dist = 0;
56  m_arrival_target = -1;
58  m_departure_target = -1;
63  //}}AFX_DATA_INIT
64  modified = 0;
65  select_sexp_node = -1;
66  bypass_errors = 0;
67 }
68 
69 void wing_editor::DoDataExchange(CDataExchange* pDX)
70 {
71  CString str;
72 
73  CDialog::DoDataExchange(pDX);
74  //{{AFX_DATA_MAP(wing_editor)
77  DDX_Control(pDX, IDC_DEPARTURE_TREE, m_departure_tree);
78  DDX_Control(pDX, IDC_ARRIVAL_TREE, m_arrival_tree);
79  DDX_Control(pDX, IDC_SPIN_WAVE_THRESHOLD, m_threshold_spin);
80  DDX_Control(pDX, IDC_SPIN_WAVES, m_waves_spin);
81  DDX_Text(pDX, IDC_WING_NAME, m_wing_name);
83  DDX_CBIndex(pDX, IDC_WING_SPECIAL_SHIP, m_special_ship);
84  DDX_CBIndex(pDX, IDC_ARRIVAL_LOCATION, m_arrival_location);
86  DDX_Check(pDX, IDC_REINFORCEMENT, m_reinforcement);
87  DDX_CBIndex(pDX, IDC_HOTKEY, m_hotkey);
88  DDX_Check(pDX, IDC_IGNORE_COUNT, m_ignore_count);
89  DDX_Text(pDX, IDC_ARRIVAL_DISTANCE, m_arrival_dist);
90  DDX_CBIndex(pDX, IDC_ARRIVAL_TARGET, m_arrival_target);
92  DDX_CBIndex(pDX, IDC_DEPARTURE_TARGET, m_departure_target);
94  DDX_Check(pDX, IDC_NO_ARRIVAL_WARP, m_no_arrival_warp);
96  DDX_Check(pDX, IDC_NO_DYNAMIC, m_no_dynamic);
97  //}}AFX_DATA_MAP
98 
99  if (pDX->m_bSaveAndValidate) { // get dialog control values
100  GetDlgItem(IDC_ARRIVAL_DELAY)->GetWindowText(str);
101  m_arrival_delay = atoi(str);
102  if (m_arrival_delay < 0)
103  m_arrival_delay = 0;
104 
105  GetDlgItem(IDC_DEPARTURE_DELAY)->GetWindowText(str);
106  m_departure_delay = atoi(str);
107  if (m_departure_delay < 0)
108  m_departure_delay = 0;
109 
110  GetDlgItem(IDC_WING_WAVES)->GetWindowText(str);
111  m_waves = atoi(str);
112  if (m_waves < 0)
113  m_waves = 0;
114 
115  GetDlgItem(IDC_WING_WAVE_THRESHOLD)->GetWindowText(str);
116  m_threshold = atoi(str);
117  if (m_threshold < 0)
118  m_threshold = 0;
119 
120  GetDlgItem(IDC_ARRIVAL_DELAY_MIN)->GetWindowText(str);
121  m_arrival_delay_min = atoi(str);
122  if (m_arrival_delay_min < 0)
124 
125  GetDlgItem(IDC_ARRIVAL_DELAY_MAX)->GetWindowText(str);
126  m_arrival_delay_max = atoi(str);
127  if (m_arrival_delay_max < 0)
129 
130  } else {
131  DDX_Text(pDX, IDC_ARRIVAL_DELAY, m_arrival_delay);
132  DDX_Text(pDX, IDC_DEPARTURE_DELAY, m_departure_delay);
133  DDX_Text(pDX, IDC_WING_WAVES, m_waves);
134  DDX_Text(pDX, IDC_WING_WAVE_THRESHOLD, m_threshold);
137  }
138 }
139 
140 BEGIN_MESSAGE_MAP(wing_editor, CDialog)
141  //{{AFX_MSG_MAP(wing_editor)
142  ON_WM_INITMENU()
143  ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_WAVES, OnDeltaposSpinWaves)
144  ON_NOTIFY(NM_RCLICK, IDC_ARRIVAL_TREE, OnRclickArrivalTree)
145  ON_NOTIFY(NM_RCLICK, IDC_DEPARTURE_TREE, OnRclickDepartureTree)
146  ON_NOTIFY(TVN_BEGINLABELEDIT, IDC_ARRIVAL_TREE, OnBeginlabeleditArrivalTree)
147  ON_NOTIFY(TVN_BEGINLABELEDIT, IDC_DEPARTURE_TREE, OnBeginlabeleditDepartureTree)
148  ON_NOTIFY(TVN_ENDLABELEDIT, IDC_ARRIVAL_TREE, OnEndlabeleditArrivalTree)
149  ON_NOTIFY(TVN_ENDLABELEDIT, IDC_DEPARTURE_TREE, OnEndlabeleditDepartureTree)
150  ON_BN_CLICKED(IDC_DELETE_WING, OnDeleteWing)
151  ON_BN_CLICKED(IDC_DISBAND_WING, OnDisbandWing)
152  ON_WM_CLOSE()
153  ON_BN_CLICKED(IDC_GOALS2, OnGoals2)
154  ON_BN_CLICKED(IDC_REINFORCEMENT, OnReinforcement)
155  ON_BN_CLICKED(IDC_NEXT, OnNext)
156  ON_NOTIFY(TVN_SELCHANGED, IDC_ARRIVAL_TREE, OnSelchangedArrivalTree)
157  ON_NOTIFY(TVN_SELCHANGED, IDC_DEPARTURE_TREE, OnSelchangedDepartureTree)
158  ON_BN_CLICKED(IDC_HIDE_CUES, OnHideCues)
159  ON_BN_CLICKED(IDC_PREV, OnPrev)
160  ON_CBN_SELCHANGE(IDC_ARRIVAL_LOCATION, OnSelchangeArrivalLocation)
161  ON_CBN_SELCHANGE(IDC_DEPARTURE_LOCATION, OnSelchangeDepartureLocation)
162  ON_CBN_SELCHANGE(IDC_HOTKEY, OnSelchangeHotkey)
163  ON_BN_CLICKED(IDC_WING_SQUAD_LOGO_BUTTON, OnSquadLogo)
164  ON_BN_CLICKED(IDC_RESTRICT_ARRIVAL, OnRestrictArrival)
165  ON_BN_CLICKED(IDC_RESTRICT_DEPARTURE, OnRestrictDeparture)
166  //}}AFX_MSG_MAP
167 END_MESSAGE_MAP()
168 
170 // wing_editor message handlers
171 
172 BOOL wing_editor::Create()
173 {
174  BOOL r;
175  int i;
176  CComboBox *box;
177 
178  r = CDialog::Create(IDD, Fred_main_wnd);
179  box = (CComboBox *) GetDlgItem(IDC_ARRIVAL_LOCATION);
180  box->ResetContent();
181  for (i=0; i<MAX_ARRIVAL_NAMES; i++)
182  box->AddString(Arrival_location_names[i]);
183 
184  box = (CComboBox *) GetDlgItem(IDC_DEPARTURE_LOCATION);
185  box->ResetContent();
186  for (i=0; i<MAX_DEPARTURE_NAMES; i++)
187  box->AddString(Departure_location_names[i]);
188 
189  m_hotkey = 0;
190  m_waves_spin.SetRange(1, 99);
191  m_arrival_tree.link_modified(&modified); // provide way to indicate trees are modified in dialog
192  m_arrival_tree.setup((CEdit *) GetDlgItem(IDC_HELP_BOX));
193  m_departure_tree.link_modified(&modified);
194  m_departure_tree.setup();
195  m_arrival_delay_spin.SetRange(0, 999);
196  m_departure_delay_spin.SetRange(0, 999);
197 
198  initialize_data(1);
199  return r;
200 }
201 
202 void wing_editor::OnInitMenu(CMenu* pMenu)
203 {
204  CMenu *m;
205 
206  m = pMenu->GetSubMenu(0);
207  clear_menu(m);
208  generate_wing_popup_menu(m, ID_WING_MENU, MF_ENABLED);
209  if (cur_wing != -1)
210  m->CheckMenuItem(ID_WING_MENU + cur_wing, MF_BYCOMMAND | MF_CHECKED);
211 
212  CDialog::OnInitMenu(pMenu);
213 }
214 
216 {
217  HWND h;
218  CWnd *w;
219 
220  w = GetFocus();
221  if (w) {
222  h = w->m_hWnd;
223  GetDlgItem(IDC_ARRIVAL_TREE)->SetFocus();
224  ::SetFocus(h);
225  }
226 }
227 
229 {
230  if (verify() && (!bypass_errors)) {
231  SetWindowPos(&wndTop, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
232  bypass_errors = 0;
233  return;
234  }
235 
236  if (update_data()) {
237  SetWindowPos(&wndTop, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
238  bypass_errors = 0;
239  return;
240  }
241 
242  SetWindowPos(Fred_main_wnd, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_HIDEWINDOW);
243  Fred_main_wnd->SetWindowPos(&wndTop, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
244 }
245 
246 // initialize everything that update_data_safe() saves.
248 {
249  int i, enable = TRUE, player_wing = 0, player_enabled = 1;
250  CComboBox *arrival_box, *departure_box;
251 
252  nprintf(("Fred routing", "Wing dialog load safe\n"));
253  if (!GetSafeHwnd())
254  return;
255 
256  arrival_box = (CComboBox *) GetDlgItem(IDC_ARRIVAL_TARGET);
257  departure_box = (CComboBox *)GetDlgItem(IDC_DEPARTURE_TARGET);
258 
259  m_ignore_count = 0;
260  if (cur_wing < 0) {
261  m_wing_squad_filename = _T("");
262  m_special_ship = -1;
263  m_arrival_location = -1;
265  m_arrival_delay = 0;
268  m_arrival_dist = 0;
269  m_arrival_target = -1;
270  m_departure_target = -1;
271  m_departure_delay = 0;
274  m_arrival_tree.DeleteAllItems();
275  m_departure_tree.DeleteAllItems();
277  m_hotkey = 0;
278  m_ignore_count = 0;
279  m_no_arrival_music = 0;
281  m_no_arrival_warp = 0;
283  m_no_dynamic = 0;
284  player_enabled = enable = FALSE;
285 
286  } else {
287  CComboBox *ptr;
288 
290  {
292  {
293  for (i=0; i<MAX_TVT_WINGS; i++)
294  {
295  if (cur_wing == TVT_wings[i])
296  player_enabled = 0;
297  }
298  }
299  else
300  {
301  for (i=0; i<MAX_STARTING_WINGS; i++)
302  {
303  if (cur_wing == Starting_wings[i])
304  player_enabled = 0;
305  }
306  }
307  }
308  else
309  {
310  if (cur_wing == Ships[Player_start_shipnum].wingnum)
311  player_enabled = 0;
312  }
313 
315  if (Ships[Player_start_shipnum].wingnum == cur_wing)
316  player_wing = 1;
317 
318  m_wing_squad_filename = _T(Wings[cur_wing].wing_squad_filename);
331 
332  // Add the ships/special items to the combo box here before data is updated
335  } else {
337  }
338 
339  // Goober5000 - gah, this is ridiculous! Prior to this point in the function (and only in this function),
340  // m_arrival_target seems to refer to the arrival anchor. The rest of the time, it refers to the index
341  // of the drop-down list.
342  if (m_arrival_target >= 0)
343  {
345  {
346  // figure out what the box represents this as
347  char tmp[NAME_LENGTH + 15];
349 
350  // find it in the box
351  m_arrival_target = arrival_box->FindStringExact(-1, tmp);
352  }
353  else
354  {
355  // find it in the box
356  m_arrival_target = arrival_box->FindStringExact(-1, Ships[m_arrival_target].ship_name);
357  }
358  }
359 
360  // add the ships to the departure target combo box
363  } else {
364  departure_box->ResetContent();
365  }
366 
367  if ( m_departure_target >= 0 )
368  m_departure_target = departure_box->FindStringExact(-1, Ships[m_departure_target].ship_name);
369 
371  if (player_wing)
373  else
374  m_arrival_tree.load_tree(Wings[cur_wing].arrival_cue);
375 
376  m_departure_tree.load_tree(Wings[cur_wing].departure_cue, "false");
379  m_ignore_count = 1;
380  else
381  m_ignore_count = 0;
382 
384  m_no_arrival_music = 1;
385  else
386  m_no_arrival_music = 0;
387 
390  else
392 
394  m_no_arrival_warp = 1;
395  else
396  m_no_arrival_warp = 0;
397 
400  else
402 
403  ptr = (CComboBox *) GetDlgItem(IDC_WING_SPECIAL_SHIP);
404  ptr->ResetContent();
405  for (i=0; i<Wings[cur_wing].wave_count; i++)
406  ptr->AddString(Ships[Wings[cur_wing].ship_index[i]].ship_name);
407 
408  m_threshold_spin.SetRange(0, static_cast<short>(calc_max_wave_treshold()));
409  for (i=0; i<Num_reinforcements; i++)
410  if (!stricmp(Reinforcements[i].name, Wings[cur_wing].name))
411  break;
412 
413  if (i < Num_reinforcements)
415  else
417  }
418 
419  if (full_update)
420  UpdateData(FALSE);
421 
422  GetDlgItem(IDC_WING_NAME)->EnableWindow(enable);
423  GetDlgItem(IDC_WING_SQUAD_LOGO_BUTTON)->EnableWindow(enable);
424  GetDlgItem(IDC_WING_SPECIAL_SHIP)->EnableWindow(enable);
425  GetDlgItem(IDC_WING_WAVES)->EnableWindow(player_enabled);
426  GetDlgItem(IDC_WING_WAVE_THRESHOLD)->EnableWindow(player_enabled);
427  GetDlgItem(IDC_DISBAND_WING)->EnableWindow(enable);
428  GetDlgItem(IDC_SPIN_WAVES)->EnableWindow(player_enabled);
429  GetDlgItem(IDC_SPIN_WAVE_THRESHOLD)->EnableWindow(player_enabled);
430  GetDlgItem(IDC_ARRIVAL_LOCATION)->EnableWindow(enable);
431 
432  GetDlgItem(IDC_ARRIVAL_DELAY)->EnableWindow(player_enabled);
433  GetDlgItem(IDC_ARRIVAL_DELAY_MIN)->EnableWindow(player_enabled);
434  GetDlgItem(IDC_ARRIVAL_DELAY_MAX)->EnableWindow(player_enabled);
435  GetDlgItem(IDC_ARRIVAL_DELAY_SPIN)->EnableWindow(player_enabled);
436  if (m_arrival_location) {
437  GetDlgItem(IDC_ARRIVAL_DISTANCE)->EnableWindow(enable);
438  GetDlgItem(IDC_ARRIVAL_TARGET)->EnableWindow(enable);
439  } else {
440  GetDlgItem(IDC_ARRIVAL_DISTANCE)->EnableWindow(FALSE);
441  GetDlgItem(IDC_ARRIVAL_TARGET)->EnableWindow(FALSE);
442  }
444  GetDlgItem(IDC_RESTRICT_ARRIVAL)->EnableWindow(enable);
445  } else {
446  GetDlgItem(IDC_RESTRICT_ARRIVAL)->EnableWindow(FALSE);
447  }
448  GetDlgItem(IDC_NO_DYNAMIC)->EnableWindow(enable);
449 
450  if (m_departure_location) {
451  GetDlgItem(IDC_DEPARTURE_TARGET)->EnableWindow(enable);
452  } else {
453  GetDlgItem(IDC_DEPARTURE_TARGET)->EnableWindow(FALSE);
454  }
456  GetDlgItem(IDC_RESTRICT_DEPARTURE)->EnableWindow(enable);
457  } else {
458  GetDlgItem(IDC_RESTRICT_DEPARTURE)->EnableWindow(FALSE);
459  }
460 
461  if (player_wing)
462  GetDlgItem(IDC_ARRIVAL_TREE)->EnableWindow(0);
463  else
464  GetDlgItem(IDC_ARRIVAL_TREE)->EnableWindow(enable);
465 
466  GetDlgItem(IDC_DEPARTURE_LOCATION)->EnableWindow(enable);
467  GetDlgItem(IDC_DEPARTURE_DELAY)->EnableWindow(enable);
468  GetDlgItem(IDC_DEPARTURE_DELAY_SPIN)->EnableWindow(enable);
469  GetDlgItem(IDC_DEPARTURE_TREE)->EnableWindow(enable);
470  GetDlgItem(IDC_GOALS2)->EnableWindow(enable);
471  GetDlgItem(IDC_DELETE_WING)->EnableWindow(enable);
472  GetDlgItem(IDC_REINFORCEMENT)->EnableWindow(enable);
473  GetDlgItem(IDC_HOTKEY)->EnableWindow(enable);
474  GetDlgItem(IDC_IGNORE_COUNT)->EnableWindow(enable);
475  GetDlgItem(IDC_NO_ARRIVAL_MUSIC)->EnableWindow(enable);
476  GetDlgItem(IDC_NO_ARRIVAL_MESSAGE)->EnableWindow(enable);
477  GetDlgItem(IDC_NO_ARRIVAL_WARP)->EnableWindow(enable);
478  GetDlgItem(IDC_NO_DEPARTURE_WARP)->EnableWindow(enable);
479 
480  if (cur_wing >= 0) {
481  enable = TRUE;
482 
483  // check to see if the wing has a ship which is not a fighter/bomber type. If so, then disable
484  // the wing_waves and wing_threshold stuff
485  for (i = 0; i < Wings[cur_wing].wave_count; i++ ) {
486  int sflag;
487 
489  if ( !(sflag & SIF_FIGHTER) && !(sflag & SIF_BOMBER) )
490  enable = FALSE;
491  }
492 
493  } else
494  enable = FALSE;
495 }
496 
497 void wing_editor::initialize_data(int full_update)
498 {
499  int i;
500  CWnd *w = NULL;
501 
502  nprintf(("Fred routing", "Wing dialog load\n"));
503  if (!GetSafeHwnd())
504  return;
505 
507  select_sexp_node = -1;
508  if (cur_wing == -1)
509  m_wing_name = _T("");
510  else
512 
513  initialize_data_safe(full_update);
514  modified = 0;
515  if (w)
516  w -> SetFocus();
517 
519  if (i != -1) {
520  w = GetDlgItem(IDC_ARRIVAL_TREE);
522 
523  } else {
525  if (i != -1) {
526  w = GetDlgItem(IDC_DEPARTURE_TREE);
528  }
529  }
530 }
531 
532 // update wing structure(s) with dialog data. The data is first checked for errors. If
533 // no errors occur, returns 0. If an error occurs, returns -1. If the update is bypassed,
534 // returns 1. Bypass is necessary to avoid an infinite loop, and it doesn't actually
535 // update the data. Bypass only occurs if bypass mode is active and we still get an error.
536 // Once the error no longer occurs, bypass mode is cleared and data is updated.
538 {
539  char *str, old_name[255], buf[512];
540  int i, z;
541  object *ptr;
542 
543  nprintf(("Fred routing", "Wing dialog save\n"));
544  if (!GetSafeHwnd())
545  return 0;
546 
547  UpdateData(TRUE);
548  UpdateData(TRUE);
549 
550  m_wing_name.TrimLeft();
551  m_wing_name.TrimRight();
552 
553  if (cur_wing >= 0) {
554  for (i=0; i<MAX_WINGS; i++)
555  if (Wings[i].wave_count && !stricmp(Wings[i].name, m_wing_name) && (i != cur_wing)) {
556  if (bypass_errors)
557  return 1;
558 
559  bypass_errors = 1;
560  z = MessageBox("This wing name is already being used by another wing\n"
561  "Press OK to restore old name", "Error", MB_ICONEXCLAMATION | MB_OKCANCEL);
562 
563  if (z == IDCANCEL)
564  return -1;
565 
566  m_wing_name = _T(Wings[cur_wing].name);
567  UpdateData(FALSE);
568  }
569 
570  ptr = GET_FIRST(&obj_used_list);
571  while (ptr != END_OF_LIST(&obj_used_list)) {
572  if ((ptr->type == OBJ_SHIP) || (ptr->type == OBJ_START)) {
573  if (!stricmp(m_wing_name, Ships[ptr->instance].ship_name)) {
574  if (bypass_errors)
575  return 1;
576 
577  bypass_errors = 1;
578  z = MessageBox("This wing name is already being used by a ship\n"
579  "Press OK to restore old name", "Error", MB_ICONEXCLAMATION | MB_OKCANCEL);
580 
581  if (z == IDCANCEL)
582  return -1;
583 
584  m_wing_name = _T(Wings[cur_wing].name);
585  UpdateData(FALSE);
586  }
587  }
588 
589  ptr = GET_NEXT(ptr);
590  }
591 
592  for (i=0; i<Num_iffs; i++) {
593  if (!stricmp(m_wing_name, Iff_info[i].iff_name))
594  {
595  if (bypass_errors)
596  return 1;
597 
598  bypass_errors = 1;
599  z = MessageBox("This wing name is already being used by a team.\n"
600  "Press OK to restore old name", "Error", MB_ICONEXCLAMATION | MB_OKCANCEL);
601 
602  if (z == IDCANCEL)
603  return -1;
604 
605  m_wing_name = _T(Wings[cur_wing].name);
606  UpdateData(FALSE);
607  }
608  }
609 
610  for ( i=0; i < (int)Ai_tp_list.size(); i++) {
611  if (!stricmp(m_wing_name, Ai_tp_list[i].name))
612  {
613  if (bypass_errors)
614  return 1;
615 
616  bypass_errors = 1;
617  z = MessageBox("This wing name is already being used by a target priority group.\n"
618  "Press OK to restore old name", "Error", MB_ICONEXCLAMATION | MB_OKCANCEL);
619 
620  if (z == IDCANCEL)
621  return -1;
622 
623  m_wing_name = _T(Wings[cur_wing].name);
624  UpdateData(FALSE);
625  }
626  }
627 
628  if (find_matching_waypoint_list((LPCSTR) m_wing_name) != NULL)
629  {
630  if (bypass_errors)
631  return 1;
632 
633  bypass_errors = 1;
634  z = MessageBox("This wing name is already being used by a waypoint path\n"
635  "Press OK to restore old name", "Error", MB_ICONEXCLAMATION | MB_OKCANCEL);
636 
637  if (z == IDCANCEL)
638  return -1;
639 
640  m_wing_name = _T(Wings[cur_wing].name);
641  UpdateData(FALSE);
642  }
643 
644  if(jumpnode_get_by_name(m_wing_name) != NULL)
645  {
646  if (bypass_errors)
647  return 1;
648 
649  bypass_errors = 1;
650  z = MessageBox("This wing name is already being used by a jump node\n"
651  "Press OK to restore old name", "Error", MB_ICONEXCLAMATION | MB_OKCANCEL);
652 
653  if (z == IDCANCEL)
654  return -1;
655 
656  m_wing_name = _T(Wings[cur_wing].name);
657  UpdateData(FALSE);
658  }
659 
660  if (!stricmp(m_wing_name.Left(1), "<")) {
661  if (bypass_errors)
662  return 1;
663 
664  bypass_errors = 1;
665  z = MessageBox("Wing names not allowed to begin with <\n"
666  "Press OK to restore old name", "Error", MB_ICONEXCLAMATION | MB_OKCANCEL);
667 
668  if (z == IDCANCEL)
669  return -1;
670 
671  m_wing_name = _T(Wings[cur_wing].name);
672  UpdateData(FALSE);
673  }
674 
675  strcpy_s(old_name, Wings[cur_wing].name);
676  string_copy(Wings[cur_wing].name, m_wing_name, NAME_LENGTH, 1);
678 
680 
681  bypass_errors = 0;
682  modified = 0;
683  str = Wings[cur_wing].name;
684  if (strcmp(old_name, str)) {
685  update_sexp_references(old_name, str);
687  update_texture_replacements(old_name, str);
688  for (i=0; i<Num_reinforcements; i++)
689  if (!strcmp(old_name, Reinforcements[i].name)) {
690  Assert(strlen(str) < NAME_LENGTH);
691  strcpy_s(Reinforcements[i].name, str);
692  }
693 
694  for (i=0; i<Wings[cur_wing].wave_count; i++) {
696  wing_bash_ship_name(buf, str, i + 1);
697  rename_ship(Wings[cur_wing].ship_index[i], buf);
698  }
699  }
700 
701  Update_window = 1;
702  }
703 
704  //Check if we're trying to add more and we've got too many.
706  {
707  if (bypass_errors)
708  return 1;
709 
710  bypass_errors = 1;
711 
712  char error_message[256];
713  sprintf(error_message, "Too many reinforcements; could not add wing '%s' to reinforcement list!", str);
714  MessageBox(error_message, "Error", MB_ICONEXCLAMATION | MB_OK);
715 
716  //clear the flag
717  m_reinforcement = 0;
718  UpdateData(FALSE);
719 
720  return -1;
721 
722  }
723  //Otherwise, just update as normal.
724  else if (set_reinforcement(str, m_reinforcement) == 1)
725  {
726  free_sexp2(Wings[cur_wing].arrival_cue);
728  }
729  }
730 
731  if (redraw)
733 
734  return 0;
735 }
736 
737 // update parts of wing that can't fail. This is useful if for when you need to change
738 // something in a wing that this updates elsewhere in Fred. Normally when auto-update
739 // kicks in, the changes you make will be wiped out by the auto=update, so instead you
740 // would call this function to update the wing, make your changes, and then call the
741 // initialize_data_safe() function to show your changes in the dialog
743 {
744  char buf[512];
745  int i, d, hotkey = -1;
746 
747  nprintf(("Fred routing", "Wing dialog save safe\n"));
748  if (!GetSafeHwnd())
749  return;
750 
751  UpdateData(TRUE);
752  UpdateData(TRUE);
753 
754  if (cur_wing < 0)
755  return;
756 
759  if (!bypass_errors) {
760  sprintf(buf, "Wave threshold is set too high. Value has been lowered to %d", (int) m_threshold);
761  MessageBox(buf);
762  }
763  }
764 
765  if (m_waves < 1) {
766  m_waves = 1;
767  if (!bypass_errors) {
768  sprintf(buf, "Number of waves illegal. Can not have %d waves. Number of waves has as been set to 1.", (int) m_waves);
769  MessageBox(buf);
770  }
771  }
772 
773  MODIFY(Wings[cur_wing].special_ship, m_special_ship);
774  MODIFY(Wings[cur_wing].num_waves, m_waves);
775  MODIFY(Wings[cur_wing].threshold, m_threshold);
776  MODIFY(Wings[cur_wing].arrival_location, m_arrival_location);
777  MODIFY(Wings[cur_wing].departure_location, m_departure_location);
778  MODIFY(Wings[cur_wing].arrival_delay, m_arrival_delay);
780  if (!bypass_errors) {
781  sprintf(buf, "Arrival delay minimum greater than maximum. Value lowered to %d", m_arrival_delay_max);
782  MessageBox(buf);
783  }
784 
786  }
787 
788  MODIFY(Wings[cur_wing].wave_delay_min, m_arrival_delay_min);
789  MODIFY(Wings[cur_wing].wave_delay_max, m_arrival_delay_max);
790  MODIFY(Wings[cur_wing].arrival_distance, m_arrival_dist);
791  if (m_arrival_target >= 0) {
792  i = ((CComboBox *) GetDlgItem(IDC_ARRIVAL_TARGET))->GetItemData(m_arrival_target);
793  MODIFY(Wings[cur_wing].arrival_anchor, i);
794 
795  // when arriving near or in front of a ship, be sure that we are far enough away from it!!!
797  d = int(min(500, 2.0f * Objects[Ships[i].objnum].radius));
798  if ((Wings[cur_wing].arrival_distance < d) && (Wings[cur_wing].arrival_distance > -d)) {
799  if (!bypass_errors) {
800  sprintf(buf, "Ship must arrive at least %d meters away from target.\n"
801  "Value has been reset to this. Use with caution!\r\n"
802  "Recommended distance is %d meters.\r\n", d, (int)(2.0f * Objects[Ships[i].objnum].radius) );
803 
804  MessageBox(buf);
805  }
806 
807  if (Wings[cur_wing].arrival_distance < 0)
809  else
811 
813  }
814  }
815  }
816  if (m_departure_target >= 0) {
817  i = ((CComboBox *) GetDlgItem(IDC_DEPARTURE_TARGET))->GetItemData(m_departure_target);
818  MODIFY(Wings[cur_wing].departure_anchor, i);
819  }
820 
821  MODIFY(Wings[cur_wing].departure_delay, m_departure_delay);
822  hotkey = m_hotkey - 1;
823  MODIFY(Wings[cur_wing].hotkey, hotkey);
824  if ( m_ignore_count ) {
825  if ( !(Wings[cur_wing].flags & WF_IGNORE_COUNT) )
826  set_modified();
828 
829  } else {
831  set_modified();
832  Wings[cur_wing].flags &= ~WF_IGNORE_COUNT;
833  }
834 
835  if ( m_no_arrival_music ) {
837  set_modified();
839 
840  } else {
842  set_modified();
843  Wings[cur_wing].flags &= ~WF_NO_ARRIVAL_MUSIC;
844  }
845 
846  // check the no message flag
847  if ( m_no_arrival_message ) {
849  set_modified();
851 
852  } else {
854  set_modified();
855  Wings[cur_wing].flags &= ~WF_NO_ARRIVAL_MESSAGE;
856  }
857 
858  // set the no warp effect for wings flag
859  if ( m_no_arrival_warp ) {
861  set_modified();
863  } else {
865  set_modified();
866  Wings[cur_wing].flags &= ~WF_NO_ARRIVAL_WARP;
867  }
868  // set the no warp effect for wings flag
869  if ( m_no_departure_warp ) {
871  set_modified();
873  } else {
875  set_modified();
876  Wings[cur_wing].flags &= ~WF_NO_DEPARTURE_WARP;
877  }
878 
879  if ( m_no_dynamic ) {
880  if ( !(Wings[cur_wing].flags & WF_NO_DYNAMIC) )
881  set_modified();
883  } else {
885  set_modified();
886  Wings[cur_wing].flags &= ~WF_NO_DYNAMIC;
887  }
888 
889  if (Wings[cur_wing].arrival_cue >= 0)
890  free_sexp2(Wings[cur_wing].arrival_cue);
892 
893  if (Wings[cur_wing].departure_cue >= 0)
894  free_sexp2(Wings[cur_wing].departure_cue);
896 
897  // copy squad stuff
898  if(stricmp(m_wing_squad_filename, Wings[cur_wing].wing_squad_filename))
899  {
901  set_modified();
902  }
903 
904  if (modified)
905  set_modified();
906 }
907 
909 {
910  int id, wing;
911 
912  id = LOWORD(wParam);
913  if (id >= ID_WING_MENU && id < ID_WING_MENU + MAX_WINGS) {
914  if (!update_data()) {
915  wing = id - ID_WING_MENU;
916  mark_wing(wing);
917  return 1;
918  }
919  }
920 
921  return CDialog::OnCommand(wParam, lParam);
922 }
923 
924 void wing_editor::OnDeltaposSpinWaves(NMHDR* pNMHDR, LRESULT* pResult)
925 {
926  int new_pos;
927  NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
928 
929  new_pos = pNMUpDown->iPos + pNMUpDown->iDelta;
930  if (new_pos > 0 && new_pos < 100) {
931  *pResult = 0;
932  modified = 1;
933 
934  } else
935  *pResult = 1;
936 }
937 
938 void wing_editor::OnRclickArrivalTree(NMHDR* pNMHDR, LRESULT* pResult)
939 {
941  *pResult = 0;
942 }
943 
944 void wing_editor::OnRclickDepartureTree(NMHDR* pNMHDR, LRESULT* pResult)
945 {
947  *pResult = 0;
948 }
949 
950 void wing_editor::OnBeginlabeleditArrivalTree(NMHDR* pNMHDR, LRESULT* pResult)
951 {
952  TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR;
953 
954  if (m_arrival_tree.edit_label(pTVDispInfo->item.hItem) == 1) {
955  *pResult = 0;
956  modified = 1;
957 
958  } else
959  *pResult = 1;
960 }
961 
963 {
964  TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR;
965 
966  if (m_departure_tree.edit_label(pTVDispInfo->item.hItem) == 1) {
967  *pResult = 0;
968  modified = 1;
969 
970  } else
971  *pResult = 1;
972 }
973 
974 void wing_editor::OnEndlabeleditArrivalTree(NMHDR* pNMHDR, LRESULT* pResult)
975 {
976  TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR;
977 
978  *pResult = m_arrival_tree.end_label_edit(pTVDispInfo->item);
979 }
980 
981 void wing_editor::OnEndlabeleditDepartureTree(NMHDR* pNMHDR, LRESULT* pResult)
982 {
983  TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR;
984 
985  *pResult = m_departure_tree.end_label_edit(pTVDispInfo->item);
986 }
987 
989 {
990  nprintf(("Fred routing", "Wing dialog verify\n"));
991  if (!GetSafeHwnd() || !modified)
992  return 0;
993 
994  if (bypass_errors)
995  return 1;
996 
997  return 0;
998 }
999 
1000 // delete wing and all ships that are part of the wing
1002 {
1003  modified = 0; // no need to run update checks, since wing will be gone shortly anyway.
1005 }
1006 
1007 // delete wing, but leave ships intact and wingless
1009 {
1010  modified = 0; // no need to run update checks, since wing will be gone shortly anyway.
1012 }
1013 
1015 {
1016  ShipGoalsDlg dlg_goals;
1017 
1018  Assert(cur_wing != -1);
1019  dlg_goals.self_wing = cur_wing;
1020  dlg_goals.DoModal();
1022  MessageBox("One or more ships of this wing also has initial orders",
1023  "Possible conflict");
1024 }
1025 
1027 {
1028  UpdateData(TRUE);
1029  UpdateData(TRUE);
1030  //if (m_reinforcement)
1031  // m_arrival_tree.clear_tree("false");
1032 }
1033 
1035 {
1036  int wing, count = 0;
1037 
1038  if (!update_data() && Num_wings) {
1039  wing = cur_wing - 1;
1040  if (wing < 0)
1041  wing = MAX_WINGS - 1;
1042 
1043  while (!Wings[wing].wave_count) {
1044  wing--;
1045  if (count++ > MAX_WINGS)
1046  return;
1047 
1048  if (wing < 0)
1049  wing = MAX_WINGS - 1;
1050  }
1051 
1052  mark_wing(wing);
1054  Update_wing = 0;
1055  }
1056 
1057  return;
1058 }
1059 
1061 {
1062  int wing, count = 0;
1063 
1064  if (!update_data() && Num_wings) {
1065  wing = cur_wing + 1;
1066  if (wing >= MAX_WINGS)
1067  wing = 0;
1068 
1069  while (!Wings[wing].wave_count) {
1070  wing++;
1071  if (count++ > MAX_WINGS)
1072  return;
1073 
1074  if (wing >= MAX_WINGS)
1075  wing = 0;
1076  }
1077 
1078  mark_wing(wing);
1080  Update_wing = 0;
1081  }
1082 
1083  return;
1084 }
1085 
1086 void wing_editor::OnSelchangedArrivalTree(NMHDR* pNMHDR, LRESULT* pResult)
1087 {
1088  HTREEITEM h;
1089 
1090  NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
1091  h = pNMTreeView->itemNew.hItem;
1092  if (h)
1094 
1095  *pResult = 0;
1096 }
1097 
1098 void wing_editor::OnSelchangedDepartureTree(NMHDR* pNMHDR, LRESULT* pResult)
1099 {
1100  HTREEITEM h;
1101 
1102  NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
1103  h = pNMTreeView->itemNew.hItem;
1104  if (h)
1106 
1107  *pResult = 0;
1108 }
1109 
1111 {
1112  CRect cue;
1113 
1114  GetDlgItem(IDC_CUE_FRAME)->GetWindowRect(cue);
1115  cue_height = cue.bottom - cue.top + 10;
1116  if (Show_sexp_help)
1118 
1119  if (Hide_wing_cues) {
1120  ((CButton *) GetDlgItem(IDC_HIDE_CUES)) -> SetCheck(1);
1121  OnHideCues();
1122  }
1123 }
1124 
1126 {
1127  CRect rect;
1128 
1129  if (Show_sexp_help)
1131  else
1133 
1134  if (((CButton *) GetDlgItem(IDC_HIDE_CUES)) -> GetCheck())
1135  return;
1136 
1137  GetWindowRect(rect);
1138  if (Show_sexp_help)
1139  rect.bottom += SEXP_HELP_BOX_SIZE;
1140  else
1141  rect.bottom -= SEXP_HELP_BOX_SIZE;
1142 
1143  MoveWindow(rect);
1144 }
1145 
1147 {
1148  CRect rect;
1149 
1150  GetWindowRect(rect);
1151  if (((CButton *) GetDlgItem(IDC_HIDE_CUES)) -> GetCheck()) {
1152  rect.bottom -= cue_height;
1153  Hide_wing_cues = 1;
1154 
1155  } else {
1156  rect.bottom += cue_height;
1157  Hide_wing_cues = 0;
1158  }
1159 
1160  MoveWindow(rect);
1161 }
1162 
1164 {
1165  CComboBox *box;
1166 
1167  box = (CComboBox *)GetDlgItem(IDC_ARRIVAL_TARGET);
1168  UpdateData();
1169  if (m_arrival_location) {
1170  GetDlgItem(IDC_ARRIVAL_DISTANCE)->EnableWindow(TRUE);
1171  GetDlgItem(IDC_ARRIVAL_TARGET)->EnableWindow(TRUE);
1172  if (m_arrival_target < 0) {
1173  m_arrival_target = 0;
1174  }
1175 
1176  // determine which items we should put into the arrival target combo box
1179  } else {
1181  }
1182  } else {
1183  m_arrival_target = -1;
1184  GetDlgItem(IDC_ARRIVAL_DISTANCE)->EnableWindow(FALSE);
1185  GetDlgItem(IDC_ARRIVAL_TARGET)->EnableWindow(FALSE);
1186  }
1187 
1189  GetDlgItem(IDC_RESTRICT_ARRIVAL)->EnableWindow(TRUE);
1190  } else {
1191  GetDlgItem(IDC_RESTRICT_ARRIVAL)->EnableWindow(FALSE);
1192  }
1193 
1194  UpdateData(FALSE);
1195 }
1196 
1198 {
1199  CComboBox *box;
1200 
1201  box = (CComboBox *)GetDlgItem(IDC_DEPARTURE_TARGET);
1202  UpdateData();
1203  if (m_departure_location) {
1204  GetDlgItem(IDC_DEPARTURE_TARGET)->EnableWindow(TRUE);
1205  if (m_departure_target < 0) {
1206  m_departure_target = 0;
1207  }
1208  // we need to build up the list box content based on the departure type. When
1209  // from a docking bay, only show ships in the list which have them. Show all ships otherwise
1212  } else {
1213  // I think that this section is currently illegal
1214  Int3();
1215  }
1216  } else {
1217  m_departure_target = -1;
1218  GetDlgItem(IDC_DEPARTURE_TARGET)->EnableWindow(FALSE);
1219  }
1220 
1222  GetDlgItem(IDC_RESTRICT_DEPARTURE)->EnableWindow(TRUE);
1223  } else {
1224  GetDlgItem(IDC_RESTRICT_DEPARTURE)->EnableWindow(FALSE);
1225  }
1226 
1227  UpdateData(FALSE);
1228 }
1229 
1230 // see if hotkey should possibly be reserved for player starting wing
1232 {
1233  char buf[256];
1234  int set_num, i;
1235 
1236  UpdateData(TRUE);
1237  set_num = m_hotkey - 1; // hotkey sets are 1 index based
1238 
1239  // first, determine if we are currently working with a starting wing
1240  for ( i = 0; i < MAX_STARTING_WINGS; i++ ) {
1242  break;
1243  }
1244  if ( i == MAX_STARTING_WINGS )
1245  return;
1246 
1247  // we have a player starting wing. See if we assigned a non-standard hotkey
1248  if ( (set_num >= MAX_STARTING_WINGS) || (set_num != i) ) {
1249  sprintf(buf, "Assigning nonstandard hotkey to wing %s (default is F%d)", Wings[cur_wing].name, 5+i);
1250  MessageBox(buf, NULL, MB_OK | MB_ICONEXCLAMATION );
1251  }
1252 }
1253 
1255 {
1256  int z;
1257  char *Logo_ext = "Image Files (*.dds, *.pcx)|*.dds;*.pcx|"
1258  "DDS Files (*.dds)|*.dds|"
1259  "PCX Files (*.pcx)|*.pcx|"
1260  "All Files (*.*)|*.*|"
1261  "|";
1262 
1263  //phreak 05/05/2003
1264  //this needs to be here or else the data in the wing editor dialog will revert
1265  //to what it was before it was opened.
1266  UpdateData(TRUE);
1267 
1268  // get list of squad images
1270  CFileDialog dlg(TRUE, NULL, NULL, OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR, Logo_ext);
1271 
1272  // if we have a result
1273  if (dlg.DoModal() == IDOK) {
1274  m_wing_squad_filename = dlg.GetFileName();
1275  } else {
1276  m_wing_squad_filename = _T("");
1277  }
1278  UpdateData(FALSE);
1279 
1280  // restore directory
1281  if (!z){
1282  cfile_pop_dir();
1283  }
1284 }
1285 
1286 // Goober5000
1288 {
1289  int arrive_from_ship;
1290  CComboBox *box;
1291  restrict_paths dlg;
1292 
1293  // grab stuff from GUI
1294  UpdateData(TRUE);
1295 
1297  {
1298  Int3();
1299  return;
1300  }
1301 
1302  box = (CComboBox *) GetDlgItem(IDC_ARRIVAL_TARGET);
1303  if (box->GetCount() == 0)
1304  return;
1305 
1306  arrive_from_ship = box->GetItemData(m_arrival_target);
1307 
1308  if (!ship_has_dock_bay(arrive_from_ship))
1309  {
1310  Int3();
1311  return;
1312  }
1313 
1314  dlg.m_arrival = true;
1315  dlg.m_ship_class = Ships[arrive_from_ship].ship_info_index;
1317 
1318  dlg.DoModal();
1319 }
1320 
1321 // Goober5000
1323 {
1324  int depart_to_ship;
1325  CComboBox *box;
1326  restrict_paths dlg;
1327 
1328  // grab stuff from GUI
1329  UpdateData(TRUE);
1330 
1332  {
1333  Int3();
1334  return;
1335  }
1336 
1337  box = (CComboBox *) GetDlgItem(IDC_DEPARTURE_TARGET);
1338  if (box->GetCount() == 0)
1339  return;
1340 
1341  depart_to_ship = box->GetItemData(m_departure_target);
1342 
1343  if (!ship_has_dock_bay(depart_to_ship))
1344  {
1345  Int3();
1346  return;
1347  }
1348 
1349  dlg.m_arrival = false;
1350  dlg.m_ship_class = Ships[depart_to_ship].ship_info_index;
1352 
1353  dlg.DoModal();
1354 }
1355 
1357 {
1358  const int treshold1 = Wings[cur_wing].wave_count - 1; // At least 1 ship must have died before allowing respawn
1359  const int treshold2 = MAX_SHIPS_PER_WING - Wings[cur_wing].wave_count; // Maximum MAX_SHIPS_PER_WING ships can be alive at any given time
1360  return min(treshold1, treshold2);
1361 }
afx_msg void OnClose()
#define IDC_NO_ARRIVAL_MUSIC
Definition: resource.h:909
#define MAX_FILENAME_LEN
Definition: pstypes.h:324
#define MB_OKCANCEL
Definition: config.h:180
char Starting_wing_names[MAX_STARTING_WINGS][NAME_LENGTH]
Definition: ship.cpp:139
CSpinButtonCtrl m_arrival_delay_spin
Definition: wing_editor.h:41
int m_arrival_delay_max
Definition: wing_editor.h:57
#define IDC_REINFORCEMENT
Definition: resource.h:736
wing Wings[MAX_WINGS]
Definition: ship.cpp:128
void wing_bash_ship_name(char *ship_name, const char *wing_name, int index)
Definition: ship.cpp:12686
afx_msg void OnRclickDepartureTree(NMHDR *pNMHDR, LRESULT *pResult)
void * HWND
Definition: config.h:104
int i
Definition: multi_pxo.cpp:466
int wave_delay_min
Definition: ship.h:1552
afx_msg void OnInitMenu(CMenu *pMenu)
int Locked_sexp_false
Definition: sexp.cpp:828
afx_msg void OnBeginlabeleditDepartureTree(NMHDR *pNMHDR, LRESULT *pResult)
#define WF_IGNORE_COUNT
Definition: ship.h:1503
afx_msg void OnRclickArrivalTree(NMHDR *pNMHDR, LRESULT *pResult)
sexp_tree m_departure_tree
Definition: wing_editor.h:42
int m_departure_target
Definition: wing_editor.h:62
int arrival_anchor
Definition: ship.h:1541
int wave_delay_max
Definition: ship.h:1553
int arrival_distance
Definition: ship.h:1540
GLfloat GLfloat GLfloat GLfloat h
Definition: Glext.h:7280
int game_type
Definition: missionparse.h:138
int Player_start_shipnum
BOOL m_no_arrival_warp
Definition: wing_editor.h:64
void calc_cue_height()
int arrival_location
Definition: ship.h:1539
afx_msg void OnSelchangeHotkey()
void update_custom_wing_indexes()
int m_arrival_target
Definition: wing_editor.h:60
afx_msg void OnSelchangeArrivalLocation()
#define REF_TYPE_WING
Definition: sexp.h:837
afx_msg void OnNext()
#define MAX_WINGS
Definition: globals.h:50
#define MAX_SHIPS
Definition: globals.h:37
#define IDC_HELP_BOX
Definition: resource.h:872
BOOL m_ignore_count
Definition: wing_editor.h:56
int rename_ship(int ship, char *name)
void remove_wing(int wing_num)
Definition: wing.cpp:117
#define SHIPS_2_COMBO_DOCKING_BAY_ONLY
Definition: management.h:135
Assert(pm!=NULL)
int m_arrival_delay_min
Definition: wing_editor.h:58
void stuff_special_arrival_anchor_name(char *buf, int iff_index, int restrict_to_players, int retail_format)
int departure_anchor
Definition: ship.h:1547
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam)
afx_msg void OnSquadLogo()
wing_editor(CWnd *pParent=NULL)
Definition: wing_editor.cpp:37
int cfile_pop_dir()
Definition: cfile.cpp:381
GLclampf f
Definition: Glext.h:7097
#define IDC_RESTRICT_ARRIVAL
Definition: resource.h:1068
#define IDC_ARRIVAL_DELAY_MAX
Definition: resource.h:788
void update_sexp_references(const char *old_name, const char *new_name, int format, int node)
Definition: sexp.cpp:28332
#define TRUE
Definition: pstypes.h:399
#define WF_NO_ARRIVAL_MUSIC
Definition: ship.h:1506
#define MISSION_TYPE_MULTI
Definition: missionparse.h:62
#define WF_NO_DYNAMIC
Definition: ship.h:1511
UINT WPARAM wParam
Definition: msacm.h:1064
object obj_used_list
Definition: object.cpp:53
int cur_wing
Definition: management.cpp:77
#define IDC_DEPARTURE_TARGET
Definition: resource.h:537
#define IDC_RESTRICT_DEPARTURE
Definition: resource.h:1070
CMainFrame * Fred_main_wnd
Definition: mainfrm.cpp:89
#define CF_TYPE_SQUAD_IMAGES
Definition: cfile.h:69
CString m_wing_squad_filename
Definition: wing_editor.h:67
int edit_label(HTREEITEM h)
Definition: sexp_tree.cpp:1349
UINT WPARAM LPARAM lParam
Definition: msacm.h:1064
#define MAX_SHIPS_PER_WING
Definition: globals.h:52
#define Int3()
Definition: pstypes.h:292
#define IDC_WING_SPECIAL_SHIP
Definition: resource.h:164
int arrival_delay
Definition: ship.h:1544
#define MODIFY(a, b)
Definition: fred.h:26
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: Glext.h:7308
#define MAX_TVT_WINGS
Definition: globals.h:59
void right_clicked(int mode=0)
Definition: sexp_tree.cpp:570
int hotkey
Definition: ship.h:1520
#define SPECIAL_ARRIVAL_ANCHOR_FLAG
Definition: missionparse.h:37
long LPARAM
Definition: config.h:101
GLenum type
Definition: Gl.h:1492
iff_info Iff_info[MAX_IFFS]
Definition: iff_defs.cpp:20
reinforcements Reinforcements[MAX_REINFORCEMENTS]
Definition: ship.cpp:165
afx_msg void OnHideCues()
afx_msg void OnSelchangedDepartureTree(NMHDR *pNMHDR, LRESULT *pResult)
int arrival_path_mask
Definition: ship.h:1542
#define IDC_CUE_FRAME
Definition: resource.h:886
#define IDC_GOALS2
Definition: resource.h:271
int cfile_push_chdir(int type)
Push current directory onto a 'stack' and change to a new directory.
Definition: cfile.cpp:342
#define SIF_BOMBER
Definition: ship.h:886
void update_help(HTREEITEM h)
Definition: sexp_tree.cpp:3891
int Locked_sexp_true
Definition: sexp.cpp:828
CSpinButtonCtrl m_departure_delay_spin
Definition: wing_editor.h:40
typedef int(SCP_EXT_CALLCONV *SCPDLL_PFVERSION)(SCPDLL_Version *)
#define IDC_ARRIVAL_DELAY_MIN
Definition: resource.h:774
int instance
Definition: object.h:150
#define DEPART_AT_DOCK_BAY
Definition: missionparse.h:246
#define IDC_DEPARTURE_TREE
Definition: resource.h:625
#define IDC_WING_NAME
Definition: resource.h:234
#define OBJ_START
Definition: object.h:35
afx_msg void OnSelchangedArrivalTree(NMHDR *pNMHDR, LRESULT *pResult)
GLdouble GLdouble GLdouble r
Definition: Glext.h:5337
char * Departure_location_names[MAX_DEPARTURE_NAMES]
int update_data(int redraw=1)
#define MAX_DEPARTURE_NAMES
Definition: missionparse.h:244
afx_msg void OnEndlabeleditDepartureTree(NMHDR *pNMHDR, LRESULT *pResult)
#define WF_NO_DEPARTURE_WARP
Definition: ship.h:1510
afx_msg void OnDeleteWing()
#define nprintf(args)
Definition: pstypes.h:239
#define IDC_ARRIVAL_DELAY
Definition: resource.h:731
#define IDC_NO_DYNAMIC
Definition: resource.h:947
char name[NAME_LENGTH]
Definition: ship.h:1517
int m_departure_delay
Definition: wing_editor.h:53
int Update_wing
Definition: management.cpp:88
#define IDC_DISBAND_WING
Definition: resource.h:558
int end_label_edit(TVITEMA &item)
Definition: sexp_tree.cpp:1412
#define MAX_STARTING_WINGS
Definition: globals.h:54
int m_special_ship
Definition: wing_editor.h:47
int departure_cue
Definition: ship.h:1549
int m_departure_location
Definition: wing_editor.h:51
#define SHIPS_2_COMBO_SPECIAL
Definition: management.h:133
#define w(p)
Definition: modelsinc.h:68
sprintf(buf,"(%f,%f,%f)", v3->xyz.x, v3->xyz.y, v3->xyz.z)
#define WF_NO_ARRIVAL_WARP
Definition: ship.h:1509
GLdouble GLdouble z
Definition: Glext.h:5451
int free_sexp2(int num)
Definition: sexp.cpp:1321
#define IDC_ARRIVAL_DISTANCE
Definition: resource.h:801
int Num_wings
Definition: ship.cpp:120
#define MB_OK
Definition: config.h:179
sexp_tree m_arrival_tree
Definition: wing_editor.h:43
int wing_objects[MAX_WINGS][MAX_SHIPS_PER_WING]
Definition: management.cpp:97
#define IDC_WING_WAVE_THRESHOLD
Definition: resource.h:154
void initialize_data(int full)
#define IDC_ARRIVAL_DELAY_SPIN
Definition: resource.h:733
GLenum GLuint id
Definition: Glext.h:5156
#define WF_NO_ARRIVAL_MESSAGE
Definition: ship.h:1508
#define ID_WING_MENU
Definition: wing_editor.cpp:27
#define ARRIVE_AT_LOCATION
Definition: missionparse.h:237
void update_data_safe()
void ai_update_goal_references(ai_goal *goals, int type, const char *old_name, const char *new_name)
Definition: aigoals.cpp:2295
#define IDC_SPIN_WAVES
Definition: resource.h:612
int wave_count
Definition: ship.h:1527
object Objects[MAX_OBJECTS]
Definition: object.cpp:62
afx_msg void OnEndlabeleditArrivalTree(NMHDR *pNMHDR, LRESULT *pResult)
afx_msg void OnGoals2()
#define IDC_ARRIVAL_TREE
Definition: resource.h:624
#define IDC_HIDE_CUES
Definition: resource.h:885
int m_arrival_location
Definition: wing_editor.h:50
void string_copy(char *dest, const CString &src, int max_len, int modify)
Definition: management.cpp:142
BOOL m_no_arrival_message
Definition: wing_editor.h:63
int num_waves
Definition: ship.h:1522
#define IDC_HOTKEY
Definition: resource.h:766
BOOL m_no_arrival_music
Definition: wing_editor.h:61
int TVT_wings[MAX_TVT_WINGS]
Definition: ship.cpp:136
#define OBJ_SHIP
Definition: object.h:32
int m_arrival_dist
Definition: wing_editor.h:59
wing_editor Wing_editor_dialog
Definition: fred.cpp:56
#define IDC_PREV
Definition: resource.h:851
GLbitfield flags
Definition: Glext.h:6722
BOOL m_reinforcement
Definition: wing_editor.h:54
afx_msg void OnSelchangeDepartureLocation()
int Starting_wings[MAX_STARTING_WINGS]
Definition: ship.cpp:132
void set_modified(BOOL arg)
Definition: freddoc.cpp:676
GLuint const GLchar * name
Definition: Glext.h:5608
int departure_path_mask
Definition: ship.h:1548
#define IDC_NO_ARRIVAL_WARP
Definition: resource.h:912
GLboolean enable
Definition: Glext.h:10591
int BOOL
Definition: config.h:80
ship Ships[MAX_SHIPS]
Definition: ship.cpp:122
CJumpNode * jumpnode_get_by_name(const CString &name)
int calc_max_wave_treshold()
#define IDC_DELETE_WING
Definition: resource.h:556
#define IDC_DEPARTURE_DELAY
Definition: resource.h:732
int bypass_errors
Definition: wing_editor.h:22
afx_msg void OnPrev()
#define MB_ICONEXCLAMATION
Definition: config.h:184
#define IDC_WING_WAVES
Definition: resource.h:149
int Hide_wing_cues
Definition: fredview.cpp:113
waypoint_list * find_matching_waypoint_list(const char *name)
Definition: waypoint.cpp:164
bool ship_has_dock_bay(int shipnum)
Definition: ship.cpp:17435
int arrival_cue
Definition: ship.h:1543
#define NAME_LENGTH
Definition: globals.h:15
GLubyte GLubyte GLubyte GLubyte w
Definition: Glext.h:5679
int delete_wing(int wing_num, int bypass)
Definition: wing.cpp:72
int select_sexp_node
Definition: wing_editor.h:24
afx_msg void OnBeginlabeleditArrivalTree(NMHDR *pNMHDR, LRESULT *pResult)
int special_ship
Definition: ship.h:1537
#define IDC_SPIN_WAVE_THRESHOLD
Definition: resource.h:614
int save_tree(int node=-1)
Definition: sexp_tree.cpp:237
int departure_location
Definition: ship.h:1546
int set_reinforcement(char *name, int state)
void generate_wing_popup_menu(CMenu *mptr, int first_id, int state)
BOOL m_no_dynamic
Definition: wing_editor.h:66
#define SHIPS_2_COMBO_ALL_SHIPS
Definition: management.h:134
int m_arrival_delay
Definition: wing_editor.h:52
CString m_wing_name
Definition: wing_editor.h:46
long LRESULT
Definition: config.h:100
afx_msg void OnDeltaposSpinWaves(NMHDR *pNMHDR, LRESULT *pResult)
int departure_delay
Definition: ship.h:1550
int ship_info_index
Definition: ship.h:539
#define MAX_REINFORCEMENTS
Definition: ship.h:58
#define IDC_ARRIVAL_LOCATION
Definition: resource.h:616
SCP_vector< ship_info > Ship_info
Definition: ship.cpp:164
int MessageBox(HWND h, const char *s1, const char *s2, int i)
#define SIF_FIGHTER
Definition: ship.h:885
#define IDC_DEPARTURE_DELAY_SPIN
Definition: resource.h:300
BOOL m_no_departure_warp
Definition: wing_editor.h:65
const GLfloat * m
Definition: Glext.h:10319
void load_tree(int index, const char *deflt="true")
Definition: sexp_tree.cpp:124
int threshold
Definition: ship.h:1523
GLint GLsizei count
Definition: Gl.h:1491
int query_initial_orders_conflict(int wing)
virtual void DoDataExchange(CDataExchange *pDX)
Definition: wing_editor.cpp:69
void hilite_item(int node)
Definition: sexp_tree.cpp:3139
void mark_wing(int wing)
Definition: wing.cpp:60
#define IDC_NO_DEPARTURE_WARP
Definition: resource.h:913
int Num_reinforcements
Definition: ship.cpp:121
#define MAX_ARRIVAL_NAMES
Definition: missionparse.h:236
int ship_index[MAX_SHIPS_PER_WING]
Definition: ship.h:1531
afx_msg void OnRestrictArrival()
CSpinButtonCtrl m_waves_spin
Definition: wing_editor.h:45
int Num_iffs
Definition: iff_defs.cpp:19
afx_msg void OnDisbandWing()
int select_sexp_node
Definition: sexp_tree.h:283
void clear_menu(CMenu *ptr)
void show_hide_sexp_help()
#define IDC_NO_ARRIVAL_MESSAGE
Definition: resource.h:919
mission The_mission
#define ARRIVE_FROM_DOCK_BAY
Definition: missionparse.h:240
afx_msg void OnReinforcement()
#define SEXP_HELP_BOX_SIZE
Definition: fredview.h:18
char type
Definition: object.h:146
#define IDC_WING_SQUAD_LOGO_BUTTON
Definition: resource.h:1047
int cue_height
Definition: wing_editor.h:21
#define FALSE
Definition: pstypes.h:400
#define IDC_IGNORE_COUNT
Definition: resource.h:427
SCP_vector< ai_target_priority > Ai_tp_list
Definition: ship.cpp:396
int Show_sexp_help
Definition: fredview.cpp:87
#define stricmp(s1, s2)
Definition: config.h:271
#define IDC_ARRIVAL_TARGET
Definition: resource.h:525
void management_add_ships_to_combo(CComboBox *box, int flags)
void initialize_data_safe(int full_update)
#define IDC_WING_SQUAD_LOGO
Definition: resource.h:808
void update_texture_replacements(const char *old_name, const char *new_name)
afx_msg void OnRestrictDeparture()
char ship_name[NAME_LENGTH]
Definition: ship.h:604
#define IDC_DEPARTURE_LOCATION
Definition: resource.h:620
void clear_tree(const char *op=NULL)
Definition: sexp_tree.cpp:99
CSpinButtonCtrl m_threshold_spin
Definition: wing_editor.h:44
struct wing wing
int Update_window
Definition: fred.cpp:48
int flags
Definition: ship.h:1556
#define strcpy_s(...)
Definition: safe_strings.h:67
void update_map_window()
Definition: fred.cpp:532
int m_threshold
Definition: wing_editor.h:49
#define MISSION_TYPE_MULTI_TEAMS
Definition: missionparse.h:65
#define IDC_NEXT
Definition: resource.h:844
char * Arrival_location_names[MAX_ARRIVAL_NAMES]