FS2_Open
Open source remastering of the Freespace 2 engine
initialstatus.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 // InitialStatus.cpp : implementation file
11 //
12 
13 #include "stdafx.h"
14 #include "FRED.h"
15 #include "FREDDoc.h"
16 #include "InitialStatus.h"
17 #include "Management.h"
18 #include "globalincs/linklist.h"
19 #include "globalincs/alphacolors.h"
20 #include "object/objectdock.h"
21 
22 #ifdef _DEBUG
23 #undef THIS_FILE
24 static char THIS_FILE[] = __FILE__;
25 #endif
26 
27 
28 // non-class function prototypes, bah
31 void reset_arrival_to_false(int shipnum, bool reset_wing);
32 
33 
35 // initial_status dialog
36 
37 initial_status::initial_status(CWnd* pParent /*=NULL*/)
38  : CDialog(initial_status::IDD, pParent)
39 {
40  //{{AFX_DATA_INIT(initial_status)
41  m_damage = 0;
42  m_shields = 0;
43  m_velocity = 0;
44  m_hull = 0;
53  m_cargo_name = _T("");
54  //}}AFX_DATA_INIT
55  inited = 0;
56  cur_subsys = LB_ERR;
57 
58  dockpoint_array = NULL;
59  num_dock_points = 0;
60 
61  cur_docker_point = -1;
62  cur_dockee = -1;
63  cur_dockee_point = -1;
64 
65  m_multi_edit = 0;
66 }
67 
69 {
70  if (dockpoint_array != NULL)
71  delete [] dockpoint_array;
72 }
73 
74 void initial_status::DoDataExchange(CDataExchange* pDX)
75 {
76  CString str;
77 
78  CDialog::DoDataExchange(pDX);
79  //{{AFX_DATA_MAP(initial_status)
80  DDX_Control(pDX, IDC_HULL_SPIN, m_hull_spin);
81  DDX_Control(pDX, IDC_VELOCITY_SPIN, m_velocity_spin);
82  DDX_Control(pDX, IDC_SHIELDS_SPIN, m_shields_spin);
83  DDX_Control(pDX, IDC_DAMAGE_SPIN, m_damage_spin);
84  DDX_Control(pDX, IDC_TEAMSELECT, m_team_color_setting);
85  DDX_Text(pDX, IDC_DAMAGE, m_damage);
86  DDV_MinMaxInt(pDX, m_damage, 0, 100);
87  DDX_Check(pDX, IDC_HAS_SHIELDS, m_has_shields);
88  DDX_Check(pDX, IDC_FORCE_SHIELDS, m_force_shields);
89  DDX_Check(pDX, IDC_SHIP_LOCKED, m_ship_locked);
90  DDX_Check(pDX, IDC_WEAPONS_LOCKED, m_weapons_locked);
93  DDX_Check(pDX, IDC_TURRETS_LOCKED, m_turrets_locked);
95  DDX_Text(pDX, IDC_CARGO_NAME, m_cargo_name);
96  DDV_MaxChars(pDX, m_cargo_name, 20);
97  //}}AFX_DATA_MAP
98 
99  if (pDX->m_bSaveAndValidate) {
100  GetDlgItem(IDC_VELOCITY)->GetWindowText(str);
101  m_velocity = atoi(str);
102  if (m_velocity < 0)
103  m_velocity = 0;
104  if (m_velocity > 100)
105  m_velocity = 100;
106 
107  GetDlgItem(IDC_SHIELDS)->GetWindowText(str);
108  m_shields = atoi(str);
109  if (m_shields < 0)
110  m_shields = 0;
111  if (m_shields > 100)
112  m_shields = 100;
113 
114  GetDlgItem(IDC_HULL)->GetWindowText(str);
115  m_hull = atoi(str);
116  if (m_hull < 0)
117  m_hull = 0;
118  if (m_hull > 100)
119  m_hull = 100;
120  }
121 }
122 
123 BEGIN_MESSAGE_MAP(initial_status, CDialog)
124  //{{AFX_MSG_MAP(initial_status)
125  ON_LBN_SELCHANGE(IDC_SUBSYS, OnSelchangeSubsys)
126  ON_LBN_SELCHANGE(IDC_DOCKER_POINT, OnSelchangeDockerPoint)
127  ON_CBN_SELCHANGE(IDC_DOCKEE, OnSelchangeDockee)
128  ON_CBN_SELCHANGE(IDC_DOCKEE_POINT, OnSelchangeDockeePoint)
129  ON_BN_CLICKED(IDC_HAS_SHIELDS, OnHasShields)
130  ON_BN_CLICKED(IDC_FORCE_SHIELDS, OnForceShields)
131  ON_BN_CLICKED(IDC_SHIP_LOCKED, OnShipLocked)
132  ON_BN_CLICKED(IDC_WEAPONS_LOCKED, OnWeaponsLocked)
133  ON_BN_CLICKED(IDC_PRIMARIES_LOCKED, OnPrimariesLocked)
134  ON_BN_CLICKED(IDC_SECONDARIES_LOCKED, OnSecondariesLocked)
135  ON_BN_CLICKED(IDC_TURRETS_LOCKED, OnTurretsLocked)
136  ON_BN_CLICKED(IDC_AFTERBURNER_LOCKED, OnAfterburnersLocked)
137  //}}AFX_MSG_MAP
138 END_MESSAGE_MAP()
139 
141 // initial_status message handlers
142 
143 BOOL initial_status::OnInitDialog()
144 {
145  int z, vflag, sflag, hflag;
146  ship_subsys *ptr;
147  CString str;
148  object *objp = NULL;
149 
150  m_ship = cur_ship;
151  if (m_ship == -1) {
154  Assert(m_ship >= 0);
155  }
156 
157  // initialize dockpoint stuff
158  if (!m_multi_edit)
159  {
160  num_dock_points = model_get_num_dock_points(Ship_info[Ships[m_ship].ship_info_index].model_num);
161  dockpoint_array = new dockpoint_information[num_dock_points];
162  objp = &Objects[Ships[m_ship].objnum];
163  for (int i = 0; i < num_dock_points; i++)
164  {
165  object *docked_objp = dock_find_object_at_dockpoint(objp, i);
166  if (docked_objp != NULL)
167  {
168  dockpoint_array[i].dockee_shipnum = docked_objp->instance;
169  dockpoint_array[i].dockee_point = dock_find_dockpoint_used_by_object(docked_objp, objp);
170  }
171  else
172  {
173  dockpoint_array[i].dockee_shipnum = -1;
174  dockpoint_array[i].dockee_point = -1;
175  }
176  }
177  }
178 
179  vflag = sflag = hflag = 0;
180  m_velocity = (int) Objects[cur_object_index].phys_info.speed;
181  m_shields = (int) Objects[cur_object_index].shield_quadrant[0];
182  m_hull = (int) Objects[cur_object_index].hull_strength;
184  m_has_shields = 0;
185  else
186  m_has_shields = 1;
187 
188  if (Ships[m_ship].flags2 & SF2_FORCE_SHIELDS_ON)
189  m_force_shields = 1;
190  else
191  m_force_shields = 0;
192 
193  if (Ships[m_ship].flags2 & SF2_SHIP_LOCKED)
194  m_ship_locked = 1;
195  else
196  m_ship_locked = 0;
197 
198  if (Ships[m_ship].flags2 & SF2_WEAPONS_LOCKED)
199  m_weapons_locked = 1;
200  else
201  m_weapons_locked = 0;
202 
203  // Lock primaries
204  if (Ships[m_ship].flags2 & SF2_PRIMARIES_LOCKED) {
205  m_primaries_locked = 1;
206  }
207  else {
208  m_primaries_locked = 0;
209  }
210 
211  //Lock secondaries
212  if (Ships[m_ship].flags2 & SF2_SECONDARIES_LOCKED) {
213  m_secondaries_locked = 1;
214  }
215  else {
216  m_secondaries_locked = 0;
217  }
218 
219  //Lock turrets
220  if (Ships[m_ship].flags2 & SF2_LOCK_ALL_TURRETS_INITIALLY) {
221  m_turrets_locked = 1;
222  }
223  else {
224  m_turrets_locked = 0;
225  }
226 
227  if (Ships[m_ship].flags2 & SF2_AFTERBURNER_LOCKED) {
228  m_afterburner_locked = 1;
229  }
230  else {
231  m_afterburner_locked = 0;
232  }
233 
234 
235 
236  if (m_multi_edit) {
237  objp = GET_FIRST(&obj_used_list);
238  while (objp != END_OF_LIST(&obj_used_list)) {
239  if (((objp->type == OBJ_SHIP) || (objp->type == OBJ_START)) && (objp->flags & OF_MARKED)) {
240  if (objp->phys_info.speed != m_velocity)
241  vflag = 1;
242  if ((int) objp->shield_quadrant[0] != m_shields)
243  sflag = 1;
244  if ((int) objp->hull_strength != m_hull)
245  hflag = 1;
246  if (objp->flags & OF_NO_SHIELDS) {
247  if (m_has_shields)
248  m_has_shields = 2;
249 
250  } else {
251  if (!m_has_shields)
252  m_has_shields = 2;
253  }
254 
255  Assert((objp->type == OBJ_SHIP) || (objp->type == OBJ_START));
256 
257  if (Ships[get_ship_from_obj(objp)].flags2 & SF2_FORCE_SHIELDS_ON) {
258  if (!m_force_shields)
259  m_force_shields = 2;
260 
261  } else {
262  if (m_force_shields)
263  m_force_shields = 2;
264  }
265 
266  if (Ships[get_ship_from_obj(objp)].flags2 & SF2_SHIP_LOCKED) {
267  if (!m_ship_locked)
268  m_ship_locked = 2;
269 
270  } else {
271  if (m_ship_locked)
272  m_ship_locked = 2;
273  }
274 
275  if (Ships[get_ship_from_obj(objp)].flags2 & SF2_WEAPONS_LOCKED) {
276  if (!m_weapons_locked)
277  m_weapons_locked = 2;
278 
279  } else {
280  if (m_weapons_locked)
281  m_weapons_locked = 2;
282  }
283 
284  if (Ships[get_ship_from_obj(objp)].flags2 & SF2_PRIMARIES_LOCKED){
285  if (!m_primaries_locked)
286  m_primaries_locked = 2;
287  }
288  else {
289  if (m_primaries_locked)
290  m_primaries_locked = 2;
291  }
292 
293  if (Ships[get_ship_from_obj(objp)].flags2 & SF2_SECONDARIES_LOCKED){
294  if (!m_secondaries_locked)
295  m_secondaries_locked = 2;
296  }
297  else {
298  if (m_secondaries_locked)
299  m_secondaries_locked = 2;
300  }
301 
302  if (Ships[get_ship_from_obj(objp)].flags2 & SF2_LOCK_ALL_TURRETS_INITIALLY){
303  if (!m_turrets_locked)
304  m_turrets_locked = 2;
305  }
306  else {
307  if (m_turrets_locked)
308  m_turrets_locked = 2;
309  }
310 
311  if (Ships[get_ship_from_obj(objp)].flags2 & SF2_AFTERBURNER_LOCKED){
312  if (!m_afterburner_locked)
313  m_afterburner_locked = 2;
314  }
315  else {
316  if (m_afterburner_locked)
317  m_afterburner_locked = 2;
318  }
319  }
320 
321  objp = GET_NEXT(objp);
322  }
323  }
324 
325  CDialog::OnInitDialog();
326  str.Format("%d", m_velocity);
327  GetDlgItem(IDC_VELOCITY)->SetWindowText(str);
328  str.Format("%d", m_shields);
329  GetDlgItem(IDC_SHIELDS)->SetWindowText(str);
330  str.Format("%d", m_hull);
331  GetDlgItem(IDC_HULL)->SetWindowText(str);
332 
333  inited = 1;
334 
335  GetDlgItem(IDC_SHIELDS)->EnableWindow(m_has_shields ? TRUE : FALSE);
336  GetDlgItem(IDC_SHIELDS_SPIN)->EnableWindow(m_has_shields ? TRUE : FALSE);
337 
338  m_velocity_spin.SetRange(0, 100);
339  m_hull_spin.SetRange(0, 100);
340  m_shields_spin.SetRange(0, 100);
341  m_damage_spin.SetRange(0, 100);
342 
343  // init boxes
344  lstDockerPoints = (CListBox *) GetDlgItem(IDC_DOCKER_POINT);
345  cboDockees = (CComboBox *) GetDlgItem(IDC_DOCKEE);
346  cboDockeePoints = (CComboBox *) GetDlgItem(IDC_DOCKEE_POINT);
347  lstDockerPoints->ResetContent();
348  cboDockees->ResetContent();
349  cboDockeePoints->ResetContent();
350 
351  if (!m_multi_edit)
352  {
353  for (int dockpoint = 0; dockpoint < num_dock_points; dockpoint++)
354  {
355  z = lstDockerPoints->AddString(model_get_dock_name(Ship_info[Ships[m_ship].ship_info_index].model_num, dockpoint));
356  lstDockerPoints->SetItemData(z, dockpoint);
357  }
358 
359  for (ptr = GET_FIRST(&Ships[m_ship].subsys_list); ptr != END_OF_LIST(&Ships[m_ship].subsys_list); ptr = GET_NEXT(ptr))
360  {
361  ((CListBox *) GetDlgItem(IDC_SUBSYS))->AddString(ptr->system_info->subobj_name);
362  }
363  }
364  else
365  {
366  GetDlgItem(IDC_SUBSYS)->EnableWindow(FALSE);
367  GetDlgItem(IDC_DAMAGE)->EnableWindow(FALSE);
368  }
369  change_docker_point(false);
370  change_subsys();
371 
372  UpdateData(FALSE);
373 
374  if (vflag)
375  GetDlgItem(IDC_VELOCITY)->SetWindowText("");
376  if (sflag)
377  GetDlgItem(IDC_SHIELDS)->SetWindowText("");
378  if (hflag)
379  GetDlgItem(IDC_HULL)->SetWindowText("");
380 
381  if (objp != NULL) {
382  if (objp->type == OBJ_SHIP || objp->type == OBJ_START) {
383  ship* shipp = &Ships[objp->instance];
384  int i = 0;
385 
386  if (Ship_info[shipp->ship_info_index].uses_team_colors) {
387  //Add a "None" entry at the beginning to allow simple deselection of colours
388  int t = m_team_color_setting.AddString("None");
389  m_team_color_setting.SetItemData(t, i);
390  ++i;
391 
392  for (SCP_vector<SCP_string>::iterator tni = Team_Names.begin(); tni != Team_Names.end(); ++tni) {
393  int z = m_team_color_setting.AddString(tni->c_str());
394  if (!stricmp(tni->c_str(), shipp->team_name.c_str())) {
395  m_team_color_setting.SetCurSel(i);
396  }
397  m_team_color_setting.SetItemData(z, i);
398  i++;
399 
400  }
401  m_team_color_setting.EnableWindow();
402  } else {
403  m_team_color_setting.EnableWindow(FALSE);
404  }
405  }
406  }
407 
408  return TRUE;
409 }
410 
412 {
413  char buf[256];
414  int vflag = 0, sflag = 0, hflag = 0;
415  object *objp;
416 
417  if (GetDlgItem(IDC_VELOCITY)->GetWindowText(buf, 255))
418  vflag = 1;
419  if (GetDlgItem(IDC_SHIELDS)->GetWindowText(buf, 255))
420  sflag = 1;
421  if (GetDlgItem(IDC_HULL)->GetWindowText(buf, 255))
422  hflag = 1;
423 
424  UpdateData(TRUE);
425 
426  change_subsys();
427 
428  if (m_multi_edit) {
429  objp = GET_FIRST(&obj_used_list);
430  while (objp != END_OF_LIST(&obj_used_list)) {
431  if (((objp->type == OBJ_SHIP) || (objp->type == OBJ_START)) && (objp->flags & OF_MARKED)) {
432  if (vflag)
433  MODIFY(objp->phys_info.speed, (float) m_velocity);
434 
435  if (sflag)
436  MODIFY(objp->shield_quadrant[0], (float) m_shields);
437 
438  if (hflag)
439  MODIFY(objp->hull_strength, (float) m_hull);
440 
441  if (m_has_shields == 1)
442  objp->flags &= ~OF_NO_SHIELDS;
443  else if (!m_has_shields)
444  objp->flags |= OF_NO_SHIELDS;
445 
446  if (m_force_shields == 1) {
448  }
449  else if (!m_force_shields) {
451  }
452 
453  if (m_ship_locked == 1)
455  else if (!m_ship_locked)
457 
458  if (m_weapons_locked == 1)
460  else if (!m_weapons_locked)
462 
463  if (m_primaries_locked == 1) {
465  }
466  else if (!m_primaries_locked) {
468  }
469 
470  if (m_secondaries_locked == 1) {
472  }
473  else if (!m_secondaries_locked) {
475  }
476 
477  if (m_turrets_locked == 1) {
479  }
480  else if (!m_turrets_locked) {
482  }
483 
484  if (m_afterburner_locked == 1) {
486  }
487  else if (!m_afterburner_locked) {
489  }
490  }
491 
492  objp = GET_NEXT(objp);
493  }
494 
495  } else {
496  MODIFY(Objects[cur_object_index].phys_info.speed, (float) m_velocity);
497  MODIFY(Objects[cur_object_index].shield_quadrant[0], (float) m_shields);
498  MODIFY(Objects[cur_object_index].hull_strength, (float) m_hull);
499  if (m_has_shields)
501  else
503 
504  if (m_force_shields == 1)
506  else if (!m_force_shields)
508 
509  if (m_ship_locked == 1)
511  else if (!m_ship_locked)
513 
514  if (m_weapons_locked == 1)
516  else if (!m_weapons_locked)
518 
519  if (m_primaries_locked == 1)
521  else if (!m_primaries_locked)
523 
524  if (m_secondaries_locked == 1)
526  else if (!m_secondaries_locked)
528 
529  if (m_turrets_locked == 1)
531  else if (!m_turrets_locked)
533 
534  if (m_afterburner_locked == 1)
536  else if (!m_afterburner_locked)
538  }
539 
540  if (m_team_color_setting.IsWindowEnabled() && m_team_color_setting.GetCurSel() > 0)
541  Ships[m_ship].team_name = Team_Names[m_team_color_setting.GetCurSel() - 1];
542  else
543  Ships[m_ship].team_name = "none";
544 
545  update_docking_info();
546 
547  CDialog::OnOK();
548 }
549 
551 {
552  if (m_has_shields == 1) {
553  m_has_shields = 0;
554 
555  // can't force shields and also have them off
556  if (m_force_shields) {
557  m_force_shields = 0;
558  ((CButton *) GetDlgItem(IDC_FORCE_SHIELDS))->SetCheck(m_force_shields);
559 
560  // warn on multiple ships of different state
561  if (m_multi_edit) {
562  MessageBox("At least one selected ship was set to Force Shields On. This is now turned off for all selected ships", "Resetting Flag", MB_OK | MB_ICONEXCLAMATION);
563  }
564  }
565  }
566  else
567  m_has_shields = 1;
568 
569  ((CButton *) GetDlgItem(IDC_HAS_SHIELDS))->SetCheck(m_has_shields);
570  GetDlgItem(IDC_SHIELDS)->EnableWindow(m_has_shields);
571  GetDlgItem(IDC_SHIELDS_SPIN)->EnableWindow(m_has_shields);
572 }
573 
575 {
576  if (m_force_shields == 1)
577  m_force_shields = 0;
578  else {
579  m_force_shields = 1;
580 
581  // can't force shields and also turn have them off
582  if (m_has_shields != 1) {
583  m_has_shields = 1;
584  ((CButton *) GetDlgItem(IDC_HAS_SHIELDS))->SetCheck(m_has_shields);
585  GetDlgItem(IDC_SHIELDS)->EnableWindow(m_has_shields);
586  GetDlgItem(IDC_SHIELDS_SPIN)->EnableWindow(m_has_shields);
587 
588  // warn on multiple ships of different state
589  if (m_multi_edit) {
590  MessageBox("At least one selected ship was set to have no shields. Shields are now enabled for all selected ships", "Resetting Flag", MB_OK | MB_ICONEXCLAMATION);
591  }
592  }
593  }
594 
595  ((CButton *) GetDlgItem(IDC_FORCE_SHIELDS))->SetCheck(m_force_shields);
596 }
597 
599 {
600  if (m_ship_locked == 1)
601  m_ship_locked = 0;
602  else
603  m_ship_locked = 1;
604 
605  ((CButton *) GetDlgItem(IDC_SHIP_LOCKED))->SetCheck(m_ship_locked);
606 }
607 
609 {
610  if (m_weapons_locked == 1)
611  m_weapons_locked = 0;
612  else
613  m_weapons_locked = 1;
614 
615  ((CButton *) GetDlgItem(IDC_WEAPONS_LOCKED))->SetCheck(m_weapons_locked);
616 }
617 
619 {
620  UpdateData(TRUE);
621  change_subsys();
622  UpdateData(FALSE);
623 }
624 
626 {
627  int z, cargo_index, enable = FALSE, enable_cargo_name = FALSE;
628  int ship_has_scannable_subsystems;
629  ship_subsys *ptr;
630 
631  // Goober5000
632  ship_has_scannable_subsystems = (Ship_info[Ships[m_ship].ship_info_index].flags & SIF_HUGE_SHIP);
634  ship_has_scannable_subsystems = !ship_has_scannable_subsystems;
635 
636  if (cur_subsys != LB_ERR) {
637  ptr = GET_FIRST(&Ships[m_ship].subsys_list);
638  while (cur_subsys--) {
639  Assert(ptr != END_OF_LIST(&Ships[m_ship].subsys_list));
640  ptr = GET_NEXT(ptr);
641  }
642 
643  MODIFY(ptr -> current_hits, 100.0f - (float) m_damage);
644 
645  // update cargo name
646  if (strlen(m_cargo_name) > 0) { //-V805
648  if (cargo_index == -1) {
649  if (Num_cargo < MAX_CARGO);
650  cargo_index = Num_cargo++;
651  strcpy(Cargo_names[cargo_index], m_cargo_name);
652  ptr->subsys_cargo_name = cargo_index;
653  } else {
654  ptr->subsys_cargo_name = cargo_index;
655  }
656  } else {
657  ptr->subsys_cargo_name = 0;
658  }
659  set_modified();
660  }
661 
662  cur_subsys = z = ((CListBox *) GetDlgItem(IDC_SUBSYS)) -> GetCurSel();
663  if (z == LB_ERR) {
664  m_damage = 100;
665 
666  } else {
667  ptr = GET_FIRST(&Ships[m_ship].subsys_list);
668  while (z--) {
669  Assert(ptr != END_OF_LIST(&Ships[m_ship].subsys_list));
670  ptr = GET_NEXT(ptr);
671  }
672 
673  m_damage = 100 - (int) ptr -> current_hits;
674  if ( ship_has_scannable_subsystems && valid_cap_subsys_cargo_list(ptr->system_info->subobj_name) ) {
675  enable_cargo_name = TRUE;
676  if (ptr->subsys_cargo_name > 0) {
678  } else {
679  m_cargo_name = _T("");
680  }
681  } else {
682  m_cargo_name = _T("");
683  }
684  enable = TRUE;
685  }
686 
687  GetDlgItem(IDC_DAMAGE) -> EnableWindow(enable);
688  GetDlgItem(IDC_DAMAGE_SPIN) -> EnableWindow(enable);
689  GetDlgItem(IDC_CARGO_NAME)->EnableWindow(enable && enable_cargo_name);
690 }
691 
693 {
694  change_docker_point(true);
695 }
696 
697 void initial_status::change_docker_point(bool store_selection)
698 {
699  int sel;
700 
701  // grab from controls
702  UpdateData(TRUE);
703 
704  // get new selection
705  sel = lstDockerPoints->GetCurSel();
706  if (sel != LB_ERR)
707  cur_docker_point = lstDockerPoints->GetItemData(sel);
708  else
709  cur_docker_point = -1;
710 
711  // populate the next dropdowns
712  if (cur_docker_point < 0)
713  {
714  // clear the dropdowns
715  list_dockees(-1);
716  list_dockee_points(-1);
717  }
718  else
719  {
720  // populate with all possible dockees
721  list_dockees(model_get_dock_index_type(Ship_info[Ships[m_ship].ship_info_index].model_num, cur_docker_point));
722 
723  // see if there's a dockee here
724  if (dockpoint_array[cur_docker_point].dockee_shipnum >= 0)
725  {
726  // select the dockee
727  cboDockees->SelectString(-1, Ships[dockpoint_array[cur_docker_point].dockee_shipnum].ship_name);
728  change_dockee(false);
729  }
730  else
731  {
732  // select "Nothing"
733  cboDockees->SetCurSel(0);
734  change_dockee(true);
735  }
736  }
737 
738  // store to controls
739  UpdateData(FALSE);
740 }
741 
743 {
744  change_dockee(true);
745 }
746 
747 void initial_status::change_dockee(bool store_selection)
748 {
749  int sel;
750 
751  // grab from controls
752  UpdateData(TRUE);
753 
754  // get new selection
755  sel = cboDockees->GetCurSel();
756  if (sel != CB_ERR)
757  cur_dockee = cboDockees->GetItemData(sel);
758  else
759  cur_dockee = -1;
760 
761  // are we storing it?
762  if (store_selection)
763  {
764  dockpoint_array[cur_docker_point].dockee_shipnum = cur_dockee;
765  dockpoint_array[cur_docker_point].dockee_point = -1;
766  }
767 
768  // populate the next dropdown
769  if (cur_dockee < 0)
770  {
771  // clear the dropdown
772  list_dockee_points(-1);
773  }
774  else
775  {
776  // populate with dockee points
777  list_dockee_points(cur_dockee);
778 
779  // see if there's a dockpoint here
780  if (dockpoint_array[cur_docker_point].dockee_point >= 0)
781  {
782  // select the dockpoint
783  cboDockeePoints->SelectString(-1, model_get_dock_name(Ship_info[Ships[cur_dockee].ship_info_index].model_num, dockpoint_array[cur_docker_point].dockee_point));
784  change_dockee_point(false);
785  }
786  // there might not be any dockpoints available
787  else if (cboDockeePoints->GetCount() == 0)
788  {
789  cboDockeePoints->EnableWindow(FALSE);
790  change_dockee_point(false);
791  }
792  else
793  {
794  // just select the first dockpoint
795  cboDockeePoints->SetCurSel(0);
796  change_dockee_point(true);
797  }
798  }
799 
800  // store to controls
801  UpdateData(FALSE);
802 }
803 
805 {
806  change_dockee_point(true);
807 }
808 
809 void initial_status::change_dockee_point(bool store_selection)
810 {
811  int sel;
812 
813  // grab from controls
814  UpdateData(TRUE);
815 
816  // get new value
817  sel = cboDockeePoints->GetCurSel();
818  if (sel != CB_ERR)
819  cur_dockee_point = cboDockeePoints->GetItemData(sel);
820  else
821  cur_dockee_point = -1;
822 
823  // are we storing it?
824  if (store_selection)
825  {
826  dockpoint_array[cur_docker_point].dockee_point = cur_dockee_point;
827  }
828 
829  // store to controls
830  UpdateData(FALSE);
831 }
832 
833 void initial_status::list_dockees(int dock_types)
834 {
835  int z;
836 
837  // enable/disable dropdown
838  cboDockees->EnableWindow((dock_types >= 0) ? TRUE : FALSE);
839 
840  // clear the existing dockees
841  cboDockees->ResetContent();
842 
843  // that might be all we need to do
844  if (dock_types < 0)
845  return;
846 
847  // populate with potential dockees
848 
849  // add "nothing"
850  z = cboDockees->AddString("Nothing");
851  cboDockees->SetItemData(z, static_cast<DWORD_PTR>(-1));
852 
853  // add ships
855  {
856  if ((objp->type == OBJ_SHIP) || (objp->type == OBJ_START))
857  {
858  int ship = get_ship_from_obj(objp);
859 
860  // mustn't be the same ship
861  if (ship == m_ship)
862  continue;
863 
864  // mustn't also be docked elsewhere
865  bool docked_elsewhere = false;
866  for (int i = 0; i < num_dock_points; i++)
867  {
868  // don't erroneously check the same point
869  if (i == cur_docker_point)
870  continue;
871 
872  // see if this ship is also on a different dockpoint
873  if (dockpoint_array[i].dockee_shipnum == ship)
874  {
875  docked_elsewhere = true;
876  break;
877  }
878  }
879 
880  if (docked_elsewhere)
881  continue;
882 
883  // docking must be valid
884  if (!ship_docking_valid(m_ship, ship) && !ship_docking_valid(ship, m_ship))
885  continue;
886 
887  // dock types must match
888  if (!(model_get_dock_types(Ship_info[Ships[ship].ship_info_index].model_num) & dock_types))
889  continue;
890 
891  // add to list
892  z = cboDockees->AddString(Ships[ship].ship_name);
893  cboDockees->SetItemData(z, ship);
894  }
895  }
896 }
897 
898 void initial_status::list_dockee_points(int shipnum)
899 {
900  int z;
901  ship *shipp = &Ships[m_ship];
902  ship *other_shipp = &Ships[shipnum];
903 
904  // enable/disable dropdown
905  cboDockeePoints->EnableWindow((shipnum >= 0) ? TRUE : FALSE);
906 
907  // clear the existing dockee points
908  cboDockeePoints->ResetContent();
909 
910  // that might be all we need to do
911  if (shipnum < 0)
912  return;
913 
914  // get the required dock type(s)
915  int dock_type = model_get_dock_index_type(Ship_info[shipp->ship_info_index].model_num, cur_docker_point);
916 
917  // populate with the right kind of dockee points
918  for (int i = 0; i < model_get_num_dock_points(Ship_info[other_shipp->ship_info_index].model_num); i++)
919  {
920  // make sure this dockpoint is not occupied by someone else
921  object *docked_objp = dock_find_object_at_dockpoint(&Objects[other_shipp->objnum], i);
922  if ((docked_objp != NULL) && (docked_objp != &Objects[shipp->objnum]))
923  continue;
924 
925  // make sure its type matches
926  if (!(model_get_dock_index_type(Ship_info[other_shipp->ship_info_index].model_num, i) & dock_type))
927  continue;
928 
929  // add to list
930  z = cboDockeePoints->AddString(model_get_dock_name(Ship_info[other_shipp->ship_info_index].model_num, i));
931  cboDockeePoints->SetItemData(z, i);
932  }
933 }
934 
935 void initial_status::update_docking_info()
936 {
937  int i;
938  object *objp = &Objects[Ships[m_ship].objnum];
939 
940  // remove old info
941  for (i = 0; i < num_dock_points; i++)
942  {
943  // see if the object at this point is no longer there
944  object *dockee_objp = dock_find_object_at_dockpoint(objp, i);
945  if (dockee_objp != NULL)
946  {
947  // check if the dockee ship thinks that this ship is docked to this dock point
948  if (objp != dock_find_object_at_dockpoint(dockee_objp, dockpoint_array[i].dockee_point) ) {
949  // undock it
950  undock(objp, dockee_objp);
951  }
952  }
953  }
954 
955  // add new info
956  for (i = 0; i < num_dock_points; i++)
957  {
958  // see if there is an object at this point that wasn't there before
959  if (dockpoint_array[i].dockee_shipnum >= 0)
960  {
961  if (dock_find_object_at_dockpoint(objp, i) == NULL)
962  {
963  object *dockee_objp = &Objects[Ships[dockpoint_array[i].dockee_shipnum].objnum];
964  int dockee_point = dockpoint_array[i].dockee_point;
965 
966  // dock it
967  dock(objp, i, dockee_objp, dockee_point);
968  }
969  }
970  }
971 
973 }
974 
975 void initial_status::dock(object *objp, int dockpoint, object *other_objp, int other_dockpoint)
976 {
977  if (objp == NULL || other_objp == NULL)
978  return;
979 
980  if (dockpoint < 0 || other_dockpoint < 0)
981  return;
982 
983  dock_function_info dfi;
984 
985  // do the docking (do it in reverse so that the current object stays put)
986  ai_dock_with_object(other_objp, other_dockpoint, objp, dockpoint, AIDO_DOCK_NOW);
987 
988  // unmark the handled flag in preparation for the next step
990 
991  // move all other objects to catch up with it
993 
994  // set the dock leader
996 
997  // if no leader, mark me
998  if (dfi.maintained_variables.int_value == 0)
999  Ships[objp->instance].flags |= SF_DOCK_LEADER;
1000 }
1001 
1002 void initial_status::undock(object *objp1, object *objp2)
1003 {
1004  vec3d v;
1005  int ship_num, other_ship_num;
1006 
1007  if (objp1 == NULL || objp2 == NULL)
1008  return;
1009 
1010  vm_vec_sub(&v, &objp2->pos, &objp1->pos);
1011  vm_vec_normalize(&v);
1012  ship_num = get_ship_from_obj(OBJ_INDEX(objp1));
1013  other_ship_num = get_ship_from_obj(OBJ_INDEX(objp2));
1014 
1015  if (ship_class_compare(Ships[ship_num].ship_info_index, Ships[other_ship_num].ship_info_index) <= 0)
1016  vm_vec_scale_add2(&objp2->pos, &v, objp2->radius * 2.0f);
1017  else
1018  vm_vec_scale_add2(&objp1->pos, &v, objp1->radius * -2.0f);
1019 
1020  ai_do_objects_undocked_stuff(objp1, objp2);
1021 
1022  // check to see if one of these ships has an arrival cue of false. If so, then
1023  // reset it back to default value of true. be sure to correctly update before
1024  // and after setting data.
1025  // Goober5000 - but don't reset it if it's part of a wing!
1027 
1028  if ( Ships[ship_num].arrival_cue == Locked_sexp_false && Ships[ship_num].wingnum < 0 ) {
1029  Ships[ship_num].arrival_cue = Locked_sexp_true;
1030  } else if ( Ships[other_ship_num].arrival_cue == Locked_sexp_false && Ships[other_ship_num].wingnum < 0 ) {
1031  Ships[other_ship_num].arrival_cue = Locked_sexp_true;
1032  }
1033 
1034  // if this ship is no longer docked, ensure its dock leader flag is clear
1035  if (!object_is_docked(&Objects[Ships[ship_num].objnum]))
1036  Ships[ship_num].flags &= ~SF_DOCK_LEADER;
1037 
1038  // same for the other ship
1039  if (!object_is_docked(&Objects[Ships[other_ship_num].objnum]))
1040  Ships[other_ship_num].flags &= ~SF_DOCK_LEADER;
1041 
1043 }
1044 
1045 // ----- the following are not contained in the class because of apparent scope issues -----
1046 
1047 bool set_cue_to_false(int *cue)
1048 {
1049  // if the cue is not false, make it false. Be sure to set all ship editor dialog functions
1050  // to update data before and after we modify the cue.
1051  if (*cue != Locked_sexp_false)
1052  {
1055 
1056  free_sexp2(*cue);
1057  *cue = Locked_sexp_false;
1058 
1061 
1062  return true;
1063  }
1064  else
1065  return false;
1066 }
1067 
1068 // function to set the arrival cue of a ship to false
1069 void reset_arrival_to_false(int shipnum, bool reset_wing)
1070 {
1071  char buf[256];
1072  ship *shipp = &Ships[shipnum];
1073 
1074  // falsify the ship cue
1075  if (set_cue_to_false(&shipp->arrival_cue))
1076  {
1077  sprintf(buf, "Setting arrival cue of ship %s\nto false for initial docking purposes.", shipp->ship_name);
1078  MessageBox(NULL, buf, "", MB_OK | MB_ICONEXCLAMATION);
1079  }
1080 
1081  // falsify the wing cue and all ships in that wing
1082  if (reset_wing && shipp->wingnum >= 0)
1083  {
1084  int i;
1085  wing *wingp = &Wings[shipp->wingnum];
1086 
1087  if (set_cue_to_false(&wingp->arrival_cue))
1088  {
1089  sprintf(buf, "Setting arrival cue of wing %s\nto false for initial docking purposes.", wingp->name);
1090  MessageBox(NULL, buf, "", MB_OK | MB_ICONEXCLAMATION);
1091  }
1092 
1093  for (i = 0; i < wingp->wave_count; i++)
1094  reset_arrival_to_false(wingp->ship_index[i], false);
1095  }
1096 }
1097 
1098 // NOTE - in both retail and SCP, the dock "leader" is defined as the only guy in his
1099 // group with a non-false arrival cue
1101 {
1102  ship *shipp = &Ships[objp->instance];
1103  int cue_to_check;
1104 
1105  // if this guy is part of a wing, he uses his wing's arrival cue
1106  if (shipp->wingnum >= 0)
1107  {
1108  cue_to_check = Wings[shipp->wingnum].arrival_cue;
1109  }
1110  // check the ship's arrival cue
1111  else
1112  {
1113  cue_to_check = shipp->arrival_cue;
1114  }
1115 
1116  // all ships except the leader should have a locked false arrival cue
1117  if (cue_to_check != Locked_sexp_false)
1118  {
1119  object *existing_leader;
1120 
1121  // increment number of leaders found
1123 
1124  // see if we already found a leader
1125  existing_leader = infop->maintained_variables.objp_value;
1126  if (existing_leader != NULL)
1127  {
1128  ship *leader_shipp = &Ships[existing_leader->instance];
1129 
1130  // keep existing leader if he has a higher priority than us
1131  if (ship_class_compare(shipp->ship_info_index, leader_shipp->ship_info_index) >= 0)
1132  {
1133  // set my arrival cue to false
1134  reset_arrival_to_false(SHIP_INDEX(shipp), true);
1135  return;
1136  }
1137 
1138  // otherwise, unmark the existing leader and set his arrival cue to false
1139  leader_shipp->flags &= ~SF_DOCK_LEADER;
1140  reset_arrival_to_false(SHIP_INDEX(leader_shipp), true);
1141  }
1142 
1143  // mark and save me as the leader
1144  shipp->flags |= SF_DOCK_LEADER;
1146  }
1147 }
1148 
1149 // self-explanatory, really
1151 {
1152  objp->flags &= ~OF_DOCKED_ALREADY_HANDLED;
1153 }
1154 
1156 {
1157  if (m_primaries_locked == 1)
1158  m_primaries_locked = 0;
1159  else
1160  m_primaries_locked = 1;
1161 
1162  ((CButton *) GetDlgItem(IDC_PRIMARIES_LOCKED))->SetCheck(m_primaries_locked);
1163 }
1164 
1166 {
1167  if (m_secondaries_locked == 1)
1169  else
1171 
1172  ((CButton *) GetDlgItem(IDC_SECONDARIES_LOCKED))->SetCheck(m_secondaries_locked);
1173 }
1174 
1176 {
1177  if (m_turrets_locked == 1)
1178  m_turrets_locked = 0;
1179  else
1180  m_turrets_locked = 1;
1181 
1182  ((CButton *) GetDlgItem(IDC_TURRETS_LOCKED))->SetCheck(m_turrets_locked);
1183 }
1184 
1186 {
1187  if (m_afterburner_locked == 1)
1189  else
1191 
1192  ((CButton *) GetDlgItem(IDC_AFTERBURNER_LOCKED))->SetCheck(m_afterburner_locked);
1193 }
#define SF2_TOGGLE_SUBSYSTEM_SCANNING
Definition: ship.h:490
#define SF2_WEAPONS_LOCKED
Definition: ship.h:507
#define AIDO_DOCK_NOW
Definition: ai.h:82
wing Wings[MAX_WINGS]
Definition: ship.cpp:128
#define IDC_PRIMARIES_LOCKED
Definition: resource.h:1121
int i
Definition: multi_pxo.cpp:466
model_subsystem * system_info
Definition: ship.h:314
int Locked_sexp_false
Definition: sexp.cpp:828
int m_secondaries_locked
Definition: initialstatus.h:58
int objnum
Definition: ship.h:537
afx_msg void OnSecondariesLocked()
CShipEditorDlg Ship_editor_dialog
Definition: fred.cpp:55
#define IDC_VELOCITY_SPIN
Definition: resource.h:828
char * model_get_dock_name(int modelnum, int index)
Definition: modelread.cpp:5103
physics_info phys_info
Definition: object.h:157
int model_get_dock_index_type(int modelnum, int index)
Definition: modelread.cpp:5120
#define SF2_FORCE_SHIELDS_ON
Definition: ship.h:502
#define SF_DOCK_LEADER
Definition: ship.h:455
void dock(object *objp1, int dockpoint1, object *objp2, int dockpoint2)
Assert(pm!=NULL)
Definition: pstypes.h:88
afx_msg void OnTurretsLocked()
int update_data(int redraw=1)
#define IDC_TURRETS_LOCKED
Definition: resource.h:1150
GLclampf f
Definition: Glext.h:7097
object * dock_find_object_at_dockpoint(object *objp, int dockpoint)
Definition: objectdock.cpp:106
#define TRUE
Definition: pstypes.h:399
#define SHIP_INDEX(shipp)
Definition: ship.h:1602
#define OF_NO_SHIELDS
Definition: object.h:110
int Num_cargo
#define IDC_SHIELDS
Definition: resource.h:816
int dock_find_dockpoint_used_by_object(object *objp, object *other_objp)
Definition: objectdock.cpp:116
object obj_used_list
Definition: object.cpp:53
Definition: ship.h:1516
void vm_vec_scale_add2(vec3d *dest, const vec3d *src, float k)
Definition: vecmat.cpp:284
uint flags
Definition: ship.h:644
int model_get_num_dock_points(int modelnum)
Definition: modelread.cpp:5112
char dockee_point[NAME_LENGTH]
void dock_move_docked_objects(object *objp)
Definition: objectdock.cpp:371
object * objp
Definition: lua.cpp:3105
ship * shipp
Definition: lua.cpp:9162
vec3d pos
Definition: object.h:152
#define MODIFY(a, b)
Definition: fred.h:26
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: Glext.h:7308
GLenum type
Definition: Gl.h:1492
#define IDC_HULL_SPIN
Definition: resource.h:830
void change_docker_point(bool store_selection)
#define IDC_HULL
Definition: resource.h:831
int valid_cap_subsys_cargo_list(char *subsys)
Definition: ship.cpp:16984
#define IDC_WEAPONS_LOCKED
Definition: resource.h:923
#define IDC_CARGO_NAME
Definition: resource.h:995
int object_is_docked(object *objp)
Definition: object.cpp:2019
int Locked_sexp_true
Definition: sexp.cpp:828
typedef int(SCP_EXT_CALLCONV *SCPDLL_PFVERSION)(SCPDLL_Version *)
int instance
Definition: object.h:150
afx_msg void OnAfterburnersLocked()
#define OBJ_START
Definition: object.h:35
int update_data(int redraw=1)
void reset_arrival_to_false(int shipnum, bool reset_wing)
char name[NAME_LENGTH]
Definition: ship.h:1517
afx_msg void OnForceShields()
int wingnum
Definition: ship.h:623
void ai_dock_with_object(object *docker, int docker_index, object *dockee, int dockee_index, int dock_type)
Definition: aicode.cpp:3098
float speed
Definition: physics.h:79
CString m_cargo_name
Definition: initialstatus.h:56
#define IDC_SHIELDS_SPIN
Definition: resource.h:827
CSpinButtonCtrl m_velocity_spin
Definition: initialstatus.h:45
float hull_strength
Definition: object.h:160
sprintf(buf,"(%f,%f,%f)", v3->xyz.x, v3->xyz.y, v3->xyz.z)
#define MAX_CARGO
Definition: missionparse.h:222
GLdouble GLdouble z
Definition: Glext.h:5451
int free_sexp2(int num)
Definition: sexp.cpp:1321
#define IDC_FORCE_SHIELDS
Definition: resource.h:1152
#define MB_OK
Definition: config.h:179
#define IDC_SHIP_LOCKED
Definition: resource.h:922
CSpinButtonCtrl m_damage_spin
Definition: initialstatus.h:47
void initialize_data(int full)
#define IDC_DOCKEE_POINT
Definition: resource.h:587
int subsys_cargo_name
Definition: ship.h:373
void initial_status_mark_dock_leader_helper(object *objp, dock_function_info *infop)
Definition: ship.h:534
void undock(object *objp1, object *objp2)
int ship_class_compare(int ship_class_1, int ship_class_2)
Definition: ship.cpp:17715
GLdouble GLdouble t
Definition: Glext.h:5329
afx_msg void OnShipLocked()
int wave_count
Definition: ship.h:1527
object Objects[MAX_OBJECTS]
Definition: object.cpp:62
#define IDC_DAMAGE
Definition: resource.h:823
int model_get_dock_types(int modelnum)
Definition: modelread.cpp:5128
#define OBJ_INDEX(objp)
Definition: object.h:235
#define OF_MARKED
Definition: object.h:125
SCP_string team_name
Definition: ship.h:812
int inited
Definition: fredrender.cpp:76
#define OBJ_SHIP
Definition: object.h:32
wing_editor Wing_editor_dialog
Definition: fred.cpp:56
GLbitfield flags
Definition: Glext.h:6722
#define SIF_HUGE_SHIP
Definition: ship.h:945
void set_modified(BOOL arg)
Definition: freddoc.cpp:676
void vm_vec_sub(vec3d *dest, const vec3d *src0, const vec3d *src1)
Definition: vecmat.cpp:168
GLboolean enable
Definition: Glext.h:10591
int BOOL
Definition: config.h:80
#define SF2_PRIMARIES_LOCKED
Definition: ship.h:492
ship Ships[MAX_SHIPS]
Definition: ship.cpp:122
int string_lookup(const CString &str1, char *strlist[], int max)
afx_msg void OnSelchangeDockerPoint()
virtual void DoDataExchange(CDataExchange *pDX)
#define MB_ICONEXCLAMATION
Definition: config.h:184
afx_msg void OnHasShields()
int arrival_cue
Definition: ship.h:1543
afx_msg void OnWeaponsLocked()
int ship_docking_valid(int docker, int dockee)
Definition: ship.cpp:14494
#define IDC_SECONDARIES_LOCKED
Definition: resource.h:1123
SCP_vector< SCP_string > Team_Names
Definition: alphacolors.cpp:16
#define SF2_LOCK_ALL_TURRETS_INITIALLY
Definition: ship.h:501
#define IDC_DAMAGE_SPIN
Definition: resource.h:825
#define IDC_TEAMSELECT
Definition: resource.h:646
struct dock_function_info::@258 maintained_variables
#define SF2_SHIP_LOCKED
Definition: ship.h:506
object * objp_value
Definition: objectdock.h:38
int cur_ship
Definition: management.cpp:80
char subobj_name[MAX_NAME_LEN]
Definition: model.h:172
void dock_evaluate_all_docked_objects(object *objp, dock_function_info *infop, void(*function)(object *, dock_function_info *))
Definition: objectdock.cpp:285
int ship_info_index
Definition: ship.h:539
afx_msg void OnPrimariesLocked()
SCP_vector< ship_info > Ship_info
Definition: ship.cpp:164
void ai_do_objects_undocked_stuff(object *docker, object *dockee)
Definition: aicode.cpp:3054
int MessageBox(HWND h, const char *s1, const char *s2, int i)
#define SF2_AFTERBURNER_LOCKED
Definition: ship.h:499
SCP_vector< float > shield_quadrant
Definition: object.h:159
#define IDC_DOCKEE
Definition: resource.h:822
#define IDC_HAS_SHIELDS
Definition: resource.h:888
CSpinButtonCtrl m_shields_spin
Definition: initialstatus.h:46
bool set_cue_to_false(int *cue)
void change_dockee_point(bool store_selection)
afx_msg void OnSelchangeDockeePoint()
uint flags2
Definition: ship.h:645
#define IDC_SUBSYS
Definition: resource.h:805
#define IDC_DOCKER_POINT
Definition: resource.h:522
int cur_object_index
Definition: management.cpp:79
int ship_index[MAX_SHIPS_PER_WING]
Definition: ship.h:1531
afx_msg void OnSelchangeSubsys()
void change_dockee(bool store_selection)
int arrival_cue
Definition: ship.h:614
uint flags
Definition: object.h:151
int get_ship_from_obj(int obj)
float radius
Definition: object.h:154
void initial_status_unmark_dock_handled_flag(object *objp, dock_function_info *infop)
int model_num
Definition: lua.cpp:4996
char type
Definition: object.h:146
#define FALSE
Definition: pstypes.h:400
#define IDC_AFTERBURNER_LOCKED
Definition: resource.h:1151
#define SF2_SECONDARIES_LOCKED
Definition: ship.h:493
char * Cargo_names[]
#define IDC_VELOCITY
Definition: resource.h:811
int m_afterburner_locked
Definition: initialstatus.h:60
#define stricmp(s1, s2)
Definition: config.h:271
const GLdouble * v
Definition: Glext.h:5322
CComboBox m_team_color_setting
Definition: initialstatus.h:61
afx_msg void OnSelchangeDockee()
char ship_name[NAME_LENGTH]
Definition: ship.h:604
CSpinButtonCtrl m_hull_spin
Definition: initialstatus.h:44
#define OF_DOCKED_ALREADY_HANDLED
Definition: object.h:117
initial_status(CWnd *pParent=NULL)
float vm_vec_normalize(vec3d *v)
Definition: vecmat.cpp:460
void initialize_data(int full)
void update_map_window()
Definition: fred.cpp:532