void initial_status::undock(object *objp1, object *objp2)
{
	vec3d v;
	int ship_num, other_ship_num;

	if (objp1 == NULL || objp2 == NULL)
		return;

	vm_vec_sub(&v, &objp2->pos, &objp1->pos);
	vm_vec_normalize(&v);
	ship_num = get_ship_from_obj(OBJ_INDEX(objp1));
	other_ship_num = get_ship_from_obj(OBJ_INDEX(objp2));

	if (ship_class_compare(Ships[ship_num].ship_info_index, Ships[other_ship_num].ship_info_index) <= 0)
		vm_vec_scale_add2(&objp2->pos, &v, objp2->radius * 2.0f);
	else
		vm_vec_scale_add2(&objp1->pos, &v, objp1->radius * -2.0f);

	ai_do_objects_undocked_stuff(objp1, objp2);

	// check to see if one of these ships has an arrival cue of false.  If so, then
	// reset it back to default value of true.  be sure to correctly update before
	// and after setting data.
	// Goober5000 - but don't reset it if it's part of a wing!
	Ship_editor_dialog.update_data(1);

	if ( Ships[ship_num].arrival_cue == Locked_sexp_false && Ships[ship_num].wingnum < 0 ) {
		Ships[ship_num].arrival_cue = Locked_sexp_true;
	} else if ( Ships[other_ship_num].arrival_cue == Locked_sexp_false && Ships[other_ship_num].wingnum < 0 ) {
		Ships[other_ship_num].arrival_cue = Locked_sexp_true;
	}

	// if this ship is no longer docked, ensure its dock leader flag is clear
    if (!object_is_docked(&Objects[Ships[ship_num].objnum]))
        Ships[ship_num].flags.remove(Ship::Ship_Flags::Dock_leader);

	// same for the other ship
    if (!object_is_docked(&Objects[Ships[other_ship_num].objnum]))
        Ships[other_ship_num].flags.remove(Ship::Ship_Flags::Dock_leader);

	Ship_editor_dialog.initialize_data(1);
}
void initial_status::list_dockees(int dock_types)
{
	int z;

	// enable/disable dropdown
	cboDockees->EnableWindow((dock_types >= 0) ? TRUE : FALSE);

	// clear the existing dockees
	cboDockees->ResetContent();

	// that might be all we need to do
	if (dock_types < 0)
		return;

	// populate with potential dockees

	// add "nothing"
	z = cboDockees->AddString("Nothing");
	cboDockees->SetItemData(z, static_cast<DWORD_PTR>(-1));

	// add ships
	for (object *objp = GET_FIRST(&obj_used_list); objp != END_OF_LIST(&obj_used_list); objp = GET_NEXT(objp))
	{
		if ((objp->type == OBJ_SHIP) || (objp->type == OBJ_START))
		{
			int ship = get_ship_from_obj(objp);

			// mustn't be the same ship
			if (ship == m_ship)
				continue;

			// mustn't also be docked elsewhere
			bool docked_elsewhere = false;
			for (int i = 0; i < num_dock_points; i++)
			{
				// don't erroneously check the same point
				if (i == cur_docker_point)
					continue;

				// see if this ship is also on a different dockpoint
				if (dockpoint_array[i].dockee_shipnum == ship)
				{
					docked_elsewhere = true;
					break;
				}
			}

			if (docked_elsewhere)
				continue;

			// docking must be valid
			if (!ship_docking_valid(m_ship, ship) && !ship_docking_valid(ship, m_ship))
				continue;

			// dock types must match
			if (!(model_get_dock_types(Ship_info[Ships[ship].ship_info_index].model_num) & dock_types))
				continue;

			// add to list
			z = cboDockees->AddString(Ships[ship].ship_name);
			cboDockees->SetItemData(z, ship);
		}
	}
}
BOOL initial_status::OnInitDialog() 
{
	int z, vflag, sflag, hflag;
	ship_subsys *ptr;
	CString str;
	object *objp = NULL;

	m_ship = cur_ship;
	if (m_ship == -1) {
		Assert((Objects[cur_object_index].type == OBJ_SHIP) || (Objects[cur_object_index].type == OBJ_START));
		m_ship = get_ship_from_obj(cur_object_index);
		Assert(m_ship >= 0);
	}

	// initialize dockpoint stuff
	if (!m_multi_edit)
	{
		num_dock_points = model_get_num_dock_points(Ship_info[Ships[m_ship].ship_info_index].model_num);
		dockpoint_array = new dockpoint_information[num_dock_points];
		objp = &Objects[Ships[m_ship].objnum];
		for (int i = 0; i < num_dock_points; i++)
		{
			object *docked_objp = dock_find_object_at_dockpoint(objp, i);
			if (docked_objp != NULL)
			{
				dockpoint_array[i].dockee_shipnum = docked_objp->instance;
				dockpoint_array[i].dockee_point = dock_find_dockpoint_used_by_object(docked_objp, objp);
			}
			else
			{
				dockpoint_array[i].dockee_shipnum = -1;
				dockpoint_array[i].dockee_point = -1;
			}
		}
	}

	vflag = sflag = hflag = 0;
	m_velocity = (int) Objects[cur_object_index].phys_info.speed;
	m_shields = (int) Objects[cur_object_index].shield_quadrant[0];
	m_hull = (int) Objects[cur_object_index].hull_strength;
	if (Objects[cur_object_index].flags[Object::Object_Flags::No_shields])
		m_has_shields = 0;
	else
		m_has_shields = 1;
	
	if (Ships[m_ship].flags[Ship::Ship_Flags::Force_shields_on])
		m_force_shields = 1;
	else
		m_force_shields = 0;

	if (Ships[m_ship].flags[Ship::Ship_Flags::Ship_locked])
		m_ship_locked = 1;
	else
		m_ship_locked = 0;

	if (Ships[m_ship].flags[Ship::Ship_Flags::Weapons_locked])
		m_weapons_locked = 1;
	else
		m_weapons_locked = 0;

	// Lock primaries
	if (Ships[m_ship].flags[Ship::Ship_Flags::Primaries_locked]) {
		m_primaries_locked = 1;
	}
	else {
		m_primaries_locked = 0;
	}

	//Lock secondaries
	if (Ships[m_ship].flags[Ship::Ship_Flags::Secondaries_locked]) {
		m_secondaries_locked = 1;
	}
	else {
		m_secondaries_locked = 0;
	}

	//Lock turrets
	if (Ships[m_ship].flags[Ship::Ship_Flags::Lock_all_turrets_initially]) {
		m_turrets_locked = 1;
	}
	else {
		m_turrets_locked = 0;
	}

	if (Ships[m_ship].flags[Ship::Ship_Flags::Afterburner_locked]) {
		m_afterburner_locked = 1;
	}
	else {
		m_afterburner_locked = 0;
	}



	if (m_multi_edit) {
		objp = GET_FIRST(&obj_used_list);
		while (objp != END_OF_LIST(&obj_used_list)) {
			if (((objp->type == OBJ_SHIP) || (objp->type == OBJ_START)) && (objp->flags[Object::Object_Flags::Marked])) {
				if (objp->phys_info.speed != m_velocity)
					vflag = 1;
				if ((int) objp->shield_quadrant[0] != m_shields)
					sflag = 1;
				if ((int) objp->hull_strength != m_hull)
					hflag = 1;
				if (objp->flags[Object::Object_Flags::No_shields]) {
					if (m_has_shields)
						m_has_shields = 2;

				} else {
					if (!m_has_shields)
						m_has_shields = 2;
				}

				Assert((objp->type == OBJ_SHIP) || (objp->type == OBJ_START));
				
				if (Ships[get_ship_from_obj(objp)].flags[Ship::Ship_Flags::Force_shields_on]) {
					if (!m_force_shields)
						m_force_shields = 2;

				} else {
					if (m_force_shields)
						m_force_shields = 2;
				}

				if (Ships[get_ship_from_obj(objp)].flags[Ship::Ship_Flags::Ship_locked]) {
					if (!m_ship_locked)
						m_ship_locked = 2;

				} else {
					if (m_ship_locked)
						m_ship_locked = 2;
				}

				if (Ships[get_ship_from_obj(objp)].flags[Ship::Ship_Flags::Weapons_locked]) {
					if (!m_weapons_locked)
						m_weapons_locked = 2;

				} else {
					if (m_weapons_locked)
						m_weapons_locked = 2;
				}

				if (Ships[get_ship_from_obj(objp)].flags[Ship::Ship_Flags::Primaries_locked]){
					if (!m_primaries_locked)
						m_primaries_locked = 2;
				}
				else {
					if (m_primaries_locked)
						m_primaries_locked = 2;
				}
				
				if (Ships[get_ship_from_obj(objp)].flags[Ship::Ship_Flags::Secondaries_locked]){
					if (!m_secondaries_locked)
						m_secondaries_locked = 2;
				}
				else {
					if (m_secondaries_locked)
						m_secondaries_locked = 2;
				}
								
				if (Ships[get_ship_from_obj(objp)].flags[Ship::Ship_Flags::Lock_all_turrets_initially]){
					if (!m_turrets_locked)
						m_turrets_locked = 2;
				}
				else {
					if (m_turrets_locked)
						m_turrets_locked = 2;
				}
				
				if (Ships[get_ship_from_obj(objp)].flags[Ship::Ship_Flags::Afterburner_locked]){
					if (!m_afterburner_locked)
						m_afterburner_locked = 2;
				}
				else {
					if (m_afterburner_locked)
						m_afterburner_locked = 2;
				}
			}

			objp = GET_NEXT(objp);
		}
	}

	CDialog::OnInitDialog();
	str.Format("%d", m_velocity);
	GetDlgItem(IDC_VELOCITY)->SetWindowText(str);
	str.Format("%d", m_shields);
	GetDlgItem(IDC_SHIELDS)->SetWindowText(str);
	str.Format("%d", m_hull);
	GetDlgItem(IDC_HULL)->SetWindowText(str);

	inited = 1;

	GetDlgItem(IDC_SHIELDS)->EnableWindow(m_has_shields ? TRUE : FALSE);
	GetDlgItem(IDC_SHIELDS_SPIN)->EnableWindow(m_has_shields ? TRUE : FALSE);

	m_velocity_spin.SetRange(0, 100);
	m_hull_spin.SetRange(0, 100);
	m_shields_spin.SetRange(0, 100);
	m_damage_spin.SetRange(0, 100);

	// init boxes
	lstDockerPoints = (CListBox *) GetDlgItem(IDC_DOCKER_POINT);
	cboDockees = (CComboBox *) GetDlgItem(IDC_DOCKEE);
	cboDockeePoints = (CComboBox *) GetDlgItem(IDC_DOCKEE_POINT);
	lstDockerPoints->ResetContent();
	cboDockees->ResetContent();
	cboDockeePoints->ResetContent();

	if (!m_multi_edit)
	{
		for (int dockpoint = 0; dockpoint < num_dock_points; dockpoint++)
		{
			z = lstDockerPoints->AddString(model_get_dock_name(Ship_info[Ships[m_ship].ship_info_index].model_num, dockpoint));
			lstDockerPoints->SetItemData(z, dockpoint);
		}

		for (ptr = GET_FIRST(&Ships[m_ship].subsys_list); ptr != END_OF_LIST(&Ships[m_ship].subsys_list); ptr = GET_NEXT(ptr))
		{
			((CListBox *) GetDlgItem(IDC_SUBSYS))->AddString(ptr->system_info->subobj_name);
		}
	}
	else
	{
		GetDlgItem(IDC_SUBSYS)->EnableWindow(FALSE);
		GetDlgItem(IDC_DAMAGE)->EnableWindow(FALSE);
	}
	change_docker_point(false);
	change_subsys();

	UpdateData(FALSE);

	if (vflag)
		GetDlgItem(IDC_VELOCITY)->SetWindowText("");
	if (sflag)
		GetDlgItem(IDC_SHIELDS)->SetWindowText("");
	if (hflag)
		GetDlgItem(IDC_HULL)->SetWindowText("");

	if (objp != NULL) {
		if (objp->type == OBJ_SHIP || objp->type == OBJ_START) {
			ship* shipp = &Ships[objp->instance];
			int i = 0;

			if (Ship_info[shipp->ship_info_index].uses_team_colors) {
				//Add a "None" entry at the beginning to allow simple deselection of colours
				int t = m_team_color_setting.AddString("None");
				m_team_color_setting.SetItemData(t, i);
				++i;

				for (SCP_vector<SCP_string>::iterator tni = Team_Names.begin(); tni != Team_Names.end(); ++tni) {
					z = m_team_color_setting.AddString(tni->c_str());
					if (!stricmp(tni->c_str(), shipp->team_name.c_str())) {
						m_team_color_setting.SetCurSel(i);
					}
					m_team_color_setting.SetItemData(z, i);
					i++;

				}
				m_team_color_setting.EnableWindow();
			} else {
				m_team_color_setting.EnableWindow(FALSE);
			}
		}
	}

	return TRUE;
}
void initial_status::OnOK()
{
	char buf[256];
	int vflag = 0, sflag = 0, hflag = 0;
	object *objp;

	if (GetDlgItem(IDC_VELOCITY)->GetWindowText(buf, 255))
		vflag = 1;
	if (GetDlgItem(IDC_SHIELDS)->GetWindowText(buf, 255))
		sflag = 1;
	if (GetDlgItem(IDC_HULL)->GetWindowText(buf, 255))
		hflag = 1;

	UpdateData(TRUE);

	change_subsys();

	if (m_multi_edit) {
		objp = GET_FIRST(&obj_used_list);
		while (objp != END_OF_LIST(&obj_used_list)) {
			if (((objp->type == OBJ_SHIP) || (objp->type == OBJ_START)) && (objp->flags[Object::Object_Flags::Marked])) {
				if (vflag)
					MODIFY(objp->phys_info.speed, (float) m_velocity);

				if (sflag)
					MODIFY(objp->shield_quadrant[0], (float) m_shields);

				if (hflag)
					MODIFY(objp->hull_strength, (float) m_hull);

				objp->flags.set(Object::Object_Flags::No_shields, m_has_shields == 0);

                auto shipp = &Ships[get_ship_from_obj(objp)];
				
                shipp->flags.set(Ship::Ship_Flags::Force_shields_on, m_force_shields == 1);
                shipp->flags.set(Ship::Ship_Flags::Ship_locked, m_ship_locked == 1);
                shipp->flags.set(Ship::Ship_Flags::Weapons_locked, m_weapons_locked == 1);
                shipp->flags.set(Ship::Ship_Flags::Primaries_locked, m_primaries_locked == 1);
                shipp->flags.set(Ship::Ship_Flags::Secondaries_locked, m_secondaries_locked == 1);
                shipp->flags.set(Ship::Ship_Flags::Lock_all_turrets_initially, m_turrets_locked == 1);
                shipp->flags.set(Ship::Ship_Flags::Afterburner_locked, m_afterburner_locked == 1);
			}

			objp = GET_NEXT(objp);
		}

	} else {
		MODIFY(Objects[cur_object_index].phys_info.speed, (float) m_velocity);
		MODIFY(Objects[cur_object_index].shield_quadrant[0], (float) m_shields);
		MODIFY(Objects[cur_object_index].hull_strength, (float) m_hull);

		Objects[cur_object_index].flags.set(Object::Object_Flags::No_shields, m_has_shields != 0);

        Ships[m_ship].flags.set(Ship::Ship_Flags::Force_shields_on, m_force_shields == 1);
        Ships[m_ship].flags.set(Ship::Ship_Flags::Ship_locked, m_ship_locked == 1);
        Ships[m_ship].flags.set(Ship::Ship_Flags::Weapons_locked, m_weapons_locked == 1);
        Ships[m_ship].flags.set(Ship::Ship_Flags::Primaries_locked, m_primaries_locked == 1);
        Ships[m_ship].flags.set(Ship::Ship_Flags::Secondaries_locked, m_secondaries_locked == 1);
        Ships[m_ship].flags.set(Ship::Ship_Flags::Lock_all_turrets_initially, m_turrets_locked == 1);
        Ships[m_ship].flags.set(Ship::Ship_Flags::Afterburner_locked, m_afterburner_locked == 1);
	}

	if (m_team_color_setting.IsWindowEnabled() && m_team_color_setting.GetCurSel() > 0)
		Ships[m_ship].team_name = Team_Names[m_team_color_setting.GetCurSel() - 1];
	else
		Ships[m_ship].team_name = "none";

	update_docking_info();

	CDialog::OnOK();
}
void initial_status::OnOK()
{
	char buf[256];
	int vflag = 0, sflag = 0, hflag = 0;
	object *objp;

	if (GetDlgItem(IDC_VELOCITY)->GetWindowText(buf, 255))
		vflag = 1;
	if (GetDlgItem(IDC_SHIELDS)->GetWindowText(buf, 255))
		sflag = 1;
	if (GetDlgItem(IDC_HULL)->GetWindowText(buf, 255))
		hflag = 1;

	UpdateData(TRUE);

	change_subsys();

	if (m_multi_edit) {
		objp = GET_FIRST(&obj_used_list);
		while (objp != END_OF_LIST(&obj_used_list)) {
			if (((objp->type == OBJ_SHIP) || (objp->type == OBJ_START)) && (objp->flags & OF_MARKED)) {
				if (vflag)
					MODIFY(objp->phys_info.speed, (float) m_velocity);

				if (sflag)
					MODIFY(objp->shield_quadrant[0], (float) m_shields);

				if (hflag)
					MODIFY(objp->hull_strength, (float) m_hull);

				if (m_has_shields == 1)
					objp->flags &= ~OF_NO_SHIELDS;
				else if (!m_has_shields)
					objp->flags |= OF_NO_SHIELDS;
				
				if (m_force_shields == 1) {
					Ships[get_ship_from_obj(objp)].flags2 |= SF2_FORCE_SHIELDS_ON;
				}
				else if (!m_force_shields) {
					Ships[get_ship_from_obj(objp)].flags2 &= ~SF2_FORCE_SHIELDS_ON;
				}
				
				if (m_ship_locked == 1)
					Ships[get_ship_from_obj(objp)].flags2 |= SF2_SHIP_LOCKED;
				else if (!m_ship_locked)
					Ships[get_ship_from_obj(objp)].flags2 &= ~SF2_SHIP_LOCKED;
				
				if (m_weapons_locked == 1)
					Ships[get_ship_from_obj(objp)].flags2 |= SF2_WEAPONS_LOCKED;
				else if (!m_weapons_locked)
					Ships[get_ship_from_obj(objp)].flags2 &= ~SF2_WEAPONS_LOCKED;

				if (m_primaries_locked == 1) {
					Ships[get_ship_from_obj(objp)].flags2 |= SF2_PRIMARIES_LOCKED;
				}
				else if (!m_primaries_locked) {
					Ships[get_ship_from_obj(objp)].flags2 &= ~SF2_PRIMARIES_LOCKED;
				}

				if (m_secondaries_locked == 1) {
					Ships[get_ship_from_obj(objp)].flags2 |= SF2_SECONDARIES_LOCKED;
				}
				else if (!m_secondaries_locked)	{
					Ships[get_ship_from_obj(objp)].flags2 &= ~SF2_SECONDARIES_LOCKED;
				}

				if (m_turrets_locked == 1) {
					Ships[get_ship_from_obj(objp)].flags2 |= SF2_LOCK_ALL_TURRETS_INITIALLY;
				}
				else if (!m_turrets_locked) {
					Ships[get_ship_from_obj(objp)].flags2 &= ~SF2_LOCK_ALL_TURRETS_INITIALLY;
				}
				
				if (m_afterburner_locked == 1) {
					Ships[get_ship_from_obj(objp)].flags2 |= SF2_AFTERBURNER_LOCKED;
				}
				else if (!m_afterburner_locked)	{
					Ships[get_ship_from_obj(objp)].flags2 &= ~SF2_AFTERBURNER_LOCKED;
				}
			}

			objp = GET_NEXT(objp);
		}

	} else {
		MODIFY(Objects[cur_object_index].phys_info.speed, (float) m_velocity);
		MODIFY(Objects[cur_object_index].shield_quadrant[0], (float) m_shields);
		MODIFY(Objects[cur_object_index].hull_strength, (float) m_hull);
		if (m_has_shields)
			Objects[cur_object_index].flags &= ~OF_NO_SHIELDS;
		else
			Objects[cur_object_index].flags |= OF_NO_SHIELDS;

		if (m_force_shields == 1)
			Ships[m_ship].flags2 |= SF2_FORCE_SHIELDS_ON;
		else if (!m_force_shields)
			Ships[m_ship].flags2 &= ~SF2_FORCE_SHIELDS_ON;		

		if (m_ship_locked == 1)
			Ships[m_ship].flags2 |= SF2_SHIP_LOCKED;
		else if (!m_ship_locked)
			Ships[m_ship].flags2 &= ~SF2_SHIP_LOCKED;		

		if (m_weapons_locked == 1)
			Ships[m_ship].flags2 |= SF2_WEAPONS_LOCKED;
		else if (!m_weapons_locked)
			Ships[m_ship].flags2 &= ~SF2_WEAPONS_LOCKED;				

		if (m_primaries_locked == 1)
			Ships[m_ship].flags2 |= SF2_PRIMARIES_LOCKED;
		else if (!m_primaries_locked)
			Ships[m_ship].flags2 &= ~SF2_PRIMARIES_LOCKED;		

		if (m_secondaries_locked == 1)
			Ships[m_ship].flags2 |= SF2_SECONDARIES_LOCKED;
		else if (!m_secondaries_locked)
			Ships[m_ship].flags2 &= ~SF2_SECONDARIES_LOCKED;		

		if (m_turrets_locked == 1)
			Ships[m_ship].flags2 |= SF2_LOCK_ALL_TURRETS_INITIALLY;
		else if (!m_turrets_locked)
			Ships[m_ship].flags2 &= ~SF2_LOCK_ALL_TURRETS_INITIALLY;		

		if (m_afterburner_locked == 1)
			Ships[m_ship].flags2 |= SF2_AFTERBURNER_LOCKED;
		else if (!m_afterburner_locked)
			Ships[m_ship].flags2 &= ~SF2_AFTERBURNER_LOCKED;
	}

	if (m_team_color_setting.IsWindowEnabled() && m_team_color_setting.GetCurSel() > 0)
		Ships[m_ship].team_name = Team_Names[m_team_color_setting.GetCurSel() - 1];
	else
		Ships[m_ship].team_name = "none";

	update_docking_info();

	CDialog::OnOK();
}