2 * Copyright (C) Volition, Inc. 1999. All rights reserved.
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
9 // InitialStatus.cpp : implementation file
15 #include "initialstatus.h"
16 #include "management.h"
22 static char THIS_FILE[] = __FILE__;
25 /////////////////////////////////////////////////////////////////////////////
26 // initial_status dialog
28 initial_status::initial_status(CWnd* pParent /*=NULL*/)
29 : CDialog(initial_status::IDD, pParent)
31 //{{AFX_DATA_INIT(initial_status)
39 m_has_shields = FALSE;
41 m_cargo_name = _T("");
48 void initial_status::DoDataExchange(CDataExchange* pDX)
52 CDialog::DoDataExchange(pDX);
53 //{{AFX_DATA_MAP(initial_status)
54 DDX_Control(pDX, IDC_HULL_SPIN, m_hull_spin);
55 DDX_Control(pDX, IDC_VELOCITY_SPIN, m_velocity_spin);
56 DDX_Control(pDX, IDC_SHIELDS_SPIN, m_shields_spin);
57 DDX_Control(pDX, IDC_DAMAGE_SPIN, m_damage_spin);
58 DDX_Text(pDX, IDC_DAMAGE, m_damage);
59 DDV_MinMaxInt(pDX, m_damage, 0, 100);
60 DDX_CBIndex(pDX, IDC_DOCKED, m_docked);
61 DDX_CBIndex(pDX, IDC_DOCKEE_POINT, m_dockee_point);
62 DDX_CBIndex(pDX, IDC_DOCKER_POINT, m_docker_point);
63 DDX_Check(pDX, IDC_HAS_SHIELDS, m_has_shields);
64 DDX_Check(pDX, IDC_LOCKED, m_locked);
65 DDX_Text(pDX, IDC_CARGO_NAME, m_cargo_name);
66 DDV_MaxChars(pDX, m_cargo_name, 20);
69 if (pDX->m_bSaveAndValidate) {
70 GetDlgItem(IDC_VELOCITY)->GetWindowText(str);
71 m_velocity = atoi(str);
77 GetDlgItem(IDC_SHIELDS)->GetWindowText(str);
78 m_shields = atoi(str);
84 GetDlgItem(IDC_HULL)->GetWindowText(str);
93 BEGIN_MESSAGE_MAP(initial_status, CDialog)
94 //{{AFX_MSG_MAP(initial_status)
95 ON_LBN_SELCHANGE(IDC_SUBSYS, OnSelchangeSubsys)
96 ON_CBN_SELCHANGE(IDC_DOCKED, OnSelchangeDocked)
97 ON_CBN_SELCHANGE(IDC_DOCKER_POINT, OnSelchangeDockerPoint)
98 ON_BN_CLICKED(IDC_HAS_SHIELDS, OnHasShields)
99 ON_BN_CLICKED(IDC_LOCKED, OnLocked)
103 /////////////////////////////////////////////////////////////////////////////
104 // initial_status message handlers
106 BOOL initial_status::OnInitDialog()
108 int z, vflag, sflag, hflag, ship, type;
116 SDL_assert((Objects[cur_object_index].type == OBJ_SHIP) || (Objects[cur_object_index].type == OBJ_START));
117 m_ship = get_ship_from_obj(cur_object_index);
118 SDL_assert(m_ship >= 0);
121 vflag = sflag = hflag = 0;
122 m_velocity = (int) Objects[cur_object_index].phys_info.speed;
123 m_shields = (int) Objects[cur_object_index].shields[0];
124 m_hull = (int) Objects[cur_object_index].hull_strength;
125 if (Objects[cur_object_index].flags & OF_NO_SHIELDS)
130 if (Ships[m_ship].flags & SF_LOCKED)
136 objp = GET_FIRST(&obj_used_list);
137 while (objp != END_OF_LIST(&obj_used_list)) {
138 if (((objp->type == OBJ_SHIP) || (objp->type == OBJ_START)) && (objp->flags & OF_MARKED)) {
139 if (objp->phys_info.speed != m_velocity)
141 if ((int) objp->shields[0] != m_shields)
143 if ((int) objp->hull_strength != m_hull)
145 if (objp->flags & OF_NO_SHIELDS) {
154 SDL_assert((objp->type == OBJ_SHIP) || (objp->type == OBJ_START));
155 if (Ships[get_ship_from_obj(objp)].flags & SF_LOCKED) {
165 objp = GET_NEXT(objp);
169 CDialog::OnInitDialog();
170 str.Format("%d", m_velocity);
171 GetDlgItem(IDC_VELOCITY)->SetWindowText(str);
172 str.Format("%d", m_shields);
173 GetDlgItem(IDC_SHIELDS)->SetWindowText(str);
174 str.Format("%d", m_hull);
175 GetDlgItem(IDC_HULL)->SetWindowText(str);
178 box = (CComboBox *) GetDlgItem(IDC_DOCKED);
181 z = box->AddString("Nothing");
184 type = model_get_dock_types(Ships[m_ship].modelnum);
185 objp = GET_FIRST(&obj_used_list);
186 while (objp != END_OF_LIST(&obj_used_list)) {
187 if ((objp->type == OBJ_SHIP) || (objp->type == OBJ_START)) {
188 ship = get_ship_from_obj(objp);
189 if ((ship != m_ship) && (ship_docking_valid(m_ship, ship) || ship_docking_valid(ship, m_ship))) {
190 if (model_get_dock_types(Ships[ship].modelnum) & type) {
191 z = box->AddString(Ships[ship].ship_name);
192 box->SetItemData(z, ship);
197 objp = GET_NEXT(objp);
201 z = Ai_info[Ships[m_ship].ai_index].dock_objnum;
203 SDL_assert(Objects[z].type == OBJ_SHIP);
204 z = m_docked_with = get_ship_from_obj(z);
205 m_docked = box->FindStringExact(-1, Ships[z].ship_name);
207 m_docker_index = Ai_info[Ships[m_ship].ai_index].dock_index;
208 m_dockee_index = Ai_info[Ships[m_ship].ai_index].dockee_index;
209 initialize_docker_points();
210 initialize_dockee_points();
213 m_docker_index = m_dockee_index = m_docker_point = m_dockee_point = -1;
214 GetDlgItem(IDC_DOCKER_POINT)->EnableWindow(FALSE);
215 GetDlgItem(IDC_DOCKEE_POINT)->EnableWindow(FALSE);
218 ptr = GET_FIRST(&Ships[m_ship].subsys_list);
219 while (ptr != END_OF_LIST(&Ships[m_ship].subsys_list)) {
220 ((CListBox *) GetDlgItem(IDC_SUBSYS)) -> AddString(ptr->system_info->subobj_name);
225 GetDlgItem(IDC_DOCKED)->EnableWindow(FALSE);
226 GetDlgItem(IDC_DOCKER_POINT)->EnableWindow(FALSE);
227 GetDlgItem(IDC_DOCKEE_POINT)->EnableWindow(FALSE);
228 GetDlgItem(IDC_SUBSYS)->EnableWindow(FALSE);
229 GetDlgItem(IDC_DAMAGE)->EnableWindow(FALSE);
232 GetDlgItem(IDC_SHIELDS)->EnableWindow(m_has_shields ? TRUE : FALSE);
233 GetDlgItem(IDC_SHIELDS_SPIN)->EnableWindow(m_has_shields ? TRUE : FALSE);
235 m_velocity_spin.SetRange(0, 100);
236 m_hull_spin.SetRange(0, 100);
237 m_shields_spin.SetRange(0, 100);
238 m_damage_spin.SetRange(0, 100);
242 GetDlgItem(IDC_VELOCITY)->SetWindowText("");
244 GetDlgItem(IDC_SHIELDS)->SetWindowText("");
246 GetDlgItem(IDC_HULL)->SetWindowText("");
251 void initial_status::initialize_docker_points()
256 box = (CComboBox *) GetDlgItem(IDC_DOCKER_POINT);
258 if (m_docked_with < 0) {
259 m_docker_index = m_docker_point = -1;
263 type = model_get_dock_types(Ships[m_docked_with].modelnum);
264 set_valid_dock_points(m_ship, type, box);
266 SDL_assert(i); // this shouldn't happen.
268 if ((int) box->GetItemData(i) == m_docker_index)
274 m_docker_index = box->GetItemData(0);
278 void initial_status::initialize_dockee_points()
283 box = (CComboBox *) GetDlgItem(IDC_DOCKEE_POINT);
285 if ((m_docked_with < 0) || (m_docker_index < 0)) {
286 m_dockee_index = m_dockee_point = -1;
290 type = model_get_dock_index_type(Ships[m_ship].modelnum, m_docker_index);
291 set_valid_dock_points(m_docked_with, type, box);
293 SDL_assert(i); // this shouldn't happen.
295 if ((int) box->GetItemData(i) == m_dockee_index)
301 m_dockee_index = box->GetItemData(0);
305 void initial_status::change_subsys()
307 int z, cargo_index, enable = FALSE, enable_cargo_name = FALSE;
310 if (cur_subsys != LB_ERR) {
311 ptr = GET_FIRST(&Ships[m_ship].subsys_list);
312 while (cur_subsys--) {
313 SDL_assert(ptr != END_OF_LIST(&Ships[m_ship].subsys_list));
317 MODIFY(ptr -> current_hits, 100.0f - (float) m_damage);
320 if (strlen(m_cargo_name) > 0) {
321 cargo_index = string_lookup(m_cargo_name, Cargo_names, Num_cargo);
322 if (cargo_index == -1) {
323 if (Num_cargo < MAX_CARGO);
324 cargo_index = Num_cargo++;
325 strcpy(Cargo_names[cargo_index], m_cargo_name);
326 ptr->subsys_cargo_name = cargo_index;
328 ptr->subsys_cargo_name = cargo_index;
331 ptr->subsys_cargo_name = -1;
336 cur_subsys = z = ((CListBox *) GetDlgItem(IDC_SUBSYS)) -> GetCurSel();
341 ptr = GET_FIRST(&Ships[m_ship].subsys_list);
343 SDL_assert(ptr != END_OF_LIST(&Ships[m_ship].subsys_list));
347 m_damage = 100 - (int) ptr -> current_hits;
348 if ( (Ship_info[Ships[m_ship].ship_info_index].flags & SIF_HUGE_SHIP) && valid_cap_subsys_cargo_list(ptr->system_info->subobj_name) ) {
349 enable_cargo_name = TRUE;
350 if (ptr->subsys_cargo_name != -1) {
351 m_cargo_name = Cargo_names[ptr->subsys_cargo_name];
353 m_cargo_name = _T("");
356 m_cargo_name = _T("");
361 GetDlgItem(IDC_DAMAGE) -> EnableWindow(enable);
362 GetDlgItem(IDC_DAMAGE_SPIN) -> EnableWindow(enable);
363 GetDlgItem(IDC_CARGO_NAME)->EnableWindow(enable && enable_cargo_name);
367 void initial_status::OnOK()
370 int z, obj, vflag = 0, sflag = 0, hflag = 0;
371 object *o1, *o2, *objp;
373 if (GetDlgItem(IDC_VELOCITY)->GetWindowText(buf, 255))
375 if (GetDlgItem(IDC_SHIELDS)->GetWindowText(buf, 255))
377 if (GetDlgItem(IDC_HULL)->GetWindowText(buf, 255))
384 objp = GET_FIRST(&obj_used_list);
385 while (objp != END_OF_LIST(&obj_used_list)) {
386 if (((objp->type == OBJ_SHIP) || (objp->type == OBJ_START)) && (objp->flags & OF_MARKED)) {
388 MODIFY(objp->phys_info.speed, (float) m_velocity);
391 MODIFY(objp->shields[0], (float) m_shields);
394 MODIFY(objp->hull_strength, (float) m_hull);
396 if (m_has_shields == 1)
397 objp->flags &= ~OF_NO_SHIELDS;
398 else if (!m_has_shields)
399 objp->flags |= OF_NO_SHIELDS;
402 Ships[get_ship_from_obj(objp)].flags |= SF_LOCKED;
403 else if (!m_has_shields)
404 Ships[get_ship_from_obj(objp)].flags &= ~SF_LOCKED;
407 objp = GET_NEXT(objp);
411 MODIFY(Objects[cur_object_index].phys_info.speed, (float) m_velocity);
412 MODIFY(Objects[cur_object_index].shields[0], (float) m_shields);
413 MODIFY(Objects[cur_object_index].hull_strength, (float) m_hull);
415 Objects[cur_object_index].flags &= ~OF_NO_SHIELDS;
417 Objects[cur_object_index].flags |= OF_NO_SHIELDS;
420 Ships[m_ship].flags |= SF_LOCKED;
422 Ships[m_ship].flags &= ~SF_LOCKED;
425 if (m_docked_with >= 0)
426 obj = Ships[m_docked_with].objnum;
428 z = Ai_info[Ships[m_ship].ai_index].dock_objnum;
433 o = Ai_info[Ships[get_ship_from_obj(obj)].ai_index].dock_objnum;
438 undock(Ships[m_ship].objnum);
442 MODIFY(Ai_info[Ships[m_ship].ai_index].dock_objnum, obj);
446 // sets up the actual docking on the Fred screen. After docking is done, use a loose
447 // set of rules to possibly set an arrival cue to false
448 o1 = &Objects[Ships[m_ship].objnum];
449 o2 = &Objects[Ships[m_docked_with].objnum];
450 m_docker_index = ((CComboBox *) GetDlgItem(IDC_DOCKER_POINT)) -> GetItemData(m_docker_point);
451 MODIFY(Ai_info[Ships[m_ship].ai_index].dock_index, m_docker_index);
452 m_dockee_index = ((CComboBox *) GetDlgItem(IDC_DOCKEE_POINT)) -> GetItemData(m_dockee_point);
453 MODIFY(Ai_info[Ships[m_ship].ai_index].dockee_index, m_dockee_index);
455 // based on the types of the two ships docked, set the arrival cue of the "smaller" ship
457 s1type = Ship_info[Ships[m_ship].ship_info_index].flags;
458 s2type = Ship_info[Ships[m_docked_with].ship_info_index].flags;
460 if (ship_docking_valid(m_ship, m_docked_with)) {
461 ai_dock_with_object(o1, o2, 89, AIDO_DOCK_NOW, m_docker_index, m_dockee_index);
463 ai_dock_with_object(o2, o1, 89, AIDO_DOCK_NOW, m_dockee_index, m_docker_index);
466 // based on the rules already defined for docking (see ship_docking_valid()), we can make
467 // assumptions about what are "small" and "large" ships in this process. Set the arrival
468 // cue of the small ships to false so that they can properly arrive in the mission when
470 if ( (s2type & SIF_CARGO) || (s1type & SIF_BIG_SHIP) ) {
471 reset_arrival_to_false( m_docked_with );
472 } else if ( (s1type & SIF_CARGO) || (s2type & SIF_BIG_SHIP) ) {
473 reset_arrival_to_false( m_ship );
475 // default rule -- pick one!
476 reset_arrival_to_false( m_ship );
479 SDL_assert ( (Ships[m_ship].flags & SF_INITIALLY_DOCKED) || (Ships[m_docked_with].flags & SF_INITIALLY_DOCKED) );
491 void initial_status::undock(int obj)
495 int ship_num, other_ship_num;
497 o2 = Ai_info[Ships[get_ship_from_obj(obj)].ai_index].dock_objnum;
501 vm_vec_sub(&v, &Objects[obj].pos, &Objects[o2].pos);
502 vm_vec_normalize(&v);
503 ship_num = get_ship_from_obj(obj);
504 other_ship_num = get_ship_from_obj(o2);
506 if (ship_docking_valid(ship_num, other_ship_num) )
507 vm_vec_scale_add2(&Objects[obj].pos, &v, Objects[obj].radius * 2.0f);
509 vm_vec_scale_add2(&Objects[o2].pos, &v, Objects[o2].radius * -2.0f);
511 Ai_info[Ships[ship_num].ai_index].dock_objnum = -1;
512 Ai_info[Ships[other_ship_num].ai_index].dock_objnum = -1;
514 // check to see if one of these ships has an arrival cue of false. If so, then
515 // reset it back to default value of true. be sure to correctly update before
516 // and after setting data.
517 Ship_editor_dialog.update_data(1);
518 if ( Ships[ship_num].arrival_cue == Locked_sexp_false ) {
519 Ships[ship_num].arrival_cue = Locked_sexp_true;
520 } else if ( Ships[other_ship_num].arrival_cue == Locked_sexp_false ) {
521 Ships[other_ship_num].arrival_cue = Locked_sexp_true;
524 // reset the initially docked flags on both ships (only one will be set, but this s
526 Ships[ship_num].flags &= ~(SF_INITIALLY_DOCKED);
527 Ships[other_ship_num].flags &= ~(SF_INITIALLY_DOCKED);
528 Ship_editor_dialog.initialize_data(1);
532 void initial_status::OnSelchangeSubsys()
539 void initial_status::OnSelchangeDocked()
544 GetDlgItem(IDC_DOCKER_POINT)->EnableWindow(TRUE);
545 GetDlgItem(IDC_DOCKEE_POINT)->EnableWindow(TRUE);
547 m_docked_with = ((CComboBox *) GetDlgItem(IDC_DOCKED)) -> GetItemData(m_docked);
548 initialize_docker_points();
549 initialize_dockee_points();
551 } else { // selected 'nothing' as being docked with
552 m_docked_with = m_docker_index = m_dockee_index = m_docker_point = m_dockee_point = -1;
553 GetDlgItem(IDC_DOCKER_POINT)->EnableWindow(FALSE);
554 GetDlgItem(IDC_DOCKEE_POINT)->EnableWindow(FALSE);
560 void initial_status::OnSelchangeDockerPoint()
564 initialize_dockee_points();
568 void initial_status::OnHasShields()
570 if (m_has_shields == 1)
575 ((CButton *) GetDlgItem(IDC_HAS_SHIELDS))->SetCheck(m_has_shields);
576 GetDlgItem(IDC_SHIELDS)->EnableWindow(m_has_shields);
577 GetDlgItem(IDC_SHIELDS_SPIN)->EnableWindow(m_has_shields);
580 // function to set the arrival cue of a ship to false
581 void initial_status::reset_arrival_to_false( int shipnum )
585 // if the cue is not false, make it false. Be sure to all ship editor dialog functions
586 // to update date before and after we modify the cue.
587 if ( Ships[shipnum].arrival_cue != Locked_sexp_false ) {
588 Ship_editor_dialog.update_data(1);
589 free_sexp2(Ships[shipnum].arrival_cue);
590 Ships[shipnum].arrival_cue = Locked_sexp_false;
591 Ship_editor_dialog.initialize_data(1);
592 sprintf(buf, "Setting arrival cue of ship %s\nto false for initial docking purposes.", Ships[shipnum].ship_name);
593 MessageBox(buf, "", MB_OK | MB_ICONEXCLAMATION);
596 Ships[shipnum].flags |= SF_INITIALLY_DOCKED;
599 void initial_status::OnLocked()
606 ((CButton *) GetDlgItem(IDC_LOCKED))->SetCheck(m_locked);