26 #include "../../DateTime.h" 27 #include "../../cl_shared.h" 28 #include "../../../shared/parse.h" 29 #include "../../../shared/shared.h" 35 #include "../../ui/node/ui_node_linechart.h" 39 #define HAPPINESS_ALIEN_MISSION_LOSS -0.02 40 #define HAPPINESS_MAX_MISSION_IMPACT 0.07 66 if (nationID ==
nullptr) {
67 cgi->Com_Printf(
"NAT_GetNationByID: nullptr nationID\n");
71 if (
Q_streq(nation->id, nationID))
75 cgi->Com_Printf(
"NAT_GetNationByID: Could not find nation '%s'\n", nationID);
94 float happinessFactor;
96 switch (mission->stage) {
135 return &nation->
stats[0];
146 if (happiness < 0.015)
147 return _(
"Giving up");
148 else if (happiness < 0.025)
150 else if (happiness < 0.04)
152 else if (happiness < 0.06)
154 else if (happiness < 0.10)
156 else if (happiness < 0.20)
157 return _(
"Tolerant");
158 else if (happiness < 0.30)
160 else if (happiness < 0.50)
162 else if (happiness < 0.70)
164 else if (happiness < 0.95)
167 return _(
"Exuberant");
192 const char* newString;
194 const float oldHappiness = stats->
happiness;
195 const float middleHappiness = (minhappiness + 1.0) / 2;
206 if (oldString != newString) {
208 _(
"Nation %s changed happiness from %s to %s"),
_(nation->
name), oldString, newString);
210 }
else if (oldHappiness > middleHappiness && happiness < middleHappiness) {
212 _(
"Nation %s changed happiness to %s"),
_(nation->
name), newString);
214 }
else if (happiness < minhappiness && oldHappiness > minhappiness) {
216 _(
"Happiness of nation %s is %s and less than minimal happiness allowed to the campaign"),
_(nation->
name), newString);
269 float performanceAlien;
270 float performanceCivilian;
271 float deltaHappiness = 0.0f;
272 float happinessDivisor = 5.0f;
273 float victoryBonusPerAlien = 0.1f;
281 if (civilianSum <= 1) {
282 performanceCivilian = 0.0f;
297 performance = performanceCivilian + performanceAlien;
300 deltaHappiness = 0.004 * civilianSum + 0.004 * alienSum;
308 float happinessFactor;
311 if (nation == affectedNation)
312 happinessFactor = deltaHappiness;
314 happinessFactor = deltaHappiness / happinessDivisor;
388 cgi->Com_Printf(
"CL_ParseNations: nation def \"%s\" with same name found, second ignored\n",
name);
452 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)
653 cgi->UI_ExecuteConfunc(
"ui_nation_graph_add_point %s %d %f",
654 nation->id, (monthIdx * dx), height - dyFunding * funding);
656 cgi->UI_ExecuteConfunc(
"ui_nation_graph_add_point %s %d %f",
657 nation->id, (monthIdx * dx), height - (height * nation->stats[monthIdx].happiness));
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}
xmlNode_t *IMPORT * XML_GetNode(xmlNode_t *parent, const char *name)
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.
#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.
A base with all it's data.
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
static void NAT_DrawCharts_f(void)
Console command for UI to draw charts.
Detailed information about the nation relationship (currently per month, but could be used elsewhere)...
#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
const char *IMPORT * Cmd_Argv(int n)
float victoryBonusPerAlien
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
linkedList_t * populations
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...
char *IMPORT * PoolStrDup(const char *in, memPool_t *pool, const int tagNum)
#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.
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.
const char *IMPORT * XML_GetString(xmlNode_t *parent, const char *name)
#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)
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)
xmlNode_t *IMPORT * XML_GetNextNode(xmlNode_t *current, xmlNode_t *parent, const char *name)
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
static const short MONTHS_PER_YEAR
int NAT_GetFunding(const nation_t *const nation, int month)
Get the funding of a nation at a certain month.
const linkedList_t *IMPORT * LIST_ContainsString(const linkedList_t *list, const char *string)
Structure with mission info needed to create results summary at menu won.
nationInfo_t stats[DateTime::MONTHS_PER_YEAR]
int civiliansKilledFriendlyFire
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.
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
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.
const char *IMPORT * Com_UFOTypeToShortName(ufoType_t type)
nation_t * GEO_GetNation(const vec2_t pos)
Translate nation map color to nation.
bool NAT_ScriptSanityCheck(void)
Checks the parsed nations and cities for errors.
uiNode_t *IMPORT * UI_GetNodeByPath(const char *path)
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.