2 Copyright (C) 2004-2011 Parallel Realities
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.
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.
13 See the GNU General Public License for more details.
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.
21 #include "mapEditor.h"
23 MedalServer medalServer;
25 ReplayData replayData;
27 void drawMap(int mapX, int mapY)
32 for (int x = 0 ; x < 20 ; x++)
34 for (int y = 0 ; y < 15 ; y++)
38 r.w = r.h = BRICKSIZE - 1;
40 tile = map.data[x + mapX][y + mapY];
42 if (tile == MAP_WATERANIM)
44 tile = graphics.getWaterAnim();
49 graphics.blit(graphics.tile[tile], r.x, r.y, graphics.screen, false);
51 if ((tile >= MAP_NORESET) && (tile < MAP_DECORATION))
53 graphics.drawRect(r.x, r.y, 32, 4, graphics.yellow, graphics.screen);
60 void showMap(int *mapX, int *mapY)
62 SDL_FillRect(graphics.screen, NULL, graphics.black);
64 engine.keyState[SDLK_SPACE] = 0;
69 graphics.updateScreen();
73 if (engine.keyState[SDLK_SPACE])
76 for (int x = 0 ; x < MAPWIDTH ; x++)
78 for (int y = 0 ; y < MAPHEIGHT ; y++)
80 switch (map.data[x][y])
83 graphics.putPixel(x, y, 9, graphics.screen);
86 graphics.putPixel(x, y,graphics.blue, graphics.screen);
89 graphics.putPixel(x, y, graphics.green, graphics.screen);
92 graphics.putPixel(x, y, graphics.red, graphics.screen);
95 graphics.putPixel(x, y, graphics.white, graphics.screen);
103 if (engine.keyState[SDLK_LEFT])
106 if (engine.keyState[SDLK_RIGHT])
109 if (engine.keyState[SDLK_UP])
112 if (engine.keyState[SDLK_DOWN])
117 Math::limitInt(&moveTimer, 0, 60);
119 graphics.drawRect(*mapX, *mapY, 20, 1, graphics.green, graphics.screen);
120 graphics.drawRect(*mapX, *mapY, 1, 15, graphics.green, graphics.screen);
121 graphics.drawRect(*mapX, *mapY + 15, 20, 1, graphics.green, graphics.screen);
122 graphics.drawRect(*mapX + 20, *mapY, 1, 15, graphics.green, graphics.screen);
127 engine.keyState[SDLK_SPACE] = 0;
130 int nextBlock(int current, int dir)
132 if ((current + dir) > 255)
135 if ((current + dir) < 0)
138 int wanted = current;
144 if (wanted < 0) return current;
145 if (wanted > 255) return current;
147 if (graphics.tile[wanted])
154 Entity *enemy = (Entity*)map.enemyList.getHead();
156 int x, y, absX, absY;
158 while (enemy->next != NULL)
160 enemy = (Entity*)enemy->next;
162 if (enemy->owner != enemy)
164 enemy->face = enemy->owner->face;
165 (enemy->face == 0) ? enemy->x = enemy->owner->x + enemy->tx : enemy->x = enemy->owner->x + -enemy->tx;
166 enemy->y = enemy->owner->y + enemy->ty;
169 x = (int)(enemy->x - engine.playerPosX);
170 y = (int)(enemy->y - engine.playerPosY);
175 if ((absX < 800) && (absY < 600))
177 graphics.blit(enemy->getFaceImage(), x, y, graphics.screen, false);
180 if ((!(enemy->flags & ENT_WEIGHTLESS)) && (!(enemy->flags & ENT_FLIES)) && (!(enemy->flags & ENT_SWIMS)))
181 enemy->applyGravity();
186 void deleteEnemy(int x, int y)
191 Entity *enemy = (Entity*)map.enemyList.getHead();
192 Entity *previous = enemy;
194 while (enemy->next != NULL)
196 enemy = (Entity*)enemy->next;
198 if ((enemy->x == x) && (enemy->y == y))
200 map.enemyList.remove(previous, enemy);
210 void saveMap(const char *name)
212 FILE *fp = fopen(name, "wb");
213 Entity *enemy = (Entity*)map.enemyList.getHead();
218 for (int y = 0 ; y < MAPHEIGHT ; y++)
220 for (int x = 0 ; x < MAPWIDTH ; x++)
222 fprintf(fp, "%d ", map.data[x][y]);
227 str = stringHead->next;
230 fprintf(fp, "%s", str->string);
234 while (enemy->next != NULL)
236 enemy = (Entity*)enemy->next;
237 fprintf(fp, "EMH ENEMY \"%s\" %d %d\n", enemy->name, (int)enemy->x, (int)enemy->y);
240 fprintf(fp, "@EOF@\n");
245 printf("Saved %s (%d)\n", name, SDL_GetTicks());
248 void collectMapData()
250 FILE *fp = fopen(game.mapName, "rb");
257 for (int y = 0 ; y < 300 ; y++)
258 fgets(string, 1024, fp);
262 fgets(string, 1024, fp);
263 printf("Read: %s", string);
265 if (strstr(string, "@EOF@"))
268 if (!strstr(string, " ENEMY \""))
271 strlcpy(str->string, string, sizeof str->string);
272 stringTail->next = str;
276 if (strstr(string, "TILESET gfx/ancient"))
278 for (int x = 0 ; x < MAPWIDTH ; x++)
280 for (int y = 0 ; y < MAPHEIGHT ; y++)
282 if ((map.data[x][y] >= 9) && (map.data[x][y] <= 20) && ((Math::prand() % 2) == 0))
283 map.data[x][y] = Math::rrand(9, 20);
288 if (strstr(string, "TILESET gfx/caves"))
290 for (int x = 0 ; x < MAPWIDTH ; x++)
292 for (int y = 0 ; y < MAPHEIGHT ; y++)
294 if ((map.data[x][y] >= 9) && (map.data[x][y] <= 20))
295 map.data[x][y] = Math::rrand(9, 12);
304 void newMap(const char *name)
306 FILE *fp = fopen(name, "wb");
310 for (int y = 0 ; y < MAPHEIGHT ; y++)
312 for (int x = 0 ; x < MAPWIDTH ; x++)
314 fprintf(fp, "%d ", map.data[x][y]);
319 fprintf(fp, "EMH STAGENAME \"unnamed\"\n");
321 fprintf(fp, "EMH TILESET gfx/grasslands\n");
322 fprintf(fp, "EMH BACKGROUND gfx/grasslands/stone.jpg\n");
323 fprintf(fp, "EMH MUSIC music/tunnel\n");
325 fprintf(fp, "EMH ALPHATILES 1 2 3 200 201 202 203 204 244 245 246 -1\n");
327 fprintf(fp, "EMH START 10 10\n");
329 fprintf(fp, "@EOF@\n");
339 void addTileDecoration()
341 printf("Adding Tile Decoration...\n");
343 for (int y = 1 ; y < MAPHEIGHT ; y++)
345 for (int x = 0 ; x < MAPWIDTH ; x++)
347 if ((map.data[x][y] == 9) && (map.data[x][y - 1] == MAP_AIR))
349 if (Math::prand() % 4)
350 map.data[x][y - 1] = 241;
355 for (int y = 0 ; y < MAPHEIGHT ; y++)
357 for (int x = 0 ; x < MAPWIDTH ; x++)
359 if (map.data[x][y] == 241)
361 if ((Math::prand() % 3) == 0)
362 map.data[x][y] = 242;
367 engine.keyState[SDLK_F1] = 0;
370 void fillHorizontal(int block, int x, int y)
372 bool moveLeft = true;
373 bool moveRight = true;
379 if (map.data[x][y] == 0)
381 map.data[x][y] = block;
394 if (map.data[left][y] == 0)
396 map.data[left][y] = block;
407 if (right >= MAPWIDTH)
409 right = MAPWIDTH - 1;
413 if (map.data[right][y] == 0)
415 map.data[right][y] = block;
422 if ((!moveLeft) && (!moveRight))
430 int main(int argc, char *argv[])
434 printf("Usage: mapeditor <filename>\n\n");
438 config.engine = &engine;
448 FILE *fp = fopen(argv[1], "rb");
454 game.setMapName(argv[1]);
460 int mapX, mapY, allowMove, x, y;
461 mapX = mapY = allowMove = x = y = 0;
464 int currentMonster = 0;
466 int currentBlock = 1;
474 unsigned int frameLimit = SDL_GetTicks() + 16;
481 engine.doFrameLoop();
483 graphics.updateScreen();
484 graphics.animateSprites();
485 graphics.drawBackground();
487 engine.setPlayerPosition((mapX * 32) + 320, (mapY * 32) + 240, map.limitLeft, map.limitRight, map.limitUp, map.limitDown);
503 x = engine.getMouseX();
504 y = engine.getMouseY();
517 graphics.drawRect(r.x - 1, r.y - 1, 34, 1, graphics.yellow, graphics.screen);
518 graphics.drawRect(r.x - 1, r.y - 1, 1, 34, graphics.yellow, graphics.screen);
519 graphics.drawRect(r.x + 32, r.y - 1, 1, 34, graphics.yellow, graphics.screen);
520 graphics.drawRect(r.x - 1, r.y + 32, 34, 1, graphics.yellow, graphics.screen);
521 graphics.blit(graphics.tile[currentBlock], r.x, r.y, graphics.screen, false);
522 if (engine.mouseLeft)
523 map.data[mapX + x][mapY + y] = currentBlock;
526 graphics.blit(defEnemy[currentMonster].getFaceImage(), r.x, r.y, graphics.screen, false);
527 if (engine.mouseLeft)
529 addEnemy(defEnemy[currentMonster].name, (mapX + x) * BRICKSIZE, (mapY + y) * BRICKSIZE, 0);
530 engine.mouseLeft = 0;
534 graphics.blit(defItem[currentItem].getFaceImage(), r.x, r.y, graphics.screen, false);
535 if (engine.mouseLeft)
537 addItem(defItem[currentItem].id, defItem[currentItem].name, (mapX + x) * BRICKSIZE, (mapY + y) * BRICKSIZE, defItem[currentItem].sprite[0]->name, 0, defItem[currentItem].value, 0, true);
538 engine.mouseLeft = 0;
543 if (engine.mouseRight)
545 if (editing == 0) map.data[mapX + x][mapY + y] = MAP_AIR;
546 if (editing == 1) deleteEnemy(mapX + x, mapY + y);
550 if (allowMove < 1) allowMove = 0;
554 if (engine.keyState[SDLK_UP]) {mapY--; allowMove = MOVESPEED;}
555 if (engine.keyState[SDLK_DOWN]) {mapY++; allowMove = MOVESPEED;}
556 if (engine.keyState[SDLK_LEFT]) {mapX--; allowMove = MOVESPEED;}
557 if (engine.keyState[SDLK_RIGHT]) {mapX++; allowMove = MOVESPEED;}
559 if (engine.keyState[SDLK_PAGEDOWN]) {mapY += 10; allowMove = MOVESPEED;}
560 if (engine.keyState[SDLK_PAGEUP]) {mapY -= 10; allowMove = MOVESPEED;}
562 if (engine.keyState[SDLK_1]) editing = 0;
563 if (engine.keyState[SDLK_2]) editing = 1;
564 if (engine.keyState[SDLK_3]) editing = 2;
566 if (engine.keyState[SDLK_0]) fillHorizontal(currentBlock, mapX + x, mapY + y);
568 if (engine.keyState[SDLK_F1]) addTileDecoration();
570 if (engine.keyState[SDLK_ESCAPE]) break;
573 if (engine.keyState[SDLK_PERIOD])
578 currentBlock = nextBlock(currentBlock, 1);
588 engine.keyState[SDLK_PERIOD] = 0;
591 if (engine.keyState[SDLK_COMMA])
596 currentBlock = nextBlock(currentBlock, -1);
606 engine.keyState[SDLK_COMMA] = 0;
609 Math::limitInt(¤tMonster, 0, MAX_ENEMIES - 1);
610 Math::limitInt(¤tItem, 0, MAX_ITEMS - 1);
612 if (defEnemy[currentMonster].sprite[0] == NULL)
615 if (defItem[currentItem].sprite[0] == NULL)
618 if (engine.keyState[SDLK_SPACE]) {showMap(&mapX, &mapY);}
620 if (engine.keyState[SDLK_s]) {saveMap(game.mapName); engine.keyState[SDLK_s] = 0;}
622 if (mapX < 0) mapX = 0;
623 if (mapY < 0) mapY = 0;
624 if (mapX > MAPWIDTH - 40) mapX = MAPWIDTH - 40;
625 if (mapY > MAPHEIGHT - 30) mapY = MAPHEIGHT - 30;
628 snprintf(string, sizeof string, "Index : %d:%d ; Screen %d:%d ; Tile %d", mapX + x, mapY + y, (mapX + x) * BRICKSIZE, (mapY + y) * BRICKSIZE, currentBlock);
629 else if (editing == 1)
630 snprintf(string, sizeof string, "Index : %d:%d ; Screen %d:%d ; %s", mapX + x, mapY + y, (mapX + x) * BRICKSIZE, (mapY + y) * BRICKSIZE, defEnemy[currentMonster].name);
631 else if (editing == 2)
632 snprintf(string, sizeof string, "Index : %d:%d ; Screen %d:%d ; %s", mapX + x, mapY + y, (mapX + x) * BRICKSIZE, (mapY + y) * BRICKSIZE, defItem[currentItem].name);
638 if (mapY < MAPHEIGHT - 30)
643 SDL_FillRect(graphics.screen, &r, graphics.black);
645 graphics.drawString(string, 320, r.y + 5, true, graphics.screen);
647 engine.delay(frameLimit);
648 frameLimit = SDL_GetTicks() + 16;
651 String *str = stringHead->next;
656 printf("Deleting %s", str->string);