1 // InitialStatus.cpp : implementation file
7 #include "initialstatus.h"
8 #include "management.h"
14 static char THIS_FILE[] = __FILE__;
17 /////////////////////////////////////////////////////////////////////////////
18 // initial_status dialog
20 initial_status::initial_status(CWnd* pParent /*=NULL*/)
21 : CDialog(initial_status::IDD, pParent)
23 //{{AFX_DATA_INIT(initial_status)
31 m_has_shields = FALSE;
33 m_cargo_name = _T("");
40 void initial_status::DoDataExchange(CDataExchange* pDX)
44 CDialog::DoDataExchange(pDX);
45 //{{AFX_DATA_MAP(initial_status)
46 DDX_Control(pDX, IDC_HULL_SPIN, m_hull_spin);
47 DDX_Control(pDX, IDC_VELOCITY_SPIN, m_velocity_spin);
48 DDX_Control(pDX, IDC_SHIELDS_SPIN, m_shields_spin);
49 DDX_Control(pDX, IDC_DAMAGE_SPIN, m_damage_spin);
50 DDX_Text(pDX, IDC_DAMAGE, m_damage);
51 DDV_MinMaxInt(pDX, m_damage, 0, 100);
52 DDX_CBIndex(pDX, IDC_DOCKED, m_docked);
53 DDX_CBIndex(pDX, IDC_DOCKEE_POINT, m_dockee_point);
54 DDX_CBIndex(pDX, IDC_DOCKER_POINT, m_docker_point);
55 DDX_Check(pDX, IDC_HAS_SHIELDS, m_has_shields);
56 DDX_Check(pDX, IDC_LOCKED, m_locked);
57 DDX_Text(pDX, IDC_CARGO_NAME, m_cargo_name);
58 DDV_MaxChars(pDX, m_cargo_name, 20);
61 if (pDX->m_bSaveAndValidate) {
62 GetDlgItem(IDC_VELOCITY)->GetWindowText(str);
63 m_velocity = atoi(str);
69 GetDlgItem(IDC_SHIELDS)->GetWindowText(str);
70 m_shields = atoi(str);
76 GetDlgItem(IDC_HULL)->GetWindowText(str);
85 BEGIN_MESSAGE_MAP(initial_status, CDialog)
86 //{{AFX_MSG_MAP(initial_status)
87 ON_LBN_SELCHANGE(IDC_SUBSYS, OnSelchangeSubsys)
88 ON_CBN_SELCHANGE(IDC_DOCKED, OnSelchangeDocked)
89 ON_CBN_SELCHANGE(IDC_DOCKER_POINT, OnSelchangeDockerPoint)
90 ON_BN_CLICKED(IDC_HAS_SHIELDS, OnHasShields)
91 ON_BN_CLICKED(IDC_LOCKED, OnLocked)
95 /////////////////////////////////////////////////////////////////////////////
96 // initial_status message handlers
98 BOOL initial_status::OnInitDialog()
100 int z, vflag, sflag, hflag, ship, type;
108 Assert((Objects[cur_object_index].type == OBJ_SHIP) || (Objects[cur_object_index].type == OBJ_START));
109 m_ship = get_ship_from_obj(cur_object_index);
113 vflag = sflag = hflag = 0;
114 m_velocity = (int) Objects[cur_object_index].phys_info.speed;
115 m_shields = (int) Objects[cur_object_index].shields[0];
116 m_hull = (int) Objects[cur_object_index].hull_strength;
117 if (Objects[cur_object_index].flags & OF_NO_SHIELDS)
122 if (Ships[m_ship].flags & SF_LOCKED)
128 objp = GET_FIRST(&obj_used_list);
129 while (objp != END_OF_LIST(&obj_used_list)) {
130 if (((objp->type == OBJ_SHIP) || (objp->type == OBJ_START)) && (objp->flags & OF_MARKED)) {
131 if (objp->phys_info.speed != m_velocity)
133 if ((int) objp->shields[0] != m_shields)
135 if ((int) objp->hull_strength != m_hull)
137 if (objp->flags & OF_NO_SHIELDS) {
146 Assert((objp->type == OBJ_SHIP) || (objp->type == OBJ_START));
147 if (Ships[get_ship_from_obj(objp)].flags & SF_LOCKED) {
157 objp = GET_NEXT(objp);
161 CDialog::OnInitDialog();
162 str.Format("%d", m_velocity);
163 GetDlgItem(IDC_VELOCITY)->SetWindowText(str);
164 str.Format("%d", m_shields);
165 GetDlgItem(IDC_SHIELDS)->SetWindowText(str);
166 str.Format("%d", m_hull);
167 GetDlgItem(IDC_HULL)->SetWindowText(str);
170 box = (CComboBox *) GetDlgItem(IDC_DOCKED);
173 z = box->AddString("Nothing");
176 type = model_get_dock_types(Ships[m_ship].modelnum);
177 objp = GET_FIRST(&obj_used_list);
178 while (objp != END_OF_LIST(&obj_used_list)) {
179 if ((objp->type == OBJ_SHIP) || (objp->type == OBJ_START)) {
180 ship = get_ship_from_obj(objp);
181 if ((ship != m_ship) && (ship_docking_valid(m_ship, ship) || ship_docking_valid(ship, m_ship))) {
182 if (model_get_dock_types(Ships[ship].modelnum) & type) {
183 z = box->AddString(Ships[ship].ship_name);
184 box->SetItemData(z, ship);
189 objp = GET_NEXT(objp);
193 z = Ai_info[Ships[m_ship].ai_index].dock_objnum;
195 Assert(Objects[z].type == OBJ_SHIP);
196 z = m_docked_with = get_ship_from_obj(z);
197 m_docked = box->FindStringExact(-1, Ships[z].ship_name);
199 m_docker_index = Ai_info[Ships[m_ship].ai_index].dock_index;
200 m_dockee_index = Ai_info[Ships[m_ship].ai_index].dockee_index;
201 initialize_docker_points();
202 initialize_dockee_points();
205 m_docker_index = m_dockee_index = m_docker_point = m_dockee_point = -1;
206 GetDlgItem(IDC_DOCKER_POINT)->EnableWindow(FALSE);
207 GetDlgItem(IDC_DOCKEE_POINT)->EnableWindow(FALSE);
210 ptr = GET_FIRST(&Ships[m_ship].subsys_list);
211 while (ptr != END_OF_LIST(&Ships[m_ship].subsys_list)) {
212 ((CListBox *) GetDlgItem(IDC_SUBSYS)) -> AddString(ptr->system_info->subobj_name);
217 GetDlgItem(IDC_DOCKED)->EnableWindow(FALSE);
218 GetDlgItem(IDC_DOCKER_POINT)->EnableWindow(FALSE);
219 GetDlgItem(IDC_DOCKEE_POINT)->EnableWindow(FALSE);
220 GetDlgItem(IDC_SUBSYS)->EnableWindow(FALSE);
221 GetDlgItem(IDC_DAMAGE)->EnableWindow(FALSE);
224 GetDlgItem(IDC_SHIELDS)->EnableWindow(m_has_shields ? TRUE : FALSE);
225 GetDlgItem(IDC_SHIELDS_SPIN)->EnableWindow(m_has_shields ? TRUE : FALSE);
227 m_velocity_spin.SetRange(0, 100);
228 m_hull_spin.SetRange(0, 100);
229 m_shields_spin.SetRange(0, 100);
230 m_damage_spin.SetRange(0, 100);
234 GetDlgItem(IDC_VELOCITY)->SetWindowText("");
236 GetDlgItem(IDC_SHIELDS)->SetWindowText("");
238 GetDlgItem(IDC_HULL)->SetWindowText("");
243 void initial_status::initialize_docker_points()
248 box = (CComboBox *) GetDlgItem(IDC_DOCKER_POINT);
250 if (m_docked_with < 0) {
251 m_docker_index = m_docker_point = -1;
255 type = model_get_dock_types(Ships[m_docked_with].modelnum);
256 set_valid_dock_points(m_ship, type, box);
258 Assert(i); // this shouldn't happen.
260 if ((int) box->GetItemData(i) == m_docker_index)
266 m_docker_index = box->GetItemData(0);
270 void initial_status::initialize_dockee_points()
275 box = (CComboBox *) GetDlgItem(IDC_DOCKEE_POINT);
277 if ((m_docked_with < 0) || (m_docker_index < 0)) {
278 m_dockee_index = m_dockee_point = -1;
282 type = model_get_dock_index_type(Ships[m_ship].modelnum, m_docker_index);
283 set_valid_dock_points(m_docked_with, type, box);
285 Assert(i); // this shouldn't happen.
287 if ((int) box->GetItemData(i) == m_dockee_index)
293 m_dockee_index = box->GetItemData(0);
297 void initial_status::change_subsys()
299 int z, cargo_index, enable = FALSE, enable_cargo_name = FALSE;
302 if (cur_subsys != LB_ERR) {
303 ptr = GET_FIRST(&Ships[m_ship].subsys_list);
304 while (cur_subsys--) {
305 Assert(ptr != END_OF_LIST(&Ships[m_ship].subsys_list));
309 MODIFY(ptr -> current_hits, 100.0f - (float) m_damage);
312 if (strlen(m_cargo_name) > 0) {
313 cargo_index = string_lookup(m_cargo_name, Cargo_names, Num_cargo);
314 if (cargo_index == -1) {
315 if (Num_cargo < MAX_CARGO);
316 cargo_index = Num_cargo++;
317 strcpy(Cargo_names[cargo_index], m_cargo_name);
318 ptr->subsys_cargo_name = cargo_index;
320 ptr->subsys_cargo_name = cargo_index;
323 ptr->subsys_cargo_name = -1;
328 cur_subsys = z = ((CListBox *) GetDlgItem(IDC_SUBSYS)) -> GetCurSel();
333 ptr = GET_FIRST(&Ships[m_ship].subsys_list);
335 Assert(ptr != END_OF_LIST(&Ships[m_ship].subsys_list));
339 m_damage = 100 - (int) ptr -> current_hits;
340 if ( (Ship_info[Ships[m_ship].ship_info_index].flags & SIF_HUGE_SHIP) && valid_cap_subsys_cargo_list(ptr->system_info->subobj_name) ) {
341 enable_cargo_name = TRUE;
342 if (ptr->subsys_cargo_name != -1) {
343 m_cargo_name = Cargo_names[ptr->subsys_cargo_name];
345 m_cargo_name = _T("");
348 m_cargo_name = _T("");
353 GetDlgItem(IDC_DAMAGE) -> EnableWindow(enable);
354 GetDlgItem(IDC_DAMAGE_SPIN) -> EnableWindow(enable);
355 GetDlgItem(IDC_CARGO_NAME)->EnableWindow(enable && enable_cargo_name);
359 void initial_status::OnOK()
362 int z, obj, vflag = 0, sflag = 0, hflag = 0;
363 object *o1, *o2, *objp;
365 if (GetDlgItem(IDC_VELOCITY)->GetWindowText(buf, 255))
367 if (GetDlgItem(IDC_SHIELDS)->GetWindowText(buf, 255))
369 if (GetDlgItem(IDC_HULL)->GetWindowText(buf, 255))
376 objp = GET_FIRST(&obj_used_list);
377 while (objp != END_OF_LIST(&obj_used_list)) {
378 if (((objp->type == OBJ_SHIP) || (objp->type == OBJ_START)) && (objp->flags & OF_MARKED)) {
380 MODIFY(objp->phys_info.speed, (float) m_velocity);
383 MODIFY(objp->shields[0], (float) m_shields);
386 MODIFY(objp->hull_strength, (float) m_hull);
388 if (m_has_shields == 1)
389 objp->flags &= ~OF_NO_SHIELDS;
390 else if (!m_has_shields)
391 objp->flags |= OF_NO_SHIELDS;
394 Ships[get_ship_from_obj(objp)].flags |= SF_LOCKED;
395 else if (!m_has_shields)
396 Ships[get_ship_from_obj(objp)].flags &= ~SF_LOCKED;
399 objp = GET_NEXT(objp);
403 MODIFY(Objects[cur_object_index].phys_info.speed, (float) m_velocity);
404 MODIFY(Objects[cur_object_index].shields[0], (float) m_shields);
405 MODIFY(Objects[cur_object_index].hull_strength, (float) m_hull);
407 Objects[cur_object_index].flags &= ~OF_NO_SHIELDS;
409 Objects[cur_object_index].flags |= OF_NO_SHIELDS;
412 Ships[m_ship].flags |= SF_LOCKED;
414 Ships[m_ship].flags &= ~SF_LOCKED;
417 if (m_docked_with >= 0)
418 obj = Ships[m_docked_with].objnum;
420 z = Ai_info[Ships[m_ship].ai_index].dock_objnum;
425 o = Ai_info[Ships[get_ship_from_obj(obj)].ai_index].dock_objnum;
430 undock(Ships[m_ship].objnum);
434 MODIFY(Ai_info[Ships[m_ship].ai_index].dock_objnum, obj);
438 // sets up the actual docking on the Fred screen. After docking is done, use a loose
439 // set of rules to possibly set an arrival cue to false
440 o1 = &Objects[Ships[m_ship].objnum];
441 o2 = &Objects[Ships[m_docked_with].objnum];
442 m_docker_index = ((CComboBox *) GetDlgItem(IDC_DOCKER_POINT)) -> GetItemData(m_docker_point);
443 MODIFY(Ai_info[Ships[m_ship].ai_index].dock_index, m_docker_index);
444 m_dockee_index = ((CComboBox *) GetDlgItem(IDC_DOCKEE_POINT)) -> GetItemData(m_dockee_point);
445 MODIFY(Ai_info[Ships[m_ship].ai_index].dockee_index, m_dockee_index);
447 // based on the types of the two ships docked, set the arrival cue of the "smaller" ship
449 s1type = Ship_info[Ships[m_ship].ship_info_index].flags;
450 s2type = Ship_info[Ships[m_docked_with].ship_info_index].flags;
452 if (ship_docking_valid(m_ship, m_docked_with)) {
453 ai_dock_with_object(o1, o2, 89, AIDO_DOCK_NOW, m_docker_index, m_dockee_index);
455 ai_dock_with_object(o2, o1, 89, AIDO_DOCK_NOW, m_dockee_index, m_docker_index);
458 // based on the rules already defined for docking (see ship_docking_valid()), we can make
459 // assumptions about what are "small" and "large" ships in this process. Set the arrival
460 // cue of the small ships to false so that they can properly arrive in the mission when
462 if ( (s2type & SIF_CARGO) || (s1type & SIF_BIG_SHIP) ) {
463 reset_arrival_to_false( m_docked_with );
464 } else if ( (s1type & SIF_CARGO) || (s2type & SIF_BIG_SHIP) ) {
465 reset_arrival_to_false( m_ship );
467 // default rule -- pick one!
468 reset_arrival_to_false( m_ship );
471 Assert ( (Ships[m_ship].flags & SF_INITIALLY_DOCKED) || (Ships[m_docked_with].flags & SF_INITIALLY_DOCKED) );
483 void initial_status::undock(int obj)
487 int ship_num, other_ship_num;
489 o2 = Ai_info[Ships[get_ship_from_obj(obj)].ai_index].dock_objnum;
493 vm_vec_sub(&v, &Objects[obj].pos, &Objects[o2].pos);
494 vm_vec_normalize(&v);
495 ship_num = get_ship_from_obj(obj);
496 other_ship_num = get_ship_from_obj(o2);
498 if (ship_docking_valid(ship_num, other_ship_num) )
499 vm_vec_scale_add2(&Objects[obj].pos, &v, Objects[obj].radius * 2.0f);
501 vm_vec_scale_add2(&Objects[o2].pos, &v, Objects[o2].radius * -2.0f);
503 Ai_info[Ships[ship_num].ai_index].dock_objnum = -1;
504 Ai_info[Ships[other_ship_num].ai_index].dock_objnum = -1;
506 // check to see if one of these ships has an arrival cue of false. If so, then
507 // reset it back to default value of true. be sure to correctly update before
508 // and after setting data.
509 Ship_editor_dialog.update_data(1);
510 if ( Ships[ship_num].arrival_cue == Locked_sexp_false ) {
511 Ships[ship_num].arrival_cue = Locked_sexp_true;
512 } else if ( Ships[other_ship_num].arrival_cue == Locked_sexp_false ) {
513 Ships[other_ship_num].arrival_cue = Locked_sexp_true;
516 // reset the initially docked flags on both ships (only one will be set, but this s
518 Ships[ship_num].flags &= ~(SF_INITIALLY_DOCKED);
519 Ships[other_ship_num].flags &= ~(SF_INITIALLY_DOCKED);
520 Ship_editor_dialog.initialize_data(1);
524 void initial_status::OnSelchangeSubsys()
531 void initial_status::OnSelchangeDocked()
536 GetDlgItem(IDC_DOCKER_POINT)->EnableWindow(TRUE);
537 GetDlgItem(IDC_DOCKEE_POINT)->EnableWindow(TRUE);
539 m_docked_with = ((CComboBox *) GetDlgItem(IDC_DOCKED)) -> GetItemData(m_docked);
540 initialize_docker_points();
541 initialize_dockee_points();
543 } else { // selected 'nothing' as being docked with
544 m_docked_with = m_docker_index = m_dockee_index = m_docker_point = m_dockee_point = -1;
545 GetDlgItem(IDC_DOCKER_POINT)->EnableWindow(FALSE);
546 GetDlgItem(IDC_DOCKEE_POINT)->EnableWindow(FALSE);
552 void initial_status::OnSelchangeDockerPoint()
556 initialize_dockee_points();
560 void initial_status::OnHasShields()
562 if (m_has_shields == 1)
567 ((CButton *) GetDlgItem(IDC_HAS_SHIELDS))->SetCheck(m_has_shields);
568 GetDlgItem(IDC_SHIELDS)->EnableWindow(m_has_shields);
569 GetDlgItem(IDC_SHIELDS_SPIN)->EnableWindow(m_has_shields);
572 // function to set the arrival cue of a ship to false
573 void initial_status::reset_arrival_to_false( int shipnum )
577 // if the cue is not false, make it false. Be sure to all ship editor dialog functions
578 // to update date before and after we modify the cue.
579 if ( Ships[shipnum].arrival_cue != Locked_sexp_false ) {
580 Ship_editor_dialog.update_data(1);
581 free_sexp2(Ships[shipnum].arrival_cue);
582 Ships[shipnum].arrival_cue = Locked_sexp_false;
583 Ship_editor_dialog.initialize_data(1);
584 sprintf(buf, "Setting arrival cue of ship %s\nto false for initial docking purposes.", Ships[shipnum].ship_name);
585 MessageBox(buf, "", MB_OK | MB_ICONEXCLAMATION);
588 Ships[shipnum].flags |= SF_INITIALLY_DOCKED;
591 void initial_status::OnLocked()
598 ((CButton *) GetDlgItem(IDC_LOCKED))->SetCheck(m_locked);