예제 #1
0
/**
 * @brief Choose nation if needed for given mission.
 * @param[in] mission Pointer to the mission we are creating.
 * @param[out] nationList linkedList that will contain the name of the nation where the mission should take place.
 * @note nationList should be empty if no nation should be favoured.
 * @return True if nationList has been filled, false else.
 */
static bool CP_ChooseNation (const mission_t* mission, linkedList_t** nationList)
{
	int randomNumber, max = 0;
	/* Increase this factor to make probability to select non-infected nation higher
	 * Used to make sure that non-infected nation can still be attacked */
	const int OFFSET = 1;
	int i;

	if (mission->ufo)
		return false;

	/* favour mission with higher XVI level */
	for (i = 0; i < ccs.numNations; i++) {
		const nation_t* nation = NAT_GetNationByIDX(i);
		const nationInfo_t* stats = NAT_GetCurrentMonthInfo(nation);
		max += OFFSET + stats->xviInfection;
	}

	randomNumber = (int) (frand() * (float) max);

	/* Select the corresponding nation */
	for (i = 0; i < ccs.numNations; i++) {
		const nation_t* nation = NAT_GetNationByIDX(i);
		const nationInfo_t* stats = NAT_GetCurrentMonthInfo(nation);
		randomNumber -= OFFSET + stats->xviInfection;
		if (randomNumber < 0) {
			cgi->LIST_AddString(nationList, nation->id);
			return true;
		}
	}

	return false;
}
/**
 * @brief Compare nations by happiness.
 * @param[in] a First item to compare
 * @param[in] b Second item to compare
 * @return 1 if a > b
 * @return -1 if b > a
 * @return 0 if a == b
 * @sa UR_SortNations
 */
static int UR_CompareByHappiness (ufoRecoveryNation_t *a, ufoRecoveryNation_t *b)
{
	const nationInfo_t *statsA = NAT_GetCurrentMonthInfo(a->nation);
	const nationInfo_t *statsB = NAT_GetCurrentMonthInfo(b->nation);

	if (statsA->happiness > statsB->happiness)
		return 1;
	if (statsA->happiness < statsB->happiness)
		return -1;
	return 0;
}
/**
 * @brief Function to initialize list to sell recovered UFO to desired nation.
 * @note Command to call this: cp_uforecovery_sell_init.
 */
static void UR_DialogInitSell_f (void)
{
	int i;

	/* Do nothing if recovery process is finished. */
	if (ufoRecovery.recoveryDone)
		return;
	/* Do nothing without a ufoTemplate set */
	if (!ufoRecovery.ufoTemplate)
		return;

	for (i = 0; i < ccs.numNations; i++) {
		const nation_t *nation = NAT_GetNationByIDX(i);
		const nationInfo_t *stats = NAT_GetCurrentMonthInfo(nation);
		int price;

		price = (int) (ufoRecovery.ufoTemplate->price * (.85f + frand() * .3f));
		/* Nation will pay less if corrupted */
		price = (int) (price * exp(-stats->xviInfection / 20.0f));

		ufoRecovery.ufoNations[i].nation = nation;
		ufoRecovery.ufoNations[i].price = price;
	}
	UR_SortNations(UR_GetSortFunctionByColumn(ufoRecovery.sortedColumn), ufoRecovery.sortDescending);
	UR_DialogFillNations();
	cgi->UI_ExecuteConfunc("btnatsel disable");
}
예제 #4
0
파일: cp_xvi.cpp 프로젝트: cigo/ufoai
/**
 * @brief Return the average XVI rate
 * @note XVI = eXtraterrestial Viral Infection
 */
int CP_GetAverageXVIRate (void)
{
	assert(ccs.numNations);

	/* check for XVI infection rate */
	int xviRate = 0;
	for (int i = 0; i < ccs.numNations; i++) {
		const nation_t* nation = NAT_GetNationByIDX(i);
		const nationInfo_t* stats = NAT_GetCurrentMonthInfo(nation);
		xviRate += stats->xviInfection;
	}
	xviRate /= ccs.numNations;
	return xviRate;
}
예제 #5
0
/**
 * @brief Recreates all the employees for a particular employee type in the global list.
 * But it does not overwrite any employees already hired.
 * @param[in] type The type of the employee list to process.
 * @param[in] excludeUnhappyNations True if a nation is unhappy then they wont
 * send any pilots, false if happiness of nations in not considered.
 * @sa CP_NationHandleBudget
 */
int E_RefreshUnhiredEmployeeGlobalList (const employeeType_t type, const qboolean excludeUnhappyNations)
{
	const nation_t *happyNations[MAX_NATIONS];
	int numHappyNations = 0;
	int idx, nationIdx, cnt;
	employee_t *employee;

	happyNations[0] = NULL;
	/* get a list of nations,  if excludeHappyNations is qtrue then also exclude
	 * unhappy nations (unhappy nation: happiness <= 0) from the list */
	for (idx = 0; idx < ccs.numNations; idx++) {
		const nation_t *nation = NAT_GetNationByIDX(idx);
		const nationInfo_t *stats = NAT_GetCurrentMonthInfo(nation);
		if (stats->happiness > 0 || !excludeUnhappyNations) {
			happyNations[numHappyNations] = nation;
			numHappyNations++;
		}
	}

	if (!numHappyNations)
		return 0;

	idx = 0;
	/* Fill the global data employee list with employees, evenly distributed
	 * between nations in the happyNations list */
	E_Foreach(type, employee) {
		/* we don't want to overwrite employees that have already been hired */
		if (!E_IsHired(employee)) {
			E_DeleteEmployee(employee);
			idx++;
		}
	}

	nationIdx = 0;
	cnt = 0;
	while (idx-- > 0) {
		if (E_CreateEmployee(type, happyNations[nationIdx], NULL) != NULL)
			cnt++;
		nationIdx = (nationIdx + 1) % numHappyNations;
	}

	return cnt;
}
예제 #6
0
/**
 * @brief Subverting Mission ends: UFO leave earth.
 * @note Build Base mission -- Stage 3
 */
static void CP_BuildBaseGovernmentLeave (const campaign_t* campaign, mission_t* mission)
{
	nation_t* nation;

	assert(mission);
	assert(mission->ufo);

	mission->stage = STAGE_RETURN_TO_ORBIT;

	/* Mission is a success: government is subverted => lower happiness */
	nation = GEO_GetNation(mission->pos);
	/** @todo when the mission is created, we should select a position where nation exists,
	 * otherwise subverting a government is meaningless */
	if (nation) {
		const nationInfo_t* stats = NAT_GetCurrentMonthInfo(nation);
		NAT_SetHappiness(campaign->minhappiness, nation, stats->happiness + HAPPINESS_SUBVERSION_LOSS);
	}

	CP_MissionDisableTimeLimit(mission);
	UFO_SetRandomDest(mission->ufo);
	/* Display UFO on geoscape if it is detected */
	mission->ufo->landed = false;
}
예제 #7
0
/**
 * @brief Changes nation happiness by given value.
 * @note There must be argument passed to this function being converted to float.
 */
static void CP_ChangeNationHappiness_f (void)
{
	float change;
	nation_t *nation;
	const nationInfo_t *stats;
	const mission_t *mission = MAP_GetSelectedMission();

	if (Cmd_Argc() < 2) {
		Com_Printf("Usage: %s <absolute change value>\n", Cmd_Argv(0));
		return;
	}
	change = atof(Cmd_Argv(1));

	if (!mission) {
		Com_Printf("No mission selected - could not determine nation to use\n");
		return;
	}

	nation = MAP_GetNation(mission->pos);
	assert(nation);

	stats = NAT_GetCurrentMonthInfo(nation);
	NAT_SetHappiness(ccs.curCampaign->minhappiness, nation, stats->happiness + change);
}
예제 #8
0
static int CP_CheckTriggerEvent (const char *expression, const void* userdata)
{
	const char *type;

	/* check that a particular installation type is built already */
	type = Q_strstart(expression, "installation");
	if (type != 0) {
		if (strlen(type) <= 1)
			return -1;
		char value[MAX_VAR];
		Q_strncpyz(value, type + 1, sizeof(value));
		value[strlen(value) - 1] = '\0';
		const installationType_t insType = INS_GetType(value);
		if (INS_HasType(insType, INSTALLATION_NOT_USED))
			return 1;
		return 0;
	}

	/* check whether a particular ufo was detected */
	type = Q_strstart(expression, "ufo");
	if (type != 0) {
		if (strlen(type) <= 1)
			return -1;
		char value[MAX_VAR];
		Q_strncpyz(value, type + 1, sizeof(value));
		value[strlen(value) - 1] = '\0';
		const char* detectedUFO = static_cast<const char*>(userdata);
		if (Q_strnull(detectedUFO))
			return -1;
		return Q_streq(detectedUFO, value);
	}

	/* check that the given xvi level is reached in any nation */
	type = Q_strstart(expression, "xvi");
	if (type != 0) {
		int xvi;
		if (sscanf(type, "[%i]", &xvi) != 1)
			return -1;
		int i;
		/* check for XVI infection rate */
		for (i = 0; i < ccs.numNations; i++) {
			const nation_t *nation = NAT_GetNationByIDX(i);
			const nationInfo_t *stats = NAT_GetCurrentMonthInfo(nation);
			if (stats->xviInfection >= xvi)
				return 1;
		}
		return 0;
	}

	/* check for nation happiness - also see the lost conditions in the campaign */
	type = Q_strstart(expression, "nationhappiness");
	if (type != 0) {
		int nationAmount;

		if (sscanf(type, "[%i]", &nationAmount) != 1)
			return -1;

		int j, nationBelowLimit = 0;
		for (j = 0; j < ccs.numNations; j++) {
			const nation_t *nation = NAT_GetNationByIDX(j);
			const nationInfo_t *stats = NAT_GetCurrentMonthInfo(nation);
			if (stats->happiness < ccs.curCampaign->minhappiness) {
				nationBelowLimit++;
				if (nationBelowLimit >= nationAmount)
					return 1;
			}
		}
		return 0;
	}

	/* check that the given average xvi level is reached */
	type = Q_strstart(expression, "averagexvi");
	if (type != 0) {
		int xvipercent;
		if (sscanf(type, "[%i]", &xvipercent) != 1)
			return -1;
		if (xvipercent < 0 || xvipercent > 100)
			return -1;
		const int xvi = CP_GetAverageXVIRate();
		if (xvi > ccs.curCampaign->maxAllowedXVIRateUntilLost * xvipercent / 100)
			return 1;
		return 0;
	}

	type = Q_strstart(expression, "difficulty");
	if (type != 0) {
		int difficulty;
		if (sscanf(type, "[%i]", &difficulty) != 1)
			return -1;
		return ccs.curCampaign->difficulty == difficulty;
	}

	/* check that these days have passed in the campaign */
	type = Q_strstart(expression, "days");
	if (type != 0) {
		int days;
		if (sscanf(type, "[%i]", &days) != 1)
			return -1;
		date_t d = ccs.curCampaign->date;
		d.day += days;
		if (Date_IsDue(&d))
			return 1;
		return 0;
	}

	type = Q_strstart(expression, "alienscaptured");
	if (type != 0) {
		if (ccs.campaignStats.capturedAliens > 0)
			return 1;
		return 0;
	}

	type = Q_strstart(expression, "samsitearmed");
	if (type != 0) {
		if (!INS_HasType(INSTALLATION_DEFENCE))
			return 1;

		INS_ForeachOfType(installation, INSTALLATION_DEFENCE) {
			if (installation->installationStatus == INSTALLATION_WORKING) {
				for (int i = 0; i < installation->installationTemplate->maxBatteries; i++) {
					const aircraftSlot_t *slot = &installation->batteries[i].slot;
					if (slot->ammoLeft > 0)
						return 1;
				}
			}
		}

		return 0;
	}

	return -1;
}