]> git.mxchange.org Git - quix0rs-blobwars.git/blob - src/mapData.cpp
Fix new compiler warnings thrown by gcc-4.6
[quix0rs-blobwars.git] / src / mapData.cpp
1 /*
2 Copyright (C) 2004-2010 Parallel Realities
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13 See the GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
19 */
20
21 #include "mapData.h"
22
23 void getMapTokens()
24 {
25         char skillLevel[10];
26         char mapEntity[255];
27         char string[10][1024];
28         int param[10];
29         bool allowAtSkillLevel = false;
30         
31         bool previouslyCleared = false;
32         
33         char *token = NULL;
34         
35         Persistant *persistant = NULL;
36         PersistData *persistData = NULL;
37         
38         while (true)
39         {
40                 if (!previouslyCleared)
41                 {
42                         token = strtok(NULL, "\n");
43                 }
44                 else
45                 {
46                         persistData = (PersistData*)persistData->next;
47                         
48                         if (persistData == NULL)
49                                 break;
50                         
51                         token = persistData->data;
52                 }
53
54                 #if USEPAK
55                 graphics.showLoading(1, 100);
56                 graphics.delay(1);
57                 #endif
58
59                 allowAtSkillLevel = false;
60
61                 sscanf(token, "%s", skillLevel);
62
63                 if ((strstr(skillLevel, "E")) && (game.skill == 0))
64                 {
65                         allowAtSkillLevel = true;
66                 }
67
68                 if ((strstr(skillLevel, "M")) && (game.skill == 1))
69                 {
70                         allowAtSkillLevel = true;
71                 }
72
73                 if ((strstr(skillLevel, "H")) && (game.skill >= 2))
74                 {
75                         allowAtSkillLevel = true;
76                 }
77                 
78                 if ((strstr(skillLevel, "X")) && (game.skill == 3))
79                 {
80                         allowAtSkillLevel = true;
81                 }
82                         
83                 // This is just for practice missions
84                 if (game.skill == -1)
85                         allowAtSkillLevel = true;
86
87                 // Ignore comments
88                 if (strstr(skillLevel, "//"))
89                         allowAtSkillLevel = false;
90
91                 if (strcmp("@EOF@", skillLevel) == 0)
92                 {
93                         break;
94                 }
95
96                 if (allowAtSkillLevel)
97                 {
98                         sscanf(token, "%*s %s", mapEntity);
99
100                         if (strcmp("STAGENAME", mapEntity) == 0)
101                         {
102                                 sscanf(token, "%*s %*s %*c %[^\"] %*c", string[0]);
103
104                                 map.setName(string[0]);
105                                 game.setStageName(string[0]);
106                         }
107                         else if (strcmp("PREVIOUSLY_VISITED", mapEntity) == 0)
108                         {
109                                 previouslyCleared = gameData.stagePreviouslyCleared(map.name);
110                                 
111                                 if (previouslyCleared)
112                                 {
113                                         debug(("Reading Persistance Data...\n"));
114                                         persistant = map.getPersistant(map.name);
115                                         persistData = (PersistData*)persistant->dataList.getHead();
116                                 }
117                         }
118                         else if (strcmp("TIMELIMIT", mapEntity) == 0)
119                         {
120                                 debug(("Loading Time Limit: %s\n", token));
121                                 sscanf(token, "%*s %*s %d %d", &param[0], &param[1]);
122                                 map.remainingMinutes = param[0];
123                                 map.remainingSeconds = param[1];
124                         }
125                         else if (strcmp("TRAIN", mapEntity) == 0)
126                         {
127                                 sscanf(token, "%*s %*s %s %d %d %d %d %d %s %s", string[0], &param[0], &param[1], &param[2], &param[3], &param[4], string[1], string[2]);
128                                 map.addTrain(string[0], param[0], param[1], param[2], param[3], param[4], engine.getValueOfDefine(string[1]), engine.getValueOfDefine(string[2]));
129                         }
130                         else if (strcmp("DOOR", mapEntity) == 0)
131                         {
132                                 sscanf(token, "%*s %*s %s %s %d %d %d %d %s", string[0], string[1], &param[0], &param[1], &param[2], &param[3], string[2]);
133                                 map.addDoor(string[0], engine.getValueOfDefine(string[1]), param[0], param[1], param[2], param[3], engine.getValueOfDefine(string[2]));
134                         }
135                         else if (strcmp("SWITCH", mapEntity) == 0)
136                         {
137                                 sscanf(token, "%*s %*s %*c %[^\"] %*c %s %*c %[^\"] %*c %*c %[^\"] %*c %s %d %d %s", string[0], string[1], string[2], string[3], string[4], &param[0], &param[1], string[5]);
138                                 map.addSwitch(string[0], string[1], string[2], string[3], engine.getValueOfDefine(string[4]), param[0], param[1], engine.getValueOfDefine(string[5]));
139                         }
140                         else if (strcmp("ITEM", mapEntity) == 0)
141                         {
142                                 sscanf(token, "%*s %*s %d %*c %[^\"] %*c %d %d %s", &param[0], string[0], &param[1], &param[2], string[1]);
143                                 
144                                 addItem(param[0], string[0], param[1], param[2], string[1], 60, 1, 0, false);
145
146                                 if (param[0] >= ITEM_MISC)
147                                 {
148                                         map.totalItems++;
149                                 }
150                         }
151                         else if (strcmp("OBSTACLE", mapEntity) == 0)
152                         {
153                                 sscanf(token, "%*s %*s %*c %[^\"] %*c %d %d %s", string[0], &param[0], &param[1], string[1]);
154
155                                 addObstacle(string[0], param[0], param[1], string[1]);
156                         }
157                         else if (strcmp("OBJECTIVE", mapEntity) == 0)
158                         {
159                                 sscanf(token, "%*s %*s %*c %[^\"] %*c %*c %[^\"] %*c %d %s", string[0], string[1], &param[0], string[2]);
160
161                                 map.addObjective(string[0], string[1], param[0], engine.getValueOfDefine(string[2]));
162                         }
163                         else if (strcmp("START", mapEntity) == 0)
164                         {
165                                 sscanf(token, "%*s %*s %d %d", &param[0], &param[1]);
166
167                                 player.place(param[0], param[1]);
168
169                                 game.setCheckPoint(param[0], param[1]);
170                                 game.setObjectiveCheckPoint();
171
172                         }
173                         else if (strcmp("ENEMY", mapEntity) == 0)
174                         {
175                                 if (!engine.devNoMonsters)
176                                 {
177                                         sscanf(token, "%*s %*s %*c %[^\"] %*c %d %d", string[0], &param[0], &param[1]);
178                                         
179                                         if ((game.skill == 0) && (map.waterLevel != -1))
180                                         {
181                                                 addEnemy("Aqua Blob", param[0], param[1], 0);
182                                         }
183                                         else
184                                         {
185                                                 addEnemy(string[0], param[0], param[1], 0);
186                                         }
187                                 }
188                         }
189                         else if (strcmp("MIA", mapEntity) == 0)
190                         {
191                                 sscanf(token, "%*s %*s %*c %[^\"] %*c %d %d %s", string[0], &param[0], &param[1], string[1]);
192                                 addMIA(string[0], param[0], param[1], engine.getValueOfDefine(string[1]));
193                                 map.totalMIAs++;
194                         }
195                         else if (strcmp("REQUIREDMIAS", mapEntity) == 0)
196                         {
197                                 sscanf(token, "%*s %*s %d", &param[0]);
198                                 map.requiredMIAs = param[0];
199                         }
200                         else if (strcmp("LINEDEF", mapEntity) == 0)
201                         {
202                                 sscanf(token, "%*s %*s %*c %[^\"] %*c %s %*c %[^\"] %*c %d %d %d %d %s", string[0], string[1], string[2], &param[0], &param[1], &param[2], &param[3], string[3]);
203
204                                 addLineDef(string[0], string[1], string[2], param[0], param[1], param[2], param[3], engine.getValueOfDefine(string[3]));
205                         }
206                         else if (strcmp("SPAWNPOINT", mapEntity) == 0)
207                         {
208                                 sscanf(token, "%*s %*s %s %d %d %s %s %d %d %s", string[0], &param[0], &param[1], string[1], string[2], &param[2], &param[3], string[3]);
209                                 map.addSpawnPoint(string[0], param[0], param[1], engine.getValueOfDefine(string[1]), engine.getValueOfDefine(string[2]), param[2], param[3], engine.getValueOfDefine(string[3]));
210                         }
211                         else if (strcmp("SPAWNABLE_ENEMY", mapEntity) == 0)
212                         {
213                                 sscanf(token, "%*s %*s %*c %[^\"] %*c", string[0]);
214                                 map.setAllowableEnemy(getDefinedEnemy(string[0]));
215                         }
216                         else if (strcmp("TELEPORTER", mapEntity) == 0)
217                         {
218                                 sscanf(token, "%*s %*s %s %d %d %d %d %s", string[0], &param[0], &param[1], &param[2], &param[3], string[1]);
219                                 addTeleporter(string[0], param[0], param[1], param[2], param[3], engine.getValueOfDefine(string[1]));
220                         }
221                         else if (strcmp("TRAP", mapEntity) == 0)
222                         {
223                                 sscanf(token, "%*s %*s %s %s %d %d %d %d %d %d %d %d %s %s", string[0], string[1], &param[0], &param[1], &param[2], &param[3], &param[4], &param[5], &param[6], &param[7], string[2], string[3]);
224                                 addTrap(string[0], engine.getValueOfDefine(string[1]), param[0], param[1], param[2], param[3], param[4], param[5], param[6], param[7], string[2], engine.getValueOfDefine(string[3]));
225                         }
226                         else if (strcmp("SPRITE", mapEntity) == 0)
227                         {
228                                 sscanf(token, "%*s %*s %[^\n\r]", string[0]);
229                                 loadSprite(string[0]);
230                         }
231                         else if (strcmp("DEFENEMY", mapEntity) == 0)
232                         {
233                                 sscanf(token, "%*s %*s %[^\n\r]", string[0]);
234                                 loadEnemy(string[0]);
235                         }
236                         else if (strcmp("TILESET", mapEntity) == 0)
237                         {
238                                 sscanf(token, "%*s %*s %s", string[0]);
239                                 map.evalTileset(string[0]);
240                                 graphics.loadMapTiles(string[0]);
241                         }
242                         else if (strcmp("CLIPPING", mapEntity) == 0)
243                         {
244                                 sscanf(token, "%*s %*s %d %d %d %d", &param[0], &param[1], &param[2], &param[3]);
245                                 map.setClipping(param[0], param[1], param[2], param[3]);
246                         }
247                         else if (strcmp("AMBIENCE", mapEntity) == 0)
248                         {
249                                 sscanf(token, "%*s %*s %s", string[0]);
250                                 audio.loadSound(SND_AMBIANCE, string[0]);
251                         }
252                         else if (strcmp("WATERLEVEL", mapEntity) == 0)
253                         {
254                                 sscanf(token, "%*s %*s %d", &param[0]);
255                                 
256                                 map.requiredWaterLevel = param[0];
257                                 
258                                 if (!previouslyCleared)
259                                 {
260                                         map.waterLevel = param[0];
261                                 }
262                                 else
263                                 {
264                                         map.waterLevel = 281;
265                                 }
266                                 
267                                 if (game.skill == 0)
268                                 {
269                                         map.waterLevel = 281;
270                                         map.requiredWaterLevel = 222;
271                                 }                               
272                         }
273                         else if (strcmp("ALPHATILES", mapEntity) == 0)
274                         {
275                                 for (int i = 0 ; i < 15 ; i++)
276                                         token++;
277
278                                 while (true)
279                                 {
280                                         sscanf(token, "%d", &param[0]);
281
282                                         if (param[0] == -1)
283                                                 break;
284                                                 
285                                         debug(("Setting Alpha for Tile %d\n", param[0]));
286
287                                         SDL_SetAlpha(graphics.tile[param[0]], SDL_SRCALPHA|SDL_RLEACCEL, 130);
288
289                                         while (true)
290                                         {
291                                                 token++;
292
293                                                 if (*token == ' ')
294                                                         break;
295                                         }
296                                 }
297                         }
298                         else if (strcmp("BACKGROUND", mapEntity) == 0)
299                         {
300                                 sscanf(token, "%*s %*s %s", string[0]);
301                                 graphics.loadBackground(string[0]);
302                         }
303                         else if (strcmp("MUSIC", mapEntity) == 0)
304                         {
305                                 sscanf(token, "%*s %*s %s", string[0]);
306                                 audio.loadMusic(string[0]);
307                         }
308                         else if (allowAtSkillLevel)
309                         {
310                                 graphics.showErrorAndExit("Symbol '%s' not recognised or not implemented in map data", mapEntity);
311                         }
312                 }
313                 else
314                 {
315                         //debug(("Ignoring Line: %s\n", token));
316                 }
317         }
318         
319         /*
320         We need to make sure the player doesn't appear in a wall that was previously
321         destroyed. Things like this aren't stored so we will just remove a block they
322         make have been "in"
323         */
324         if (previouslyCleared)
325         {
326                 int x = game.checkPointX;
327                 int y = game.checkPointY;
328                 
329                 x = x >> BRICKSHIFT;
330                 y = y >> BRICKSHIFT;
331                 
332                 if ((map.data[x][y] >= MAP_BREAKABLE) && (map.data[x][y] <= MAP_BREAKABLE2))
333                 {
334                         map.data[x][y] = MAP_AIR;
335                 }
336         }
337 }
338
339 const char *getActiveState(bool active)
340 {
341         if (active)
342         {
343                 return "ACTIVE";
344         }
345         
346         return "INACTIVE";
347 }
348
349 void createPersistantMapData()
350 {
351         if (!engine.loadDefines())
352         {
353                 graphics.showErrorAndExit("Could not load map define list '%s'", "data/defines.h");
354         }
355         
356         Persistant *persistant = (Persistant*)map.createPersistant(map.name);
357         persistant->clear();
358         
359         if (perfectlyCompleted())
360         {
361                 debug(("createPersistantMapData :: Perfect - Skipping\n"));
362                 return;
363         }
364         
365         char line[1024];
366         line[0] = 0;
367         
368         char skill;
369         
370         switch (game.skill)
371         {
372                 case 0:
373                         skill = 'E';
374                         break;
375                 case 1:
376                         skill = 'M';
377                         break;
378                 default:
379                         skill = 'H';
380                         break;
381         }
382         
383         snprintf(line, sizeof line, "%c START %d %d\n", skill, (int)game.checkPointX, (int)game.checkPointY);
384         persistant->addLine(line);
385
386         Entity *ent;
387         Switch *swt;
388         Train *train;
389         Trap *trap;
390         Teleporter *teleporter;
391         LineDef *lineDef;
392         SpawnPoint *spawnPoint;
393         
394         char *define[3];
395         
396         ent = (Entity*)map.enemyList.getHead();
397         
398         while (ent->next != NULL)
399         {
400                 ent = (Entity*)ent->next;
401                 snprintf(line, sizeof line, "%c ENEMY \"%s\" %d %d\n", skill, ent->name, (int)ent->x, (int)ent->y);
402                 persistant->addLine(line);
403         }
404         
405         ent = (Entity*)map.itemList.getHead();
406         
407         while (ent->next != NULL)
408         {
409                 ent = (Entity*)ent->next;
410                 
411                 // Don't save items that are dying...
412                 if (ent->flags & ENT_DYING)
413                 {
414                         continue;
415                 }
416                 
417                 snprintf(line, sizeof line, "%c ITEM %d \"%s\" %d %d %s\n", skill, ent->id, ent->name, (int)ent->x, (int)ent->y, ent->sprite[0]->name);
418                 persistant->addLine(line);
419         }
420         
421         ent = (Entity*)map.obstacleList.getHead();
422         
423         while (ent->next != NULL)
424         {
425                 ent = (Entity*)ent->next;
426                 snprintf(line, sizeof line, "%c OBSTACLE \"%s\" %d %d %s\n", skill, ent->name, (int)ent->x, (int)ent->y, ent->sprite[0]->name);
427                 persistant->addLine(line);
428         }
429         
430         swt = (Switch*)map.switchList.getHead();
431         
432         while (swt->next != NULL)
433         {
434                 swt = (Switch*)swt->next;
435                 define[0] = engine.getDefineOfValue("SWT_", swt->type);
436                 define[1] = (char*)getActiveState(swt->activated);
437                 
438                 snprintf(line, sizeof line, "%c SWITCH \"%s\" %s \"%s\" \"%s\" %s %d %d %s\n", skill, swt->name, swt->linkName, swt->requiredObjectName, swt->activateMessage, define[0], (int)swt->x, (int)swt->y, define[1]);
439                 
440                 persistant->addLine(line);
441         }
442         
443         train = (Train*)map.trainList.getHead();
444         
445         while (train->next != NULL)
446         {
447                 train = (Train*)train->next;
448                 
449                 if (train->type != TR_TRAIN)
450                 {
451                         if (train->type >= TR_SLIDEDOOR)
452                         {
453                                 define[0] = engine.getDefineOfValue("_SLIDE", train->type);
454                         }
455                         else
456                         {
457                                 define[0] = engine.getDefineOfValue("_DOO", train->type);
458                         }
459                         
460                         define[1] = (char*)getActiveState(train->active);
461                         snprintf(line, sizeof line, "%c DOOR %s %s %d %d %d %d %s\n", skill, train->name, define[0], train->startX, train->startY, train->endX, train->endY, define[1]);
462                 }
463                 else
464                 {
465                         define[0] = engine.getDefineOfValue("TR_A", train->waitAtStart);
466                         define[1] = (char*)getActiveState(train->active);
467                         snprintf(line, sizeof line, "%c TRAIN %s %d %d %d %d %d %s %s\n", skill, train->name, train->startX, train->startY, train->endX, train->endY, train->getPause(), define[0], define[1]);
468                 }
469                                 
470                 persistant->addLine(line);
471         }
472         
473         trap = (Trap*)map.trapList.getHead();
474         
475         while (trap->next != NULL)
476         {
477                 trap = (Trap*)trap->next;
478                 define[0] = engine.getDefineOfValue("TRAP_TYPE", trap->type);
479                 define[1] = (char*)getActiveState(trap->active);
480                 snprintf(line, sizeof line, "%c TRAP %s %s %d %d %d %d %d %d %d %d %s %s\n", skill, trap->name, define[0], (int)trap->damage, (int)trap->speed, (int)trap->startX, (int)trap->startY, (int)trap->endX, (int)trap->endY, (int)trap->waitTime[0], (int)trap->waitTime[1], trap->sprite->name, define[1]);
481                 persistant->addLine(line);
482         }
483         
484         teleporter = (Teleporter*)map.teleportList.getHead();
485         
486         while (teleporter->next != NULL)
487         {
488                 teleporter = (Teleporter*)teleporter->next;
489                 define[0] = (char*)getActiveState(teleporter->active);
490                 snprintf(line, sizeof line, "%c TELEPORTER %s %d %d %d %d %s\n", skill, teleporter->name, (int)teleporter->x, (int)teleporter->y, (int)teleporter->destX, (int)teleporter->destY, define[0]);
491                 persistant->addLine(line);
492         }
493         
494         lineDef = (LineDef*)map.lineList.getHead();
495         
496         while (lineDef->next != NULL)
497         {
498                 lineDef = (LineDef*)lineDef->next;
499                 define[0] = (char*)getActiveState(lineDef->activated);
500                 snprintf(line, sizeof line, "%c LINEDEF \"%s\" %s \"%s\" %d %d %d %d %s\n", skill, lineDef->name, lineDef->linkName, lineDef->activateMessage, (int)lineDef->x, (int)lineDef->y, (int)lineDef->width, (int)lineDef->height, define[0]);
501                 persistant->addLine(line);
502         }
503         
504         spawnPoint = (SpawnPoint*)map.spawnList.getHead();
505         
506         while (spawnPoint->next != NULL)
507         {
508                 spawnPoint = (SpawnPoint*)spawnPoint->next;
509                 define[0] = engine.getDefineOfValue("SPW_", spawnPoint->spawnType);
510                 
511                 if (strstr(define[0], "HAZARD"))
512                 {
513                         define[1] = engine.getDefineOfValue("HAZARD_", spawnPoint->spawnSubType);
514                 }
515                 else
516                 {
517                         define[1] = engine.getDefineOfValue("SPW_", spawnPoint->spawnSubType);
518                 }
519                         
520                 define[2] = (char*)getActiveState(spawnPoint->active);
521                 snprintf(line, sizeof line, "%c SPAWNPOINT %s %d %d %s %s %d %d %s\n", skill, spawnPoint->name, (int)spawnPoint->x, (int)spawnPoint->y, define[0], define[1], (int)(spawnPoint->minInterval / 60), (int)(spawnPoint->maxInterval / 60), define[2]);
522                 persistant->addLine(line);
523         }
524         
525         for (int i = 0 ; i < 10 ; i++)
526         {
527                 if (map.getSpawnableEnemy(i) != NULL)
528                 {
529                         snprintf(line, sizeof line, "%c SPAWNABLE_ENEMY \"%s\"\n", skill, map.getSpawnableEnemy(i));
530                         persistant->addLine(line);
531                 }
532         }
533         
534         if (map.waterLevel != -1)
535         {
536                 snprintf(line, sizeof line, "%c WATERLEVEL %d\n", skill, (int)map.waterLevel);
537                 persistant->addLine(line);
538         }
539         
540         // We don't need this anymore. Remove it to free up some memory...
541         engine.defineList.clear();
542 }