Ejemplo n.º 1
0
void briefing_editor_dlg::OnMakeIcon() 
{
	char *name;
	int z, len, team, ship, waypoint, count = -1;
	int cargo = 0, cargo_count = 0, freighter_count = 0;
	object *ptr;
	vec3d min, max, pos;
	brief_icon *iconp;

	if (Briefing->stages[m_cur_stage].num_icons >= MAX_STAGE_ICONS)
		return;

	m_cur_icon = Briefing->stages[m_cur_stage].num_icons++;
	iconp = &Briefing->stages[m_cur_stage].icons[m_cur_icon];
	ship = waypoint = -1;
	team = 0;
	jump_node *jnp = NULL;

	vm_vec_make(&min, 9e19f, 9e19f, 9e19f);
	vm_vec_make(&max, -9e19f, -9e19f, -9e19f);
	ptr = GET_FIRST(&obj_used_list);
	while (ptr != END_OF_LIST(&obj_used_list)) {
		if (ptr->flags & OF_MARKED) {
			if (ptr->pos.xyz.x < min.xyz.x)
				min.xyz.x = ptr->pos.xyz.x;
			if (ptr->pos.xyz.x > max.xyz.x)
				max.xyz.x = ptr->pos.xyz.x;
			if (ptr->pos.xyz.y < min.xyz.y)
				min.xyz.y = ptr->pos.xyz.y;
			if (ptr->pos.xyz.y > max.xyz.y)
				max.xyz.y = ptr->pos.xyz.y;
			if (ptr->pos.xyz.z < min.xyz.z)
				min.xyz.z = ptr->pos.xyz.z;
			if (ptr->pos.xyz.z > max.xyz.z)
				max.xyz.z = ptr->pos.xyz.z;
			
			switch (ptr->type) {
				case OBJ_SHIP:
				case OBJ_START:
					ship = ptr->instance;
					break;

				case OBJ_WAYPOINT:
					waypoint = ptr->instance;
					break;
				
				case OBJ_JUMP_NODE:
					jnp = ptr->jnp;
					break;

				default:
					Int3();
			}

			if (ship >= 0) {
				team = Ships[ship].team;

				z = ship_query_general_type(ship);
				if (Ship_info[Ships[ship].ship_info_index].flags & SIF_CARGO)
					cargo_count++;

				if (Ship_info[Ships[ship].ship_info_index].flags & SIF_FREIGHTER)
				{
					// direct docked with any marked cargo?
					for (dock_instance *dock_ptr = ptr->dock_list; dock_ptr != NULL; dock_ptr = dock_ptr->next)
					{
						if (dock_ptr->docked_objp->flags & OF_MARKED)
						{
							if (Ship_info[Ships[dock_ptr->docked_objp->instance].ship_info_index].flags & SIF_CARGO)
								freighter_count++;
						}
					}
				}
			}

			count++;
		}

		ptr = GET_NEXT(ptr);
	}

	if (cargo_count && cargo_count == freighter_count)
		cargo = 1;

	vm_vec_avg(&pos, &min, &max);
	if (ship >= 0)
		name = Ships[ship].ship_name;
	else if (waypoint >= 0)
		name = Waypoint_lists[waypoint / 65536].name;
	else if (jnp != NULL)
		name = jnp->get_name_ptr();
	else
		return;

	len = strlen(name);
	if (len >= MAX_LABEL_LEN - 1)
		len = MAX_LABEL_LEN - 1;

	strncpy(iconp->label, name, len);
	iconp->label[len] = 0;
//	iconp->text[0] = 0;
	iconp->type = 0;
	iconp->team = team;
	iconp->pos = pos;
	iconp->flags = 0;
	iconp->id = Cur_brief_id++;
	if (ship >= 0) {
		iconp->ship_class = Ships[ship].ship_info_index;
		switch (Ship_info[Ships[ship].ship_info_index].flags & SIF_ALL_SHIP_TYPES) {
			case SIF_KNOSSOS_DEVICE:
				iconp->type = ICON_KNOSSOS_DEVICE;
				break;

			case SIF_CORVETTE:
				iconp->type = ICON_CORVETTE;
				break;

			case SIF_GAS_MINER:
				iconp->type = ICON_GAS_MINER;
				break;

			case SIF_SUPERCAP:
				iconp->type = ICON_SUPERCAP;
				break;

			case SIF_SENTRYGUN:
				iconp->type = ICON_SENTRYGUN;
				break;

			case SIF_AWACS:
				iconp->type = ICON_AWACS;
				break;

			case SIF_CARGO:
				if (cargo)
					iconp->type = (count == 1) ? ICON_FREIGHTER_WITH_CARGO : ICON_FREIGHTER_WING_WITH_CARGO;
				else
					iconp->type = count ? ICON_CARGO_WING : ICON_CARGO;

				break;

			case SIF_SUPPORT:
				iconp->type = ICON_SUPPORT_SHIP;
				break;

			case SIF_FIGHTER:
				iconp->type = count ? ICON_FIGHTER_WING : ICON_FIGHTER;
				break;

			case SIF_BOMBER:
				iconp->type = count ? ICON_BOMBER_WING : ICON_BOMBER;
				break;

			case SIF_FREIGHTER:
				if (cargo)
					iconp->type = (count == 1) ? ICON_FREIGHTER_WITH_CARGO : ICON_FREIGHTER_WING_WITH_CARGO;
				else
					iconp->type = count ? ICON_FREIGHTER_WING_NO_CARGO : ICON_FREIGHTER_NO_CARGO;

				break;

			case SIF_CRUISER:
				iconp->type = count ? ICON_CRUISER_WING : ICON_CRUISER;
				break;

			case SIF_TRANSPORT:
				iconp->type = count ? ICON_TRANSPORT_WING : ICON_TRANSPORT;
				break;

			case SIF_CAPITAL:			
			case SIF_DRYDOCK:
				iconp->type = ICON_CAPITAL;
				break;			

			case SIF_NAVBUOY:
				iconp->type = ICON_WAYPOINT;
				break;

			default:
				iconp->type = ICON_ASTEROID_FIELD;
				break;
		}
	}
	// jumpnodes
	else if(jnp != NULL){
		// find the first navbuoy
		iconp->ship_class = -1;
		for (int i = 0; i < Num_ship_classes; i++)
		{
			if (Ship_info[i].flags & SIF_NAVBUOY)
			{
				iconp->ship_class = i;
				break;
			}
		}
		iconp->type = ICON_JUMP_NODE;
	} 
	// everything else
	else {
		// find the first navbuoy
		iconp->ship_class = -1;
		for (int i = 0; i < Num_ship_classes; i++)
		{
			if (Ship_info[i].flags & SIF_NAVBUOY)
			{
				iconp->ship_class = i;
				break;
			}
		}
		iconp->type = ICON_WAYPOINT;
	}

	if (!m_change_local){
		propagate_icon(m_cur_icon);
	}

	icon_obj[m_cur_icon] = obj_create(OBJ_POINT, -1, m_cur_icon, NULL, &pos, 0.0f, OF_RENDERS);
	Assert(icon_obj[m_cur_icon] >= 0);
	obj_merge_created_list();
	unmark_all();
	set_cur_object_index(icon_obj[m_cur_icon]);
	GetDlgItem(IDC_MAKE_ICON) -> EnableWindow(FALSE);
	GetDlgItem(IDC_PROPAGATE_ICONS) -> EnableWindow(TRUE);
	update_data(1);
}
Ejemplo n.º 2
0
// Forms a wing from marked objects
int create_wing()
{
	char msg[1024];
	int i, ship, wing = -1, waypoints = 0, count = 0, illegal_ships = 0;
	int leader, leader_team;
	object *ptr;
	create_wing_dlg dlg;

	if (!query_valid_object())
		return -1;

	leader = cur_object_index;
	ptr = GET_FIRST(&obj_used_list);
	while (ptr != END_OF_LIST(&obj_used_list)) {
		if (( (ptr->type == OBJ_SHIP) || (ptr->type == OBJ_START) ) && (ptr->flags & OF_MARKED)) {
			count++;
			i = -1;
			switch (ptr->type) {
				case OBJ_SHIP:
				case OBJ_START:
					i = Ships[ptr->instance].wingnum;
					break;
			}

			if (i >= 0) {
				if (wing < 0)
					wing = i;
				else if (wing != i)
					wing = MULTI_WING;
			}
		}

		ptr = GET_NEXT(ptr);
	}

	if (count > MAX_SHIPS_PER_WING) {
		sprintf(msg, "You have too many ships marked!\n"
			"A wing is limited to %d ships total", MAX_SHIPS_PER_WING);

		Fred_main_wnd->MessageBox(msg, "Error", MB_ICONEXCLAMATION);
		return -1;
	}

	if ((wing >= 0) && (wing != MULTI_WING)) {
		sprintf(msg, "Do you want to reform wing \"%s\"?", Wings[wing].name);
		i = Fred_main_wnd->MessageBox(msg, "Query", MB_YESNOCANCEL);
		if (i == IDCANCEL)
			return -1;

		else if (i == IDNO)
			wing = -1;

		else {  // must be IDYES
			for (i=Wings[wing].wave_count-1; i>=0; i--) {
				ptr = &Objects[wing_objects[wing][i]];
				switch (ptr->type) {
					case OBJ_SHIP:
						remove_ship_from_wing(ptr->instance, 0);
						break;

					case OBJ_START:
						remove_player_from_wing(ptr->instance, 0);
						break;

					default:
						Int3();  // shouldn't be in a wing!
				}
			}

			Assert(!Wings[wing].wave_count);
			Num_wings--;
		}

	} else
		wing = -1;

	if (wing < 0) {
		wing = find_free_wing();

		if (wing < 0) {
			Fred_main_wnd->MessageBox("Too many wings, can't create more!",
				"Error", MB_ICONEXCLAMATION);

			return -1;
		}

		Wings[wing].num_waves = 1;
		Wings[wing].threshold = 0;
		Wings[wing].arrival_location = Wings[wing].departure_location = 0;
		Wings[wing].arrival_distance = 0;
		Wings[wing].arrival_anchor = -1;
		Wings[wing].arrival_delay = 0;
		Wings[wing].arrival_cue = Locked_sexp_true;
		Wings[wing].departure_delay = 0;
		Wings[wing].departure_cue = Locked_sexp_false;
		Wings[wing].hotkey = -1;
		Wings[wing].flags = 0;
		Wings[wing].wave_delay_min = 0;
		Wings[wing].wave_delay_max = 0;

		for (i=0; i<MAX_AI_GOALS; i++) {
			Wings[wing].ai_goals[i].ai_mode = AI_GOAL_NONE;
			Wings[wing].ai_goals[i].priority = -1;				// this sets up the priority field to be like ships
		}

		if (dlg.DoModal() == IDCANCEL)
			return -1;

		dlg.m_name.TrimLeft();
		dlg.m_name.TrimRight();
		string_copy(Wings[wing].name, dlg.m_name, NAME_LENGTH - 1);
	}

	set_cur_indices(-1);
	ptr = GET_FIRST(&obj_used_list);
	while (ptr != END_OF_LIST(&obj_used_list)) {
		if (ptr->flags & OF_MARKED) {
//			if ((ptr->type == OBJ_START) && (ptr->instance)) {
//				starts++;
//				unmark_object(OBJ_INDEX(ptr));

//			} else if (ptr->type == OBJ_WAYPOINT) {
			if (ptr->type == OBJ_WAYPOINT) {
				waypoints++;
				unmark_object(OBJ_INDEX(ptr));

			} else if (ptr->type == OBJ_SHIP) {
				int ship_type = ship_query_general_type(ptr->instance);
				if(ship_type < 0 || !(Ship_types[ship_type].ai_bools & STI_AI_CAN_FORM_WING))
				{
					illegal_ships++;
					unmark_object(OBJ_INDEX(ptr));
				}
			}
		}

		ptr = GET_NEXT(ptr);
	}

	// if this wing is a player starting wing, automatically set the hotkey for this wing
	for (i = 0; i < MAX_STARTING_WINGS; i++ ) {
		if ( !stricmp(Wings[wing].name, Starting_wing_names[i]) ) {
			Wings[wing].hotkey = i;
			break;
		}
	}

	count = 0;
	if (Objects[Ships[Player_start_shipnum].objnum].flags & OF_MARKED)
		count = 1;

	ptr = GET_FIRST(&obj_used_list);
	while (ptr != END_OF_LIST(&obj_used_list)) {
		if (ptr->flags & OF_MARKED) {
			if ((ptr->type == OBJ_START) && (ptr->instance == Player_start_shipnum))
				i = 0;  // player 1 start always goes to front of the wing
			else
				i = count++;

			Assert((ptr->type == OBJ_SHIP) || (ptr->type == OBJ_START));
			ship = ptr->instance;
			if (Ships[ship].wingnum != -1) {
				if (ptr->type == OBJ_SHIP)
					remove_ship_from_wing(ship);
				else
					remove_player_from_wing(ptr->instance);
			}

			wing_bash_ship_name(msg, Wings[wing].name, i + 1);
			rename_ship(ship, msg);

			Wings[wing].ship_index[i] = ship;
			Ships[ship].wingnum = wing;
			if (Ships[ship].arrival_cue >= 0)
				free_sexp2(Ships[ship].arrival_cue);

			Ships[ship].arrival_cue = Locked_sexp_false;
			if (Ships[ship].departure_cue >= 0)
				free_sexp2(Ships[ship].departure_cue);

			Ships[ship].departure_cue = Locked_sexp_false;

			wing_objects[wing][i] = OBJ_INDEX(ptr);
			if (OBJ_INDEX(ptr) == leader)
				Wings[wing].special_ship = i;
		}

		ptr = GET_NEXT(ptr);
	}

	if (!count)  // this should never happen, so if it does, needs to be fixed now.
		Error(LOCATION, "No valid ships were selected to form wing from");

	Wings[wing].wave_count = count;
	Num_wings++;

//	if (starts)
//		Fred_main_wnd->MessageBox("Multi-player starting points can't be part of a wing!\n"
//			"All marked multi-player starting points were ignored",
//			"Error", MB_ICONEXCLAMATION);

	if (waypoints)
		Fred_main_wnd->MessageBox("Waypoints can't be part of a wing!\n"
			"All marked waypoints were ignored",
			"Error", MB_ICONEXCLAMATION);

	if (illegal_ships)
		Fred_main_wnd->MessageBox("Some ship types aren't allowed to be in a wing.\n"
			"All marked ships of these types were ignored",
			"Error", MB_ICONEXCLAMATION);


	leader_team = Ships[Wings[wing].ship_index[Wings[wing].special_ship]].team;
	for (i = 0; i < Wings[wing].wave_count; i++)
	{
		if (Ships[Wings[wing].ship_index[i]].team != leader_team)
		{
			Fred_main_wnd->MessageBox("Wing contains ships on different teams", "Warning");
			break;
		}
	}

	mark_wing(wing);

	update_custom_wing_indexes();

	return 0;
}
Ejemplo n.º 3
0
// Forms a wing from marked objects
int create_wing()
{
	char msg[1024];
	int i, ship, wing = -1, waypoints = 0, count = 0, illegal_ships = 0;
	int friendly, hostile, leader;
	object *ptr;
	create_wing_dlg dlg;

	if (!query_valid_object())
		return -1;

	leader = cur_object_index;
	ptr = GET_FIRST(&obj_used_list);
	while (ptr != END_OF_LIST(&obj_used_list)) {
		if ((ptr->type == OBJ_SHIP) && (ptr->flags & OF_MARKED)) {
			count++;
			i = -1;
			switch (ptr->type) {
				case OBJ_SHIP:
				case OBJ_START:
					i = Ships[ptr->instance].wingnum;
					break;
			}

			if (i >= 0) {
				if (wing < 0)
					wing = i;
				else if (wing != i)
					wing = MULTI_WING;
			}
		}

		ptr = GET_NEXT(ptr);
	}

	if (count > MAX_SHIPS_PER_WING) {
		sprintf(msg, "You have too many ships marked!\n"
			"A flight group is limited to %d ships total", MAX_SHIPS_PER_WING);

		Fred_main_wnd->MessageBox(msg, "Error", MB_ICONEXCLAMATION);
		return -1;
	}

	if ((wing >= 0) && (wing != MULTI_WING)) {
		sprintf(msg, "Do you want to reform flight group \"%s\"?", Wings[wing].name);
		i = Fred_main_wnd->MessageBox(msg, "Query", MB_YESNOCANCEL);
		if (i == IDCANCEL)
			return -1;

		else if (i == IDNO)
			wing = -1;

		else {  // must be IDYES
			for (i=Wings[wing].wave_count-1; i>=0; i--) {
				ptr = &Objects[wing_objects[wing][i]];
				switch (ptr->type) {
					case OBJ_SHIP:
						remove_ship_from_wing(ptr->instance, 0);
						break;

					case OBJ_START:
						remove_player_from_wing(ptr->instance, 0);
						break;

					default:
						Int3();  // shouldn't be in a wing!
				}
			}

			Assert(!Wings[wing].wave_count);
			num_wings--;
		}

	} else
		wing = -1;

	if (wing < 0) {
		wing = find_free_wing();
		Wings[wing].num_waves = 1;
		Wings[wing].threshold = 0;
		Wings[wing].arrival_location = Wings[wing].departure_location = 0;
		Wings[wing].arrival_distance = 0;
		Wings[wing].arrival_anchor = -1;
		Wings[wing].arrival_cue = Locked_sexp_true;
		Wings[wing].departure_cue = Locked_sexp_false;
		Wings[wing].hotkey = -1;
		Wings[wing].flags = 0;

		for (i=0; i<MAX_AI_GOALS; i++) {
			Wings[wing].ai_goals[i].ai_mode = AI_GOAL_NONE;
			Wings[wing].ai_goals[i].priority = -1;				// this sets up the priority field to be like ships
		}

		if (wing < 0) {
			Fred_main_wnd->MessageBox("Too many flight groups, can't create more!",
				"Error", MB_ICONEXCLAMATION);

			return -1;
		}

		if (dlg.DoModal() == IDCANCEL)
			return -1;

		string_copy(Wings[wing].name, dlg.m_name, NAME_LENGTH - 1);
	}

	set_cur_indices(-1);
	ptr = GET_FIRST(&obj_used_list);
	while (ptr != END_OF_LIST(&obj_used_list)) {
		if (ptr->flags & OF_MARKED) {
//			if ((ptr->type == OBJ_START) && (ptr->instance)) {
//				starts++;
//				unmark_object(OBJ_INDEX(ptr));

//			} else if (ptr->type == OBJ_WAYPOINT) {
			if (ptr->type == OBJ_WAYPOINT) {
				waypoints++;
				unmark_object(OBJ_INDEX(ptr));

			} else if (ptr->type == OBJ_SHIP) {
				switch (ship_query_general_type(ptr->instance))
				{
					case SHIP_TYPE_CARGO:						
					case SHIP_TYPE_FIGHTER_BOMBER:			
					case SHIP_TYPE_CRUISER:					
					case SHIP_TYPE_FREIGHTER:			
					case SHIP_TYPE_CAPITAL:					
					case SHIP_TYPE_TRANSPORT:				
					case SHIP_TYPE_REPAIR_REARM:		
					case SHIP_TYPE_NAVBUOY:					
					case SHIP_TYPE_SENTRYGUN:
					case SHIP_TYPE_SPACE_OBJECT:
					case SHIP_TYPE_ESCAPEPOD:				
					case SHIP_TYPE_SUPERCAP:					
					case SHIP_TYPE_STEALTH:					
					case SHIP_TYPE_DRYDOCK:					
					//case SHIP_TYPE_AWACS:						
					//case SHIP_TYPE_GAS_MINER:
						
					// all ships added so that any craft type can be formed into a flight group
					/*case SHIP_TYPE_FIGHTER_BOMBER:
					case SHIP_TYPE_CRUISER:
					case SHIP_TYPE_AWACS:
					case SHIP_TYPE_GAS_MINER:
					case SHIP_TYPE_CORVETTE:
					case SHIP_TYPE_FREIGHTER:
					case SHIP_TYPE_CAPITAL:
					case SHIP_TYPE_TRANSPORT:
					case SHIP_TYPE_SUPERCAP:*/
						break;

					default:
						illegal_ships++;
						unmark_object(OBJ_INDEX(ptr));
				}
			}
		}

		ptr = GET_NEXT(ptr);
	}

	// if this wing is a player starting wing, automatically set the hotkey for this wing
	for (i = 0; i < MAX_STARTING_WINGS; i++ ) {
		if ( !stricmp(Wings[wing].name, Starting_wing_names[i]) ) {
			Wings[wing].hotkey = i;
			break;
		}
	}

	count = friendly = hostile = 0;
	if (Objects[Ships[Player_start_shipnum].objnum].flags & OF_MARKED)
		count = 1;

	ptr = GET_FIRST(&obj_used_list);
	while (ptr != END_OF_LIST(&obj_used_list)) {
		if (ptr->flags & OF_MARKED) {
			if ((ptr->type == OBJ_START) && (ptr->instance == Player_start_shipnum))
				i = 0;  // player 1 start always goes to front of the wing
			else
				i = count++;

			Assert((ptr->type == OBJ_SHIP) || (ptr->type == OBJ_START));
			ship = ptr->instance;
			if (Ships[ship].wingnum != -1) {
				if (ptr->type == OBJ_SHIP)
					remove_ship_from_wing(ship);
				else
					remove_player_from_wing(ptr->instance);
			}

			sprintf(msg, "%s %d", Wings[wing].name, i + 1);
			rename_ship(ship, msg);
			if (Ships[ship].team == TEAM_FRIENDLY)
				friendly = 1;
			else if ((Ships[ship].team == TEAM_HOSTILE) || (Ships[ship].team == TEAM_NEUTRAL))
				hostile = 1;

			Wings[wing].ship_index[i] = ship;
			Ships[ship].wingnum = wing;
			if (Ships[ship].arrival_cue >= 0)
				free_sexp2(Ships[ship].arrival_cue);

			Ships[ship].arrival_cue = Locked_sexp_false;
			if (Ships[ship].departure_cue >= 0)
				free_sexp2(Ships[ship].departure_cue);

			Ships[ship].departure_cue = Locked_sexp_false;

			wing_objects[wing][i] = OBJ_INDEX(ptr);
			if (OBJ_INDEX(ptr) == leader)
				Wings[wing].special_ship = i;
		}

		ptr = GET_NEXT(ptr);
	}

	if (!count)  // this should never happen, so if it does, needs to be fixed now.
		Error(LOCATION, "No valid ships were selected to form wing from");

	Wings[wing].wave_count = count;
	num_wings++;

//	if (starts)
//		Fred_main_wnd->MessageBox("Multi-player starting points can't be part of a wing!\n"
//			"All marked multi-player starting points were ignored",
//			"Error", MB_ICONEXCLAMATION);

	if (waypoints)
		Fred_main_wnd->MessageBox("Waypoints can't be part of a wing!\n"
			"All marked waypoints were ignored",
			"Error", MB_ICONEXCLAMATION);

	if (illegal_ships)
		Fred_main_wnd->MessageBox("Some ship types aren't allowed to be in a wing.\n"
			"All marked ships of these types were ignored",
			"Error", MB_ICONEXCLAMATION);

	if (friendly && hostile)
		Fred_main_wnd->MessageBox("Both hostile and friendly ships in same wing", "Warning");

	mark_wing(wing);
	return 0;
}