/** * @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"); }
/** * @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; }
/** * @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; }
/** * @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; }
/** * @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); }
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; }