]> git.mxchange.org Git - quix0rs-blobwars.git/blob - src/CGameData.cpp
Fix reading one element past the end of an array.
[quix0rs-blobwars.git] / src / CGameData.cpp
1 /*
2 Copyright (C) 2004-2011 Parallel Realities
3 Copyright (C) 2011-2015 Perpendicular Dimensions
4
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
14 See the GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19
20 */
21
22 #include "headers.h"
23
24 GameData::GameData()
25 {
26         completedWorld = false;
27 }
28
29 void GameData::clear()
30 {
31         dataList.clear();
32 }
33
34 void GameData::destroy()
35 {
36         clear();
37 }
38
39 void GameData::addCompletedObjective(const char *key, const char *value, int current, int target)
40 {
41         Data *data = (Data*)dataList.getHead();
42
43         while (data->next != NULL)
44         {
45                 data = (Data*)data->next;
46                 if (strcmp(key, data->key) == 0)
47                 {
48                         if (strcmp(value, data->value) == 0)
49                         {
50                                 data->set(key, value, current, target);
51                                 return;
52                         }
53                 }
54         }
55
56         data = new Data();
57         data->set(key, value, current, target);
58
59         dataList.add(data);
60 }
61
62 void GameData::addCompletedObjective(Data *newData)
63 {
64         Data *data = (Data*)dataList.getHead();
65
66         while (data->next != NULL)
67         {
68                 data = (Data*)data->next;
69                 if (strcmp(data->key, newData->key) == 0)
70                 {
71                         if (strcmp(data->value, newData->value) == 0)
72                         {
73                                 data->set(newData->key, newData->value, newData->current, newData->target);
74                                 return;
75                         }
76                 }
77         }
78
79         dataList.add(newData);
80 }
81
82 void GameData::setMIARescueCount(const char *key, int rescues, int total)
83 {
84         Data *data = (Data*)dataList.getHead();
85
86         char newKey[100];
87         snprintf(newKey, sizeof newKey, "%s MIAs", key);
88
89         while (data->next != NULL)
90         {
91                 data = (Data*)data->next;
92                 if (strcmp(newKey, data->key) == 0)
93                 {
94                         strlcpy(data->value, "MIAs", sizeof data->value);
95                         data->current = rescues;
96                         data->target = total;
97                         return;
98                 }
99         }
100
101         data = new Data();
102
103         data->set(newKey, "MIAs", rescues, total);
104
105         dataList.add(data);
106 }
107
108 bool GameData::MIARescued(const char *stageName, char *name)
109 {
110         Data *data = (Data*)dataList.getHead();
111
112         char newName[100];
113         snprintf(newName, sizeof newName, "MIA_%s", name);
114
115         while (data->next != NULL)
116         {
117                 data = (Data*)data->next;
118                 if (strcmp(data->key, stageName) == 0)
119                 {
120                         if (strcmp(data->value, newName) == 0)
121                         {
122                                 return data->isComplete();
123                         }
124                 }
125         }
126
127         return false;
128 }
129
130 bool GameData::objectiveCompleted(const char *stageName, const char *name)
131 {
132         Data *data = (Data*)dataList.getHead();
133
134         while (data->next != NULL)
135         {
136                 data = (Data*)data->next;
137                 if (strcmp(data->key, stageName) == 0)
138                 {
139                         if (strcmp(data->value, name) == 0)
140                         {
141                                 return (data->current == data->target);
142                         }
143                 }
144         }
145
146         return false;
147 }
148
149 void GameData::getObjectiveValues(const char *stageName, const char *name, int *current, int *target)
150 {
151         *current = -1;
152         *target = -1;
153         
154         Data *data = (Data*)dataList.getHead();
155
156         while (data->next != NULL)
157         {
158                 data = (Data*)data->next;
159                 if (strcmp(data->key, stageName) == 0)
160                 {
161                         if (strcmp(data->value, name) == 0)
162                         {
163                                 data->getCurrentTarget(current, target);
164                                 return;
165                         }
166                 }
167         }
168 }
169
170 bool GameData::stagePreviouslyCleared(const char *stageName)
171 {
172         Data *data = (Data*)dataList.getHead();
173
174         while (data->next != NULL)
175         {
176                 data = (Data*)data->next;
177                 if (strcmp(data->key, stageName) == 0)
178                 {
179                         return true;
180                 }
181         }
182
183         return false;
184 }
185
186 bool GameData::isCompleted(const char *key, const char *value)
187 {
188         Data *data = (Data*)dataList.getHead();
189
190         while (data->next != NULL)
191         {
192                 data = (Data*)data->next;
193                 if (strcmp(key, data->key) == 0)
194                 {
195                         if (strcmp(value, data->value) == 0)
196                                 return true;
197                 }
198         }
199
200         return false;
201 }
202
203 bool GameData::levelPrefectlyCleared(const char *level)
204 {
205         Data *data = (Data*)dataList.getHead();
206         
207         bool found = false;
208
209         while (data->next != NULL)
210         {
211                 data = (Data*)data->next;
212
213                 if (strcmp(data->key, level) == 0)
214                 {
215                         found = true;
216
217                         if (!data->isComplete())
218                                 return false;
219                 }
220         }
221         
222         if (!found)
223                 return false;
224
225         return true;
226 }
227
228 bool GameData::requiredLevelCleared(const char *requiredLevel)
229 {
230         Data *data = (Data*)dataList.getHead();
231
232         while (data->next != NULL)
233         {
234                 data = (Data*)data->next;
235
236                 if (strcmp(data->key, requiredLevel) == 0)
237                 {
238                         return true;
239                 }
240         }
241
242         return false;
243 }
244
245 /*
246 Whether or not all the levels in the game have been unlocked
247 */
248 void GameData::calculateWorldCompleted()
249 {
250         completedWorld = false;
251         
252         Data *data = (Data*)dataList.getHead();
253
254         while (data->next != NULL)
255         {
256                 data = (Data*)data->next;
257                 
258                 if (strcmp(data->key, "BioMech HQ") == 0)
259                 {
260                         completedWorld = true;
261                 }
262         }
263 }
264
265 int GameData::getPercentageComplete()
266 {
267         float percentage, total, completed;
268
269         total = completed = percentage = 0;
270
271         Data *data = (Data*)dataList.getHead();
272
273         while (data->next != NULL)
274         {
275                 data = (Data*)data->next;
276
277                 total++;
278
279                 if (data->isComplete())
280                         completed++;
281         }
282
283         if ((total == 0) || (completed == 0))
284                 return 0;
285
286         percentage = (completed / total);
287         percentage *= 100;
288
289         return (int)percentage;
290 }