Beispiel #1
0
/**
 * @brief Sells the given aircraft with all the equipment.
 * @param aircraft The aircraft to sell
 * @return @c true if the aircraft could get sold, @c false otherwise
 */
bool BS_SellAircraft (aircraft_t* aircraft)
{
	int j;

	if (AIR_GetTeamSize(aircraft) > 0)
		return false;

	if (!AIR_IsAircraftInBase(aircraft))
		return false;

	/* sell off any items which are mounted on it */
	for (j = 0; j < aircraft->maxWeapons; j++) {
		const aircraftSlot_t* slot = &aircraft->weapons[j];
		BS_ProcessCraftItemSale(slot->item, 1);
		BS_ProcessCraftItemSale(slot->ammo, 1);
	}

	BS_ProcessCraftItemSale(aircraft->shield.item, 1);
	/* there should be no ammo here, but checking can't hurt */
	BS_ProcessCraftItemSale(aircraft->shield.ammo, 1);

	for (j = 0; j < aircraft->maxElectronics; j++) {
		const aircraftSlot_t* slot = &aircraft->electronics[j];
		BS_ProcessCraftItemSale(slot->item, 1);
		/* there should be no ammo here, but checking can't hurt */
		BS_ProcessCraftItemSale(slot->ammo, 1);
	}

	/* the capacities are also updated here */
	BS_AddAircraftToMarket(aircraft, 1);
	CP_UpdateCredits(ccs.credits + BS_GetAircraftSellingPrice(aircraft));
	AIR_DeleteAircraft(aircraft);

	return true;
}
Beispiel #2
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);
}
Beispiel #3
0
TEST_F(CampaignTest, testAircraftHandling)
{
	const vec2_t destination = { 10, 10 };
	base_t* base;
	aircraft_t* aircraft;
	aircraft_t* newAircraft;
	aircraft_t* aircraftTemplate;
	int firstIdx;
	int initialCount;
	int count;
	int newFound;

	base = CreateBase("unittestaircraft", destination);
	ASSERT_TRUE(nullptr != base);

	/** @todo we should not assume that initial base has aircraft. It's a campaign parameter */
	aircraft = AIR_GetFirstFromBase(base);
	ASSERT_TRUE(nullptr != aircraft);

	/* aircraft should have a template */
	aircraftTemplate = aircraft->tpl;
	ASSERT_TRUE(nullptr != aircraftTemplate);

	firstIdx = aircraft->idx;
	initialCount = AIR_BaseCountAircraft(base);

	/* test deletion (part 1) */
	AIR_DeleteAircraft(aircraft);
	count = AIR_BaseCountAircraft(base);
	ASSERT_EQ(count, initialCount - 1);

	/* test addition (part 1) */
	newAircraft = AIR_NewAircraft(base, aircraftTemplate);
	ASSERT_TRUE(nullptr != newAircraft);
	count = AIR_BaseCountAircraft(base);
	ASSERT_EQ(count, initialCount);

	/* new aircraft assigned to the right base */
	ASSERT_EQ(newAircraft->homebase, base);

	newFound = 0;
	AIR_Foreach(a) {
		/* test deletion (part 2) */
		ASSERT_NE(firstIdx, a->idx);
		/* for test addition (part 2) */
		if (a->idx == newAircraft->idx)
			newFound++;
	}
	/* test addition (part 2) */
	ASSERT_EQ(newFound, 1);

	/* check if AIR_Foreach iterates through all aircraft */
	AIR_Foreach(a) {
		AIR_DeleteAircraft(a);
	}
	aircraft = AIR_GetFirstFromBase(base);
	ASSERT_TRUE(nullptr == aircraft);
	count = AIR_BaseCountAircraft(base);
	ASSERT_EQ(count, 0);

	/* cleanup for the following tests */
	E_DeleteAllEmployees(nullptr);

	base->founded = false;
}
Beispiel #4
0
static void testAircraftHandling (void)
{
	const vec2_t destination = { 10, 10 };
	campaign_t *campaign;
	base_t *base;
	aircraft_t *aircraft;
	aircraft_t *newAircraft;
	aircraft_t *aircraftTemplate;
	int firstIdx;
	int initialCount;
	int count;
	int newFound;

	ResetCampaignData();

	campaign = GetCampaign();

	base = CreateBase("unittestaircraft", destination);
	CU_ASSERT_PTR_NOT_NULL_FATAL(base);

	/** @todo we should not assume that initial base has aircraft. It's a campaign parameter */
	aircraft = AIR_GetFirstFromBase(base);
	CU_ASSERT_PTR_NOT_NULL_FATAL(aircraft);

	/* aircraft should have a template */
	aircraftTemplate = aircraft->tpl;
	CU_ASSERT_PTR_NOT_NULL_FATAL(aircraftTemplate);

	firstIdx = aircraft->idx;
	initialCount = AIR_BaseCountAircraft(base);

	/* test deletion (part 1) */
	AIR_DeleteAircraft(aircraft);
	count = AIR_BaseCountAircraft(base);
	CU_ASSERT_EQUAL(count, initialCount - 1);

	/* test addition (part 1) */
	newAircraft = AIR_NewAircraft(base, aircraftTemplate);
	CU_ASSERT_PTR_NOT_NULL_FATAL(newAircraft);
	count = AIR_BaseCountAircraft(base);
	CU_ASSERT_EQUAL(count, initialCount);

	/* new aircraft assigned to the right base */
	CU_ASSERT_EQUAL(newAircraft->homebase, base);

	newFound = 0;
	AIR_Foreach(aircraft) {
		/* test deletion (part 2) */
		CU_ASSERT_NOT_EQUAL(firstIdx, aircraft->idx);
		/* for test addition (part 2) */
		if (aircraft->idx == newAircraft->idx)
			newFound++;
	}
	/* test addition (part 2) */
	CU_ASSERT_EQUAL(newFound, 1);

	/* check if AIR_Foreach iterates through all aircraft */
	AIR_Foreach(aircraft) {
		AIR_DeleteAircraft(aircraft);
	}
	aircraft = AIR_GetFirstFromBase(base);
	CU_ASSERT_PTR_NULL_FATAL(aircraft);
	count = AIR_BaseCountAircraft(base);
	CU_ASSERT_EQUAL(count, 0);

	/* cleanup for the following tests */
	E_DeleteAllEmployees(NULL);

	base->founded = qfalse;
}