]> git.mxchange.org Git - quix0rs-blobwars.git/blob - src/CMap.cpp
1a57b3133a3023fe8ea7adc4690ae230f2fe0c6b
[quix0rs-blobwars.git] / src / CMap.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 "headers.h"
22
23 Map::Map()
24 {
25         clear();
26         
27         for (int i = 0 ; i < 10 ; i++)
28         {
29                 boss[i] = NULL;
30         }
31 }
32
33
34 void Map::clear()
35 {
36         fightingGaldov = false;
37         bossNextThink = 0;
38
39         foundItems = totalItems = 0;
40         foundMIAs = totalMIAs = 0;
41         requiredMIAs = 0;
42
43         limitLeft = limitUp = 0;
44         limitRight = ((MAPWIDTH - 40) * BRICKSIZE);
45         limitDown = ((MAPHEIGHT - 30) * BRICKSIZE);
46
47         name[0] = 0;
48
49         for (int x = 0 ; x < MAPWIDTH ; x++)
50                 for (int y = 0 ; y < MAPHEIGHT ; y++)
51                         data[x][y] = 0;
52
53         for (int i = 0 ; i < 10 ; i++)
54                 allowableEnemy[i] = NULL;
55
56         maxAllowableEnemies = 0;
57
58         trainList.clear();
59         itemList.clear();
60         bulletList.clear();
61         enemyList.clear();
62         miaList.clear();
63         obstacleList.clear();
64         particleList.clear();
65         switchList.clear();
66         spawnList.clear();
67         effectList.clear();
68         objectiveList.clear();
69         teleportList.clear();
70         lineList.clear();
71         trapList.clear();
72         
73         remainingMinutes = 0;
74         remainingSeconds = 0;
75         
76         waterLevel = requiredWaterLevel = -1;
77         isBossMission = false;
78         isIceLevel = false;
79         isBlizzardLevel = false;
80         isCavesTileset = false;
81         isGrasslandsTileset = false;
82         bossNextThink = 0;
83         mainBossPart = NULL;
84         doBossLevelAction = NULL;
85         bossEnergyMeterBit = 0;
86         
87         for (int i = 0 ; i < 10 ; i++)
88         {
89                 if (boss[i] != NULL)
90                 {
91                         delete boss[i];
92                 }
93                 boss[i] = NULL;
94         }
95         
96         windPower = windChangeTime = 0;
97 }
98
99 void Map::destroy()
100 {
101         clear();
102         
103         persistantList.clear();
104 }
105
106 bool Map::isPracticeMission()
107 {
108         if (strstr(name, "Practice"))
109                 return true;
110                 
111         return false;
112 }
113
114 bool Map::isSolid(int x, int y)
115 {
116         if ((data[x][y] >= MAP_BREAKABLE) && (data[x][y] < MAP_DECORATION))
117         {
118                 return true;
119         }
120
121         return false;
122 }
123
124 bool Map::isBreakable(int x, int y)
125 {
126         if ((data[x][y] >= MAP_BREAKABLE) && (data[x][y] <= MAP_BREAKABLE2))
127         {
128                 return true;
129         }
130
131         return false;
132 }
133
134 bool Map::isNoReset(int x, int y)
135 {
136         if ((data[x][y] >= MAP_NORESET) && (data[x][y] < MAP_DECORATION))
137         {
138                 return true;
139         }
140
141         return false;
142 }
143
144 bool Map::isLiquid(int x, int y)
145 {
146         if (data[x][y] == 0)
147         {
148                 return false;
149         }
150         else if ((data[x][y] >= MAP_WATER) && (data[x][y] <= MAP_LAVA))
151         {
152                 return true;
153         }
154         else if ((data[x][y] >= MAP_WATERANIM) && (data[x][y] <= MAP_LAVAANIM))
155         {
156                 return true;
157         }
158
159         return false;
160 }
161
162 bool Map::isTopLayer(int x, int y)
163 {
164         if (data[x][y] >= MAP_TOPLAYER)
165         {
166                 return true;
167         }
168
169         return false;
170 }
171
172 Persistant *Map::getPersistant(const char *name)
173 {
174         Persistant *p = (Persistant*)persistantList.getHead();
175         
176         while (p->next != NULL)
177         {
178                 p = (Persistant*)p->next;
179                 
180                 if (strcmp(p->stageName, name) == 0)
181                 {
182                         return p;
183                 }
184         }
185         
186         return NULL;
187 }
188
189 Persistant *Map::createPersistant(const char *name)
190 {
191         Persistant *p = (Persistant*)persistantList.getHead();
192         
193         while (p->next != NULL)
194         {
195                 p = (Persistant*)p->next;
196                 
197                 if (strcmp(p->stageName, name) == 0)
198                 {
199                         return p;
200                 }
201         }
202         
203         debug(("Creating %s in persistance list...\n", name));
204         
205         p = new Persistant();
206         p->setName(name);
207         
208         persistantList.add(p);
209         
210         return p;
211 }
212
213 void Map::destroyPersistant(const char *name)
214 {
215         Persistant *p = (Persistant*)persistantList.getHead();
216         
217         while (p->next != NULL)
218         {
219                 p = (Persistant*)p->next;
220                 
221                 if (strcmp(p->stageName, name) == 0)
222                 {
223                         strlcpy(p->stageName, "@none@", sizeof p->stageName);
224                         p->clear();
225                         return;
226                 }
227         }
228 }
229
230 void Map::setName(const char *name)
231 {
232         strlcpy(this->name, name, sizeof this->name);
233         
234         if (strstr(name, "BioMech"))
235         {
236                 isBossMission = true;
237         }
238                 
239         if (strcmp(name, "Galdov") == 0)
240         {
241                 isBossMission = true;
242         }
243
244         if (strcmp(name, "Final Battle") == 0)
245         {
246                 isBossMission = true;
247         }
248                 
249         if (strstr(name, "Ice"))
250         {
251                 isIceLevel = true;
252         }
253                 
254         if (strstr(name, "Arctic"))
255         {
256                 isIceLevel = true;
257                 isBlizzardLevel = true;
258         }
259 }
260
261 void Map::setClipping(int limitLeft, int limitRight, int limitUp, int limitDown)
262 {
263         if (limitLeft != -1) this->limitLeft = limitLeft;
264         if (limitRight != -1) this->limitRight = limitRight;
265         if (limitUp != -1) this->limitUp = limitUp;
266         if (limitDown != -1) this->limitDown = limitDown;
267 }
268
269 void Map::addTrain(const char *name, int startX, int startY, int endX, int endY, int pause, bool atStart, bool active)
270 {
271         Train *train = new Train();
272         train->setName(name);
273         train->type = TR_TRAIN;
274         train->set(startX, startY, endX, endY, pause, atStart);
275         train->active = active;
276
277         train->width = 64;
278         train->height = 16;
279         
280         if (pause == 0)
281         {
282                 debug(("WARNING: TRAIN WITH 0 WAIT TIME ADDED '%s' (%d:%d)\n", name, startX, startY));
283         }
284
285         trainList.add(train);
286 }
287
288 void Map::addDoor(const char *name, int type, int startX, int startY, int endX, int endY, bool active)
289 {
290         Train *train = new Train();
291         train->setName(name);
292
293         train->type = type;
294
295         train->set(startX, startY, endX, endY, 0, false);
296         train->active = active;
297
298         if (type < TR_SLIDEDOOR)
299         {
300                 train->width = 16;
301                 train->height = 64;
302         }
303         else
304         {
305                 train->width = 64;
306                 train->height = 16;
307         }
308         
309         trainList.add(train);
310 }
311
312 void Map::addSwitch(const char *name, const char *linkName, const char *requiredObjectName, const char *activateMessage, int type, int x, int y, bool activated)
313 {
314         Switch *swt = new Switch();
315         swt->set(name, linkName, requiredObjectName, activateMessage, type, x, y, activated);
316
317         switchList.add(swt);
318 }
319
320 void Map::addItem(Entity *item)
321 {
322         itemList.add(item);
323 }
324
325 void Map::addBullet(Entity *bullet)
326 {
327         bulletList.add(bullet);
328 }
329
330 void Map::addParticle(float x, float y, float dx, float dy, int health, int color, Sprite *sprite, int flags)
331 {
332         Particle *particle = new Particle();
333         particle->set(x, y, dx, dy, color, health, flags);
334         particle->setSprite(sprite);
335         
336         particleList.add(particle);
337 }
338
339 void Map::addEnemy(Entity *enemy)
340 {
341         enemyList.add(enemy);
342 }
343
344 void Map::addMIA(Entity *mia)
345 {
346         miaList.add(mia);
347 }
348
349 void Map::addObstacle(Entity *obstacle)
350 {
351         obstacleList.add(obstacle);
352 }
353
354 void Map::addSpawnPoint(const char *name, int x, int y, int type, int subtype, int min, int max, bool active)
355 {
356         SpawnPoint *spawnPoint = new SpawnPoint();
357         spawnPoint->create(name, x, y, type, subtype, min, max, active);
358
359         spawnList.add(spawnPoint);
360 }
361
362 void Map::addEffect(Effect *effect)
363 {
364         effectList.add(effect);
365 }
366
367 void Map::addObjective(const char *description, const char *target, int targetValue, bool required)
368 {
369         Objective *objective = new Objective(description, target, targetValue, required);
370
371         objectiveList.add(objective);
372 }
373
374 void Map::addTeleporter(Teleporter *teleporter)
375 {
376         teleportList.add(teleporter);
377 }
378
379 void Map::addLineDef(LineDef *lineDef)
380 {
381         lineList.add(lineDef);
382 }
383
384 void Map::addTrap(Trap *trap)
385 {
386         trapList.add(trap);
387 }
388
389 void Map::evalTileset(const char *baseDir)
390 {
391         if (strstr(baseDir, "caves"))
392         {
393                 isCavesTileset = true;
394         }
395         else if (strstr(baseDir, "grasslands"))
396         {
397                 isGrasslandsTileset = true;
398         }
399 }
400
401 void Map::killAllEnemies()
402 {
403         Entity *enemy = (Entity*)enemyList.getHead()->next;
404
405         while (enemy != NULL)
406         {
407                 enemy->health = -1;
408
409                 enemy = (Entity*)enemy->next;
410         }
411 }
412
413 void Map::setAllowableEnemy(Entity *enemy)
414 {
415         for (int i = 0 ; i < 10 ; i++)
416         {
417                 if (allowableEnemy[i] == NULL)
418                 {
419                         allowableEnemy[i] = enemy;
420                         maxAllowableEnemies = i + 1;
421                         return;
422                 }
423         }
424
425         debug(("WARNING: Can't add anymore spawnable enemies to list!!!\n"));
426 }
427
428 char *Map::getSpawnableEnemy(int i)
429 {
430         if (allowableEnemy[i] == NULL)
431                 return NULL;
432         
433         return allowableEnemy[i]->name;
434 }
435
436 char *Map::getSpawnableEnemy()
437 {
438         if (maxAllowableEnemies == 0)
439         {
440                 printf("ERROR: No enemy spawn list defined for map '%s'!! Please report this Error!\n", name);
441                 exit(1);
442         }
443
444         return allowableEnemy[Math::prand() % maxAllowableEnemies]->name;
445 }
446
447 void Map::getRandomEntityPosition(int *x, int *y)
448 {
449         Entity *ent = (Entity*)miaList.getHead();
450
451         while (ent->next != NULL)
452         {
453                 ent = (Entity*)ent->next;
454
455                 if ((Math::prand() % 5) == 0)
456                 {
457                         *x = (int)ent->x;
458                         *y = (int)ent->y;
459                         return;
460                 }
461         }
462
463         ent = (Entity*)enemyList.getHead();
464
465         while (ent->next != NULL)
466         {
467                 ent = (Entity*)ent->next;
468
469                 if ((Math::prand() % 5) == 0)
470                 {
471                         *x = (int)ent->x;
472                         *y = (int)ent->y;
473                         return;
474                 }
475         }
476
477         ent = (Entity*)itemList.getHead();
478
479         while (ent->next != NULL)
480         {
481                 ent = (Entity*)ent->next;
482
483                 if ((Math::prand() % 5) == 0)
484                 {
485                         *x = (int)ent->x;
486                         *y = (int)ent->y;
487                         return;
488                 }
489         }
490 }
491
492 void Map::setMainBossPart(Boss *boss)
493 {
494         mainBossPart = boss;
495         
496         if (mainBossPart != NULL)
497         {
498                 bossEnergyMeterBit = 200;
499                 bossEnergyMeterBit /= boss->maxHealth;
500         }
501 }