26 #include "../../cl_shared.h"
27 #include "../../../shared/parse.h"
28 #include "../../../shared/shared.h"
34 #include "../../ui/node/ui_node_linechart.h"
38 #define HAPPINESS_ALIEN_MISSION_LOSS -0.02
39 #define HAPPINESS_MAX_MISSION_IMPACT 0.07
65 if (nationID ==
nullptr) {
66 cgi->Com_Printf(
"NAT_GetNationByID: nullptr nationID\n");
70 if (
Q_streq(nation->id, nationID))
74 cgi->Com_Printf(
"NAT_GetNationByID: Could not find nation '%s'\n", nationID);
93 float happinessFactor;
95 switch (mission->stage) {
134 return &nation->
stats[0];
145 if (happiness < 0.015)
146 return _(
"Giving up");
147 else if (happiness < 0.025)
149 else if (happiness < 0.04)
151 else if (happiness < 0.06)
153 else if (happiness < 0.10)
155 else if (happiness < 0.20)
156 return _(
"Tolerant");
157 else if (happiness < 0.30)
159 else if (happiness < 0.50)
161 else if (happiness < 0.70)
163 else if (happiness < 0.95)
166 return _(
"Exuberant");
191 const char* newString;
193 const float oldHappiness = stats->
happiness;
194 const float middleHappiness = (minhappiness + 1.0) / 2;
205 if (oldString != newString) {
207 _(
"Nation %s changed happiness from %s to %s"),
_(nation->
name), oldString, newString);
209 }
else if (oldHappiness > middleHappiness && happiness < middleHappiness) {
211 _(
"Nation %s changed happiness to %s"),
_(nation->
name), newString);
213 }
else if (happiness < minhappiness && oldHappiness > minhappiness) {
215 _(
"Happiness of nation %s is %s and less than minimal happiness allowed to the campaign"),
_(nation->
name), newString);
268 float performanceAlien;
269 float performanceCivilian;
270 float deltaHappiness = 0.0f;
271 float happinessDivisor = 5.0f;
272 float victoryBonusPerAlien = 0.1f;
280 if (civilianSum <= 1) {
281 performanceCivilian = 0.0f;
296 performance = performanceCivilian + performanceAlien;
299 deltaHappiness = 0.004 * civilianSum + 0.004 * alienSum;
307 float happinessFactor;
310 if (nation == affectedNation)
311 happinessFactor = deltaHappiness;
313 happinessFactor = deltaHappiness / happinessDivisor;
387 cgi->Com_Printf(
"CL_ParseNations: nation def \"%s\" with same name found, second ignored\n", name);
451 cgi->Com_Printf(
"CITY_Parse: city def \"%s\" with same name found, second ignored\n", name);
476 bool cityCanBeUsed =
false;
477 bool parametersFit =
false;
484 cgi->Com_Printf(
"...... city '%s' has no name\n", city->id);
489 cgi->Com_Printf(
"...... city '%s' has a position in the water\n", city->id);
500 parametersFit =
true;
508 for (
int i = numTypes - 1 ;
i >= 0;
i--) {
515 cityCanBeUsed =
true;
520 if (!cityCanBeUsed) {
522 cgi->Com_Printf(
"...... city '%s' can't be used in game: it has no map fitting parameters\n", city->id);
524 cgi->Com_Printf(
" (No map fitting");
525 for (
int i = 0 ;
i < numTypes;
i++)
527 cgi->Com_Printf(
")\n");
545 const int argCount =
cgi->Cmd_Argc();
547 cgi->Com_Printf(
"Usage: %s <confunc> [nationID] [monthIDX]\n",
cgi->
Cmd_Argv(0));
558 if (!nation->stats[monthIDX].inuse)
561 if (argCount >= 4 && monthIDX != -1 * atoi(
cgi->
Cmd_Argv(3)))
564 cgi->UI_ExecuteConfunc(
"%s %s \"%s\" %d %.4f \"%s\" %d \"%f, %f, %f, %f\"",
569 nation->stats[monthIDX].happiness,
586 const int argCount =
cgi->Cmd_Argc();
588 cgi->Com_Printf(
"Usage: %s <stat_type> <chartnode> <width> <height>\n",
cgi->
Cmd_Argv(0));
598 if (width <= 0 || height <= 0)
609 if (!nation->stats[monthIdx].inuse)
612 if (nationIdx == 0 && monthIdx == 0) {
614 maxXVI = nation->stats[monthIdx].xviInfection;
618 if (maxXVI < nation->stats[monthIdx].xviInfection)
619 maxXVI = nation->stats[monthIdx].xviInfection;
625 const float dyFunding = (0 != maxFunding) ? (
float) height / maxFunding : 1;
626 const float dyXvi = (0 != maxXVI) ? (
float) height / maxXVI : 1;
629 if (chart ==
nullptr) {
630 cgi->Com_Printf(
"chart node not found\n");
635 cgi->UI_ExecuteConfunc(
"ui_nation_graph_add_line %s %s %f %f %f %f %s %d",
648 if (!nation->stats[monthIdx].inuse)
651 if (
Q_streq(
"funding", type)) {
653 cgi->UI_ExecuteConfunc(
"ui_nation_graph_add_point %s %d %f",
654 nation->id, (monthIdx * dx), height - dyFunding * funding);
655 }
else if (
Q_streq(
"happiness", type)) {
656 cgi->UI_ExecuteConfunc(
"ui_nation_graph_add_point %s %d %f",
657 nation->id, (monthIdx * dx), height - (height * nation->stats[monthIdx].happiness));
658 }
else if (
Q_streq(
"xvi", type)) {
659 const int xviInfection= nation->stats[monthIdx].xviInfection;
660 cgi->UI_ExecuteConfunc(
"ui_nation_graph_add_point %s %d %f",
661 nation->id, (monthIdx * dx), height - dyXvi * xviInfection);
673 static void NAT_ListCities_f (
void)
676 cgi->Com_Printf(
"City '%s' -- position (%0.1f, %0.1f)\n", city->id, city->pos[0], city->pos[1]);
685 static void NAT_NationList_f (
void)
688 cgi->Com_Printf(
"Nation ID: %s\n", nation->id);
689 cgi->Com_Printf(
"...max-funding %i c\n", nation->maxFunding);
690 cgi->Com_Printf(
"...happiness %0.2f\n", nation->stats[0].happiness);
691 cgi->Com_Printf(
"...xviInfection %i\n", nation->stats[0].xviInfection);
692 cgi->Com_Printf(
"...max-soldiers %i\n", nation->maxSoldiers);
693 cgi->Com_Printf(
"...max-scientists %i\n", nation->maxScientists);
694 cgi->Com_Printf(
"...max-workers %i\n", nation->maxWorkers);
695 cgi->Com_Printf(
"...max-pilots %i\n", nation->maxPilots);
696 cgi->Com_Printf(
"...color r:%.2f g:%.2f b:%.2f a:%.2f\n", nation->color[0], nation->color[1], nation->color[2], nation->color[3]);
697 cgi->Com_Printf(
"...pos x:%.0f y:%.0f\n", nation->pos[0], nation->pos[1]);
719 int totalExpenditure = 0;
726 int newScientists = 0, newSoldiers = 0, newPilots = 0, newWorkers = 0;
728 totalIncome += funding;
758 Com_sprintf(message,
sizeof(message),
_(
"Gained %i %s, %i %s, %i %s, %i %s, and %i %s from nation %s (%s)"),
759 funding,
ngettext(
"credit",
"credits", funding),
760 newScientists,
ngettext(
"scientist",
"scientists", newScientists),
761 newSoldiers,
ngettext(
"soldier",
"soldiers", newSoldiers),
762 newPilots,
ngettext(
"pilot",
"pilots", newPilots),
763 newWorkers,
ngettext(
"worker",
"workers", newWorkers),
772 if (!employee->isHired())
774 cost += employee->salary();
777 totalExpenditure += cost;
792 totalExpenditure += cost;
795 Com_sprintf(message,
sizeof(message),
_(
"Paid %i credits for aircraft"), cost);
800 while ((base =
B_GetNext(base)) !=
nullptr) {
802 totalExpenditure += cost;
804 Com_sprintf(message,
sizeof(message),
_(
"Paid %i credits for upkeep of %s"), cost, base->
name);
808 if (initialCredits < 0) {
811 cost = (
int)ceil(interest);
812 Com_sprintf(message,
sizeof(message),
_(
"Paid %i credits in interest on your debt."), cost);
813 totalExpenditure += cost;
834 nation->stats[
i] = nation->stats[
i - 1];
840 {
"nation_getstats",
NAT_ListStats_f,
"Returns nation happiness and funding stats through a UI callback."},
841 {
"nation_drawcharts",
NAT_DrawCharts_f,
"Draws nation happiness and funding charts."},
843 {
"debug_listcities", NAT_ListCities_f,
"Debug function to list all cities in game."},
844 {
"debug_listnations", NAT_NationList_f,
"List all nations on the game console"},
846 {
nullptr,
nullptr,
nullptr}
854 cgi->Cmd_TableAddList(nationCmds);
865 cgi->Cmd_TableRemoveList(nationCmds);
const nationInfo_t * NAT_GetCurrentMonthInfo(const nation_t *const nation)
Get the current month nation stats.
nation_t * NAT_GetNationByID(const char *nationID)
Return a nation-pointer by the nations id.
uiNode_t *IMPORT * UI_GetNodeByPath(const char *path)
#define Vector2Equal(a, b)
uiMessageListNodeMessage_t * MSO_CheckAddNewMessage(const notify_t messagecategory, const char *title, const char *text, messageType_t type, technology_t *pedia, bool popup)
Adds a new message to message stack. It uses message settings to verify whether sound should be playe...
QGL_EXTERN GLint GLenum type
nation_t * NAT_GetRandom(void)
Return a pointer to a random nation.
float victoryBonusPerAlien
const char * NAT_GetHappinessString(const float happiness)
Translates the nation happiness float value to a string.
#define E_Foreach(employeeType, var)
XML tag constants for savegame.
#define MIS_Foreach(var)
iterates through missions
bool Com_sprintf(char *dest, size_t size, const char *fmt,...)
copies formatted string with buffer-size checking
linkedList_t * populations
static void NAT_DrawCharts_f(void)
Console command for UI to draw charts.
#define SAVE_NATION_NATIONS
const byte * GEO_GetColor(const vec2_t pos, mapType_t type, bool *coast)
Returns the color value from geoscape of a certain mask (terrain, culture or population) at a given p...
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque
uiMessageListNodeMessage_t * MS_AddNewMessage(const char *title, const char *text, messageType_t type, technology_t *pedia, bool popup, bool playSound)
Adds a new message to message stack.
static const cmdList_t nationCmds[]
memPool_t * cp_campaignPool
void CP_GameTimeStop(void)
Stop game time speed.
#define HAPPINESS_ALIEN_MISSION_LOSS
A base with all it's data.
void CP_HandleNationData(float minHappiness, mission_t *mis, const nation_t *affectedNation, const missionResults_t *results, bool won)
Updates each nation's happiness. Should be called at the completion or expiration of every mission...
const linkedList_t *IMPORT * LIST_ContainsString(const linkedList_t *list, const char *string)
#define SAVE_NATION_HAPPINESS
#define REMOVE_ELEM(array, index, n)
void Q_strncpyz(char *dest, const char *src, size_t destsize)
Safe strncpy that ensures a trailing zero.
nationInfo_t stats[MONTHS_PER_YEAR]
bool NAT_LoadXML(xmlNode_t *p)
Nation loading xml callback.
#define ngettext(x, y, cnt)
#define NAT_Foreach(var)
iterates trough nations
void NAT_SetHappiness(const float minhappiness, nation_t *nation, const float happiness)
Updates the nation happiness.
int UFO_GetAvailableUFOsForMission(const interestCategory_t missionType, ufoType_t *ufoTypes, bool checkInterest)
Fill an array with available UFOs for the mission type.
static const value_t nation_vals[]
void NAT_BackupMonthlyData(void)
Backs up each nation's relationship values.
Campaign missions headers.
base_t * B_GetNext(base_t *lastBase)
Iterates through founded bases.
static const value_t city_vals[]
Employee * E_CreateEmployee(employeeType_t type, const nation_t *nation, const ugv_t *ugvType)
Creates an entry of a new employee in the global list and assignes it to no building/base.
#define SAVE_NATION_MONTH
const cgame_import_t * cgi
bool GEO_PositionFitsTCPNTypes(const vec2_t pos, const linkedList_t *terrainTypes, const linkedList_t *cultureTypes, const linkedList_t *populationTypes, const linkedList_t *nations)
Checks for a given location, if it fulfills all criteria given via parameters (terrain, culture, population, nation type)
const char *IMPORT * Com_UFOTypeToShortName(ufoType_t type)
employeeType_t
The types of employees.
void CP_UpdateCredits(int credits)
Sets credits and update mn_credits cvar.
void NAT_UpdateHappinessForAllNations(const float minhappiness)
Lower happiness of nations depending on alien activity.
#define SAVE_NATION_MONTH_IDX
Campaign geoscape time header.
#define MapDef_ForeachSingleplayerCampaign(var)
void NAT_Shutdown(void)
Closing actions for nation-subsystem.
Header for Geoscape management.
Atomic structure used to define most of the UI.
#define HAPPINESS_MAX_MISSION_IMPACT
char cp_messageBuffer[MAX_MESSAGE_TEXT]
CGAME_HARD_LINKED_FUNCTIONS linkedList_t * LIST_Add(linkedList_t **listDest, void const *data, size_t length)
#define SAVE_NATION_NATION
int civiliansKilledFriendlyFire
int NAT_GetFunding(const nation_t *const nation, int month)
Get the funding of a nation at a certain month.
xmlNode_t *IMPORT * XML_GetNextNode(xmlNode_t *current, xmlNode_t *parent, const char *name)
QGL_EXTERN GLuint GLsizei GLsizei GLint GLenum GLchar * name
bool NAT_SaveXML(xmlNode_t *p)
Nation saving callback.
const char * E_GetEmployeeString(employeeType_t type, int n)
Convert employeeType_t to translated string.
void NAT_InitStartup(void)
Init actions for nation-subsystem.
#define MEMBER_SIZEOF(TYPE, MEMBER)
void GEO_PrintParameterStringByPos(const vec2_t pos)
Prints positions parameter in console.
#define MapIsWater(color)
#define LIST_Foreach(list, type, var)
Iterates over a linked list, it's safe to delete the returned entry from the list while looping over ...
Header file for single player campaign control.
enum nt_s notify_t
Notify types.
int CP_GetSalaryUpKeepBase(const salary_t *salary, const base_t *base)
city_t * CITY_GetById(const char *cityId)
Finds a city by it's scripted identifier.
xmlNode_t *IMPORT * XML_AddNode(xmlNode_t *parent, const char *name)
#define AIR_Foreach(var)
iterates trough all aircraft
char *IMPORT * PoolStrDup(const char *in, memPool_t *pool, const int tagNum)
city_t * CITY_GetByPos(vec2_t pos)
Finds a city by it's geoscape coordinates.
void CL_ParseNations(const char *name, const char **text)
Parse the nation data from script file.
static void NAT_ListStats_f(void)
Console command for UI to gather nation statistics.
Structure with mission info needed to create results summary at menu won.
nation_t * GEO_GetNation(const vec2_t pos)
Translate nation map color to nation.
const char *IMPORT * Cmd_Argv(int n)
const char *IMPORT * XML_GetString(xmlNode_t *parent, const char *name)
bool NAT_ScriptSanityCheck(void)
Checks the parsed nations and cities for errors.
xmlNode_t *IMPORT * XML_GetNode(xmlNode_t *parent, const char *name)
void NAT_HandleBudget(const campaign_t *campaign)
Update the nation data from all parsed nation each month.
void CITY_Parse(const char *name, const char **text)
Parse the city data from script file.
const char * NAT_GetCurrentHappinessString(const nation_t *nation)
Translates the current nation happiness float value to a string.
Detailed information about the nation relationship (currently per month, but could be used elsewhere)...