]> git.mxchange.org Git - quix0rs-blobwars.git/blob - src/mapData.cpp
Import of version 1.14 minus music and sounds.
[quix0rs-blobwars.git] / src / mapData.cpp
1 /*
2 Copyright (C) 2004 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                                 if (!audio.loadSound(SND_AMBIANCE, string[0]))
251                                         graphics.showErrorAndExit(ERR_FILE, string[0]);
252                         }
253                         else if (strcmp("WATERLEVEL", mapEntity) == 0)
254                         {
255                                 sscanf(token, "%*s %*s %d", &param[0]);
256                                 
257                                 map.requiredWaterLevel = param[0];
258                                 
259                                 if (!previouslyCleared)
260                                 {
261                                         map.waterLevel = param[0];
262                                 }
263                                 else
264                                 {
265                                         map.waterLevel = 281;
266                                 }
267                                 
268                                 if (game.skill == 0)
269                                 {
270                                         map.waterLevel = 281;
271                                         map.requiredWaterLevel = 222;
272                                 }                               
273                         }
274                         else if (strcmp("ALPHATILES", mapEntity) == 0)
275                         {
276                                 for (int i = 0 ; i < 15 ; i++)
277                                         *token++;
278
279                                 while (true)
280                                 {
281                                         sscanf(token, "%d", &param[0]);
282
283                                         if (param[0] == -1)
284                                                 break;
285                                                 
286                                         debug(("Setting Alpha for Tile %d\n", param[0]));
287
288                                         SDL_SetAlpha(graphics.tile[param[0]], SDL_SRCALPHA|SDL_RLEACCEL, 130);
289
290                                         while (true)
291                                         {
292                                                 *token++;
293
294                                                 if (*token == ' ')
295                                                         break;
296                                         }
297                                 }
298                         }
299                         else if (strcmp("BACKGROUND", mapEntity) == 0)
300                         {
301                                 sscanf(token, "%*s %*s %s", string[0]);
302                                 graphics.loadBackground(string[0]);
303                         }
304                         else if (strcmp("MUSIC", mapEntity) == 0)
305                         {
306                                 sscanf(token, "%*s %*s %s", string[0]);
307                                 audio.loadMusic(string[0]);
308                         }
309                         else if (allowAtSkillLevel)
310                         {
311                                 graphics.showErrorAndExit("Symbol '%s' not recognised or not implemented in map data", mapEntity);
312                         }
313                 }
314                 else
315                 {
316                         //debug(("Ignoring Line: %s\n", token));
317                 }
318         }
319         
320         /*
321         We need to make sure the player doesn't appear in a wall that was previously
322         destroyed. Things like this aren't stored so we will just remove a block they
323         make have been "in"
324         */
325         if (previouslyCleared)
326         {
327                 int x = game.checkPointX;
328                 int y = game.checkPointY;
329                 
330                 x = x >> BRICKSHIFT;
331                 y = y >> BRICKSHIFT;
332                 
333                 if ((map.data[x][y] >= MAP_BREAKABLE) && (map.data[x][y] <= MAP_BREAKABLE2))
334                 {
335                         map.data[x][y] = MAP_AIR;
336                 }
337         }
338 }
339
340 const char *getActiveState(bool active)
341 {
342         if (active)
343         {
344                 return "ACTIVE";
345         }
346         
347         return "INACTIVE";
348 }
349
350 void createPersistantMapData()
351 {
352         if (!engine.loadDefines())
353         {
354                 graphics.showErrorAndExit("Could not load map define list '%s'", "data/defines.h");
355         }
356         
357         Persistant *persistant = (Persistant*)map.createPersistant(map.name);
358         persistant->clear();
359         
360         if (perfectlyCompleted())
361         {
362                 debug(("createPersistantMapData :: Perfect - Skipping\n"));
363                 return;
364         }
365         
366         char line[1024];
367         strcpy(line, "");
368         
369         char skill;
370         
371         switch (game.skill)
372         {
373                 case 0:
374                         skill = 'E';
375                         break;
376                 case 1:
377                         skill = 'M';
378                         break;
379                 default:
380                         skill = 'H';
381                         break;
382         }
383         
384         sprintf(line, "%c START %d %d\n", skill, (int)game.checkPointX, (int)game.checkPointY);
385         persistant->addLine(line);
386
387         Entity *ent;
388         Switch *swt;
389         Train *train;
390         Trap *trap;
391         Teleporter *teleporter;
392         LineDef *lineDef;
393         SpawnPoint *spawnPoint;
394         
395         char *define[3];
396         
397         ent = (Entity*)map.enemyList.getHead();
398         
399         while (ent->next != NULL)
400         {
401                 ent = (Entity*)ent->next;
402                 sprintf(line, "%c ENEMY \"%s\" %d %d\n", skill, ent->name, (int)ent->x, (int)ent->y);
403                 persistant->addLine(line);
404         }
405         
406         ent = (Entity*)map.itemList.getHead();
407         
408         while (ent->next != NULL)
409         {
410                 ent = (Entity*)ent->next;
411                 
412                 // Don't save items that are dying...
413                 if (ent->flags & ENT_DYING)
414                 {
415                         continue;
416                 }
417                 
418                 sprintf(line, "%c ITEM %d \"%s\" %d %d %s\n", skill, ent->id, ent->name, (int)ent->x, (int)ent->y, ent->sprite[0]->name);
419                 persistant->addLine(line);
420         }
421         
422         ent = (Entity*)map.obstacleList.getHead();
423         
424         while (ent->next != NULL)
425         {
426                 ent = (Entity*)ent->next;
427                 sprintf(line, "%c OBSTACLE \"%s\" %d %d %s\n", skill, ent->name, (int)ent->x, (int)ent->y, ent->sprite[0]->name);
428                 persistant->addLine(line);
429         }
430         
431         swt = (Switch*)map.switchList.getHead();
432         
433         while (swt->next != NULL)
434         {
435                 swt = (Switch*)swt->next;
436                 define[0] = engine.getDefineOfValue("SWT_", swt->type);
437                 define[1] = (char*)getActiveState(swt->activated);
438                 
439                 sprintf(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]);
440                 
441                 persistant->addLine(line);
442         }
443         
444         train = (Train*)map.trainList.getHead();
445         
446         while (train->next != NULL)
447         {
448                 train = (Train*)train->next;
449                 
450                 if (train->type != TR_TRAIN)
451                 {
452                         if (train->type >= TR_SLIDEDOOR)
453                         {
454                                 define[0] = engine.getDefineOfValue("_SLIDE", train->type);
455                         }
456                         else
457                         {
458                                 define[0] = engine.getDefineOfValue("_DOO", train->type);
459                         }
460                         
461                         define[1] = (char*)getActiveState(train->active);
462                         sprintf(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]);
463                 }
464                 else
465                 {
466                         define[0] = engine.getDefineOfValue("TR_A", train->waitAtStart);
467                         define[1] = (char*)getActiveState(train->active);
468                         sprintf(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]);
469                 }
470                                 
471                 persistant->addLine(line);
472         }
473         
474         trap = (Trap*)map.trapList.getHead();
475         
476         while (trap->next != NULL)
477         {
478                 trap = (Trap*)trap->next;
479                 define[0] = engine.getDefineOfValue("TRAP_TYPE", trap->type);
480                 define[1] = (char*)getActiveState(trap->active);
481                 sprintf(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]);
482                 persistant->addLine(line);
483         }
484         
485         teleporter = (Teleporter*)map.teleportList.getHead();
486         
487         while (teleporter->next != NULL)
488         {
489                 teleporter = (Teleporter*)teleporter->next;
490                 define[0] = (char*)getActiveState(teleporter->active);
491                 sprintf(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]);
492                 persistant->addLine(line);
493         }
494         
495         lineDef = (LineDef*)map.lineList.getHead();
496         
497         while (lineDef->next != NULL)
498         {
499                 lineDef = (LineDef*)lineDef->next;
500                 define[0] = (char*)getActiveState(lineDef->activated);
501                 sprintf(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]);
502                 persistant->addLine(line);
503         }
504         
505         spawnPoint = (SpawnPoint*)map.spawnList.getHead();
506         
507         while (spawnPoint->next != NULL)
508         {
509                 spawnPoint = (SpawnPoint*)spawnPoint->next;
510                 define[0] = engine.getDefineOfValue("SPW_", spawnPoint->spawnType);
511                 
512                 if (strstr(define[0], "HAZARD"))
513                 {
514                         define[1] = engine.getDefineOfValue("HAZARD_", spawnPoint->spawnSubType);
515                 }
516                 else
517                 {
518                         define[1] = engine.getDefineOfValue("SPW_", spawnPoint->spawnSubType);
519                 }
520                         
521                 define[2] = (char*)getActiveState(spawnPoint->active);
522                 sprintf(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]);
523                 persistant->addLine(line);
524         }
525         
526         for (int i = 0 ; i < 10 ; i++)
527         {
528                 if (map.getSpawnableEnemy(i) != NULL)
529                 {
530                         sprintf(line, "%c SPAWNABLE_ENEMY \"%s\"\n", skill, map.getSpawnableEnemy(i));
531                         persistant->addLine(line);
532                 }
533         }
534         
535         if (map.waterLevel != -1)
536         {
537                 sprintf(line, "%c WATERLEVEL %d\n", skill, (int)map.waterLevel);
538                 persistant->addLine(line);
539         }
540         
541         // We don't need this anymore. Remove it to free up some memory...
542         engine.defineList.clear();
543 }