Bug Summary

File:client/cgame/campaign/cp_xvi.cpp
Location:line 151, column 4
Description:The left expression of the compound assignment is an uninitialized value. The computed value will also be garbage

Annotated Source Code

1/**
2 * @file
3 * @brief Campaign XVI code
4 */
5
6/*
7Copyright (C) 2002-2011 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_map.h"
30#include "cp_xvi.h"
31#include "save/save_xvi.h"
32
33/** @brief technology for XVI event */
34static technology_t *rsAlienXVI;
35
36/** @brief boolean used to know if each nation XVI level should be updated this day. */
37static bool xviNationInfectionNeedsUpdate = false;
38
39/**
40 * @brief The factor that is used to determine XVI radius spreading.
41 * The higher this factor, the faster XVI will spread.
42 */
43static const float XVI_FACTOR = 15.0f;
44
45/** @brief Number of days between 2 XVI decrease (everywhere around the world). */
46static const int XVI_DECREASE_DAYS = 7;
47
48/** @brief Name of the technology for the XVI event */
49#define XVI_EVENT_NAME"rs_alien_xvi_event" "rs_alien_xvi_event"
50
51/**
52 * @brief Spread XVI at a given position.
53 * @param[in] pos Position where XVI should be spread.
54 */
55void CP_SpreadXVIAtPos (const vec2_t pos)
56{
57 if (!CP_IsXVIResearched())
58 return;
59
60 CP_ChangeXVILevel(pos, XVI_FACTOR);
61
62 xviNationInfectionNeedsUpdate = true;
63}
64
65/**
66 * @brief Reduce XVI everywhere.
67 * @note This is called daily.
68 */
69void CP_ReduceXVIEverywhere (void)
70{
71 if (!CP_IsXVIResearched())
72 return;
73
74 /* Only decrease XVI if given days has passed */
75 if (ccs.date.day % XVI_DECREASE_DAYS)
76 return;
77
78 CP_DecreaseXVILevelEverywhere();
79
80 xviNationInfectionNeedsUpdate = true;
81}
82
83/**
84 * @brief Update xviInfection value for each nation, using the XVI overlay.
85 * @note should be executed after all daily event that could change XVI overlay
86 */
87void CP_UpdateNationXVIInfection (void)
88{
89 /* temporary array to store the XVI levels */
90 float xviInfection[MAX_NATIONS8];
91 int y;
92 int nationIdx;
93 /* width in pixel of the XVI overlay */
94 int width;
95 /* height in pixel of the XVI overlay */
96 int height;
97 float heightPerDegree;
98 float widthPerDegree;
99 /* current position (in latitude / longitude) */
100 vec2_t currentPos;
101 /* parameter used to normalize nation XVI level.
102 * decrease this factor to increase XVI level per nation */
103 const float AREA_FACTOR = 650.0f;
104 /* area used to normalized XVI infection level for each nation.
105 * depend on overlay size so that if we change resolution of
106 * overlay it doesn't impact nation XIInfection */
107 float normalizingArea;
108
109 /* No need to update XVI levels if the overlay didn't change */
110 if (!xviNationInfectionNeedsUpdate)
1
Assuming 'xviNationInfectionNeedsUpdate' is not equal to 0
2
Taking false branch
111 return;
112
113 /* Initialize array */
114 for (nationIdx = 0; nationIdx < ccs.numNations; nationIdx++)
3
Loop condition is false. Execution continues on line 117
115 xviInfection[nationIdx] = 0;
116
117 CP_GetXVIMapDimensions(&width, &height);
118 heightPerDegree = height / 180.0f;
119 widthPerDegree = width / 360.0f;
120 normalizingArea = width * height / AREA_FACTOR;
121
122 for (y = 0; y < height; y++) {
4
Assuming 'y' is < 'height'
5
Loop condition is true. Entering loop body
123 int x;
124 int sum[MAX_NATIONS8];
125 const byte* previousNationColor;
126 const nation_t* nation;
127
128 OBJZERO(sum)(memset(&((sum)), (0), sizeof((sum))));
129
130 Vector2Set(currentPos, 180.0f, 90.0f - y / heightPerDegree)((currentPos)[0]=(180.0f), (currentPos)[1]=(90.0f - y / heightPerDegree
))
;
131 previousNationColor = MAP_GetColor(currentPos, MAPTYPE_NATIONS, NULL__null);
132 nation = MAP_GetNation(currentPos);
133
134 for (x = 0; x < width; x++) {
6
Assuming 'x' is >= 'width'
7
Loop condition is false. Execution continues on line 150
135 const byte* nationColor;
136 currentPos[0] = 180.0f - x / widthPerDegree;
137 nationColor = MAP_GetColor(currentPos, MAPTYPE_NATIONS, NULL__null);
138 if (!VectorCompare(nationColor, previousNationColor)((nationColor)[0]==(previousNationColor)[0]?(nationColor)[1]==
(previousNationColor)[1]?(nationColor)[2]==(previousNationColor
)[2]?1:0:0:0)
) {
139 previousNationColor = nationColor;
140 nation = MAP_GetNation(currentPos);
141 }
142 if (nation) {
143 const int xviLevel = CP_GetXVILevel(x, y);
144 if (xviLevel > 0)
145 sum[nation->idx] += xviLevel;
146 }
147 }
148 /* divide the total XVI infection by the area of a pixel
149 * because pixel are smaller as you go closer from the pole */
150 for (nationIdx = 0; nationIdx < ccs.numNations; nationIdx++)
8
Loop condition is true. Entering loop body
151 xviInfection[nationIdx] += ((float) sum[nationIdx]) / (cos(torad(3.14159265358979323846264338327950288/180.0f) * currentPos[1]) * normalizingArea);
9
The left expression of the compound assignment is an uninitialized value. The computed value will also be garbage
152 }
153
154 /* copy the new values of XVI infection level into nation array */
155 for (nationIdx = 0; nationIdx < ccs.numNations; nationIdx++) {
156 nation_t* nation = NAT_GetNationByIDX(nationIdx);
157 nation->stats[0].xviInfection = ceil(xviInfection[nation->idx]);
158 }
159
160 xviNationInfectionNeedsUpdate = false;
161}
162
163/**
164 * @brief Return the average XVI rate
165 * @note XVI = eXtraterrestial Viral Infection
166 */
167int CP_GetAverageXVIRate (void)
168{
169 int XVIRate = 0;
170 int i;
171
172 assert(ccs.numNations)(__builtin_expect(!(ccs.numNations), 0) ? __assert_rtn(__func__
, "src/client/cgame/campaign/cp_xvi.cpp", 172, "ccs.numNations"
) : (void)0)
;
173
174 /* check for XVI infection rate */
175 for (i = 0; i < ccs.numNations; i++) {
176 const nation_t *nation = NAT_GetNationByIDX(i);
177 const nationInfo_t *stats = NAT_GetCurrentMonthInfo(nation);
178 XVIRate += stats->xviInfection;
179 }
180 XVIRate /= ccs.numNations;
181 return XVIRate;
182}
183
184/**
185 * @brief Spread XVI for each mission that needs to be daily spread.
186 * @note Daily called
187 */
188void CP_SpreadXVI (void)
189{
190 /* don't check if XVI spreading didn't start yet */
191 if (!CP_IsXVIResearched())
192 return;
193
194 MIS_Foreach(mission)for (bool mission__break = false, mission__once = true; mission__once
; mission__once = false) for (linkedList_t const* mission__iter
= (ccs.missions); ! mission__break && mission__iter;
) for (mission_t* const mission = ( mission__break = mission__once
= true, (mission_t*) mission__iter->data); mission__once;
mission__break = mission__once = false) if ( mission__iter =
mission__iter->next, false) {} else
{
195 if (mission->stage == STAGE_SPREAD_XVI)
196 CP_SpreadXVIAtPos(mission->pos);
197 }
198}
199
200/**
201 * @brief Returns @c true if the tech for the xvi event is already researched.
202 * If this tech is already researched the aliens will spread their XVI - but it
203 * does not mean that the Phalanx can also do anything against it or is even
204 * able to the map of XVI
205 * @see css.XVIShowMap
206 */
207bool CP_IsXVIResearched (void)
208{
209 return RS_IsResearched_ptr(rsAlienXVI);
210}
211
212void CP_XVIInit (void)
213{
214 rsAlienXVI = RS_GetTechByID(XVI_EVENT_NAME"rs_alien_xvi_event");
215 if (!rsAlienXVI)
216 Com_Error(ERR_DROP1, "CP_XVIInit: Could not find tech definition for " XVI_EVENT_NAME"rs_alien_xvi_event");
217}
218
219/**
220 * @brief XVI map saving callback
221 * @note Only save transparency
222 * @sa Savegame callback
223 * @sa SAV_InitXML
224 * @sa XVI_LoadXML
225 */
226bool XVI_SaveXML (xmlNode_tmxml_node_t *p)
227{
228 int y;
229 int width;
230 int height;
231 xmlNode_tmxml_node_t *n;
232
233 CP_GetXVIMapDimensions(&width, &height);
234
235 n = XML_AddNode(p, SAVE_XVI_XVI"XVI");
236 XML_AddInt(n, SAVE_XVI_WIDTH"width", width);
237 XML_AddInt(n, SAVE_XVI_HEIGHT"height", height);
238
239 for (y = 0; y < height; y++) {
240 int x;
241 for (x = 0; x < width; x++) {
242 const int xviLevel = CP_GetXVILevel(x, y);
243 /* That saves many bytes in the savegame */
244 if (xviLevel > 0) {
245 xmlNode_tmxml_node_t *s = XML_AddNode(n, SAVE_XVI_ENTRY"entry");
246 XML_AddInt(s, SAVE_XVI_X"x", x);
247 XML_AddInt(s, SAVE_XVI_Y"y", y);
248 XML_AddInt(s, SAVE_XVI_LEVEL"level", xviLevel);
249 }
250 }
251 }
252 return true;
253}
254
255/**
256 * @brief Load the XVI map from the savegame.
257 * @sa Savegame callback
258 * @sa SAV_InitXML
259 * @sa XVI_SaveXML
260 */
261bool XVI_LoadXML (xmlNode_tmxml_node_t *p)
262{
263 int width, height;
264 xmlNode_tmxml_node_t *s;
265 xmlNode_tmxml_node_t *n = XML_GetNode(p, SAVE_XVI_XVI"XVI");
266 /* If there is no XVI, it will not be loaded */
267 if (!n) {
268 CP_InitializeXVIOverlay(NULL__null);
269 return true;
270 }
271
272 width = XML_GetInt(n, SAVE_XVI_WIDTH"width", 0);
273 height = XML_GetInt(n, SAVE_XVI_HEIGHT"height", 0);
274
275 for (s = XML_GetNode(n, SAVE_XVI_ENTRY"entry"); s; s = XML_GetNextNode(s, n, SAVE_XVI_ENTRY"entry")) {
276 const int x = XML_GetInt(s, SAVE_XVI_X"x", 0);
277 const int y = XML_GetInt(s, SAVE_XVI_Y"y", 0);
278 const int level = XML_GetInt(s, SAVE_XVI_LEVEL"level", 0);
279
280 if (x >= 0 && x < width && y >= 0 && y <= height)
281 CP_SetXVILevel(x, y, level);
282 }
283 return true;
284}
285
286/**
287 * @brief Start XVI spreading in campaign.
288 * @note This is called when 'a new twist' technology is discovered.
289 */
290void CP_StartXVISpreading_f (void)
291{
292 int i, numAlienBases;
293 const campaign_t *campaign = ccs.curCampaign;
294
295 /** @todo ccs.XVIShowMap should not be enabled at the same time than
296 * CP_IsXVIResearched(): ccs.XVIShowMap means that PHALANX has a map of
297 * XVI, whereas CP_IsXVIResearched() means that aliens started
298 * spreading XVI */
299 ccs.XVIShowMap = true;
300
301 /* Spawn a few alien bases depending on difficulty level */
302 if (campaign->difficulty > 0)
303 numAlienBases = 3;
304 else if (campaign->difficulty < 0)
305 numAlienBases = 1;
306 else
307 numAlienBases = 2;
308
309 for (i = 0; i < numAlienBases; i++)
310 CP_CreateNewMission(INTERESTCATEGORY_BUILDING, false);
311}
312
313/**
314 * @brief This will hide or show the geoscape button for handling the xvi overlay map
315 */
316void CP_UpdateXVIMapButton (void)
317{
318 Cvar_SetValue("mn_xvimap", ccs.XVIShowMap);
319}