2 Copyright (C) 2004-2011 Parallel Realities
3 Copyright (C) 2011-2015 Perpendicular Dimensions
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.
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.
14 See the GNU General Public License for more details.
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.
28 for (int i = 0 ; i < 10 ; i++)
37 fightingGaldov = false;
40 foundItems = totalItems = 0;
41 foundMIAs = totalMIAs = 0;
44 limitLeft = limitUp = 0;
45 limitRight = ((MAPWIDTH - 40) * BRICKSIZE);
46 limitDown = ((MAPHEIGHT - 30) * BRICKSIZE);
50 for (int x = 0 ; x < MAPWIDTH ; x++)
51 for (int y = 0 ; y < MAPHEIGHT ; y++)
54 for (int i = 0 ; i < 10 ; i++)
55 allowableEnemy[i] = NULL;
57 maxAllowableEnemies = 0;
69 objectiveList.clear();
77 waterLevel = requiredWaterLevel = -1;
78 isBossMission = false;
80 isBlizzardLevel = false;
81 isCavesTileset = false;
82 isGrasslandsTileset = false;
85 doBossLevelAction = NULL;
86 bossEnergyMeterBit = 0;
88 for (int i = 0 ; i < 10 ; i++)
97 windPower = windChangeTime = 0;
104 persistantList.clear();
107 bool Map::isPracticeMission()
109 if (strstr(name, "Practice"))
115 bool Map::isSolid(int x, int y)
117 if ((data[x][y] >= MAP_BREAKABLE) && (data[x][y] < MAP_DECORATION))
125 bool Map::isBreakable(int x, int y)
127 if ((data[x][y] >= MAP_BREAKABLE) && (data[x][y] <= MAP_BREAKABLE2))
135 bool Map::isNoReset(int x, int y)
137 if ((data[x][y] >= MAP_NORESET) && (data[x][y] < MAP_DECORATION))
145 bool Map::isLiquid(int x, int y)
151 else if ((data[x][y] >= MAP_WATER) && (data[x][y] <= MAP_LAVA))
155 else if ((data[x][y] >= MAP_WATERANIM) && (data[x][y] <= MAP_LAVAANIM))
163 bool Map::isTopLayer(int x, int y)
165 if (data[x][y] >= MAP_TOPLAYER)
173 Persistant *Map::getPersistant(const char *name)
175 Persistant *p = (Persistant*)persistantList.getHead();
177 while (p->next != NULL)
179 p = (Persistant*)p->next;
181 if (strcmp(p->stageName, name) == 0)
190 Persistant *Map::createPersistant(const char *name)
192 Persistant *p = (Persistant*)persistantList.getHead();
194 while (p->next != NULL)
196 p = (Persistant*)p->next;
198 if (strcmp(p->stageName, name) == 0)
204 debug(("Creating %s in persistance list...\n", name));
206 p = new Persistant();
209 persistantList.add(p);
214 void Map::destroyPersistant(const char *name)
216 Persistant *p = (Persistant*)persistantList.getHead();
218 while (p->next != NULL)
220 p = (Persistant*)p->next;
222 if (strcmp(p->stageName, name) == 0)
224 strlcpy(p->stageName, "@none@", sizeof p->stageName);
231 void Map::setName(const char *name)
233 strlcpy(this->name, name, sizeof this->name);
235 if (strstr(name, "BioMech"))
237 isBossMission = true;
240 if (strcmp(name, "Galdov") == 0)
242 isBossMission = true;
245 if (strcmp(name, "Final Battle") == 0)
247 isBossMission = true;
250 if (strstr(name, "Ice"))
255 if (strstr(name, "Arctic"))
258 isBlizzardLevel = true;
262 void Map::setClipping(int limitLeft, int limitRight, int limitUp, int limitDown)
264 if (limitLeft != -1) this->limitLeft = limitLeft;
265 if (limitRight != -1) this->limitRight = limitRight;
266 if (limitUp != -1) this->limitUp = limitUp;
267 if (limitDown != -1) this->limitDown = limitDown;
270 void Map::addTrain(const char *name, int startX, int startY, int endX, int endY, int pause, bool atStart, bool active)
272 Train *train = new Train();
273 train->setName(name);
274 train->type = TR_TRAIN;
275 train->set(startX, startY, endX, endY, pause, atStart);
276 train->active = active;
283 debug(("WARNING: TRAIN WITH 0 WAIT TIME ADDED '%s' (%d:%d)\n", name, startX, startY));
286 trainList.add(train);
289 void Map::addDoor(const char *name, int type, int startX, int startY, int endX, int endY, bool active)
291 Train *train = new Train();
292 train->setName(name);
296 train->set(startX, startY, endX, endY, 0, false);
297 train->active = active;
299 if (type < TR_SLIDEDOOR)
310 trainList.add(train);
313 void Map::addSwitch(const char *name, const char *linkName, const char *requiredObjectName, const char *activateMessage, int type, int x, int y, bool activated)
315 Switch *swt = new Switch();
316 swt->set(name, linkName, requiredObjectName, activateMessage, type, x, y, activated);
321 void Map::addItem(Entity *item)
326 void Map::addBullet(Entity *bullet)
328 bulletList.add(bullet);
331 void Map::addParticle(float x, float y, float dx, float dy, int health, int color, Sprite *sprite, int flags)
333 Particle *particle = new Particle();
334 particle->set(x, y, dx, dy, color, health, flags);
335 particle->setSprite(sprite);
337 particleList.add(particle);
340 void Map::addEnemy(Entity *enemy)
342 enemyList.add(enemy);
345 void Map::addMIA(Entity *mia)
350 void Map::addObstacle(Entity *obstacle)
352 obstacleList.add(obstacle);
355 void Map::addSpawnPoint(const char *name, int x, int y, int type, int subtype, int min, int max, bool active)
357 SpawnPoint *spawnPoint = new SpawnPoint();
358 spawnPoint->create(name, x, y, type, subtype, min, max, active);
360 spawnList.add(spawnPoint);
363 void Map::addEffect(Effect *effect)
365 effectList.add(effect);
368 void Map::addObjective(const char *description, const char *target, int targetValue, bool required)
370 Objective *objective = new Objective(description, target, targetValue, required);
372 objectiveList.add(objective);
375 void Map::addTeleporter(Teleporter *teleporter)
377 teleportList.add(teleporter);
380 void Map::addLineDef(LineDef *lineDef)
382 lineList.add(lineDef);
385 void Map::addTrap(Trap *trap)
390 void Map::evalTileset(const char *baseDir)
392 if (strstr(baseDir, "caves"))
394 isCavesTileset = true;
396 else if (strstr(baseDir, "grasslands"))
398 isGrasslandsTileset = true;
402 void Map::killAllEnemies()
404 Entity *enemy = (Entity*)enemyList.getHead()->next;
406 while (enemy != NULL)
410 enemy = (Entity*)enemy->next;
414 void Map::setAllowableEnemy(Entity *enemy)
416 for (int i = 0 ; i < 10 ; i++)
418 if (allowableEnemy[i] == NULL)
420 allowableEnemy[i] = enemy;
421 maxAllowableEnemies = i + 1;
426 debug(("WARNING: Can't add anymore spawnable enemies to list!!!\n"));
429 char *Map::getSpawnableEnemy(int i)
431 if (allowableEnemy[i] == NULL)
434 return allowableEnemy[i]->name;
437 char *Map::getSpawnableEnemy()
439 if (maxAllowableEnemies == 0)
441 printf("ERROR: No enemy spawn list defined for map '%s'!! Please report this Error!\n", name);
445 return allowableEnemy[Math::prand() % maxAllowableEnemies]->name;
448 void Map::getRandomEntityPosition(int *x, int *y)
450 Entity *ent = (Entity*)miaList.getHead();
452 while (ent->next != NULL)
454 ent = (Entity*)ent->next;
456 if ((Math::prand() % 5) == 0)
464 ent = (Entity*)enemyList.getHead();
466 while (ent->next != NULL)
468 ent = (Entity*)ent->next;
470 if ((Math::prand() % 5) == 0)
478 ent = (Entity*)itemList.getHead();
480 while (ent->next != NULL)
482 ent = (Entity*)ent->next;
484 if ((Math::prand() % 5) == 0)
493 void Map::setMainBossPart(Boss *boss)
497 if (mainBossPart != NULL)
499 bossEnergyMeterBit = 200;
500 bossEnergyMeterBit /= boss->maxHealth;