Ingen beskrivning

map.cpp 22KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713
  1. #include "map.h"
  2. #include <QTime>
  3. #include <QDebug>
  4. #include <QPainter>
  5. #include <QImage>
  6. Map::Map(QObject *parent) : QObject(parent)
  7. {
  8. blockdata = new Blockdata;
  9. cached_blockdata = new Blockdata;
  10. cached_collision = new Blockdata;
  11. cached_border = new Blockdata;
  12. paint_tile = 1;
  13. paint_collision = 0;
  14. paint_elevation = 3;
  15. }
  16. int Map::getWidth() {
  17. return width.toInt(nullptr, 0);
  18. }
  19. int Map::getHeight() {
  20. return height.toInt(nullptr, 0);
  21. }
  22. Tileset* Map::getBlockTileset(int metatile_index) {
  23. int primary_size = 0x200;//tileset_primary->metatiles->length();
  24. if (metatile_index < primary_size) {
  25. return tileset_primary;
  26. } else {
  27. return tileset_secondary;
  28. }
  29. }
  30. QList<QList<QRgb>> Map::getBlockPalettes(int metatile_index) {
  31. QList<QList<QRgb>> palettes;
  32. for (int i = 0; i < 6; i++) {
  33. palettes.append(tileset_primary->palettes->at(i));
  34. }
  35. for (int i = 6; i < tileset_secondary->palettes->length(); i++) {
  36. palettes.append(tileset_secondary->palettes->at(i));
  37. }
  38. return palettes;
  39. }
  40. int Map::getBlockIndex(int index) {
  41. int primary_size = 0x200;
  42. if (index < primary_size) {
  43. return index;
  44. } else {
  45. return index - primary_size;
  46. }
  47. }
  48. QImage Map::getMetatileTile(int tile) {
  49. Tileset *tileset = getBlockTileset(tile);
  50. int local_index = getBlockIndex(tile);
  51. if (!tileset || !tileset->tiles) {
  52. return QImage();
  53. }
  54. return tileset->tiles->value(local_index, QImage());
  55. }
  56. Metatile* Map::getMetatile(int index) {
  57. Tileset *tileset = getBlockTileset(index);
  58. int local_index = getBlockIndex(index);
  59. if (!tileset || !tileset->metatiles) {
  60. return NULL;
  61. }
  62. Metatile *metatile = tileset->metatiles->value(local_index, NULL);
  63. return metatile;
  64. }
  65. QImage Map::getCollisionMetatileImage(Block block) {
  66. return getCollisionMetatileImage(block.collision);
  67. }
  68. QImage Map::getCollisionMetatileImage(int collision) {
  69. QImage metatile_image(16, 16, QImage::Format_RGBA8888);
  70. QColor color;
  71. if (collision == 0) {
  72. color.setGreen(0xff);
  73. } else if (collision == 1) {
  74. color.setRed(0xff);
  75. } else if (collision == 2) {
  76. color.setBlue(0xff);
  77. } else if (collision == 3) {
  78. // black
  79. }
  80. metatile_image.fill(color);
  81. return metatile_image;
  82. }
  83. QImage Map::getElevationMetatileImage(Block block) {
  84. return getElevationMetatileImage(block.elevation);
  85. }
  86. QImage Map::getElevationMetatileImage(int elevation) {
  87. QImage metatile_image(16, 16, QImage::Format_RGBA8888);
  88. QColor color;
  89. if (elevation < 15) {
  90. uint saturation = (elevation + 1) * 16 + 15;
  91. color.setGreen(saturation);
  92. color.setRed(saturation);
  93. color.setBlue(saturation);
  94. } else {
  95. color.setGreen(0xd0);
  96. color.setBlue(0xd0);
  97. color.setRed(0);
  98. }
  99. metatile_image.fill(color);
  100. //QPainter painter(&metatile_image);
  101. //painter.end();
  102. return metatile_image;
  103. }
  104. QImage Map::getMetatileImage(int tile) {
  105. QImage metatile_image(16, 16, QImage::Format_RGBA8888);
  106. Metatile* metatile = getMetatile(tile);
  107. if (!metatile || !metatile->tiles) {
  108. metatile_image.fill(0xffffffff);
  109. return metatile_image;
  110. }
  111. Tileset* blockTileset = getBlockTileset(tile);
  112. if (!blockTileset) {
  113. metatile_image.fill(0xffffffff);
  114. return metatile_image;
  115. }
  116. QList<QList<QRgb>> palettes = getBlockPalettes(tile);
  117. QPainter metatile_painter(&metatile_image);
  118. for (int layer = 0; layer < 2; layer++)
  119. for (int y = 0; y < 2; y++)
  120. for (int x = 0; x < 2; x++) {
  121. Tile tile_ = metatile->tiles->value((y * 2) + x + (layer * 4));
  122. QImage tile_image = getMetatileTile(tile_.tile);
  123. //if (tile_image.isNull()) {
  124. // continue;
  125. //}
  126. //if (blockTileset->palettes) {
  127. QList<QRgb> palette = palettes.value(tile_.palette);
  128. for (int j = 0; j < palette.length(); j++) {
  129. tile_image.setColor(j, palette.value(j));
  130. }
  131. //}
  132. //QVector<QRgb> vector = palette.toVector();
  133. //tile_image.setColorTable(vector);
  134. if (layer > 0) {
  135. QColor color(tile_image.color(15));
  136. color.setAlpha(0);
  137. tile_image.setColor(15, color.rgba());
  138. }
  139. QPoint origin = QPoint(x*8, y*8);
  140. metatile_painter.drawImage(origin, tile_image.mirrored(tile_.xflip == 1, tile_.yflip == 1));
  141. }
  142. metatile_painter.end();
  143. return metatile_image;
  144. }
  145. bool Map::blockChanged(int i, Blockdata *cache) {
  146. if (cache == NULL || cache == nullptr) {
  147. return true;
  148. }
  149. if (blockdata == NULL || blockdata == nullptr) {
  150. return true;
  151. }
  152. if (cache->blocks == NULL || cache->blocks == nullptr) {
  153. return true;
  154. }
  155. if (blockdata->blocks == NULL || blockdata->blocks == nullptr) {
  156. return true;
  157. }
  158. if (cache->blocks->length() <= i) {
  159. return true;
  160. }
  161. if (blockdata->blocks->length() <= i) {
  162. return true;
  163. }
  164. return blockdata->blocks->value(i) != cache->blocks->value(i);
  165. }
  166. void Map::cacheBorder() {
  167. if (cached_border) delete cached_border;
  168. cached_border = new Blockdata;
  169. if (border && border->blocks) {
  170. for (int i = 0; i < border->blocks->length(); i++) {
  171. Block block = border->blocks->value(i);
  172. cached_border->blocks->append(block);
  173. }
  174. }
  175. }
  176. void Map::cacheBlockdata() {
  177. if (cached_blockdata) delete cached_blockdata;
  178. cached_blockdata = new Blockdata;
  179. if (blockdata && blockdata->blocks) {
  180. for (int i = 0; i < blockdata->blocks->length(); i++) {
  181. Block block = blockdata->blocks->value(i);
  182. cached_blockdata->blocks->append(block);
  183. }
  184. }
  185. }
  186. void Map::cacheCollision() {
  187. if (cached_collision) delete cached_collision;
  188. cached_collision = new Blockdata;
  189. if (blockdata && blockdata->blocks) {
  190. for (int i = 0; i < blockdata->blocks->length(); i++) {
  191. Block block = blockdata->blocks->value(i);
  192. cached_collision->blocks->append(block);
  193. }
  194. }
  195. }
  196. QPixmap Map::renderCollision() {
  197. bool changed_any = false;
  198. int width_ = getWidth();
  199. int height_ = getHeight();
  200. if (
  201. collision_image.isNull()
  202. || collision_image.width() != width_ * 16
  203. || collision_image.height() != height_ * 16
  204. ) {
  205. collision_image = QImage(width_ * 16, height_ * 16, QImage::Format_RGBA8888);
  206. changed_any = true;
  207. }
  208. if (!(blockdata && blockdata->blocks && width_ && height_)) {
  209. collision_pixmap = collision_pixmap.fromImage(collision_image);
  210. return collision_pixmap;
  211. }
  212. QPainter painter(&collision_image);
  213. for (int i = 0; i < blockdata->blocks->length(); i++) {
  214. if (cached_collision && !blockChanged(i, cached_collision)) {
  215. continue;
  216. }
  217. changed_any = true;
  218. Block block = blockdata->blocks->value(i);
  219. QImage metatile_image = getMetatileImage(block.tile);
  220. QImage collision_metatile_image = getCollisionMetatileImage(block);
  221. QImage elevation_metatile_image = getElevationMetatileImage(block);
  222. int map_y = width_ ? i / width_ : 0;
  223. int map_x = width_ ? i % width_ : 0;
  224. QPoint metatile_origin = QPoint(map_x * 16, map_y * 16);
  225. painter.setOpacity(1);
  226. painter.drawImage(metatile_origin, metatile_image);
  227. painter.save();
  228. if (block.elevation == 15) {
  229. painter.setOpacity(0.5);
  230. } else if (block.elevation == 0) {
  231. painter.setOpacity(0);
  232. } else {
  233. painter.setOpacity(1);//(block.elevation / 16.0) * 0.8);
  234. painter.setCompositionMode(QPainter::CompositionMode_Overlay);
  235. }
  236. painter.drawImage(metatile_origin, elevation_metatile_image);
  237. painter.restore();
  238. painter.save();
  239. if (block.collision == 0) {
  240. painter.setOpacity(0.1);
  241. } else {
  242. painter.setOpacity(0.4);
  243. }
  244. painter.drawImage(metatile_origin, collision_metatile_image);
  245. painter.restore();
  246. painter.save();
  247. painter.setOpacity(0.6);
  248. painter.setPen(QColor(255, 255, 255, 192));
  249. painter.setFont(QFont("Helvetica", 8));
  250. painter.drawText(QPoint(metatile_origin.x(), metatile_origin.y() + 8), QString("%1").arg(block.elevation));
  251. painter.restore();
  252. }
  253. painter.end();
  254. cacheCollision();
  255. if (changed_any) {
  256. collision_pixmap = collision_pixmap.fromImage(collision_image);
  257. }
  258. return collision_pixmap;
  259. }
  260. QPixmap Map::render() {
  261. bool changed_any = false;
  262. int width_ = getWidth();
  263. int height_ = getHeight();
  264. if (
  265. image.isNull()
  266. || image.width() != width_ * 16
  267. || image.height() != height_ * 16
  268. ) {
  269. image = QImage(width_ * 16, height_ * 16, QImage::Format_RGBA8888);
  270. changed_any = true;
  271. }
  272. if (!(blockdata && blockdata->blocks && width_ && height_)) {
  273. pixmap = pixmap.fromImage(image);
  274. return pixmap;
  275. }
  276. QPainter painter(&image);
  277. for (int i = 0; i < blockdata->blocks->length(); i++) {
  278. if (!blockChanged(i, cached_blockdata)) {
  279. continue;
  280. }
  281. changed_any = true;
  282. Block block = blockdata->blocks->value(i);
  283. QImage metatile_image = getMetatileImage(block.tile);
  284. int map_y = width_ ? i / width_ : 0;
  285. int map_x = width_ ? i % width_ : 0;
  286. QPoint metatile_origin = QPoint(map_x * 16, map_y * 16);
  287. painter.drawImage(metatile_origin, metatile_image);
  288. }
  289. painter.end();
  290. if (changed_any) {
  291. cacheBlockdata();
  292. pixmap = pixmap.fromImage(image);
  293. }
  294. return pixmap;
  295. }
  296. QPixmap Map::renderBorder() {
  297. bool changed_any = false;
  298. int width_ = 2;
  299. int height_ = 2;
  300. if (border_image.isNull()) {
  301. border_image = QImage(width_ * 16, height_ * 16, QImage::Format_RGBA8888);
  302. changed_any = true;
  303. }
  304. if (!(border && border->blocks)) {
  305. border_pixmap = border_pixmap.fromImage(border_image);
  306. return border_pixmap;
  307. }
  308. QPainter painter(&border_image);
  309. for (int i = 0; i < border->blocks->length(); i++) {
  310. if (!blockChanged(i, cached_border)) {
  311. continue;
  312. }
  313. changed_any = true;
  314. Block block = border->blocks->value(i);
  315. QImage metatile_image = getMetatileImage(block.tile);
  316. int map_y = i / width_;
  317. int map_x = i % width_;
  318. painter.drawImage(QPoint(map_x * 16, map_y * 16), metatile_image);
  319. }
  320. painter.end();
  321. if (changed_any) {
  322. cacheBorder();
  323. border_pixmap = border_pixmap.fromImage(border_image);
  324. }
  325. return border_pixmap;
  326. }
  327. QPixmap Map::renderConnection(Connection connection) {
  328. render();
  329. int x, y, w, h;
  330. if (connection.direction == "up") {
  331. x = 0;
  332. y = getHeight() - 6;
  333. w = getWidth();
  334. h = 6;
  335. } else if (connection.direction == "down") {
  336. x = 0;
  337. y = 0;
  338. w = getWidth();
  339. h = 6;
  340. } else if (connection.direction == "left") {
  341. x = getWidth() - 6;
  342. y = 0;
  343. w = 6;
  344. h = getHeight();
  345. } else if (connection.direction == "right") {
  346. x = 0;
  347. y = 0;
  348. w = 6;
  349. h = getHeight();
  350. } else {
  351. // this should not happen
  352. x = 0;
  353. y = 0;
  354. w = getWidth();
  355. h = getHeight();
  356. }
  357. QImage connection_image = image.copy(x * 16, y * 16, w * 16, h * 16);
  358. //connection_image = connection_image.convertToFormat(QImage::Format_Grayscale8);
  359. return QPixmap::fromImage(connection_image);
  360. }
  361. QPixmap Map::renderCollisionMetatiles() {
  362. int length_ = 4;
  363. int height_ = 1;
  364. int width_ = length_ / height_;
  365. QImage image(width_ * 16, height_ * 16, QImage::Format_RGBA8888);
  366. QPainter painter(&image);
  367. for (int i = 0; i < length_; i++) {
  368. int y = i / width_;
  369. int x = i % width_;
  370. QPoint origin(x * 16, y * 16);
  371. QImage metatile_image = getCollisionMetatileImage(i);
  372. painter.drawImage(origin, metatile_image);
  373. }
  374. drawSelection(paint_collision, width_, &painter);
  375. painter.end();
  376. return QPixmap::fromImage(image);
  377. }
  378. QPixmap Map::renderElevationMetatiles() {
  379. int length_ = 16;
  380. int height_ = 2;
  381. int width_ = length_ / height_;
  382. QImage image(width_ * 16, height_ * 16, QImage::Format_RGBA8888);
  383. QPainter painter(&image);
  384. for (int i = 0; i < length_; i++) {
  385. int y = i / width_;
  386. int x = i % width_;
  387. QPoint origin(x * 16, y * 16);
  388. QImage metatile_image = getElevationMetatileImage(i);
  389. painter.drawImage(origin, metatile_image);
  390. }
  391. drawSelection(paint_elevation, width_, &painter);
  392. painter.end();
  393. return QPixmap::fromImage(image);
  394. }
  395. void Map::drawSelection(int i, int w, QPainter *painter) {
  396. int x = i % w;
  397. int y = i / w;
  398. painter->save();
  399. painter->setPen(QColor(0xff, 0xff, 0xff));
  400. painter->drawRect(x * 16, y * 16, 15, 15);
  401. painter->setPen(QColor(0, 0, 0));
  402. painter->drawRect(x * 16 - 1, y * 16 - 1, 17, 17);
  403. painter->drawRect(x * 16 + 1, y * 16 + 1, 13, 13);
  404. painter->restore();
  405. }
  406. QPixmap Map::renderMetatiles() {
  407. if (!tileset_primary || !tileset_primary->metatiles || !tileset_secondary || !tileset_secondary->metatiles) {
  408. return QPixmap();
  409. }
  410. int primary_length = tileset_primary->metatiles->length();
  411. int length_ = primary_length + tileset_secondary->metatiles->length();
  412. int width_ = 8;
  413. int height_ = length_ / width_;
  414. QImage image(width_ * 16, height_ * 16, QImage::Format_RGBA8888);
  415. QPainter painter(&image);
  416. for (int i = 0; i < length_; i++) {
  417. int tile = i;
  418. if (i >= primary_length) {
  419. tile += 0x200 - primary_length;
  420. }
  421. QImage metatile_image = getMetatileImage(tile);
  422. int map_y = i / width_;
  423. int map_x = i % width_;
  424. QPoint metatile_origin = QPoint(map_x * 16, map_y * 16);
  425. painter.drawImage(metatile_origin, metatile_image);
  426. }
  427. drawSelection(paint_tile, width_, &painter);
  428. painter.end();
  429. return QPixmap::fromImage(image);
  430. }
  431. Block* Map::getBlock(int x, int y) {
  432. if (blockdata && blockdata->blocks) {
  433. if (x >= 0 && x < getWidth())
  434. if (y >= 0 && y < getHeight()) {
  435. int i = y * getWidth() + x;
  436. return new Block(blockdata->blocks->value(i));
  437. }
  438. }
  439. return NULL;
  440. }
  441. void Map::_setBlock(int x, int y, Block block) {
  442. int i = y * getWidth() + x;
  443. if (blockdata && blockdata->blocks) {
  444. blockdata->blocks->replace(i, block);
  445. }
  446. }
  447. void Map::_floodFill(int x, int y, uint tile) {
  448. QList<QPoint> todo;
  449. todo.append(QPoint(x, y));
  450. while (todo.length()) {
  451. QPoint point = todo.takeAt(0);
  452. x = point.x();
  453. y = point.y();
  454. Block *block = getBlock(x, y);
  455. if (block == NULL) {
  456. continue;
  457. }
  458. uint old_tile = block->tile;
  459. if (old_tile == tile) {
  460. continue;
  461. }
  462. block->tile = tile;
  463. _setBlock(x, y, *block);
  464. if ((block = getBlock(x + 1, y)) && block->tile == old_tile) {
  465. todo.append(QPoint(x + 1, y));
  466. }
  467. if ((block = getBlock(x - 1, y)) && block->tile == old_tile) {
  468. todo.append(QPoint(x - 1, y));
  469. }
  470. if ((block = getBlock(x, y + 1)) && block->tile == old_tile) {
  471. todo.append(QPoint(x, y + 1));
  472. }
  473. if ((block = getBlock(x, y - 1)) && block->tile == old_tile) {
  474. todo.append(QPoint(x, y - 1));
  475. }
  476. }
  477. }
  478. void Map::_floodFillCollision(int x, int y, uint collision) {
  479. QList<QPoint> todo;
  480. todo.append(QPoint(x, y));
  481. while (todo.length()) {
  482. QPoint point = todo.takeAt(0);
  483. x = point.x();
  484. y = point.y();
  485. Block *block = getBlock(x, y);
  486. if (block == NULL) {
  487. continue;
  488. }
  489. uint old_coll = block->collision;
  490. if (old_coll == collision) {
  491. continue;
  492. }
  493. block->collision = collision;
  494. _setBlock(x, y, *block);
  495. if ((block = getBlock(x + 1, y)) && block->collision == old_coll) {
  496. todo.append(QPoint(x + 1, y));
  497. }
  498. if ((block = getBlock(x - 1, y)) && block->collision == old_coll) {
  499. todo.append(QPoint(x - 1, y));
  500. }
  501. if ((block = getBlock(x, y + 1)) && block->collision == old_coll) {
  502. todo.append(QPoint(x, y + 1));
  503. }
  504. if ((block = getBlock(x, y - 1)) && block->collision == old_coll) {
  505. todo.append(QPoint(x, y - 1));
  506. }
  507. }
  508. }
  509. void Map::_floodFillElevation(int x, int y, uint elevation) {
  510. QList<QPoint> todo;
  511. todo.append(QPoint(x, y));
  512. while (todo.length()) {
  513. QPoint point = todo.takeAt(0);
  514. x = point.x();
  515. y = point.y();
  516. Block *block = getBlock(x, y);
  517. if (block == NULL) {
  518. continue;
  519. }
  520. uint old_z = block->elevation;
  521. if (old_z == elevation) {
  522. continue;
  523. }
  524. Block block_(*block);
  525. block_.elevation = elevation;
  526. _setBlock(x, y, block_);
  527. if ((block = getBlock(x + 1, y)) && block->elevation == old_z) {
  528. todo.append(QPoint(x + 1, y));
  529. }
  530. if ((block = getBlock(x - 1, y)) && block->elevation == old_z) {
  531. todo.append(QPoint(x - 1, y));
  532. }
  533. if ((block = getBlock(x, y + 1)) && block->elevation == old_z) {
  534. todo.append(QPoint(x, y + 1));
  535. }
  536. if ((block = getBlock(x, y - 1)) && block->elevation == old_z) {
  537. todo.append(QPoint(x, y - 1));
  538. }
  539. }
  540. }
  541. void Map::_floodFillCollisionElevation(int x, int y, uint collision, uint elevation) {
  542. QList<QPoint> todo;
  543. todo.append(QPoint(x, y));
  544. while (todo.length()) {
  545. QPoint point = todo.takeAt(0);
  546. x = point.x();
  547. y = point.y();
  548. Block *block = getBlock(x, y);
  549. if (block == NULL) {
  550. continue;
  551. }
  552. uint old_coll = block->collision;
  553. uint old_elev = block->elevation;
  554. if (old_coll == collision && old_elev == elevation) {
  555. continue;
  556. }
  557. block->collision = collision;
  558. block->elevation = elevation;
  559. _setBlock(x, y, *block);
  560. if ((block = getBlock(x + 1, y)) && block->collision == old_coll && block->elevation == old_elev) {
  561. todo.append(QPoint(x + 1, y));
  562. }
  563. if ((block = getBlock(x - 1, y)) && block->collision == old_coll && block->elevation == old_elev) {
  564. todo.append(QPoint(x - 1, y));
  565. }
  566. if ((block = getBlock(x, y + 1)) && block->collision == old_coll && block->elevation == old_elev) {
  567. todo.append(QPoint(x, y + 1));
  568. }
  569. if ((block = getBlock(x, y - 1)) && block->collision == old_coll && block->elevation == old_elev) {
  570. todo.append(QPoint(x, y - 1));
  571. }
  572. }
  573. }
  574. void Map::undo() {
  575. if (blockdata) {
  576. Blockdata *commit = history.pop();
  577. if (commit != NULL) {
  578. blockdata->copyFrom(commit);
  579. emit mapChanged(this);
  580. }
  581. }
  582. }
  583. void Map::redo() {
  584. if (blockdata) {
  585. Blockdata *commit = history.next();
  586. if (commit != NULL) {
  587. blockdata->copyFrom(commit);
  588. emit mapChanged(this);
  589. }
  590. }
  591. }
  592. void Map::commit() {
  593. if (blockdata) {
  594. if (!blockdata->equals(history.history.at(history.head))) {
  595. Blockdata* commit = blockdata->copy();
  596. history.push(commit);
  597. emit mapChanged(this);
  598. }
  599. }
  600. }
  601. void Map::setBlock(int x, int y, Block block) {
  602. Block *old_block = getBlock(x, y);
  603. if (old_block && (*old_block) != block) {
  604. _setBlock(x, y, block);
  605. commit();
  606. }
  607. }
  608. void Map::floodFill(int x, int y, uint tile) {
  609. Block *block = getBlock(x, y);
  610. if (block && block->tile != tile) {
  611. _floodFill(x, y, tile);
  612. commit();
  613. }
  614. }
  615. void Map::floodFillCollision(int x, int y, uint collision) {
  616. Block *block = getBlock(x, y);
  617. if (block && block->collision != collision) {
  618. _floodFillCollision(x, y, collision);
  619. commit();
  620. }
  621. }
  622. void Map::floodFillElevation(int x, int y, uint elevation) {
  623. Block *block = getBlock(x, y);
  624. if (block && block->elevation != elevation) {
  625. _floodFillElevation(x, y, elevation);
  626. commit();
  627. }
  628. }
  629. void Map::floodFillCollisionElevation(int x, int y, uint collision, uint elevation) {
  630. Block *block = getBlock(x, y);
  631. if (block && (block->collision != collision || block->elevation != elevation)) {
  632. _floodFillCollisionElevation(x, y, collision, elevation);
  633. commit();
  634. }
  635. }
  636. QList<Event *> Map::getAllEvents() {
  637. QList<Event*> all;
  638. for (QList<Event*> list : events.values()) {
  639. all += list;
  640. }
  641. return all;
  642. }
  643. QList<Event *> Map::getEventsByType(QString type)
  644. {
  645. return events.value(type);
  646. }
  647. void Map::removeEvent(Event *event) {
  648. for (QString key : events.keys()) {
  649. events[key].removeAll(event);
  650. }
  651. }
  652. void Map::addEvent(Event *event) {
  653. events[event->get("event_type")].append(event);
  654. }
  655. bool Map::hasUnsavedChanges() {
  656. return !history.isSaved();
  657. }