FS2_Open
Open source remastering of the Freespace 2 engine
shipeditordlg.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 "FRED.h"
14 #include "FREDDoc.h"
15 #include "FREDView.h"
16 #include "MainFrm.h"
17 #include "render/3d.h"
18 #include "physics/physics.h"
19 #include "editor.h"
20 #include "ai/aigoals.h"
21 #include "parse/parselo.h"
22 #include "Management.h"
23 #include "globalincs/linklist.h"
24 #include "InitialStatus.h"
25 #include "WeaponEditorDlg.h"
26 #include "ship/ship.h"
27 #include "TextViewDlg.h"
28 #include "playerman/player.h" // used for the max_keyed_target stuff
29 #include "IgnoreOrdersDlg.h"
30 #include "mission/missionparse.h"
31 #include "model/model.h"
32 #include "starfield/starfield.h"
33 #include "jumpnode/jumpnode.h"
34 #include "ShipFlagsDlg.h"
35 #include "mission/missionmessage.h"
36 #include "ShipSpecialDamage.h"
37 #include "ShipTexturesDlg.h"
38 #include "ShipSpecialHitpoints.h"
39 #include "altshipclassdlg.h"
41 #include "iff_defs/iff_defs.h"
42 #include "restrictpaths.h"
43 
44 #define ID_SHIP_MENU 9000
45 
46 #define NO_PERSONA_INDEX 999
47 
48 #ifdef _DEBUG
49 #undef THIS_FILE
50 static char THIS_FILE[] = __FILE__;
51 #endif
52 
53 void numeric_edit_control::setup(int id, CWnd *wnd)
54 {
55  control_id = id;
56  dlg = wnd;
57 }
58 
60 {
61  value = n;
62  unique = 1;
63 }
64 
66 {
67  if (n != value){
68  unique = 0;
69  }
70 }
71 
73 {
74  CString str;
75 
76  if (unique){
77  str.Format("%d", value);
78  }
79 
80  dlg->GetDlgItem(control_id)->SetWindowText(str);
81 }
82 
84 {
85  CString str;
86 
87  if (control_id) {
88  dlg->GetDlgItem(control_id)->GetWindowText(str);
89  if (!str.IsEmpty()){
90  MODIFY(*n, atoi(str));
91  }
92  }
93 }
94 
96 {
97  if (unique) {
98  CString str;
99  CWnd *w;
100 
101  value = n;
102  str.Format("%d", n);
103  w = dlg->GetDlgItem(control_id);
104  dlg->GetDlgItem(control_id)->SetWindowText(str);
105  }
106 }
107 
109 // CShipEditorDlg dialog
110 
111 CShipEditorDlg::CShipEditorDlg(CWnd* pParent /*=NULL*/)
112  : CDialog(CShipEditorDlg::IDD, pParent)
113 {
114  //{{AFX_DATA_INIT(CShipEditorDlg)
115  m_ship_name = _T("");
116  m_cargo1 = _T("");
117  m_ship_class = -1;
118  m_team = -1;
119  m_arrival_location = -1;
121  m_ai_class = -1;
122  m_hotkey = -1;
125  m_arrival_target = -1;
126  m_departure_target = -1;
127  m_persona = -1;
128  //}}AFX_DATA_INIT
129 
130  m_pSEView = NULL;
131  initialized = editing = multi_edit = 0;
132  select_sexp_node = -1;
133  bypass_errors = 0;
134 }
135 
136 // Modeless constructor, MK
138 {
139  m_pSEView = pView;
140  initialized = editing = 0;
141  select_sexp_node = -1;
142 }
143 
144 void CShipEditorDlg::DoDataExchange(CDataExchange* pDX)
145 {
146  int n;
147  CString str;
148 
149  CDialog::DoDataExchange(pDX);
150  //{{AFX_DATA_MAP(CShipEditorDlg)
151  DDX_Control(pDX, IDC_NO_DEPARTURE_WARP, m_no_departure_warp);
152  DDX_Control(pDX, IDC_NO_ARRIVAL_WARP, m_no_arrival_warp);
153  DDX_Control(pDX, IDC_PLAYER_SHIP, m_player_ship);
155  DDX_Control(pDX, IDC_ARRIVAL_DELAY_SPIN, m_arrival_delay_spin);
156  DDX_Control(pDX, IDC_DEPARTURE_TREE, m_departure_tree);
157  DDX_Control(pDX, IDC_ARRIVAL_TREE, m_arrival_tree);
158  DDX_Text(pDX, IDC_SHIP_NAME, m_ship_name);
159  DDX_CBString(pDX, IDC_SHIP_CARGO1, m_cargo1);
160  DDX_CBIndex(pDX, IDC_SHIP_CLASS, m_ship_class);
161  DDX_CBIndex(pDX, IDC_SHIP_TEAM, m_team);
162  DDX_CBIndex(pDX, IDC_ARRIVAL_LOCATION, m_arrival_location);
163  DDX_CBIndex(pDX, IDC_DEPARTURE_LOCATION, m_departure_location);
164  DDX_CBIndex(pDX, IDC_AI_CLASS, m_ai_class);
165  DDX_CBIndex(pDX, IDC_HOTKEY, m_hotkey);
166  DDX_Check(pDX, IDC_UPDATE_ARRIVAL, m_update_arrival);
167  DDX_Check(pDX, IDC_UPDATE_DEPARTURE, m_update_departure);
168  DDX_CBIndex(pDX, IDC_ARRIVAL_TARGET, m_arrival_target);
169  DDX_CBIndex(pDX, IDC_DEPARTURE_TARGET, m_departure_target);
170  DDX_CBIndex(pDX, IDC_SHIP_PERSONA, m_persona);
171  //}}AFX_DATA_MAP
172  DDV_MaxChars(pDX, m_ship_name, NAME_LENGTH - 1);
173  DDV_MaxChars(pDX, m_cargo1, NAME_LENGTH - 1);
174 
175  if (pDX->m_bSaveAndValidate) { // get dialog control values
176  GetDlgItem(IDC_ARRIVAL_DELAY)->GetWindowText(str);
177  n = atoi(str);
178  if (n < 0){
179  n = 0;
180  }
181 
183 
184  GetDlgItem(IDC_ARRIVAL_DISTANCE)->GetWindowText(str);
185  m_arrival_dist.init(atoi(str));
186 
187  GetDlgItem(IDC_DEPARTURE_DELAY)->GetWindowText(str);
188  n = atoi(str);
189  if (n < 0)
190  n = 0;
192 
193  GetDlgItem(IDC_SCORE)->GetWindowText(str);
194  m_score.init(atoi(str));
195 
196  GetDlgItem(IDC_ASSIST_SCORE)->GetWindowText(str);
197  m_assist_score.init(atoi(str));
198  }
199 }
200 
201 BEGIN_MESSAGE_MAP(CShipEditorDlg, CDialog)
202  //{{AFX_MSG_MAP(CShipEditorDlg)
203  ON_WM_CLOSE()
204  ON_NOTIFY(NM_RCLICK, IDC_ARRIVAL_TREE, OnRclickArrivalTree)
205  ON_NOTIFY(NM_RCLICK, IDC_DEPARTURE_TREE, OnRclickDepartureTree)
206  ON_NOTIFY(TVN_BEGINLABELEDIT, IDC_ARRIVAL_TREE, OnBeginlabeleditArrivalTree)
207  ON_NOTIFY(TVN_BEGINLABELEDIT, IDC_DEPARTURE_TREE, OnBeginlabeleditDepartureTree)
208  ON_NOTIFY(TVN_ENDLABELEDIT, IDC_ARRIVAL_TREE, OnEndlabeleditArrivalTree)
209  ON_NOTIFY(TVN_ENDLABELEDIT, IDC_DEPARTURE_TREE, OnEndlabeleditDepartureTree)
210  ON_BN_CLICKED(IDC_GOALS, OnGoals)
211  ON_CBN_SELCHANGE(IDC_SHIP_CLASS, OnSelchangeShipClass)
212  ON_BN_CLICKED(IDC_INITIAL_STATUS, OnInitialStatus)
213  ON_BN_CLICKED(IDC_WEAPONS, OnWeapons)
214  ON_BN_CLICKED(IDC_SHIP_RESET, OnShipReset)
215  ON_BN_CLICKED(IDC_DELETE_SHIP, OnDeleteShip)
216  ON_BN_CLICKED(IDC_SHIP_TBL, OnShipTbl)
217  ON_BN_CLICKED(IDC_NEXT, OnNext)
218  ON_NOTIFY(TVN_SELCHANGED, IDC_ARRIVAL_TREE, OnSelchangedArrivalTree)
219  ON_NOTIFY(TVN_SELCHANGED, IDC_DEPARTURE_TREE, OnSelchangedDepartureTree)
220  ON_BN_CLICKED(IDC_HIDE_CUES, OnHideCues)
221  ON_BN_CLICKED(IDC_PREV, OnPrev)
222  ON_CBN_SELCHANGE(IDC_ARRIVAL_LOCATION, OnSelchangeArrivalLocation)
223  ON_BN_CLICKED(IDC_PLAYER_SHIP, OnPlayerShip)
224  ON_BN_CLICKED(IDC_NO_ARRIVAL_WARP, OnNoArrivalWarp)
225  ON_BN_CLICKED(IDC_NO_DEPARTURE_WARP, OnNoDepartureWarp)
226  ON_CBN_SELCHANGE(IDC_DEPARTURE_LOCATION, OnSelchangeDepartureLocation)
227  ON_CBN_SELCHANGE(IDC_HOTKEY, OnSelchangeHotkey)
228  ON_BN_CLICKED(IDC_FLAGS, OnFlags)
229  ON_BN_CLICKED(IDC_IGNORE_ORDERS, OnIgnoreOrders)
230  ON_BN_CLICKED(IDC_SPECIAL_EXP, OnSpecialExp)
231  ON_BN_CLICKED(IDC_TEXTURES, OnTextures)
232  ON_BN_CLICKED(IDC_SPECIAL_HITPOINTS, OnSpecialHitpoints)
233  ON_BN_CLICKED(IDC_ALT_SHIP_CLASS, OnAltShipClass)
234  ON_BN_CLICKED(IDC_RESTRICT_ARRIVAL, OnRestrictArrival)
235  ON_BN_CLICKED(IDC_RESTRICT_DEPARTURE, OnRestrictDeparture)
236  ON_WM_INITMENU()
237  ON_BN_CLICKED(IDC_SET_AS_PLAYER_SHIP, OnSetAsPlayerShip)
238  //}}AFX_MSG_MAP
239 END_MESSAGE_MAP()
240 
242 // CShipEditorDlg message handlers
243 
245 {
246  int i, index;
247  BOOL r;
248  CComboBox *ptr;
249 
250  r = CDialog::Create(IDD, Fred_main_wnd);
251 
252  ptr = (CComboBox *) GetDlgItem(IDC_ARRIVAL_LOCATION);
253  ptr->ResetContent();
254  for (i=0; i<MAX_ARRIVAL_NAMES; i++){
255  ptr->AddString(Arrival_location_names[i]);
256  }
257 
258  ptr = (CComboBox *) GetDlgItem(IDC_DEPARTURE_LOCATION);
259  ptr->ResetContent();
260  for (i=0; i<MAX_DEPARTURE_NAMES; i++){
261  ptr->AddString(Departure_location_names[i]);
262  }
263 
264  ptr = (CComboBox *) GetDlgItem(IDC_SHIP_CLASS);
265  ptr->ResetContent();
266  for (auto it = Ship_info.cbegin(); it != Ship_info.end(); ++it){
267  ptr->AddString(it->name);
268  }
269 
270  ptr = (CComboBox *) GetDlgItem(IDC_AI_CLASS);
271  ptr->ResetContent();
272  for (i=0; i<Num_ai_classes; i++){
273  ptr->AddString(Ai_class_names[i]);
274  }
275 
276  // alternate ship name combobox
277  ptr = (CComboBox *)GetDlgItem(IDC_SHIP_ALT);
278  ptr->ResetContent();
279  ptr->AddString("<none>");
280  ptr->SetCurSel(0);
281 
282  // deal with the persona dialog
283  ptr = (CComboBox *)GetDlgItem(IDC_SHIP_PERSONA);
284  ptr->ResetContent();
285  index = ptr->AddString("<None>");
286  if ( index >= 0 ){
287  ptr->SetItemData(index, NO_PERSONA_INDEX);
288  }
289 
290  for ( i = 0; i < Num_personas; i++ ) {
291  if ( Personas[i].flags & PERSONA_FLAG_WINGMAN ) {
292  int index;
293 
294  // don't bother putting any vasudan personas on the list -- done automatically by code
295 // if ( Personas[i].flags & PERSONA_FLAG_VASUDAN ){
296 // continue;
297 // }
298 
299  CString persona_name = Personas[i].name;
300  if ( Personas[i].flags & PERSONA_FLAG_VASUDAN ){
301  persona_name += " -Vas";
302  }
303 
304  index = ptr->AddString(persona_name);
305  if ( index >= 0 ){
306  ptr->SetItemData(index, i);
307  }
308  }
309  }
310 
311  m_score.setup(IDC_SCORE, this);
312  m_assist_score.setup(IDC_ASSIST_SCORE, this);
313  m_arrival_dist.setup(IDC_ARRIVAL_DISTANCE, this);
314  m_arrival_delay.setup(IDC_ARRIVAL_DELAY, this);
315  m_departure_delay.setup(IDC_DEPARTURE_DELAY, this);
316 
317  m_hotkey = 0;
318  m_arrival_tree.link_modified(&modified); // provide way to indicate trees are modified in dialog
319  m_arrival_tree.setup((CEdit *) GetDlgItem(IDC_HELP_BOX));
320  m_departure_tree.link_modified(&modified);
321  m_departure_tree.setup();
322  m_arrival_delay_spin.SetRange(0, 999);
323  m_departure_delay_spin.SetRange(0, 999);
324  initialize_data(1);
325 
326  return r;
327 }
328 
329 // This gets called when you click on the "X" button. Note that OnClose
330 // does not destroy the window. It only hides it.
332 {
333  if (verify() && (!bypass_errors)) {
334  SetWindowPos(&wndTop, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
335  bypass_errors = 0;
336  return;
337  }
338 
339  if (update_data()) {
340  SetWindowPos(&wndTop, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
341  bypass_errors = 0;
342  return;
343  }
344 
345  SetWindowPos(Fred_main_wnd, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_HIDEWINDOW);
346  Fred_main_wnd->SetWindowPos(&wndTop, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
347 }
348 
349 BOOL CShipEditorDlg::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)
350 {
351  BOOL r;
352 
353  r = CDialog::Create(IDD, pParentWnd);
354  return r;
355 }
356 
357 int CShipEditorDlg::tristate_set(int val, int cur_state)
358 {
359  if (val) {
360  if (!cur_state){
361  return 2;
362  }
363 
364  } else {
365  if (cur_state){
366  return 2;
367  }
368  }
369 
370  return cur_state;
371 }
372 
373 // called to initialize the dialog box to reflect what ships we currently have marked. Any
374 // time what we have marked changes, this should get called again.
375 //
376 // Notes: player_count is the number of player starts marked, when we are in a non-multiplayer
377 // mission (NMM). In a multiplayer mission (MM), player_count will always be zero.
378 // ship_count in NMM is the number of ships (i.e. not player starts) that are marked. In MM,
379 // ship_count is the number of ships and player starts. Total_count is the sum of ship_count
380 // and player_count in all cases. The reason player_count isn't used in MM, and ship_count
381 // is used instead to track player starts is because in MM, player starts can be edited as
382 // freely as AI ships, and are very likely to be AI ships sometimes. Thus, treating them like
383 // AI ships instead of player starts simplifies processing.
384 //
385 void CShipEditorDlg::initialize_data(int full_update)
386 {
387  int i, type, ship_count, player_count, total_count, wing = -1, pvalid_count;
388  int a_cue, d_cue, cue_init = 0, cargo = 0, base_ship, base_player, pship = -1;
389  int no_arrival_warp = 0, no_departure_warp = 0, escort_count, ship_orders, current_orders;
390  int pship_count; // a total count of the player ships not marked
391  object *objp;
392  CWnd *w = NULL;
393  CString str;
394  CComboBox *box;
395  CSingleLock sync(&CS_update);
396 
397  nprintf(("Fred routing", "Ship dialog load\n"));
398  if (!GetSafeHwnd() || bypass_all)
399  return;
400 
401  sync.Lock(); // don't initialize if we are still updating. Wait until update is done.
402 
403  box = (CComboBox *) GetDlgItem(IDC_ARRIVAL_TARGET);
405 
406  box = (CComboBox *)GetDlgItem(IDC_DEPARTURE_TARGET);
408 
410  mission_type = 0; // multi player mission
411  } else {
412  mission_type = 1; // non-multiplayer mission (implies single player mission I guess)
413  }
414 
415  // figure out what all we are editing.
416  ship_count = player_count = escort_count = pship_count = pvalid_count = 0;
417  base_ship = base_player = -1;
418  enable = p_enable = 1;
419  objp = GET_FIRST(&obj_used_list);
420  while (objp != END_OF_LIST(&obj_used_list)) {
421  if ((objp->type == OBJ_SHIP) && (Ships[objp->instance].flags & SF_ESCORT)){
422  escort_count++; // get a total count of escort ships
423  }
424 
425  if (objp->type == OBJ_START){
426  pship_count++; // count all player starts in mission
427  }
428 
429  if (objp->flags & OF_MARKED) {
430  type = objp->type;
431  if ((type == OBJ_START) && !mission_type){ // in multiplayer missions, starts act like ships
432  type = OBJ_SHIP;
433  }
434 
435  i = -1;
436  if (type == OBJ_START) {
437  player_count++;
438  // if player_count is 1, base_player will be the one and only player
439  i = base_player = objp->instance;
440 
441  } else if (type == OBJ_SHIP) {
442  ship_count++;
443  // if ship_count is 1, base_ship will be the one and only ship
444  i = base_ship = objp->instance;
445  }
446 
447  if (i >= 0){
448  if (Ship_info[Ships[i].ship_info_index].flags & SIF_PLAYER_SHIP){
449  pvalid_count++;
450  }
451  }
452  }
453 
454  objp = GET_NEXT(objp);
455  }
456 
457  total_count = ship_count + player_count; // get total number of objects being edited.
458  if (total_count > 1){
459  multi_edit = 1;
460  } else {
461  multi_edit = 0;
462  }
463 
464  a_cue = d_cue = -1;
465  m_arrival_location = -1;
467  m_arrival_target = -1;
470  m_departure_target = -1;
472 
473  player_ship = single_ship = -1;
475  select_sexp_node = -1;
476  ship_orders = 0; // assume they are all the same type
477  if (ship_count) {
478  box = (CComboBox *) GetDlgItem(IDC_SHIP_CARGO1);
479  box->ResetContent();
480  for (i=0; i<Num_cargo; i++){
481  box->AddString(Cargo_names[i]);
482  }
483 
484  if (!multi_edit) {
485  Assert((ship_count == 1) && (base_ship >= 0));
486  m_ship_name = Ships[base_ship].ship_name;
487  } else {
488  m_ship_name = _T("");
489  }
490 
492  base_player = 0;
493  objp = GET_FIRST(&obj_used_list);
494  while (objp != END_OF_LIST(&obj_used_list)) {
495  if ((objp->type == OBJ_START) || (objp->type == OBJ_SHIP)) {
496  if (objp->flags & OF_MARKED) {
497  // do processing for both ships and players
498  i = get_ship_from_obj(objp);
499  if (base_player >= 0) {
501  m_team = Ships[i].team;
502  pship = (objp->type == OBJ_START) ? 1 : 0;
503  base_player = -1;
504 
505  } else {
506  if (Ships[i].ship_info_index != m_ship_class)
507  m_ship_class = -1;
508  if (Ships[i].team != m_team)
509  m_team = -1;
510 
511  pship = tristate_set(Objects[Ships[i].objnum].type == OBJ_START, pship);
512  }
513 
514  // 'and' in the ship type of this ship to our running bitfield
515  current_orders = ship_get_default_orders_accepted( &Ship_info[Ships[i].ship_info_index] );
516  if (!ship_orders){
517  ship_orders = current_orders;
518  } else if (ship_orders != current_orders){
519  ship_orders = -1;
520  }
521 
522  if (Ships[i].flags & SF_ESCORT){
523  escort_count--; // remove marked escorts from count
524  }
525 
526  if (Objects[Ships[i].objnum].type == OBJ_START){
527  pship_count--; // removed marked starts from count
528  }
529 
530  // do processing only for ships (plus players if in a multiplayer mission
531  if ((objp->type == OBJ_SHIP) || ((objp->type == OBJ_START) && !mission_type)) {
532  // process this if ship not in a wing
533  if (Ships[i].wingnum < 0) {
534  if (!cue_init) {
535  cue_init = 1;
536  a_cue = Ships[i].arrival_cue;
537  d_cue = Ships[i].departure_cue;
539  m_arrival_dist.init(Ships[i].arrival_distance);
541  m_arrival_delay.init(Ships[i].arrival_delay);
543  m_departure_delay.init(Ships[i].departure_delay);
545 
546  } else {
547  cue_init++;
548  if (Ships[i].arrival_location != m_arrival_location){
549  m_arrival_location = -1;
550  }
551 
552  if (Ships[i].departure_location != m_departure_location){
554  }
555 
556  m_arrival_dist.set(Ships[i].arrival_distance);
557  m_arrival_delay.set(Ships[i].arrival_delay);
558  m_departure_delay.set(Ships[i].departure_delay);
559 
560  if (Ships[i].arrival_anchor != m_arrival_target){
561  m_arrival_target = -1;
562  }
563 
564  if (!cmp_sexp_chains(a_cue, Ships[i].arrival_cue)) {
565  a_cue = -1;
566  m_update_arrival = 0;
567  }
568 
569  if (!cmp_sexp_chains(d_cue, Ships[i].departure_cue)) {
570  d_cue = -1;
571  m_update_departure = 0;
572  }
573 
574  if ( Ships[i].departure_anchor != m_departure_target ){
575  m_departure_target = -1;
576  }
577  }
578  }
579 
580  // process the first ship in group, else process the rest
581  if (base_ship >= 0) {
583  cargo = Ships[i].cargo1;
584  m_cargo1 = Cargo_names[cargo];
585  m_hotkey = Ships[i].hotkey + 1;
586  m_score.init(Ships[i].score);
587  m_assist_score.init((int)(Ships[i].assist_score_pct*100));
588 
590 
591  // we use final_death_time member of ship structure for holding the amount of time before a mission
592  // to destroy this ship
593  wing = Ships[i].wingnum;
594  if (wing < 0) {
595  GetDlgItem(IDC_WING) -> SetWindowText("None");
596 
597  } else {
598  GetDlgItem(IDC_WING) -> SetWindowText(Wings[wing].name);
599  if (!query_whole_wing_marked(wing))
601  }
602 
603  // set routine local varaiables for ship/object flags
604  no_arrival_warp = (Ships[i].flags & SF_NO_ARRIVAL_WARP) ? 1 : 0;
605  no_departure_warp = (Ships[i].flags & SF_NO_DEPARTURE_WARP) ? 1 : 0;
606 
607  base_ship = -1;
608  if (!multi_edit)
609  single_ship = i;
610 
611  } else {
612  if (Ships[i].weapons.ai_class != m_ai_class){
613  m_ai_class = -1;
614  }
615 
616  if (Ships[i].cargo1 != cargo){
617  m_cargo1 = _T("");
618  }
619 
620  m_score.set(Ships[i].score);
621  m_assist_score.set((int)(Ships[i].assist_score_pct*100));
622 
623  if (Ships[i].hotkey != m_hotkey - 1){
624  m_hotkey = -1;
625  }
626 
627  if ( Ships[i].persona_index != m_persona ){
628  m_persona = -2;
629  }
630 
631  if (Ships[i].wingnum != wing){
632  GetDlgItem(IDC_WING) -> SetWindowText("");
633  }
634 
635  no_arrival_warp = tristate_set(Ships[i].flags & SF_NO_ARRIVAL_WARP, no_arrival_warp);
636  no_departure_warp = tristate_set(Ships[i].flags & SF_NO_DEPARTURE_WARP, no_departure_warp);
637  }
638  }
639  }
640  }
641 
642  objp = GET_NEXT(objp);
643  }
644 
645  if (multi_edit) {
648  }
649 
650  if (cue_init) {
651  m_arrival_tree.load_tree(a_cue);
652  m_departure_tree.load_tree(d_cue, "false");
653 
654  } else {
656  m_arrival_tree.DeleteAllItems();
658  m_departure_tree.DeleteAllItems();
659  }
660 
661  m_player_ship.SetCheck(pship);
662  m_no_arrival_warp.SetCheck(no_arrival_warp);
663  m_no_departure_warp.SetCheck(no_departure_warp);
664 
665  if (!multi_edit) {
667  if (i != -1) {
668  w = GetDlgItem(IDC_ARRIVAL_TREE);
670 
671  } else {
673  if (i != -1) {
674  w = GetDlgItem(IDC_DEPARTURE_TREE);
676  }
677  }
678  }
679 
680  m_persona++;
681  if (m_persona > 0) {
682  int persona_index = 0;
683  for (int i = 0; i < m_persona; i++) {
685  persona_index++;
686  }
687  m_persona = persona_index;
688  }
689 
690  } else { // no ships selected, 0 or more player ships selected
691  if (player_count > 1) { // multiple player ships selected
692  Assert(base_player >= 0);
693  m_ship_name = _T("");
694  m_player_ship.SetCheck(TRUE);
695  objp = GET_FIRST(&obj_used_list);
696  while (objp != END_OF_LIST(&obj_used_list)) {
697  if ((objp->type == OBJ_START) && (objp->flags & OF_MARKED)) {
698  i = objp->instance;
699  if (base_player >= 0) {
701  m_team = Ships[i].team;
702  base_player = -1;
703 
704  } else {
705  if (Ships[i].ship_info_index != m_ship_class)
706  m_ship_class = -1;
707  if (Ships[i].team != m_team)
708  m_team = -1;
709  }
710  }
711 
712  objp = GET_NEXT(objp);
713  }
714 
715  // only 1 player selected..
716  } else if (query_valid_object() && (Objects[cur_object_index].type == OBJ_START)) {
717  Assert((player_count == 1) && !multi_edit);
722  m_player_ship.SetCheck(TRUE);
723 
724  } else { // no ships or players selected..
725  m_ship_name = _T("");
726  m_ship_class = -1;
727  m_team = -1;
728  m_persona = -1;
729  m_player_ship.SetCheck(FALSE);
730  }
731 
732  m_ai_class = -1;
733  m_cargo1 = _T("");
734  m_hotkey = 0;
735  m_score.blank(); // cause control to be blank
737  m_arrival_location = -1;
742  m_arrival_target = -1;
743  m_departure_target = -1;
745  m_arrival_tree.DeleteAllItems();
747  m_departure_tree.DeleteAllItems();
748  m_no_arrival_warp.SetCheck(0);
749  m_no_departure_warp.SetCheck(0);
750  enable = p_enable = 0;
751  GetDlgItem(IDC_WING)->SetWindowText(_T("None"));
752  }
753 
754  box = (CComboBox *) GetDlgItem(IDC_ARRIVAL_TARGET);
755  // must put the appropriate ships into the list depending on arrival location
758  } else {
760  }
761 
762  // set the internal variable appropriatly
763  // Goober5000 - gah, this is ridiculous! Prior to this point in the function (and only in this function),
764  // m_arrival_target seems to refer to the arrival anchor. The rest of the time, it refers to the index
765  // of the drop-down list.
766  if (m_arrival_target >= 0)
767  {
769  {
770  // figure out what the box represents this as
771  char tmp[NAME_LENGTH + 15];
773 
774  // find it in the box
775  m_arrival_target = box->FindStringExact(-1, tmp);
776  }
777  else
778  {
779  // find it in the box
780  m_arrival_target = box->FindStringExact(-1, Ships[m_arrival_target].ship_name);
781  }
782  }
783 
784  box = (CComboBox *)GetDlgItem(IDC_DEPARTURE_TARGET);
785  // must put the appropriate ships into the list depending on departure location
788  } else {
789  box->ResetContent();
790  }
791 
792  if ( m_departure_target >= 0 ){
793  m_departure_target = box->FindStringExact( -1, Ships[m_departure_target].ship_name );
794  }
795 
796  initialized = 1;
797  if (player_count) {
798  box = (CComboBox *) GetDlgItem(IDC_SHIP_TEAM);
799  if (!mission_type){ // multiplayer mission
800  box->EnableWindow(TRUE);
801  }
802 
803  else {
804  box->EnableWindow(FALSE);
805  m_team = -1;
806  }
807 
808  box->ResetContent();
809  for (i=0; i<MAX_TVT_TEAMS; i++)
810  box->AddString(Iff_info[i].iff_name);
811  } else {
812  box = (CComboBox *) GetDlgItem(IDC_SHIP_TEAM);
813  box->EnableWindow(enable);
814  box->ResetContent();
815  for (i=0; i<Num_iffs; i++){
816  box->AddString(Iff_info[i].iff_name);
817  }
818  }
819 
820  m_score.display();
825 
826  if (full_update)
827  UpdateData(FALSE);
828 
829  if (!cue_init) {
830  GetDlgItem(IDC_ARRIVAL_LOCATION)->EnableWindow(FALSE);
831  GetDlgItem(IDC_ARRIVAL_DELAY)->EnableWindow(FALSE);
832  GetDlgItem(IDC_ARRIVAL_DISTANCE)->EnableWindow(FALSE);
833  GetDlgItem(IDC_ARRIVAL_TARGET)->EnableWindow(FALSE);
834  GetDlgItem(IDC_ARRIVAL_DELAY_SPIN)->EnableWindow(FALSE);
835  GetDlgItem(IDC_ARRIVAL_TREE)->EnableWindow(FALSE);
836  GetDlgItem(IDC_DEPARTURE_LOCATION)->EnableWindow(FALSE);
837  GetDlgItem(IDC_DEPARTURE_TARGET)->EnableWindow(FALSE);
838  GetDlgItem(IDC_DEPARTURE_DELAY)->EnableWindow(FALSE);
839  GetDlgItem(IDC_DEPARTURE_DELAY_SPIN)->EnableWindow(FALSE);
840  GetDlgItem(IDC_DEPARTURE_TREE)->EnableWindow(FALSE);
841  GetDlgItem(IDC_NO_ARRIVAL_WARP)->EnableWindow(FALSE);
842  GetDlgItem(IDC_NO_DEPARTURE_WARP)->EnableWindow(FALSE);
843 
844  GetDlgItem(IDC_RESTRICT_ARRIVAL)->EnableWindow(FALSE);
845  GetDlgItem(IDC_RESTRICT_DEPARTURE)->EnableWindow(FALSE);
846 
847  } else {
848  GetDlgItem(IDC_ARRIVAL_LOCATION)->EnableWindow(enable);
849  if (m_arrival_location) {
850  GetDlgItem(IDC_ARRIVAL_DISTANCE)->EnableWindow(enable);
851  GetDlgItem(IDC_ARRIVAL_TARGET)->EnableWindow(enable);
852  } else {
853  GetDlgItem(IDC_ARRIVAL_DISTANCE)->EnableWindow(FALSE);
854  GetDlgItem(IDC_ARRIVAL_TARGET)->EnableWindow(FALSE);
855  }
857  GetDlgItem(IDC_RESTRICT_ARRIVAL)->EnableWindow(enable);
858  } else {
859  GetDlgItem(IDC_RESTRICT_ARRIVAL)->EnableWindow(FALSE);
860  }
861 
862  GetDlgItem(IDC_DEPARTURE_LOCATION)->EnableWindow(enable);
863  if ( m_departure_location ) {
864  GetDlgItem(IDC_DEPARTURE_TARGET)->EnableWindow(enable);
865  } else {
866  GetDlgItem(IDC_DEPARTURE_TARGET)->EnableWindow(FALSE);
867  }
869  GetDlgItem(IDC_RESTRICT_DEPARTURE)->EnableWindow(enable);
870  } else {
871  GetDlgItem(IDC_RESTRICT_DEPARTURE)->EnableWindow(FALSE);
872  }
873 
874  GetDlgItem(IDC_ARRIVAL_DELAY)->EnableWindow(enable);
875  GetDlgItem(IDC_ARRIVAL_DELAY_SPIN)->EnableWindow(enable);
876  GetDlgItem(IDC_ARRIVAL_TREE)->EnableWindow(enable);
877  GetDlgItem(IDC_DEPARTURE_LOCATION)->EnableWindow(enable);
878  GetDlgItem(IDC_DEPARTURE_DELAY)->EnableWindow(enable);
879  GetDlgItem(IDC_DEPARTURE_DELAY_SPIN)->EnableWindow(enable);
880  GetDlgItem(IDC_DEPARTURE_TREE)->EnableWindow(enable);
881  GetDlgItem(IDC_NO_ARRIVAL_WARP)->EnableWindow(enable);
882  GetDlgItem(IDC_NO_DEPARTURE_WARP)->EnableWindow(enable);
883  }
884 
885  if (total_count) {
886  GetDlgItem(IDC_SHIP_NAME)->EnableWindow(!multi_edit);
887  GetDlgItem(IDC_SHIP_CLASS)->EnableWindow(TRUE);
888  GetDlgItem(IDC_SHIP_ALT)->EnableWindow(TRUE);
889  GetDlgItem(IDC_INITIAL_STATUS)->EnableWindow(TRUE);
890  GetDlgItem(IDC_WEAPONS)->EnableWindow(m_ship_class >= 0);
891  GetDlgItem(IDC_FLAGS)->EnableWindow(TRUE);
892  GetDlgItem(IDC_TEXTURES)->EnableWindow(TRUE);
893  GetDlgItem(IDC_ALT_SHIP_CLASS)->EnableWindow(TRUE);
894  GetDlgItem(IDC_SPECIAL_EXP)->EnableWindow(TRUE);
895  GetDlgItem(IDC_SPECIAL_HITPOINTS)->EnableWindow(TRUE);
896  } else {
897  GetDlgItem(IDC_SHIP_NAME)->EnableWindow(FALSE);
898  GetDlgItem(IDC_SHIP_CLASS)->EnableWindow(FALSE);
899  GetDlgItem(IDC_SHIP_ALT)->EnableWindow(FALSE);
900  GetDlgItem(IDC_INITIAL_STATUS)->EnableWindow(FALSE);
901  GetDlgItem(IDC_WEAPONS)->EnableWindow(FALSE);
902  GetDlgItem(IDC_FLAGS)->EnableWindow(FALSE);
903  GetDlgItem(IDC_TEXTURES)->EnableWindow(FALSE);
904  GetDlgItem(IDC_ALT_SHIP_CLASS)->EnableWindow(FALSE);
905  GetDlgItem(IDC_SPECIAL_EXP)->EnableWindow(FALSE);
906  GetDlgItem(IDC_SPECIAL_HITPOINTS)->EnableWindow(FALSE);
907  }
908 
909  // disable textures for multiple ships
910  if (multi_edit)
911  {
912  GetDlgItem(IDC_TEXTURES)->EnableWindow(FALSE);
913  }
914 
915  GetDlgItem(IDC_AI_CLASS)->EnableWindow(enable);
916  GetDlgItem(IDC_SHIP_CARGO1)->EnableWindow(enable);
917  GetDlgItem(IDC_HOTKEY)->EnableWindow(enable);
919  GetDlgItem(IDC_GOALS)->EnableWindow(enable);
920  else if (multi_edit)
921  GetDlgItem(IDC_GOALS)->EnableWindow(enable);
922  else
923  GetDlgItem(IDC_GOALS)->EnableWindow(FALSE);
924 
925  // !pship_count used because if allowed to clear, we would have no player starts
926  // mission_type 0 = multi, 1 = single
927  if (mission_type || !pship_count || (pship_count + total_count > MAX_PLAYERS) || (pvalid_count < total_count))
928  m_player_ship.EnableWindow(FALSE);
929  else
930  m_player_ship.EnableWindow(TRUE);
931 
932  // show the "set player" button only if single player
933  if (mission_type)
934  GetDlgItem(IDC_SET_AS_PLAYER_SHIP)->ShowWindow(TRUE);
935  else
936  GetDlgItem(IDC_SET_AS_PLAYER_SHIP)->ShowWindow(FALSE);
937 
938  // enable the "set player" button only if single player, single edit, and ship is in player wing
939  {
940  int marked_ship = (player_ship >= 0) ? player_ship : single_ship;
941 
942  if (mission_type && total_count && !multi_edit && wing_is_player_wing(Ships[marked_ship].wingnum))
943  GetDlgItem(IDC_SET_AS_PLAYER_SHIP)->EnableWindow(TRUE);
944  else
945  GetDlgItem(IDC_SET_AS_PLAYER_SHIP)->EnableWindow(FALSE);
946  }
947 
948  GetDlgItem(IDC_DELETE_SHIP)->EnableWindow(enable);
949  GetDlgItem(IDC_SHIP_RESET)->EnableWindow(enable);
950  GetDlgItem(IDC_SCORE)->EnableWindow(enable);
951  GetDlgItem(IDC_ASSIST_SCORE)->EnableWindow(enable);
952 
953 //#ifndef NDEBUG
954  GetDlgItem(IDC_SHIP_TBL)->EnableWindow(m_ship_class >= 0);
955 //#else
956 // GetDlgItem(IDC_SHIP_TBL)->EnableWindow(0);
957 // GetDlgItem(IDC_SHIP_TBL)->ShowWindow(SW_HIDE);
958 //#endif
959 
960  if (cue_init > 1) { // more than one ship (players don't have cues to edit)
961  GetDlgItem(IDC_UPDATE_ARRIVAL)->ShowWindow(SW_SHOW);
962  GetDlgItem(IDC_UPDATE_DEPARTURE)->ShowWindow(SW_SHOW);
963 
964  } else {
965  GetDlgItem(IDC_UPDATE_ARRIVAL)->ShowWindow(SW_HIDE);
966  GetDlgItem(IDC_UPDATE_DEPARTURE)->ShowWindow(SW_HIDE);
967  }
968 
969  if (multi_edit || (total_count > 1)) {
970  // we will allow the ignore orders dialog to be multi edit if all selected
971  // ships are the same type. the ship_type (local) variable holds the ship types
972  // for all ships. Determine how may bits set and enable/diable window
973  // as appropriate
974  if ( /*(m_team == -1) ||*/ (ship_orders == -1) ){
975  GetDlgItem(IDC_IGNORE_ORDERS)->EnableWindow(FALSE);
976  } else {
977  GetDlgItem(IDC_IGNORE_ORDERS)->EnableWindow(TRUE);
978  }
979  } else
980  // always enabled when one ship is selected
981  GetDlgItem(IDC_IGNORE_ORDERS)->EnableWindow(enable);
982 
983  // always enabled if >= 1 ship selected
984  GetDlgItem(IDC_SHIP_PERSONA)->EnableWindow(enable);
985 
986  if (multi_edit){
987  SetWindowText("Edit Marked Ships");
988  } else if (player_count) {
989  SetWindowText("Edit Player Ship");
990  } else {
991  SetWindowText("Edit Ship");
992  }
993 
994  // setup alternate name and callsign stuff
995  if(player_ship >= 0){
998  } else {
1001  }
1002 
1003  modified = 0;
1004  if (w){
1005  w->SetFocus();
1006  }
1007 }
1008 
1009 // update ship structure(s) with dialog data. The data is first checked for errors. If
1010 // no errors occur, returns 0. If an error occurs, returns -1. If the update is bypassed,
1011 // returns 1. Bypass is necessary to avoid an infinite loop, and it doesn't actually
1012 // update the data. Bypass only occurs if bypass mode is active and we still get an error.
1013 // Once the error no longer occurs, bypass mode is cleared and data is updated.
1015 {
1016  char *str, old_name[255];
1017  object *ptr;
1018  int i, z, wing;
1019  CSingleLock sync(&CS_cur_object_index), sync2(&CS_update);
1020 
1021  nprintf(("Fred routing", "Ship dialog save\n"));
1022  if (!GetSafeHwnd() || !initialized || bypass_all)
1023  return 0;
1024 
1025  sync.Lock(); // don't allow cur_object_index to change while we are using it
1026  sync2.Lock(); // don't allow reinitialization until we are done updating
1027  UpdateData(TRUE);
1028  UpdateData(TRUE);
1030  if (multi_edit) { // editing multiple ships (ships and/or players)
1031  ptr = GET_FIRST(&obj_used_list);
1032  while (ptr != END_OF_LIST(&obj_used_list)) {
1033  if (((ptr->type == OBJ_START) || (ptr->type == OBJ_SHIP)) && (ptr->flags & OF_MARKED))
1034  update_ship(get_ship_from_obj(ptr));
1035 
1036  ptr = GET_NEXT(ptr);
1037  }
1038 
1039  } else if (player_ship >= 0) { // editing a single player
1040  update_ship(player_ship);
1041 
1042  } else if (single_ship >= 0) { // editing a single ship
1043  m_ship_name.TrimLeft();
1044  m_ship_name.TrimRight();
1045  ptr = GET_FIRST(&obj_used_list);
1046  while (ptr != END_OF_LIST(&obj_used_list)) {
1047  if (((ptr->type == OBJ_SHIP) || (ptr->type == OBJ_START)) && (cur_object_index != OBJ_INDEX(ptr))) {
1048  str = Ships[ptr->instance].ship_name;
1049  if (!stricmp(m_ship_name, str)) {
1050  if (bypass_errors)
1051  return 1;
1052 
1053  bypass_errors = 1;
1054  z = MessageBox("This ship name is already being used by another ship\n"
1055  "Press OK to restore old name", "Error", MB_ICONEXCLAMATION | MB_OKCANCEL);
1056 
1057  if (z == IDCANCEL)
1058  return -1;
1059 
1060  m_ship_name = _T(Ships[single_ship].ship_name);
1061  UpdateData(FALSE);
1062  }
1063  }
1064 
1065  ptr = GET_NEXT(ptr);
1066  }
1067 
1068  for (i=0; i<MAX_WINGS; i++) {
1069  if (Wings[i].wave_count && !stricmp(Wings[i].name, m_ship_name)) {
1070  if (bypass_errors)
1071  return 1;
1072 
1073  bypass_errors = 1;
1074  z = MessageBox("This ship name is already being used by a wing\n"
1075  "Press OK to restore old name", "Error", MB_ICONEXCLAMATION | MB_OKCANCEL);
1076 
1077  if (z == IDCANCEL)
1078  return -1;
1079 
1080  m_ship_name = _T(Ships[single_ship].ship_name);
1081  UpdateData(FALSE);
1082  }
1083  }
1084 
1085  for (i=0; i<Num_iffs; i++) {
1086  if (!stricmp(m_ship_name, Iff_info[i].iff_name)) {
1087  if (bypass_errors)
1088  return 1;
1089 
1090  bypass_errors = 1;
1091  z = MessageBox("This ship name is already being used by a team.\n"
1092  "Press OK to restore old name", "Error", MB_ICONEXCLAMATION | MB_OKCANCEL);
1093 
1094  if (z == IDCANCEL)
1095  return -1;
1096 
1097  m_ship_name = _T(Ships[single_ship].ship_name);
1098  UpdateData(FALSE);
1099  }
1100  }
1101 
1102  for ( i=0; i < (int)Ai_tp_list.size(); i++) {
1103  if (!stricmp(m_ship_name, Ai_tp_list[i].name))
1104  {
1105  if (bypass_errors)
1106  return 1;
1107 
1108  bypass_errors = 1;
1109  z = MessageBox("This ship name is already being used by a target priority group.\n"
1110  "Press OK to restore old name", "Error", MB_ICONEXCLAMATION | MB_OKCANCEL);
1111 
1112  if (z == IDCANCEL)
1113  return -1;
1114 
1115  m_ship_name = _T(Ships[single_ship].ship_name);
1116  UpdateData(FALSE);
1117  }
1118  }
1119 
1120  if (find_matching_waypoint_list((LPCSTR) m_ship_name) != NULL)
1121  {
1122  if (bypass_errors)
1123  return 0;
1124 
1125  bypass_errors = 1;
1126  z = MessageBox("This ship name is already being used by a waypoint path\n"
1127  "Press OK to restore old name", "Error", MB_ICONEXCLAMATION | MB_OKCANCEL);
1128 
1129  if (z == IDCANCEL)
1130  return -1;
1131 
1132  m_ship_name = _T(Ships[single_ship].ship_name);
1133  UpdateData(FALSE);
1134  }
1135 
1136  if(jumpnode_get_by_name(m_ship_name) != NULL)
1137  {
1138  if (bypass_errors)
1139  return 1;
1140 
1141  bypass_errors = 1;
1142 
1143  z = MessageBox("This ship name is already being used by a jump node\n"
1144  "Press OK to restore old name", "Error", MB_ICONEXCLAMATION | MB_OKCANCEL);
1145 
1146  if (z == IDCANCEL)
1147  return -1;
1148 
1149  m_ship_name = _T(Ships[single_ship].ship_name);
1150  UpdateData(FALSE);
1151  }
1152 
1153  if (!stricmp(m_ship_name.Left(1), "<")) {
1154  if (bypass_errors)
1155  return 1;
1156 
1157  bypass_errors = 1;
1158  z = MessageBox("Ship names not allowed to begin with <\n"
1159  "Press OK to restore old name", "Error", MB_ICONEXCLAMATION | MB_OKCANCEL);
1160 
1161  if (z == IDCANCEL)
1162  return -1;
1163 
1164  m_ship_name = _T(Ships[single_ship].ship_name);
1165  UpdateData(FALSE);
1166  }
1167 
1168  wing = Ships[single_ship].wingnum;
1169  if (wing >= 0) {
1170  Assert((wing < MAX_WINGS) && Wings[wing].wave_count);
1171  for (i=0; i<Wings[wing].wave_count; i++)
1172  if (wing_objects[wing][i] == Ships[single_ship].objnum)
1173  break;
1174 
1175  Assert(i < Wings[wing].wave_count);
1176  wing_bash_ship_name(old_name, Wings[wing].name, i + 1);
1177  if (strcmp(old_name, m_ship_name)) {
1178  if (bypass_errors)
1179  return 0;
1180 
1181  if (MessageBox("This ship is part of a wing, and its name cannot be changed",
1182  NULL, MB_OKCANCEL) == IDCANCEL)
1183  return -1;
1184 
1185  m_ship_name = _T(old_name);
1186  UpdateData(FALSE);
1187  }
1188  }
1189 
1190  z = update_ship(single_ship);
1191  if (z)
1192  return z;
1193 
1194  strcpy_s(old_name, Ships[single_ship].ship_name);
1195  string_copy(Ships[single_ship].ship_name, m_ship_name, NAME_LENGTH, 1);
1196  str = Ships[single_ship].ship_name;
1197  if (strcmp(old_name, str)) {
1198  update_sexp_references(old_name, str);
1199  ai_update_goal_references(REF_TYPE_SHIP, old_name, str);
1200  update_texture_replacements(old_name, str);
1201  for (i=0; i<Num_reinforcements; i++)
1202  if (!strcmp(old_name, Reinforcements[i].name)) {
1203  Assert(strlen(str) < NAME_LENGTH);
1204  strcpy_s(Reinforcements[i].name, str);
1205  }
1206 
1207  Update_window = 1;
1208  }
1209  }
1210 
1211  if (Player_start_shipnum < 0 || Objects[Ships[Player_start_shipnum].objnum].type != OBJ_START) { // need a new single player start.
1212  ptr = GET_FIRST(&obj_used_list);
1213  while (ptr != END_OF_LIST(&obj_used_list)) {
1214  if (ptr->type == OBJ_START) {
1216  break;
1217  }
1218 
1219  ptr = GET_NEXT(ptr);
1220  }
1221  }
1222 
1223  if (modified)
1224  set_modified();
1225 
1227  bypass_errors = 0;
1228  modified = 0;
1229 
1230  if (redraw)
1232 
1233  return 0;
1234 }
1235 
1236 int CShipEditorDlg::update_ship(int ship)
1237 {
1238  int z, d;
1239  CString str;
1240  CComboBox *box;
1241  int persona;
1242 
1243  // THIS DIALOG IS THE SOME OF THE WORST CODE I HAVE EVER SEEN IN MY ENTIRE LIFE.
1244  // IT TOOK A RIDICULOUSLY LONG AMOUNT OF TIME TO ADD 2 FUNCTIONS. OMG
1245  ship_alt_name_close(ship);
1246  ship_callsign_close(ship);
1247 
1248  if ((Ships[ship].ship_info_index != m_ship_class) && (m_ship_class != -1)) {
1250  set_modified();
1251  }
1252 
1253  if (m_team != -1)
1254  MODIFY(Ships[ship].team, m_team);
1255 
1256  if (Objects[Ships[ship].objnum].type != OBJ_SHIP){
1257  if (mission_type || (Objects[Ships[ship].objnum].type != OBJ_START)){
1258  return 0;
1259  }
1260  }
1261 
1262  if (m_ai_class != -1){
1263  MODIFY(Ships[ship].weapons.ai_class, m_ai_class);
1264  }
1265  if (strlen(m_cargo1)) {
1267  if (z == -1) {
1268  if (Num_cargo < MAX_CARGO) {
1269  z = Num_cargo++;
1270  strcpy(Cargo_names[z], m_cargo1);
1271  }
1272  else {
1273  str.Format("Maximum number of cargo names (%d) reached.\nIgnoring new name.\n", MAX_CARGO);
1274  MessageBox(str, "Error", MB_ICONEXCLAMATION);
1275  z = 0;
1276  m_cargo1 = Cargo_names[z];
1277  }
1278  }
1279 
1280  MODIFY(Ships[ship].cargo1, (char)z);
1281  }
1282 
1283  m_score.save(&Ships[ship].score);
1284  int temp_assist = -1;
1285  m_assist_score.save(&temp_assist);
1286  if (temp_assist != -1) {
1287  Ships[ship].assist_score_pct = ((float)temp_assist)/100;
1288  // value must be a percentage
1289  if (Ships[ship].assist_score_pct < 0) {
1290  Ships[ship].assist_score_pct = 0;
1291  MessageBox("Assist Percentage too low. Set to 0. No score will be granted for an assist");
1292  }
1293  else if (Ships[ship].assist_score_pct > 1) {
1294  Ships[ship].assist_score_pct = 1;
1295  MessageBox("Assist Percentage too high. Set to 1. Assists will score as many points as a kill");
1296  }
1297  }
1298 
1299  if (m_arrival_location != -1)
1300  MODIFY(Ships[ship].arrival_location, m_arrival_location);
1301  if (m_departure_location != -1)
1302  MODIFY(Ships[ship].departure_location, m_departure_location);
1303 
1304  if (m_persona != -1)
1305  {
1306  // do the persona update
1307  // m_persona holds the index into the list. Get the item data associated with this index and then
1308  // assign to the ship taking care that we check for the NO_PERSONA_INDEX id
1309  box = (CComboBox *)GetDlgItem(IDC_SHIP_PERSONA);
1310  persona = box->GetItemData(m_persona);
1311  if ( persona == NO_PERSONA_INDEX )
1312  persona = -1;
1313 
1314  MODIFY(Ships[ship].persona_index, persona);
1315  }
1316 
1317  if (Ships[ship].wingnum < 0) {
1318  if (!multi_edit || m_update_arrival) { // should we update the arrival cue?
1319  if (Ships[ship].arrival_cue >= 0)
1320  free_sexp2(Ships[ship].arrival_cue);
1321 
1323  }
1324 
1325  if (!multi_edit || m_update_departure) {
1326  if (Ships[ship].departure_cue >= 0)
1327  free_sexp2(Ships[ship].departure_cue);
1328 
1330  }
1331 
1332  m_arrival_dist.save(&Ships[ship].arrival_distance);
1333  m_arrival_delay.save(&Ships[ship].arrival_delay);
1334  m_departure_delay.save(&Ships[ship].departure_delay);
1335  if (m_arrival_target >= 0) {
1336  z = ((CComboBox *) GetDlgItem(IDC_ARRIVAL_TARGET))->GetItemData(m_arrival_target);
1337  MODIFY(Ships[ship].arrival_anchor, z);
1338 
1339  // if the arrival is not hyperspace or docking bay -- force arrival distance to be
1340  // greater than 2*radius of target.
1342  d = int(min(500, 2.0f * Objects[Ships[ship].objnum].radius));
1343  if ((Ships[ship].arrival_distance < d) && (Ships[ship].arrival_distance > -d)) {
1344  str.Format("Ship must arrive at least %d meters away from target.\n"
1345  "Value has been reset to this. Use with caution!\r\n"
1346  "Recommended distance is %d meters.\r\n", d, (int)(2.0f * Objects[Ships[ship].objnum].radius) );
1347 
1348  MessageBox(str);
1349  if (Ships[ship].arrival_distance < 0)
1350  Ships[ship].arrival_distance = -d;
1351  else
1352  Ships[ship].arrival_distance = d;
1353 
1354  m_arrival_dist.fix(Ships[ship].arrival_distance);
1355  }
1356  }
1357  }
1358  if (m_departure_target >= 0) {
1359  z = ((CComboBox *) GetDlgItem(IDC_DEPARTURE_TARGET))->GetItemData(m_departure_target);
1360  MODIFY(Ships[ship].departure_anchor, z );
1361  }
1362  }
1363 
1364  if (m_hotkey != -1)
1365  MODIFY(Ships[ship].hotkey, m_hotkey - 1);
1366 
1367  switch( m_no_arrival_warp.GetCheck() ) {
1368  case 0:
1369  if (Ships[ship].flags & SF_NO_ARRIVAL_WARP)
1370  set_modified();
1371 
1372  Ships[ship].flags &= ~SF_NO_ARRIVAL_WARP;
1373  break;
1374 
1375  case 1:
1376  if (!(Ships[ship].flags & SF_NO_ARRIVAL_WARP))
1377  set_modified();
1378 
1379  Ships[ship].flags |= SF_NO_ARRIVAL_WARP;
1380  break;
1381  }
1382 
1383  switch( m_no_departure_warp.GetCheck() ) {
1384  case 0:
1385  if (Ships[ship].flags & SF_NO_DEPARTURE_WARP)
1386  set_modified();
1387 
1388  Ships[ship].flags &= ~SF_NO_DEPARTURE_WARP;
1389  break;
1390 
1391  case 1:
1392  if (!(Ships[ship].flags & SF_NO_DEPARTURE_WARP))
1393  set_modified();
1394 
1395  Ships[ship].flags |= SF_NO_DEPARTURE_WARP;
1396  break;
1397  }
1398 
1399  switch (m_player_ship.GetCheck()) {
1400  case 1:
1401  if (Objects[Ships[ship].objnum].type != OBJ_START) {
1402  Player_starts++;
1403  set_modified();
1404  }
1405 
1406  Objects[Ships[ship].objnum].type = OBJ_START;
1407  break;
1408 
1409  case 0:
1410  if (Objects[Ships[ship].objnum].type == OBJ_START) {
1411  Player_starts--;
1412  set_modified();
1413  }
1414 
1415  Objects[Ships[ship].objnum].type = OBJ_SHIP;
1416  break;
1417  }
1418 
1419  Update_ship = 1;
1420  return 0;
1421 }
1422 
1424 {
1425  HWND h;
1426  CWnd *w;
1427 
1428  w = GetFocus();
1429  if (w) {
1430  h = w->m_hWnd;
1431  GetDlgItem(IDC_ARRIVAL_TREE)->SetFocus();
1432  ::SetFocus(h);
1433  }
1434 }
1435 
1436 void CShipEditorDlg::OnInitMenu(CMenu *pMenu)
1437 {
1438  CMenu *m;
1439 
1440  m = pMenu->GetSubMenu(0);
1441  clear_menu(m);
1443  if (cur_ship != -1)
1444  m->CheckMenuItem(ID_SHIP_MENU + cur_ship, MF_BYCOMMAND | MF_CHECKED);
1445 
1446  CWnd::OnInitMenu(pMenu);
1447 }
1448 
1450 {
1451  int id, ship;
1452 
1453  id = LOWORD(wParam);
1454  if (id >= ID_SHIP_MENU && id < ID_SHIP_MENU + MAX_SHIPS) {
1455  if (!update_data()) {
1456  ship = id - ID_SHIP_MENU;
1457  unmark_all();
1458  set_cur_object_index(Ships[ship].objnum);
1459  return 1;
1460  }
1461  }
1462 
1463  return CDialog::OnCommand(wParam, lParam);
1464 }
1465 
1466 void CShipEditorDlg::OnRclickArrivalTree(NMHDR* pNMHDR, LRESULT* pResult)
1467 {
1469  *pResult = 0;
1470 }
1471 
1472 void CShipEditorDlg::OnRclickDepartureTree(NMHDR* pNMHDR, LRESULT* pResult)
1473 {
1475  *pResult = 0;
1476 }
1477 
1479 {
1480  TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR;
1481 
1482  if (m_arrival_tree.edit_label(pTVDispInfo->item.hItem) == 1) {
1483  *pResult = 0;
1484  modified = editing = 1;
1485 
1486  } else
1487  *pResult = 1;
1488 }
1489 
1491 {
1492  TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR;
1493 
1494  if (m_departure_tree.edit_label(pTVDispInfo->item.hItem) == 1) {
1495  *pResult = 0;
1496  modified = editing = 1;
1497 
1498  } else
1499  *pResult = 1;
1500 }
1501 
1503 {
1504  TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR;
1505 
1506  *pResult = m_arrival_tree.end_label_edit(pTVDispInfo->item);
1507  editing = 0;
1508 }
1509 
1511 {
1512  TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR;
1513 
1514  *pResult = m_departure_tree.end_label_edit(pTVDispInfo->item);
1515  editing = 0;
1516 }
1517 
1519 {
1520  nprintf(("Fred routing", "Ship dialog verify\n"));
1521  if (!GetSafeHwnd() || !modified)
1522  return 0;
1523 
1524  if (bypass_errors)
1525  return 1;
1526 
1527  return 0;
1528 }
1529 
1531 {
1532  ShipGoalsDlg dlg_goals;
1533 
1535 // if (multi_edit)
1536 // dlg_goals.initialize_multi();
1537 //
1538 // else {
1539 // Assert(single_ship != -1);
1540 // dlg_goals.self_ship = single_ship;
1541 // dlg_goals.initialize(Ai_info[Ships[single_ship].ai_index].goals);
1542 // }
1543 
1544  if (!multi_edit) {
1545  Assert(single_ship != -1);
1546  dlg_goals.self_ship = single_ship;
1547  }
1548 
1549  dlg_goals.DoModal();
1550  if (!multi_edit && !query_initial_orders_empty(Ai_info[Ships[single_ship].ai_index].goals))
1551  if ((Ships[single_ship].wingnum >= 0) && (query_initial_orders_conflict(Ships[single_ship].wingnum)))
1552  MessageBox("This ship's wing also has initial orders", "Possible conflict");
1553 }
1554 
1556 {
1557  object *ptr;
1558 
1559  UpdateData(TRUE);
1560  UpdateData(TRUE);
1561  ptr = GET_FIRST(&obj_used_list);
1562  while (ptr != END_OF_LIST(&obj_used_list)) {
1563  if (((ptr->type == OBJ_SHIP) || (ptr->type == OBJ_START)) && (ptr->flags & OF_MARKED))
1564  if (Ships[ptr->instance].ship_info_index != m_ship_class) {
1566  set_modified();
1567  }
1568 
1569  ptr = GET_NEXT(ptr);
1570  }
1571 
1573 }
1574 
1576 {
1577  initial_status dlg;
1578 
1579  dlg.m_multi_edit = multi_edit;
1580  dlg.DoModal();
1581 }
1582 
1584 {
1585  int i, ship = -1;
1586  WeaponEditorDlg dlg;
1587  object *objp;
1588  CComboBox *box;
1589 
1590  dlg.m_multi_edit = multi_edit;
1591  dlg.DoModal();
1592 
1593  if (multi_edit) {
1594  objp = GET_FIRST(&obj_used_list);
1595  while (objp != END_OF_LIST(&obj_used_list)) {
1596  if (objp->flags & OF_MARKED)
1597  if ((objp->type == OBJ_SHIP) || (objp->type == OBJ_START)) {
1598  i = objp->instance;
1599  if (ship) {
1600  if (Ships[i].weapons.ai_class != Ships[ship].weapons.ai_class)
1601  m_ai_class = -1;
1602 
1603  } else {
1604  ship = i;
1606  }
1607  }
1608 
1609  objp = GET_NEXT(objp);
1610  }
1611 
1612  } else {
1613  ship = single_ship;
1614  if (ship < 0)
1615  ship = player_ship;
1616 
1617  Assert(ship >= 0);
1618  m_ai_class = Ships[ship].weapons.ai_class;
1619  }
1620 
1621  box = (CComboBox *) GetDlgItem(IDC_AI_CLASS);
1622  box->SetCurSel(m_ai_class);
1623 }
1624 
1626 {
1627  int i, j, index, ship;
1628  object *objp;
1629  ship_info *sip;
1630  ship_subsys *ptr;
1631  ship_weapon *wp;
1632  model_subsystem *sp;
1633 
1634  m_cargo1 = "Nothing";
1636  if (m_ship_class) {
1637  m_team = Species_info[Ship_info[m_ship_class].species].default_iff;
1638  }
1639 
1640  objp = GET_FIRST(&obj_used_list);
1641  while (objp != END_OF_LIST(&obj_used_list)) {
1642  if (((objp->type == OBJ_SHIP) || ((objp->type == OBJ_START) && !mission_type)) && (objp->flags & OF_MARKED)) {
1643  ship = objp->instance;
1644 
1645  // reset ship goals
1646  for (i=0; i<MAX_AI_GOALS; i++){
1648  }
1649 
1650  objp->phys_info.speed = 0.0f;
1651  objp->shield_quadrant[0] = 100.0f;
1652  objp->hull_strength = 100.0f;
1653 
1654  sip = &Ship_info[Ships[ship].ship_info_index];
1655  for (i=0; i<sip->num_primary_banks; i++)
1656  Ships[ship].weapons.primary_bank_weapons[i] = sip->primary_bank_weapons[i];
1657 
1658  for (i=0; i<sip->num_secondary_banks; i++) {
1659  Ships[ship].weapons.secondary_bank_weapons[i] = sip->secondary_bank_weapons[i];
1660  Ships[ship].weapons.secondary_bank_capacity[i] = sip->secondary_bank_ammo_capacity[i];
1661  }
1662 
1663  index = 0;
1664  ptr = GET_FIRST(&Ships[ship].subsys_list);
1665  while (ptr != END_OF_LIST(&Ships[ship].subsys_list)) {
1666  ptr->current_hits = 0.0f;
1667  if (ptr->system_info->type == SUBSYSTEM_TURRET) {
1668  wp = &ptr->weapons;
1669  sp = &Ship_info[Ships[ship].ship_info_index].subsystems[index];
1670 
1671  j = 0;
1672  for (i=0; i<MAX_SHIP_PRIMARY_BANKS; i++){
1673  if (sp->primary_banks[i] != -1){
1674  wp->primary_bank_weapons[j++] = sp->primary_banks[i];
1675  }
1676  }
1677 
1678  wp->num_primary_banks = j;
1679  j = 0;
1680  for (i=0; i<MAX_SHIP_SECONDARY_BANKS; i++){
1681  if (sp->secondary_banks[i] != -1) {
1684  }
1685  }
1686 
1687  wp->num_secondary_banks = j;
1688  for (i=0; i<MAX_SHIP_SECONDARY_BANKS; i++){
1689  wp->secondary_bank_ammo[i] = 100;
1690  }
1691  }
1692 
1693  index++;
1694  ptr = GET_NEXT(ptr);
1695  }
1696  }
1697 
1698  objp = GET_NEXT(objp);
1699  }
1700 
1701  UpdateData(FALSE);
1702  if (multi_edit){
1703  MessageBox("Ships reset to ship class defaults");
1704  } else {
1705  MessageBox("Ship reset to ship class defaults");
1706  }
1707 }
1708 
1710 {
1711  delete_marked();
1712  unmark_all();
1713 }
1714 
1716 {
1717  text_view_dlg dlg;
1718 
1719  dlg.set(m_ship_class);
1720  dlg.DoModal();
1721 }
1722 
1723 int CShipEditorDlg::make_ship_list(int *arr)
1724 {
1725  int n = 0;
1726  object *ptr;
1727 
1728  ptr = GET_FIRST(&obj_used_list);
1729  while (ptr != END_OF_LIST(&obj_used_list)) {
1730  if ((ptr->type == OBJ_SHIP) || (ptr->type == OBJ_START)){
1731  arr[n++] = OBJ_INDEX(ptr);
1732  }
1733 
1734  ptr = GET_NEXT(ptr);
1735  }
1736 
1737  return n;
1738 }
1739 
1741 {
1742  int i, n, arr[MAX_SHIPS];
1743 
1744  if (!update_data()) {
1745  n = make_ship_list(arr);
1746  if (!n){
1747  return;
1748  }
1749 
1750  if (cur_ship < 0){
1751  i = n - 1;
1752  }
1753 
1754  else {
1755  for (i=0; i<n; i++){
1756  if (Ships[cur_ship].objnum == arr[i]){
1757  break;
1758  }
1759  }
1760 
1761  Assert(i < n);
1762  i--;
1763  if (i < 0){
1764  i = n - 1;
1765  }
1766  }
1767 
1768  unmark_all();
1769  set_cur_object_index(arr[i]);
1771  Update_ship = 0;
1772  }
1773 
1774  return;
1775 }
1776 
1778 {
1779  int i, n, arr[MAX_SHIPS];
1780 
1781  if (!update_data()) {
1782  n = make_ship_list(arr);
1783  if (!n)
1784  return;
1785 
1786  if (cur_ship < 0)
1787  i = 0;
1788 
1789  else {
1790  for (i=0; i<n; i++)
1791  if (Ships[cur_ship].objnum == arr[i])
1792  break;
1793 
1794  Assert(i < n);
1795  i++;
1796  if (i == n)
1797  i = 0;
1798  }
1799 
1800  unmark_all();
1801  set_cur_object_index(arr[i]);
1803  Update_ship = 0;
1804  }
1805 
1806  return;
1807 }
1808 
1809 void CShipEditorDlg::OnSelchangedArrivalTree(NMHDR* pNMHDR, LRESULT* pResult)
1810 {
1811  HTREEITEM h;
1812 
1813  NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
1814  h = pNMTreeView->itemNew.hItem;
1815  if (h){
1817  }
1818 
1819  *pResult = 0;
1820 }
1821 
1823 {
1824  HTREEITEM h;
1825 
1826  NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
1827  h = pNMTreeView->itemNew.hItem;
1828  if (h){
1830  }
1831 
1832  *pResult = 0;
1833 }
1834 
1836 {
1837  CRect cue, help;
1838 
1839  GetDlgItem(IDC_CUE_FRAME)->GetWindowRect(cue);
1840  cue_height = (cue.bottom - cue.top)+20;
1841  if (Show_sexp_help){
1842  GetDlgItem(IDC_HELP_BOX)->GetWindowRect(help);
1843  cue_height += (help.bottom - help.top);
1844  }
1845 
1846  if (Hide_ship_cues) {
1847  ((CButton *) GetDlgItem(IDC_HIDE_CUES)) -> SetCheck(1);
1848  OnHideCues();
1849  }
1850 }
1851 
1853 {
1854  CRect rect, help;
1855  GetDlgItem(IDC_HELP_BOX)->GetWindowRect(help);
1856  float box_size = (float)(help.bottom - help.top);
1857 
1858  if (Show_sexp_help){
1859  cue_height += (int)box_size;
1860  } else {
1861  cue_height -= (int)box_size;
1862  }
1863 
1864  if (((CButton *) GetDlgItem(IDC_HIDE_CUES)) -> GetCheck()){
1865  return;
1866  }
1867 
1868  GetWindowRect(rect);
1869 
1870  if (Show_sexp_help){
1871  rect.bottom += (LONG)box_size;
1872  } else {
1873  rect.bottom -= (LONG)box_size;
1874  }
1875 
1876  MoveWindow(rect);
1877 }
1878 
1880 {
1881  CRect rect;
1882 
1883  GetWindowRect(rect);
1884  if (((CButton *) GetDlgItem(IDC_HIDE_CUES)) -> GetCheck()) {
1885  rect.bottom -= cue_height;
1886  Hide_ship_cues = 1;
1887 
1888  } else {
1889  rect.bottom += cue_height;
1890  Hide_ship_cues = 0;
1891  }
1892 
1893  MoveWindow(rect);
1894 }
1895 
1897 {
1898  CComboBox *box;
1899 
1900  UpdateData();
1901  box = (CComboBox *)GetDlgItem( IDC_ARRIVAL_TARGET );
1902  if (m_arrival_location) {
1903  GetDlgItem(IDC_ARRIVAL_DISTANCE)->EnableWindow(TRUE);
1904  GetDlgItem(IDC_ARRIVAL_TARGET)->EnableWindow(TRUE);
1905  if (m_arrival_target < 0) {
1906  m_arrival_target = 0;
1907  }
1908 
1909  // determine which items we should put into the arrival target combo box
1912  } else {
1914  }
1915 
1916  } else {
1917  m_arrival_target = -1;
1918  GetDlgItem(IDC_ARRIVAL_DISTANCE)->EnableWindow(FALSE);
1919  GetDlgItem(IDC_ARRIVAL_TARGET)->EnableWindow(FALSE);
1920  }
1921 
1923  GetDlgItem(IDC_RESTRICT_ARRIVAL)->EnableWindow(TRUE);
1924  } else {
1925  GetDlgItem(IDC_RESTRICT_ARRIVAL)->EnableWindow(FALSE);
1926  }
1927 
1928  UpdateData(FALSE);
1929 }
1930 
1932 {
1933  CComboBox *box;
1934 
1935  UpdateData();
1936  box = (CComboBox *)GetDlgItem(IDC_DEPARTURE_TARGET);
1937  if ( m_departure_location ) {
1938  box->EnableWindow(TRUE);
1939  if ( m_departure_target < 0 ) {
1940  m_departure_target = 0;
1941  }
1942 
1943  // we need to build up the list box content based on the departure type. When
1944  // from a docking bay, only show ships in the list which have them. Show all ships otherwise
1947  } else {
1948  // I think that this section is currently illegal
1949  Int3();
1950  }
1951 
1952  } else {
1953  m_departure_target = -1;
1954  box->EnableWindow(FALSE);
1955  }
1956 
1958  GetDlgItem(IDC_RESTRICT_DEPARTURE)->EnableWindow(TRUE);
1959  } else {
1960  GetDlgItem(IDC_RESTRICT_DEPARTURE)->EnableWindow(FALSE);
1961  }
1962 
1963  UpdateData(FALSE);
1964 }
1965 
1966 
1968 {
1969  if (m_player_ship.GetCheck() == 1)
1970  m_player_ship.SetCheck(0);
1971  else
1972  m_player_ship.SetCheck(1);
1973 
1975 }
1976 
1978 {
1979  if (m_no_arrival_warp.GetCheck() == 1)
1980  m_no_arrival_warp.SetCheck(0);
1981  else
1982  m_no_arrival_warp.SetCheck(1);
1983 }
1984 
1986 {
1987  if (m_no_departure_warp.GetCheck() == 1)
1988  m_no_departure_warp.SetCheck(0);
1989  else
1990  m_no_departure_warp.SetCheck(1);
1991 }
1992 
1993 
1994 // function to possibly warn user when he selects a hotkey which might be used for
1995 // a player wing.
1997 {
1998  int set_num;
1999  char buf[256];
2000 
2001  UpdateData(TRUE);
2002  set_num = m_hotkey-1; // use -1 since values associated with hotkey sets are 1 index based
2003 
2004  // the first three sets are generally reserved for player starting wings.
2005  if ( set_num < MAX_STARTING_WINGS ) {
2006  sprintf( buf, "This hotkey set should probably be reserved\nfor wing %s", Starting_wing_names[set_num] );
2007  MessageBox(buf, NULL, MB_OK);
2008  }
2009 }
2010 
2012 {
2013  ship_flags_dlg dlg;
2014 
2015  dlg.setup(p_enable);
2016  dlg.DoModal();
2017 }
2018 
2020 {
2021  // TODO: Add your control notification handler code here
2022  ignore_orders_dlg player_order_dlg;
2023 
2025 
2026  if (!multi_edit) {
2027  if ( single_ship != -1 ){
2028  player_order_dlg.m_ship = single_ship;
2029  } else {
2030  player_order_dlg.m_ship = player_ship;
2031  }
2032  } else {
2033  player_order_dlg.m_ship = -1;
2034  }
2035 
2036  player_order_dlg.DoModal();
2037 }
2038 
2040 {
2041  // TODO: Add your control notification handler code here
2042  ShipSpecialDamage dlg;
2043  dlg.DoModal();
2044 }
2045 
2046 // alternate ship name stuff
2048 {
2049  int idx, sel_idx;
2050  CComboBox *ptr = (CComboBox*)GetDlgItem(IDC_SHIP_ALT);
2051  if(ptr == NULL){
2052  Int3();
2053  return;
2054  }
2055 
2056  // multi-edit. bah
2057  if(multi_edit){
2058  GetDlgItem(IDC_SHIP_ALT)->EnableWindow(FALSE);
2059  return;
2060  }
2061  GetDlgItem(IDC_SHIP_ALT)->EnableWindow(TRUE);
2062 
2063  // reset the combobox and add all relevant strings
2064  ptr->ResetContent();
2065  ptr->AddString("<none>");
2066  sel_idx = (base_ship < 0 || !strlen(Fred_alt_names[base_ship])) ? -1 : -2;
2067  for(idx=0; idx<Mission_alt_type_count; idx++){
2068  ptr->AddString(Mission_alt_types[idx]);
2069  if (sel_idx == -2 && !strcmp(Mission_alt_types[idx], Fred_alt_names[base_ship])) {
2070  sel_idx = idx;
2071  }
2072  }
2073  Assertion(sel_idx >= -1, "Alt name exists but can't be found in Mission_alt_types; get a coder!\n");
2074 
2075  sel_idx += 1;
2076  ptr->SetCurSel(sel_idx);
2077 }
2078 
2080 {
2081  CString cstr;
2082  char str[NAME_LENGTH+2] = "";
2083  char *p;
2084  CComboBox *ptr = (CComboBox*)GetDlgItem(IDC_SHIP_ALT);
2085 
2086  if(multi_edit){
2087  return;
2088  }
2089 
2090  if(ptr == NULL){
2091  Int3();
2092  return;
2093  }
2094 
2095  ptr->GetWindowText(cstr);
2096  cstr.TrimLeft();
2097  cstr.TrimRight();
2098  p = cstr.GetBuffer(0);
2099  if(p == NULL){
2100  return;
2101  }
2102  strcpy_s(str, p);
2103 
2104  // do we have an empty string or "none" selected?
2105  if(!*str || !stricmp(str, "<none>")) {
2106  // if we currently have an entry, remove it -- but only if it's unused
2107  if (*Fred_alt_names[base_ship]) {
2108  bool used = false;
2109  for (int i = 0; i < MAX_SHIPS; ++i) {
2110  if (i != base_ship && !strcmp(Fred_alt_names[i], Fred_alt_names[base_ship])) {
2111  used = true;
2112  break;
2113  }
2114  }
2115  if (!used) {
2117  }
2118 
2119  // zero the entry
2120  strcpy_s(Fred_alt_names[base_ship], "");
2121  }
2122  return;
2123  }
2124 
2125  // otherwise see if it already exists
2126  if(mission_parse_lookup_alt(str) >= 0){
2127  strcpy_s(Fred_alt_names[base_ship], str);
2128  return;
2129  }
2130 
2131  // otherwise try and add it
2132  if(mission_parse_add_alt(str) >= 0){
2133  strcpy_s(Fred_alt_names[base_ship], str);
2134  return;
2135  }
2136 
2137  // bad - couldn't add
2138  strcpy_s(Fred_alt_names[base_ship], "");
2139  MessageBox("Couldn't add new alternate type name. Already using too many!");
2140 }
2141 
2142 // callsign stuff
2144 {
2145  int idx, sel_idx;
2146  CComboBox *ptr = (CComboBox*)GetDlgItem(IDC_SHIP_CALLSIGN);
2147  if(ptr == NULL){
2148  Int3();
2149  return;
2150  }
2151 
2152  // multi-edit. bah
2153  if(multi_edit){
2154  GetDlgItem(IDC_SHIP_CALLSIGN)->EnableWindow(FALSE);
2155  return;
2156  }
2157  GetDlgItem(IDC_SHIP_CALLSIGN)->EnableWindow(TRUE);
2158 
2159  // reset the combobox and add all relevant strings
2160  ptr->ResetContent();
2161  ptr->AddString("<none>");
2162  sel_idx = (base_ship < 0 || !strlen(Fred_callsigns[base_ship])) ? -1 : -2;
2163  for(idx=0; idx<Mission_callsign_count; idx++){
2164  ptr->AddString(Mission_callsigns[idx]);
2165  if (sel_idx == -2 && !strcmp(Mission_callsigns[idx], Fred_callsigns[base_ship])) {
2166  sel_idx = idx;
2167  }
2168  }
2169  Assertion(sel_idx >= -1, "Callsign exists but can't be found in Mission_callsigns; get a coder!\n");
2170 
2171  sel_idx += 1;
2172  ptr->SetCurSel(sel_idx);
2173 }
2174 
2176 {
2177  CString cstr;
2178  char str[NAME_LENGTH+2] = "";
2179  char *p;
2180  CComboBox *ptr = (CComboBox*)GetDlgItem(IDC_SHIP_CALLSIGN);
2181 
2182  if(multi_edit){
2183  return;
2184  }
2185 
2186  if(ptr == NULL){
2187  Int3();
2188  return;
2189  }
2190 
2191  ptr->GetWindowText(cstr);
2192  cstr.TrimLeft();
2193  cstr.TrimRight();
2194  p = cstr.GetBuffer(0);
2195  if(p == NULL){
2196  return;
2197  }
2198  strcpy_s(str, p);
2199 
2200  // do we have an empty string or "none" selected?
2201  if(!*str || !stricmp(str, "<none>")) {
2202  // if we currently have an entry, remove it -- but only if it's unused
2203  if (*Fred_callsigns[base_ship]) {
2204  bool used = false;
2205  for (int i = 0; i < MAX_SHIPS; ++i) {
2206  if (i != base_ship && !strcmp(Fred_callsigns[i], Fred_callsigns[base_ship])) {
2207  used = true;
2208  break;
2209  }
2210  }
2211  if (!used) {
2213  }
2214 
2215  // zero the entry
2216  strcpy_s(Fred_callsigns[base_ship], "");
2217  }
2218  return;
2219  }
2220 
2221  // otherwise see if it already exists
2222  if(mission_parse_lookup_callsign(str) >= 0){
2223  strcpy_s(Fred_callsigns[base_ship], str);
2224  return;
2225  }
2226 
2227  // otherwise try and add it
2228  if(mission_parse_add_callsign(str) >= 0){
2229  strcpy_s(Fred_callsigns[base_ship], str);
2230 
2231  return;
2232  }
2233 
2234  // bad - couldn't add
2235  strcpy_s(Fred_callsigns[base_ship], "");
2236  MessageBox("Couldn't add new callsign. Already using too many!");
2237 }
2238 
2240 {
2241  CShipTexturesDlg dlg_textures;
2242 
2244 
2245  if (multi_edit)
2246  {
2247  MessageBox("Sorry, you can only edit textures for one ship at a time.", "Too many ships selected");
2248  return;
2249  }
2250 
2251  // get the ship that's marked
2252  int marked_ship = (player_ship >= 0) ? player_ship : single_ship;
2253 
2254  dlg_textures.self_ship = marked_ship;
2255  dlg_textures.DoModal();
2256 }
2257 
2259 {
2261  dlg.DoModal();
2262 }
2263 
2265 {
2266  AltShipClassDlg dlg;
2267  dlg.DoModal();
2268 }
2269 
2270 // Goober5000
2272 {
2274 
2275  if (multi_edit)
2276  {
2277  MessageBox("Please select only one ship.", "Too many ships selected");
2278  return;
2279  }
2280 
2281  // since this is single player, clear all player ships and set only this one
2282  object *objp = GET_FIRST(&obj_used_list);
2283  while (objp != END_OF_LIST(&obj_used_list))
2284  {
2285  if ((objp->type == OBJ_SHIP) || (objp->type == OBJ_START))
2286  {
2287  if (objp->flags & OF_MARKED) // there should only be one selected ship
2288  {
2289  // set as player ship
2290  objp->type = OBJ_START;
2291  objp->flags |= OF_PLAYER_SHIP;
2292  }
2293  else
2294  {
2295  // set as regular ship
2296  objp->type = OBJ_SHIP;
2297  objp->flags &= ~OF_PLAYER_SHIP;
2298  }
2299  }
2300  objp = GET_NEXT(objp);
2301  }
2302 
2303  // finally set editor dialog
2304  m_player_ship.SetCheck(1);
2306 }
2307 
2308 // Goober5000
2310 {
2311  int arrive_from_ship;
2312  CComboBox *box;
2313  restrict_paths dlg;
2314 
2315  if (multi_edit)
2316  {
2317  MessageBox("Please select only one ship.", "Too many ships selected");
2318  return;
2319  }
2320 
2321  // grab stuff from GUI
2322  UpdateData(TRUE);
2323 
2325  {
2326  Int3();
2327  return;
2328  }
2329 
2330  box = (CComboBox *) GetDlgItem(IDC_ARRIVAL_TARGET);
2331  if (box->GetCount() == 0)
2332  return;
2333 
2334  arrive_from_ship = box->GetItemData(m_arrival_target);
2335 
2336  if (!ship_has_dock_bay(arrive_from_ship))
2337  {
2338  Int3();
2339  return;
2340  }
2341 
2342  // get the ship that's marked
2343  int marked_ship = (player_ship >= 0) ? player_ship : single_ship;
2344 
2345  dlg.m_arrival = true;
2346  dlg.m_ship_class = Ships[arrive_from_ship].ship_info_index;
2347  dlg.m_path_mask = &Ships[marked_ship].arrival_path_mask;
2348 
2349  dlg.DoModal();
2350 }
2351 
2352 // Goober5000
2354 {
2355  int depart_to_ship;
2356  CComboBox *box;
2357  restrict_paths dlg;
2358 
2359  if (multi_edit)
2360  {
2361  MessageBox("Please select only one ship.", "Too many ships selected");
2362  return;
2363  }
2364 
2365  // grab stuff from GUI
2366  UpdateData(TRUE);
2367 
2369  {
2370  Int3();
2371  return;
2372  }
2373 
2374  box = (CComboBox *) GetDlgItem(IDC_DEPARTURE_TARGET);
2375  if (box->GetCount() == 0)
2376  return;
2377 
2378  depart_to_ship = box->GetItemData(m_departure_target);
2379 
2380  if (!ship_has_dock_bay(depart_to_ship))
2381  {
2382  Int3();
2383  return;
2384  }
2385 
2386  // get the ship that's marked
2387  int marked_ship = (player_ship >= 0) ? player_ship : single_ship;
2388 
2389  dlg.m_arrival = false;
2390  dlg.m_ship_class = Ships[depart_to_ship].ship_info_index;
2391  dlg.m_path_mask = &Ships[marked_ship].departure_path_mask;
2392 
2393  dlg.DoModal();
2394 }
void ship_callsign_init(int base_ship)
#define MB_OKCANCEL
Definition: config.h:180
char Starting_wing_names[MAX_STARTING_WINGS][NAME_LENGTH]
Definition: ship.cpp:139
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
void * HWND
Definition: config.h:104
int i
Definition: multi_pxo.cpp:466
afx_msg void OnNext()
int mission_parse_add_callsign(const char *name)
sexp_tree m_arrival_tree
Definition: shipeditordlg.h:98
#define IDC_SHIP_CALLSIGN
Definition: resource.h:657
model_subsystem * system_info
Definition: ship.h:314
int primary_bank_weapons[MAX_SHIP_PRIMARY_BANKS]
Definition: ship.h:103
afx_msg void OnRestrictArrival()
#define MAX_SHIP_PRIMARY_BANKS
Definition: globals.h:62
int team
Definition: ship.h:606
CSpinButtonCtrl m_arrival_delay_spin
Definition: shipeditordlg.h:96
char Mission_callsigns[MAX_CALLSIGNS][NAME_LENGTH]
int secondary_bank_weapons[MAX_SHIP_SECONDARY_BANKS]
Definition: ship.h:1299
#define AI_DEFAULT_CLASS
Definition: ai.h:27
int ai_class
Definition: ship.h:148
int num_primary_banks
Definition: ship.h:99
int objnum
Definition: ship.h:537
CString m_ship_name
Definition: shipeditordlg.h:99
GLfloat GLfloat GLfloat GLfloat h
Definition: Glext.h:7280
#define SIF_PLAYER_SHIP
Definition: ship.h:875
int game_type
Definition: missionparse.h:138
int Player_start_shipnum
int mission_parse_lookup_callsign(const char *name)
#define IDC_SHIP_ALT
Definition: resource.h:644
CShipEditorDlg Ship_editor_dialog
Definition: fred.cpp:55
ship_weapon weapons
Definition: ship.h:658
void mission_parse_remove_alt(const char *name)
GLsizei const GLfloat * value
Definition: Glext.h:5646
char ** Ai_class_names
Definition: aicode.cpp:268
GLuint index
Definition: Glext.h:5608
void unmark_all()
physics_info phys_info
Definition: object.h:157
afx_msg void OnSelchangeArrivalLocation()
#define MAX_WINGS
Definition: globals.h:50
afx_msg void OnShipReset()
#define MAX_SHIPS
Definition: globals.h:37
#define IDC_HELP_BOX
Definition: resource.h:872
void generate_ship_popup_menu(CMenu *mptr, int first_id, int state, int filter)
afx_msg void OnNoArrivalWarp()
int departure_anchor
Definition: ship.h:618
int arrival_location
Definition: ship.h:610
#define SHIPS_2_COMBO_DOCKING_BAY_ONLY
Definition: management.h:135
numeric_edit_control m_score
Assert(pm!=NULL)
void stuff_special_arrival_anchor_name(char *buf, int iff_index, int restrict_to_players, int retail_format)
int departure_location
Definition: ship.h:617
char Fred_alt_names[MAX_SHIPS][NAME_LENGTH+1]
Definition: management.cpp:93
int ai_index
Definition: ship.h:538
ship_weapon weapons
Definition: ship.h:362
#define ID_SHIP_MENU
afx_msg void OnClose()
#define IDC_ALT_SHIP_CLASS
Definition: resource.h:1137
#define SIF_CARGO
Definition: ship.h:884
afx_msg void OnWeapons()
CButton * team
afx_msg void OnIgnoreOrders()
int mission_parse_add_alt(const char *name)
#define IDC_SHIP_TBL
Definition: resource.h:841
int update_data(int redraw=1)
#define IDC_UPDATE_DEPARTURE
Definition: resource.h:843
GLclampf f
Definition: Glext.h:7097
#define IDC_RESTRICT_ARRIVAL
Definition: resource.h:1068
afx_msg void OnRclickArrivalTree(NMHDR *pNMHDR, LRESULT *pResult)
void update_sexp_references(const char *old_name, const char *new_name, int format, int node)
Definition: sexp.cpp:28332
afx_msg void OnSpecialHitpoints()
#define TRUE
Definition: pstypes.h:399
#define MISSION_TYPE_MULTI
Definition: missionparse.h:62
int Num_cargo
ai_info Ai_info[MAX_AI_INFO]
Definition: ai.cpp:23
#define Assertion(expr, msg,...)
Definition: clang.h:41
afx_msg void OnGoals()
UINT WPARAM wParam
Definition: msacm.h:1064
#define PERSONA_FLAG_WINGMAN
object obj_used_list
Definition: object.cpp:53
#define IDC_DEPARTURE_TARGET
Definition: resource.h:537
#define IDC_RESTRICT_DEPARTURE
Definition: resource.h:1070
CMainFrame * Fred_main_wnd
Definition: mainfrm.cpp:89
Definition: ship.h:1516
afx_msg void OnEndlabeleditDepartureTree(NMHDR *pNMHDR, LRESULT *pResult)
afx_msg void OnEndlabeleditArrivalTree(NMHDR *pNMHDR, LRESULT *pResult)
int edit_label(HTREEITEM h)
Definition: sexp_tree.cpp:1349
UINT WPARAM LPARAM lParam
Definition: msacm.h:1064
uint flags
Definition: ship.h:644
int primary_bank_weapons[MAX_SHIP_PRIMARY_BANKS]
Definition: ship.h:1294
#define SIF_NO_SHIP_TYPE
Definition: ship.h:894
sexp_tree m_departure_tree
Definition: shipeditordlg.h:97
unsigned int UINT
Definition: config.h:82
#define OF_PLAYER_SHIP
Definition: object.h:109
afx_msg void OnTextures()
object * objp
Definition: lua.cpp:3105
#define Int3()
Definition: pstypes.h:292
#define IDC_SPECIAL_HITPOINTS
Definition: resource.h:880
#define AI_GOAL_NONE
Definition: ai.h:194
#define MODIFY(a, b)
Definition: fred.h:26
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: Glext.h:7308
#define IDC_SHIP_TEAM
Definition: resource.h:517
void right_clicked(int mode=0)
Definition: sexp_tree.cpp:570
#define IDC_SPECIAL_EXP
Definition: resource.h:879
afx_msg void OnBeginlabeleditArrivalTree(NMHDR *pNMHDR, LRESULT *pResult)
#define SPECIAL_ARRIVAL_ANCHOR_FLAG
Definition: missionparse.h:37
long LPARAM
Definition: config.h:101
afx_msg void OnPlayerShip()
GLenum type
Definition: Gl.h:1492
int primary_banks[MAX_SHIP_PRIMARY_BANKS]
Definition: model.h:218
void ship_callsign_close(int base_ship)
CButton m_no_departure_warp
Definition: shipeditordlg.h:91
int hotkey
Definition: ship.h:540
iff_info Iff_info[MAX_IFFS]
Definition: iff_defs.cpp:20
#define NO_PERSONA_INDEX
reinforcements Reinforcements[MAX_REINFORCEMENTS]
Definition: ship.cpp:165
#define IDC_INITIAL_STATUS
Definition: resource.h:829
int query_valid_object(int index)
#define IDC_CUE_FRAME
Definition: resource.h:886
#define IDC_UPDATE_ARRIVAL
Definition: resource.h:424
void update_help(HTREEITEM h)
Definition: sexp_tree.cpp:3891
typedef int(SCP_EXT_CALLCONV *SCPDLL_PFVERSION)(SCPDLL_Version *)
#define MAX_SHIP_SECONDARY_BANKS
Definition: globals.h:63
#define IDC_SET_AS_PLAYER_SHIP
Definition: resource.h:980
int mission_parse_lookup_alt(const char *name)
int instance
Definition: object.h:150
void setup(int n)
#define PERSONA_FLAG_VASUDAN
#define DEPART_AT_DOCK_BAY
Definition: missionparse.h:246
#define IDC_DEPARTURE_TREE
Definition: resource.h:625
#define OBJ_START
Definition: object.h:35
GLdouble GLdouble GLdouble r
Definition: Glext.h:5337
char * Departure_location_names[MAX_DEPARTURE_NAMES]
#define MAX_DEPARTURE_NAMES
Definition: missionparse.h:244
afx_msg void OnInitialStatus()
#define nprintf(args)
Definition: pstypes.h:239
#define IDC_ARRIVAL_DELAY
Definition: resource.h:731
int Hide_ship_cues
Definition: fredview.cpp:113
#define IDC_FLAGS
Definition: resource.h:332
void set_cur_object_index(int obj)
char Mission_alt_types[MAX_ALT_TYPE_NAMES][NAME_LENGTH]
int secondary_bank_capacity[MAX_SHIP_SECONDARY_BANKS]
Definition: ship.h:136
void ship_alt_name_close(int base_ship)
int wingnum
Definition: ship.h:623
int end_label_edit(TVITEMA &item)
Definition: sexp_tree.cpp:1412
float speed
Definition: physics.h:79
#define MAX_STARTING_WINGS
Definition: globals.h:54
int num_secondary_banks
Definition: ship.h:100
ai_goal goals[MAX_AI_GOALS]
Definition: ai.h:412
Persona * Personas
int Mission_callsign_count
int secondary_banks[MAX_SHIP_SECONDARY_BANKS]
Definition: model.h:220
float hull_strength
Definition: object.h:160
int persona_index
Definition: ship.h:696
#define SHIPS_2_COMBO_SPECIAL
Definition: management.h:133
afx_msg void OnShipTbl()
#define w(p)
Definition: modelsinc.h:68
sprintf(buf,"(%f,%f,%f)", v3->xyz.x, v3->xyz.y, v3->xyz.z)
int ai_mode
Definition: ai.h:136
#define SHIP_FILTER_PLAYERS
Definition: management.h:22
#define MAX_CARGO
Definition: missionparse.h:222
afx_msg void OnBeginlabeleditDepartureTree(NMHDR *pNMHDR, LRESULT *pResult)
#define MAX_AI_GOALS
Definition: ai.h:91
GLdouble GLdouble z
Definition: Glext.h:5451
#define IDC_TEXTURES
Definition: resource.h:1066
afx_msg void OnSelchangeHotkey()
#define SUBSYSTEM_TURRET
Definition: model.h:54
int free_sexp2(int num)
Definition: sexp.cpp:1321
char cargo1
Definition: ship.h:549
#define IDC_WING
Definition: resource.h:734
int secondary_bank_capacity[MAX_SHIP_SECONDARY_BANKS]
Definition: model.h:221
#define IDC_ARRIVAL_DISTANCE
Definition: resource.h:801
#define MB_OK
Definition: config.h:179
afx_msg void OnAltShipClass()
int secondary_bank_weapons[MAX_SHIP_SECONDARY_BANKS]
Definition: ship.h:104
int query_whole_wing_marked(int wing)
int Num_ai_classes
Definition: aicode.cpp:195
int wing_objects[MAX_WINGS][MAX_SHIPS_PER_WING]
Definition: management.cpp:97
#define MAX_PLAYERS
Definition: pstypes.h:32
#define IDC_WEAPONS
Definition: resource.h:561
afx_msg void OnSpecialExp()
int wing_is_player_wing(int wing)
float current_hits
Definition: ship.h:319
#define IDC_ARRIVAL_DELAY_SPIN
Definition: resource.h:733
afx_msg void OnNoDepartureWarp()
int secondary_bank_ammo_capacity[MAX_SHIP_SECONDARY_BANKS]
Definition: ship.h:1300
Definition: ship.h:534
GLenum GLuint id
Definition: Glext.h:5156
unsigned long DWORD
Definition: config.h:90
#define IDC_AI_CLASS
Definition: resource.h:551
int idx
Definition: multiui.cpp:761
#define ARRIVE_AT_LOCATION
Definition: missionparse.h:237
int secondary_bank_ammo[MAX_SHIP_SECONDARY_BANKS]
Definition: ship.h:134
void update_data_safe()
#define SF_NO_DEPARTURE_WARP
Definition: ship.h:441
#define IDC_SHIP_RESET
Definition: resource.h:251
float assist_score_pct
Definition: ship.h:543
void ai_update_goal_references(ai_goal *goals, int type, const char *old_name, const char *new_name)
Definition: aigoals.cpp:2295
int wave_count
Definition: ship.h:1527
object Objects[MAX_OBJECTS]
Definition: object.cpp:62
for(int idx=0;idx< i;idx++)
Definition: multi_pxo.cpp:472
GLclampd n
Definition: Glext.h:7286
#define IDC_ARRIVAL_TREE
Definition: resource.h:624
#define IDC_HIDE_CUES
Definition: resource.h:885
void string_copy(char *dest, const CString &src, int max_len, int modify)
Definition: management.cpp:142
#define IDC_SHIP_CARGO1
Definition: resource.h:212
#define IDC_ASSIST_SCORE
Definition: resource.h:796
#define SF_NO_ARRIVAL_WARP
Definition: ship.h:440
#define OBJ_INDEX(objp)
Definition: object.h:235
#define OF_MARKED
Definition: object.h:125
#define IDC_SCORE
Definition: resource.h:776
#define IDC_HOTKEY
Definition: resource.h:766
virtual void DoDataExchange(CDataExchange *pDX)
long LONG
Definition: config.h:95
#define OBJ_SHIP
Definition: object.h:32
char name[NAME_LENGTH]
wing_editor Wing_editor_dialog
Definition: fred.cpp:56
#define IDC_PREV
Definition: resource.h:851
GLbitfield flags
Definition: Glext.h:6722
void set_modified(BOOL arg)
Definition: freddoc.cpp:676
int num_secondary_banks
Definition: ship.h:1298
GLuint const GLchar * name
Definition: Glext.h:5608
#define IDC_NO_ARRIVAL_WARP
Definition: resource.h:912
GLuint GLfloat * val
Definition: Glext.h:6741
GLboolean enable
Definition: Glext.h:10591
int Num_personas
numeric_edit_control m_arrival_delay
CShipEditorDlg(CWnd *pParent=NULL)
int BOOL
Definition: config.h:80
ship Ships[MAX_SHIPS]
Definition: ship.cpp:122
#define IDC_IGNORE_ORDERS
Definition: resource.h:877
int string_lookup(const CString &str1, char *strlist[], int max)
#define REF_TYPE_SHIP
Definition: sexp.h:836
void set(int ship)
Definition: textviewdlg.cpp:51
CJumpNode * jumpnode_get_by_name(const CString &name)
typedef float(SCP_EXT_CALLCONV *SCPTRACKIR_PFFLOATVOID)()
numeric_edit_control m_assist_score
#define IDC_DEPARTURE_DELAY
Definition: resource.h:732
#define MB_ICONEXCLAMATION
Definition: config.h:184
#define IDC_SHIP_PERSONA
Definition: resource.h:591
waypoint_list * find_matching_waypoint_list(const char *name)
Definition: waypoint.cpp:164
bool ship_has_dock_bay(int shipnum)
Definition: ship.cpp:17435
#define NAME_LENGTH
Definition: globals.h:15
CSpinButtonCtrl m_departure_delay_spin
Definition: shipeditordlg.h:95
void show_hide_sexp_help()
GLubyte GLubyte GLubyte GLubyte w
Definition: Glext.h:5679
afx_msg void OnHideCues()
afx_msg void OnFlags()
int save_tree(int node=-1)
Definition: sexp_tree.cpp:237
int query_initial_orders_empty(ai_goal *ai_goals)
void help()
#define SHIPS_2_COMBO_ALL_SHIPS
Definition: management.h:134
long LRESULT
Definition: config.h:100
int cur_ship
Definition: management.cpp:80
numeric_edit_control m_arrival_dist
int ship_info_index
Definition: ship.h:539
numeric_edit_control m_departure_delay
GLfloat GLfloat p
Definition: Glext.h:8373
#define IDC_ARRIVAL_LOCATION
Definition: resource.h:616
SCP_vector< ship_info > Ship_info
Definition: ship.cpp:164
int cmp_sexp_chains(int node1, int node2)
Definition: sexp.cpp:1408
int MessageBox(HWND h, const char *s1, const char *s2, int i)
#define IDC_DEPARTURE_DELAY_SPIN
Definition: resource.h:300
#define IDC_SHIP_NAME
Definition: resource.h:471
int Update_ship
Definition: management.cpp:87
SCP_vector< float > shield_quadrant
Definition: object.h:159
SCP_vector< species_info > Species_info
#define IDC_GOALS
Definition: resource.h:259
void delete_marked()
int ship_get_default_orders_accepted(ship_info *sip)
Definition: ship.cpp:5480
CButton m_no_arrival_warp
Definition: shipeditordlg.h:92
afx_msg void OnSelchangedDepartureTree(NMHDR *pNMHDR, LRESULT *pResult)
const GLfloat * m
Definition: Glext.h:10319
void load_tree(int index, const char *deflt="true")
Definition: sexp_tree.cpp:124
afx_msg void OnSelchangedArrivalTree(NMHDR *pNMHDR, LRESULT *pResult)
afx_msg void OnDeleteShip()
void change_ship_type(int n, int ship_type, int by_sexp)
Definition: ship.cpp:9983
#define MAX_TVT_TEAMS
Definition: globals.h:57
CCriticalSection CS_cur_object_index
Definition: management.cpp:104
int departure_path_mask
Definition: ship.h:619
int query_initial_orders_conflict(int wing)
int arrival_anchor
Definition: ship.h:612
#define IDC_SHIP_CLASS
Definition: resource.h:127
#define SF_ESCORT
Definition: ship.h:438
void hilite_item(int node)
Definition: sexp_tree.cpp:3139
#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 tristate_set(int val, int cur_state)
int cur_object_index
Definition: management.cpp:79
#define IDC_PLAYER_SHIP
Definition: resource.h:901
int departure_cue
Definition: ship.h:620
afx_msg void OnSetAsPlayerShip()
int Num_iffs
Definition: iff_defs.cpp:19
int arrival_path_mask
Definition: ship.h:613
int arrival_cue
Definition: ship.h:614
int select_sexp_node
Definition: sexp_tree.h:283
void clear_menu(CMenu *ptr)
int get_ship_from_obj(int obj)
uint flags
Definition: object.h:151
mission The_mission
afx_msg void OnSelchangeShipClass()
char Fred_callsigns[MAX_SHIPS][NAME_LENGTH+1]
Definition: management.cpp:94
#define ARRIVE_FROM_DOCK_BAY
Definition: missionparse.h:240
char type
Definition: object.h:146
CButton m_player_ship
Definition: shipeditordlg.h:93
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam)
#define FALSE
Definition: pstypes.h:400
#define wp(p)
Definition: modelsinc.h:69
char * Cargo_names[]
SCP_vector< ai_target_priority > Ai_tp_list
Definition: ship.cpp:396
char iff_name[NAME_LENGTH]
Definition: iff_defs.h:36
void ship_alt_name_init(int base_ship)
int Show_sexp_help
Definition: fredview.cpp:87
#define stricmp(s1, s2)
Definition: config.h:271
#define IDC_ARRIVAL_TARGET
Definition: resource.h:525
#define IDC_DELETE_SHIP
Definition: resource.h:494
void management_add_ships_to_combo(CComboBox *box, int flags)
afx_msg void OnRestrictDeparture()
void initialize_data_safe(int full_update)
int Mission_alt_type_count
void update_texture_replacements(const char *old_name, const char *new_name)
char ship_name[NAME_LENGTH]
Definition: ship.h:604
int arrival_distance
Definition: ship.h:611
#define IDC_DEPARTURE_LOCATION
Definition: resource.h:620
void clear_tree(const char *op=NULL)
Definition: sexp_tree.cpp:99
struct wing wing
afx_msg void OnPrev()
int Update_window
Definition: fred.cpp:48
int num_primary_banks
Definition: ship.h:1293
void OnInitMenu(CMenu *m)
#define strcpy_s(...)
Definition: safe_strings.h:67
void setup(int id, CWnd *wnd)
void update_map_window()
Definition: fred.cpp:532
void initialize_data(int full)
int Player_starts
afx_msg void OnSelchangeDepartureLocation()
#define IDC_NEXT
Definition: resource.h:844
afx_msg void OnRclickDepartureTree(NMHDR *pNMHDR, LRESULT *pResult)
char * Arrival_location_names[MAX_ARRIVAL_NAMES]
void mission_parse_remove_callsign(const char *name)