Exemplo n.º 1
0
/**
 * @brief Actions to perform when destroying one hangar.
 * @param[in] base Pointer to the base where hangar is destroyed.
 * @param[in] capacity Type of hangar capacity: CAP_AIRCRAFT_SMALL or CAP_AIRCRAFT_BIG
 * @note called when player destroy its building or hangar is destroyed during base attack.
 * @note These actions will be performed after we actually remove the building.
 * @pre we checked before calling this function that all parameters are valid.
 * @pre building is not under construction.
 * @sa B_BuildingDestroy_f
 * @todo If player choose to destroy the building, a popup should ask him if he wants to sell aircraft in it.
 */
void CAP_RemoveAircraftExceedingCapacity (base_t* base, baseCapacities_t capacity)
{
	linkedList_t *awayAircraft = nullptr;
	int numAwayAircraft;
	int randomNum;

	/* destroy aircraft only if there's not enough hangar (hangar is already destroyed) */
	if (CAP_GetFreeCapacity(base, capacity) >= 0)
		return;

	/* destroy one aircraft (must not be sold: may be destroyed by aliens) */
	AIR_ForeachFromBase(aircraft, base) {
		const int aircraftSize = aircraft->size;

		switch (aircraftSize) {
		case AIRCRAFT_SMALL:
			if (capacity != CAP_AIRCRAFT_SMALL)
				continue;
			break;
		case AIRCRAFT_LARGE:
			if (capacity != CAP_AIRCRAFT_BIG)
				continue;
			break;
		default:
			cgi->Com_Error(ERR_DROP, "B_RemoveAircraftExceedingCapacity: Unknown type of aircraft '%i'", aircraftSize);
		}

		/* Only aircraft in hangar will be destroyed by hangar destruction */
		if (!AIR_IsAircraftInBase(aircraft)) {
			if (AIR_IsAircraftOnGeoscape(aircraft))
				cgi->LIST_AddPointer(&awayAircraft, (void*)aircraft);
			continue;
		}

		/* Remove aircraft and aircraft items, but do not fire employees */
		AIR_DeleteAircraft(aircraft);
		cgi->LIST_Delete(&awayAircraft);
		return;
	}
	numAwayAircraft = cgi->LIST_Count(awayAircraft);

	if (!numAwayAircraft)
		return;
	/* All aircraft are away from base, pick up one and change it's homebase */
	randomNum = rand() % numAwayAircraft;
	if (!CL_DisplayHomebasePopup((aircraft_t*)cgi->LIST_GetByIdx(awayAircraft, randomNum), false)) {
		aircraft_t *aircraft = (aircraft_t*)cgi->LIST_GetByIdx(awayAircraft, randomNum);
		/* No base can hold this aircraft */
		UFO_NotifyPhalanxAircraftRemoved(aircraft);
		if (!MapIsWater(GEO_GetColor(aircraft->pos, MAPTYPE_TERRAIN, nullptr)))
			CP_SpawnRescueMission(aircraft, nullptr);
		else {
			/* Destroy the aircraft and everything onboard - the aircraft pointer
			 * is no longer valid after this point */
			/* Pilot skills; really kill pilot in this case? */
			AIR_DestroyAircraft(aircraft);
		}
	}
	cgi->LIST_Delete(&awayAircraft);
}
Exemplo n.º 2
0
/**
 * @brief User select a base in the popup_homebase
 * change homebase to selected base.
 */
static void CL_PopupChangeHomebase_f (void)
{
	linkedList_t* data = popupListData;	/**< Use this so we do not change the original popupListData pointer. */
	int selectedPopupIndex;
	int i;
	base_t *base;
	int baseIdx;
	aircraft_t *aircraft = MAP_GetSelectedAircraft();

	/* If popup is opened, that means an aircraft is selected */
	if (!aircraft) {
		Com_Printf("CL_PopupChangeHomebase_f: An aircraft must be selected\n");
		return;
	}

	if (Cmd_Argc() < 2) {
		Com_Printf("Usage: %s <popupIndex>\tpopupIndex=num in base list\n", Cmd_Argv(0));
		return;
	}

	/* read and range check */
	selectedPopupIndex = atoi(Cmd_Argv(1));
	Com_DPrintf(DEBUG_CLIENT, "CL_PopupHomebaseClick_f (popupNum %i, selectedPopupIndex %i)\n", popupNum, selectedPopupIndex);
	if (selectedPopupIndex < 0 || selectedPopupIndex >= popupNum)
		return;

	/* Convert list index to base idx */
	baseIdx = INVALID_BASE;
	for (i = 0; data; data = data->next, i++) {
		if (i == selectedPopupIndex) {
			baseIdx = *(int*)data->data;
			break;
		}
	}

	base = B_GetFoundedBaseByIDX(baseIdx);
	if (base == NULL)
		return;

	AIR_MoveAircraftIntoNewHomebase(aircraft, base);

	UI_PopWindow(qfalse);
	CL_DisplayHomebasePopup(aircraft, qtrue);
}