UFO: Alien Invasion
Loading...
Searching...
No Matches
cp_xvi.cpp
Go to the documentation of this file.
1
5
6/*
7Copyright (C) 2002-2025 UFO: Alien Invasion.
8
9This program is free software; you can redistribute it and/or
10modify it under the terms of the GNU General Public License
11as published by the Free Software Foundation; either version 2
12of the License, or (at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17
18See the GNU General Public License for more details.
19
20You should have received a copy of the GNU General Public License
21along with this program; if not, write to the Free Software
22Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
24*/
25
26#include "../../cl_shared.h"
27#include "cp_campaign.h"
28#include "cp_overlay.h"
29#include "cp_geoscape.h"
30#include "cp_xvi.h"
31#include "cp_missions.h"
32#include "save/save_xvi.h"
33
36
39
44static const float XVI_FACTOR = 15.0f;
45
47static const int XVI_DECREASE_DAYS = 7;
48
50#define XVI_EVENT_NAME "rs_alien_xvi_event"
51
56void CP_SpreadXVIAtPos (const vec2_t pos)
57{
58 if (!CP_IsXVIStarted())
59 return;
60
62
64}
65
71{
72 if (!CP_IsXVIStarted())
73 return;
74
75 /* Only decrease XVI if given days has passed */
76 if (ccs.date.getDateAsDays() % XVI_DECREASE_DAYS)
77 return;
78
80
82}
83
89{
90 /* No need to update XVI levels if the overlay didn't change */
92 return;
93
94 /* width in pixel of the XVI overlay */
95 int width;
96 /* height in pixel of the XVI overlay */
97 int height;
98 CP_GetXVIMapDimensions(&width, &height);
99
100 const float heightPerDegree = height / 180.0f;
101 const float widthPerDegree = width / 360.0f;
102 /* parameter used to normalize nation XVI level.
103 * decrease this factor to increase XVI level per nation */
104 const float AREA_FACTOR = 650.0f;
105 /* area used to normalized XVI infection level for each nation.
106 * depend on overlay size so that if we change resolution of
107 * overlay it doesn't impact nation XIInfection */
108 const float normalizingArea = width * height / AREA_FACTOR;
109
110 /* temporary array to store the XVI levels */
111 float* xviInfection = Mem_PoolAllocTypeN(float, ccs.numNations, cp_campaignPool);
112 OBJZERO(*xviInfection);
113
114 for (int y = 0; y < height; y++) {
115 const byte* previousNationColor;
116 const nation_t* nation;
117 /* current position (in latitude / longitude) */
118 vec2_t currentPos;
119
120 int* sum = Mem_PoolAllocTypeN(int, ccs.numNations, cp_campaignPool);
121 OBJZERO(*sum);
122
123 Vector2Set(currentPos, 180.0f, 90.0f - y / heightPerDegree);
124 previousNationColor = GEO_GetColor(currentPos, MAPTYPE_NATIONS, nullptr);
125 nation = GEO_GetNation(currentPos);
126
127 for (int x = 0; x < width; x++) {
128 const byte* nationColor;
129 currentPos[0] = 180.0f - x / widthPerDegree;
130 nationColor = GEO_GetColor(currentPos, MAPTYPE_NATIONS, nullptr);
131 if (!VectorCompare(nationColor, previousNationColor)) {
132 previousNationColor = nationColor;
133 nation = GEO_GetNation(currentPos);
134 }
135 if (nation) {
136 const int xviLevel = CP_GetXVILevel(x, y);
137 if (xviLevel > 0)
138 sum[nation->idx] += xviLevel;
139 }
140 }
141 /* divide the total XVI infection by the area of a pixel
142 * because pixel are smaller as you go closer from the pole */
143 for (int nationIdx = 0; nationIdx < ccs.numNations; nationIdx++)
144 xviInfection[nationIdx] += ((float) sum[nationIdx]) / (cos(torad * currentPos[1]) * normalizingArea);
145 cgi->Free(sum);
146 }
147
148 /* copy the new values of XVI infection level into nation array */
149 int nationIdx = 0;
150 NAT_Foreach(nation) {
151 nation->stats[0].xviInfection = ceil(xviInfection[nationIdx]);
152 nationIdx++;
153 }
154 cgi->Free(xviInfection);
155
157}
158
164{
165 assert(ccs.numNations);
166
167 /* check for XVI infection rate */
168 int xviRate = 0;
169 NAT_Foreach(nation) {
170 const nationInfo_t* stats = NAT_GetCurrentMonthInfo(nation);
171 xviRate += stats->xviInfection;
172 }
173 xviRate /= ccs.numNations;
174 return xviRate;
175}
176
181void CP_SpreadXVI (void)
182{
183 /* don't check if XVI spreading didn't start yet */
184 if (!CP_IsXVIStarted())
185 return;
186
187 MIS_Foreach(mission) {
188 if (mission->stage == STAGE_SPREAD_XVI)
189 CP_SpreadXVIAtPos(mission->pos);
190 }
191}
192
197{
199}
200
201void CP_XVIInit (void)
202{
204 if (!rsAlienXVI)
205 cgi->Com_Error(ERR_DROP, "CP_XVIInit: Could not find tech definition for " XVI_EVENT_NAME);
206}
207
216{
217 int width;
218 int height;
219
220 CP_GetXVIMapDimensions(&width, &height);
221
222 xmlNode_t* n = cgi->XML_AddNode(p, SAVE_XVI_XVI);
223 cgi->XML_AddInt(n, SAVE_XVI_WIDTH, width);
224 cgi->XML_AddInt(n, SAVE_XVI_HEIGHT, height);
225
226 for (int y = 0; y < height; y++) {
227 for (int x = 0; x < width; x++) {
228 const int xviLevel = CP_GetXVILevel(x, y);
229 /* That saves many bytes in the savegame */
230 if (xviLevel > 0) {
231 xmlNode_t* s = cgi->XML_AddNode(n, SAVE_XVI_ENTRY);
232 cgi->XML_AddInt(s, SAVE_XVI_X, x);
233 cgi->XML_AddInt(s, SAVE_XVI_Y, y);
234 cgi->XML_AddInt(s, SAVE_XVI_LEVEL, xviLevel);
235 }
236 }
237 }
238 return true;
239}
240
248{
249 int width, height;
250 xmlNode_t* s;
251 xmlNode_t* n = cgi->XML_GetNode(p, SAVE_XVI_XVI);
252 /* If there is no XVI, it will not be loaded */
253 if (!n) {
255 return true;
256 }
257
258 width = cgi->XML_GetInt(n, SAVE_XVI_WIDTH, 0);
259 height = cgi->XML_GetInt(n, SAVE_XVI_HEIGHT, 0);
260
261 for (s = cgi->XML_GetNode(n, SAVE_XVI_ENTRY); s; s = cgi->XML_GetNextNode(s, n, SAVE_XVI_ENTRY)) {
262 const int x = cgi->XML_GetInt(s, SAVE_XVI_X, 0);
263 const int y = cgi->XML_GetInt(s, SAVE_XVI_Y, 0);
264 const int level = cgi->XML_GetInt(s, SAVE_XVI_LEVEL, 0);
265
266 if (x >= 0 && x < width && y >= 0 && y <= height)
267 CP_SetXVILevel(x, y, level);
268 }
269 return true;
270}
271
277{
278 int numAlienBases;
279 const campaign_t* campaign = ccs.curCampaign;
280
281 ccs.startXVI = true;
282
283 /* Spawn a few alien bases depending on difficulty level */
284 if (campaign->difficulty > 0)
285 numAlienBases = 3;
286 else if (campaign->difficulty < 0)
287 numAlienBases = 1;
288 else
289 numAlienBases = 2;
290
291 for (int i = 0; i < numAlienBases; i++)
293}
294
299{
300 cgi->Cvar_SetValue("mn_xvimap", CP_IsXVIVisible());
301}
Share stuff between the different cgame implementations.
#define ERR_DROP
Definition common.h:211
@ INTERESTCATEGORY_BUILDING
memPool_t * cp_campaignPool
ccs_t ccs
Header file for single player campaign control.
const cgame_import_t * cgi
@ MAPTYPE_NATIONS
Definition cp_campaign.h:96
nation_t * GEO_GetNation(const vec2_t pos)
Translate nation map color to nation.
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...
Header for Geoscape management.
mission_t * CP_CreateNewMission(interestCategory_t category, bool beginNow)
Create a new mission of given category.
Campaign missions headers.
#define MIS_Foreach(var)
iterates through missions
@ STAGE_SPREAD_XVI
Definition cp_missions.h:46
const nationInfo_t * NAT_GetCurrentMonthInfo(const nation_t *const nation)
Get the current month nation stats.
#define NAT_Foreach(var)
iterates trough nations
Definition cp_nation.h:80
int CP_GetXVILevel(int x, int y)
void CP_SetXVILevel(int x, int y, int value)
void CP_InitializeXVIOverlay(void)
Initialize XVI overlay on geoscape.
void CP_GetXVIMapDimensions(int *width, int *height)
void CP_ChangeXVILevel(const vec2_t pos, float factor)
Convert the pos into degrees and increase XVI there.
void CP_DecreaseXVILevelEverywhere(void)
Functions to generate and render overlay for geoscape.
bool RS_IsResearched_ptr(const technology_t *tech)
Checks whether an item is already researched.
technology_t * RS_GetTechByID(const char *id)
return a pointer to the technology identified by given id string
void CP_UpdateXVIMapButton(void)
This will hide or show the geoscape button for handling the xvi overlay map.
Definition cp_xvi.cpp:298
void CP_ReduceXVIEverywhere(void)
Reduce XVI everywhere.
Definition cp_xvi.cpp:70
bool CP_IsXVIVisible(void)
Returns true if the XVI effect should be visible to the player.
Definition cp_xvi.cpp:196
int CP_GetAverageXVIRate(void)
Return the average XVI rate.
Definition cp_xvi.cpp:163
bool XVI_LoadXML(xmlNode_t *p)
Load the XVI map from the savegame.
Definition cp_xvi.cpp:247
void CP_SpreadXVI(void)
Spread XVI for each mission that needs to be daily spread.
Definition cp_xvi.cpp:181
static technology_t * rsAlienXVI
technology for XVI event
Definition cp_xvi.cpp:35
static const float XVI_FACTOR
The factor that is used to determine XVI radius spreading. The higher this factor,...
Definition cp_xvi.cpp:44
static const int XVI_DECREASE_DAYS
Number of days between 2 XVI decrease (everywhere around the world).
Definition cp_xvi.cpp:47
void CP_SpreadXVIAtPos(const vec2_t pos)
Spread XVI at a given position.
Definition cp_xvi.cpp:56
void CP_XVIInit(void)
Definition cp_xvi.cpp:201
void CP_StartXVISpreading_f(void)
Start XVI spreading in campaign.
Definition cp_xvi.cpp:276
bool XVI_SaveXML(xmlNode_t *p)
XVI map saving callback.
Definition cp_xvi.cpp:215
void CP_UpdateNationXVIInfection(void)
Update xviInfection value for each nation, using the XVI overlay.
Definition cp_xvi.cpp:88
static bool xviNationInfectionNeedsUpdate
boolean used to know if each nation XVI level should be updated this day.
Definition cp_xvi.cpp:38
#define XVI_EVENT_NAME
Name of the technology for the XVI event.
Definition cp_xvi.cpp:50
Campaign XVI header.
#define CP_IsXVIStarted()
Definition cp_xvi.h:37
level_locals_t level
Definition g_main.cpp:38
#define torad
Definition mathlib.h:50
#define Mem_PoolAllocTypeN(type, n, pool)
Definition mem.h:42
QGL_EXTERN GLint i
Definition r_gl.h:113
XML tag constants for savegame.
#define SAVE_XVI_X
Definition save_xvi.h:32
#define SAVE_XVI_LEVEL
Definition save_xvi.h:34
#define SAVE_XVI_Y
Definition save_xvi.h:33
#define SAVE_XVI_HEIGHT
Definition save_xvi.h:29
#define SAVE_XVI_WIDTH
Definition save_xvi.h:28
#define SAVE_XVI_ENTRY
Definition save_xvi.h:31
#define SAVE_XVI_XVI
Definition save_xvi.h:27
#define OBJZERO(obj)
Definition shared.h:178
signed int difficulty
Nation definition.
Definition cp_nation.h:46
int idx
Definition cp_nation.h:49
Detailed information about the nation relationship (currently per month, but could be used elsewhere)...
Definition cp_nation.h:35
int xviInfection
Definition cp_nation.h:40
This is the technology parsed from research.ufo.
vec_t vec2_t[2]
Definition ufotypes.h:38
#define Vector2Set(v, x, y)
Definition vector.h:61
#define VectorCompare(a, b)
Definition vector.h:63
#define xmlNode_t
Definition xml.h:24