Browse Source

lots of changes

yenatch 6 years ago
parent
commit
11212dc640

+ 16
- 0
blockdata.cpp View File

@@ -1,4 +1,5 @@
1 1
 #include "blockdata.h"
2
+#include <QDebug>
2 3
 
3 4
 Blockdata::Blockdata(QObject *parent) : QObject(parent)
4 5
 {
@@ -37,3 +38,18 @@ Blockdata* Blockdata::copy() {
37 38
     blockdata->copyFrom(this);
38 39
     return blockdata;
39 40
 }
41
+
42
+bool Blockdata::equals(Blockdata *other) {
43
+    if (!other) {
44
+        return false;
45
+    }
46
+    if (blocks->length() != other->blocks->length()) {
47
+        return false;
48
+    }
49
+    for (int i = 0; i < blocks->length(); i++) {
50
+        if (blocks->value(i) != other->blocks->value(i)) {
51
+            return false;
52
+        }
53
+    }
54
+    return true;
55
+}

+ 2
- 1
blockdata.h View File

@@ -13,12 +13,13 @@ public:
13 13
     explicit Blockdata(QObject *parent = 0);
14 14
 
15 15
 public:
16
-    QList<Block> *blocks;
16
+    QList<Block> *blocks = NULL;
17 17
     void addBlock(uint16_t);
18 18
     void addBlock(Block);
19 19
     QByteArray serialize();
20 20
     void copyFrom(Blockdata*);
21 21
     Blockdata* copy();
22
+    bool equals(Blockdata *);
22 23
 
23 24
 signals:
24 25
 

+ 345
- 61
editor.cpp View File

@@ -1,8 +1,10 @@
1 1
 #include "editor.h"
2
+#include <QPainter>
3
+#include <QMouseEvent>
2 4
 
3 5
 Editor::Editor()
4 6
 {
5
-
7
+    selected_events = new QList<DraggablePixmapItem*>;
6 8
 }
7 9
 
8 10
 void Editor::saveProject() {
@@ -31,53 +33,111 @@ void Editor::redo() {
31 33
 
32 34
 void Editor::setEditingMap() {
33 35
     current_view = map_item;
34
-    map_item->draw();
35
-    map_item->setVisible(true);
36
-    map_item->setEnabled(true);
37
-    collision_item->setVisible(false);
38
-    objects_group->setVisible(false);
36
+    if (map_item) {
37
+        map_item->draw();
38
+        map_item->setVisible(true);
39
+        map_item->setEnabled(true);
40
+    }
41
+    if (collision_item) {
42
+        collision_item->setVisible(false);
43
+    }
44
+    if (objects_group) {
45
+        objects_group->setVisible(false);
46
+    }
39 47
 }
40 48
 
41 49
 void Editor::setEditingCollision() {
42 50
     current_view = collision_item;
43
-    collision_item->draw();
44
-    collision_item->setVisible(true);
45
-    map_item->setVisible(false);
46
-    objects_group->setVisible(false);
51
+    if (collision_item) {
52
+        collision_item->draw();
53
+        collision_item->setVisible(true);
54
+    }
55
+    if (map_item) {
56
+        map_item->setVisible(false);
57
+    }
58
+    if (objects_group) {
59
+        objects_group->setVisible(false);
60
+    }
47 61
 }
48 62
 
49 63
 void Editor::setEditingObjects() {
50
-    objects_group->setVisible(true);
51
-    map_item->setVisible(true);
52
-    map_item->setEnabled(false);
53
-    collision_item->setVisible(false);
64
+    current_view = map_item;
65
+    if (objects_group) {
66
+        objects_group->setVisible(true);
67
+    }
68
+    if (map_item) {
69
+        map_item->setVisible(true);
70
+        map_item->setEnabled(false);
71
+    }
72
+    if (collision_item) {
73
+        collision_item->setVisible(false);
74
+    }
54 75
 }
55 76
 
56 77
 void Editor::setMap(QString map_name) {
57 78
     if (map_name.isNull()) {
58 79
         return;
59 80
     }
60
-    map = project->getMap(map_name);
61
-    displayMap();
81
+    if (project) {
82
+        map = project->loadMap(map_name);
83
+        displayMap();
84
+        selected_events->clear();
85
+        updateSelectedObjects();
86
+    }
87
+}
88
+
89
+void Editor::mouseEvent_map(QGraphicsSceneMouseEvent *event, MapPixmapItem *item) {
90
+    if (map_edit_mode == "paint") {
91
+        item->paint(event);
92
+    } else if (map_edit_mode == "fill") {
93
+        item->floodFill(event);
94
+    } else if (map_edit_mode == "pick") {
95
+        item->pick(event);
96
+    } else if (map_edit_mode == "select") {
97
+        item->select(event);
98
+    }
99
+}
100
+void Editor::mouseEvent_collision(QGraphicsSceneMouseEvent *event, CollisionPixmapItem *item) {
101
+    if (map_edit_mode == "paint") {
102
+        item->paint(event);
103
+    } else if (map_edit_mode == "fill") {
104
+        item->floodFill(event);
105
+    } else if (map_edit_mode == "pick") {
106
+        item->pick(event);
107
+    } else if (map_edit_mode == "select") {
108
+        item->select(event);
109
+    }
62 110
 }
63 111
 
64 112
 void Editor::displayMap() {
65 113
     scene = new QGraphicsScene;
66 114
 
67 115
     map_item = new MapPixmapItem(map);
116
+    connect(map_item, SIGNAL(mouseEvent(QGraphicsSceneMouseEvent*,MapPixmapItem*)),
117
+            this, SLOT(mouseEvent_map(QGraphicsSceneMouseEvent*,MapPixmapItem*)));
118
+
68 119
     map_item->draw();
69 120
     scene->addItem(map_item);
70 121
 
71 122
     collision_item = new CollisionPixmapItem(map);
123
+    connect(collision_item, SIGNAL(mouseEvent(QGraphicsSceneMouseEvent*,CollisionPixmapItem*)),
124
+            this, SLOT(mouseEvent_collision(QGraphicsSceneMouseEvent*,CollisionPixmapItem*)));
125
+
72 126
     collision_item->draw();
73 127
     scene->addItem(collision_item);
74 128
 
75
-    objects_group = new QGraphicsItemGroup;
129
+    objects_group = new EventGroup;
76 130
     scene->addItem(objects_group);
77 131
 
78
-    map_item->setVisible(false);
79
-    collision_item->setVisible(false);
80
-    objects_group->setVisible(false);
132
+    if (map_item) {
133
+        map_item->setVisible(false);
134
+    }
135
+    if (collision_item) {
136
+        collision_item->setVisible(false);
137
+    }
138
+    if (objects_group) {
139
+        objects_group->setVisible(false);
140
+    }
81 141
 
82 142
     int tw = 16;
83 143
     int th = 16;
@@ -122,13 +182,22 @@ void Editor::displayMapObjects() {
122 182
         objects_group->removeFromGroup(child);
123 183
     }
124 184
 
125
-    project->loadObjectPixmaps(map->object_events);
126
-    for (int i = 0; i < map->object_events.length(); i++) {
127
-        ObjectEvent *object_event = map->object_events.value(i);
128
-        DraggablePixmapItem *object = new DraggablePixmapItem(object_event);
129
-        objects_group->addToGroup(object);
185
+    QList<Event *> events = map->getAllEvents();
186
+    project->loadObjectPixmaps(events);
187
+    for (Event *event : events) {
188
+        addMapObject(event);
130 189
     }
131
-    objects_group->setFiltersChildEvents(false);
190
+    //objects_group->setFiltersChildEvents(false);
191
+    objects_group->setHandlesChildEvents(false);
192
+
193
+    emit objectsChanged();
194
+}
195
+
196
+DraggablePixmapItem *Editor::addMapObject(Event *event) {
197
+    DraggablePixmapItem *object = new DraggablePixmapItem(event);
198
+    object->editor = this;
199
+    objects_group->addToGroup(object);
200
+    return object;
132 201
 }
133 202
 
134 203
 void Editor::displayMapConnections() {
@@ -139,7 +208,7 @@ void Editor::displayMapConnections() {
139 208
         Map *connected_map = project->getMap(connection->map_name);
140 209
         QPixmap pixmap = connected_map->renderConnection(*connection);
141 210
         int offset = connection->offset.toInt(nullptr, 0);
142
-        int x, y;
211
+        int x = 0, y = 0;
143 212
         if (connection->direction == "up") {
144 213
             x = offset * 16;
145 214
             y = -pixmap.height();
@@ -154,6 +223,7 @@ void Editor::displayMapConnections() {
154 223
             y = offset * 16;
155 224
         }
156 225
         QGraphicsPixmapItem *item = new QGraphicsPixmapItem(pixmap);
226
+        item->setZValue(-1);
157 227
         item->setX(x);
158 228
         item->setY(y);
159 229
         scene->addItem(item);
@@ -167,11 +237,14 @@ void Editor::displayMapBorder() {
167 237
         QGraphicsPixmapItem *item = new QGraphicsPixmapItem(pixmap);
168 238
         item->setX(x * 16);
169 239
         item->setY(y * 16);
170
-        item->setZValue(-1);
240
+        item->setZValue(-2);
171 241
         scene->addItem(item);
172 242
     }
173 243
 }
174 244
 
245
+void MetatilesPixmapItem::paintTileChanged(Map *map) {
246
+    draw();
247
+}
175 248
 
176 249
 void MetatilesPixmapItem::draw() {
177 250
     setPixmap(map->renderMetatiles());
@@ -179,7 +252,7 @@ void MetatilesPixmapItem::draw() {
179 252
 
180 253
 void MetatilesPixmapItem::pick(uint tile) {
181 254
     map->paint_tile = tile;
182
-    draw();
255
+    emit map->paintTileChanged(map);
183 256
 }
184 257
 
185 258
 void MetatilesPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
@@ -193,6 +266,9 @@ void MetatilesPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
193 266
         pick(y * width + x);
194 267
     }
195 268
 }
269
+void MetatilesPixmapItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
270
+    mousePressEvent(event);
271
+}
196 272
 void MetatilesPixmapItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
197 273
     mousePressEvent(event);
198 274
 }
@@ -206,7 +282,10 @@ void MapPixmapItem::paint(QGraphicsSceneMouseEvent *event) {
206 282
         Block *block = map->getBlock(x, y);
207 283
         if (block) {
208 284
             block->tile = map->paint_tile;
209
-            map->setBlock(x, y, *block);
285
+            map->_setBlock(x, y, *block);
286
+        }
287
+        if (event->type() == QEvent::GraphicsSceneMouseRelease) {
288
+            map->commit();
210 289
         }
211 290
         draw();
212 291
     }
@@ -222,45 +301,95 @@ void MapPixmapItem::floodFill(QGraphicsSceneMouseEvent *event) {
222 301
     }
223 302
 }
224 303
 
304
+void MapPixmapItem::pick(QGraphicsSceneMouseEvent *event) {
305
+    QPointF pos = event->pos();
306
+    int x = (int)(pos.x()) / 16;
307
+    int y = (int)(pos.y()) / 16;
308
+    Block *block = map->getBlock(x, y);
309
+    if (block) {
310
+        map->paint_tile = block->tile;
311
+        emit map->paintTileChanged(map);
312
+    }
313
+}
314
+
315
+#define SWAP(a, b) do { if (a != b) { a ^= b; b ^= a; a ^= b; } } while (0)
316
+
317
+void MapPixmapItem::select(QGraphicsSceneMouseEvent *event) {
318
+    QPointF pos = event->pos();
319
+    int x = (int)(pos.x()) / 16;
320
+    int y = (int)(pos.y()) / 16;
321
+    if (event->type() == QEvent::GraphicsSceneMousePress) {
322
+        selection_origin = QPoint(x, y);
323
+        selection.clear();
324
+    } else if (event->type() == QEvent::GraphicsSceneMouseMove) {
325
+        if (event->buttons() & Qt::LeftButton) {
326
+            selection.clear();
327
+            selection.append(QPoint(x, y));
328
+        }
329
+    } else if (event->type() == QEvent::GraphicsSceneMouseRelease) {
330
+        if (!selection.isEmpty()) {
331
+            QPoint pos = selection.last();
332
+            int x1 = selection_origin.x();
333
+            int y1 = selection_origin.y();
334
+            int x2 = pos.x();
335
+            int y2 = pos.y();
336
+            if (x1 > x2) SWAP(x1, x2);
337
+            if (y1 > y2) SWAP(y1, y2);
338
+            selection.clear();
339
+            for (int y = y1; y <= y2; y++) {
340
+                for (int x = x1; x <= x2; x++) {
341
+                    selection.append(QPoint(x, y));
342
+                }
343
+            }
344
+            qDebug() << QString("selected (%1, %2) -> (%3, %4)").arg(x1).arg(y1).arg(x2).arg(y2);
345
+        }
346
+    }
347
+}
348
+
225 349
 void MapPixmapItem::draw() {
226
-    setPixmap(map->render());
350
+    if (map) {
351
+        setPixmap(map->render());
352
+    }
227 353
 }
228 354
 
229 355
 void MapPixmapItem::undo() {
230
-    map->undo();
231
-    draw();
356
+    if (map) {
357
+        map->undo();
358
+        draw();
359
+    }
232 360
 }
233 361
 
234 362
 void MapPixmapItem::redo() {
235
-    map->redo();
236
-    draw();
363
+    if (map) {
364
+        map->redo();
365
+        draw();
366
+    }
237 367
 }
238 368
 
239 369
 void MapPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
240
-    active = true;
241
-    if (event->button() == Qt::RightButton) {
242
-        right_click = true;
243
-        floodFill(event);
244
-    } else {
245
-        right_click = false;
246
-        paint(event);
247
-    }
370
+    emit mouseEvent(event, this);
248 371
 }
249 372
 void MapPixmapItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
250
-    if (active) {
251
-        if (right_click) {
252
-            floodFill(event);
253
-        } else {
254
-            paint(event);
255
-        }
256
-    }
373
+    emit mouseEvent(event, this);
257 374
 }
258 375
 void MapPixmapItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
259
-    active = false;
376
+    emit mouseEvent(event, this);
377
+}
378
+
379
+void CollisionPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
380
+    emit mouseEvent(event, this);
381
+}
382
+void CollisionPixmapItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
383
+    emit mouseEvent(event, this);
384
+}
385
+void CollisionPixmapItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
386
+    emit mouseEvent(event, this);
260 387
 }
261 388
 
262 389
 void CollisionPixmapItem::draw() {
263
-    setPixmap(map->renderCollision());
390
+    if (map) {
391
+        setPixmap(map->renderCollision());
392
+    }
264 393
 }
265 394
 
266 395
 void CollisionPixmapItem::paint(QGraphicsSceneMouseEvent *event) {
@@ -276,7 +405,10 @@ void CollisionPixmapItem::paint(QGraphicsSceneMouseEvent *event) {
276 405
             if (map->paint_elevation >= 0) {
277 406
                 block->elevation = map->paint_elevation;
278 407
             }
279
-            map->setBlock(x, y, *block);
408
+            map->_setBlock(x, y, *block);
409
+        }
410
+        if (event->type() == QEvent::GraphicsSceneMouseRelease) {
411
+            map->commit();
280 412
         }
281 413
         draw();
282 414
     }
@@ -300,25 +432,177 @@ void CollisionPixmapItem::floodFill(QGraphicsSceneMouseEvent *event) {
300 432
     }
301 433
 }
302 434
 
435
+void CollisionPixmapItem::pick(QGraphicsSceneMouseEvent *event) {
436
+    QPointF pos = event->pos();
437
+    int x = (int)(pos.x()) / 16;
438
+    int y = (int)(pos.y()) / 16;
439
+    Block *block = map->getBlock(x, y);
440
+    if (block) {
441
+        map->paint_collision = block->collision;
442
+        map->paint_elevation = block->elevation;
443
+        emit map->paintCollisionChanged(map);
444
+    }
445
+}
446
+
303 447
 void DraggablePixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *mouse) {
304 448
     active = true;
305
-    last_x = mouse->pos().x() / 16;
306
-    last_y = mouse->pos().y() / 16;
307
-    qDebug() << event->x_ + ", " + event->y_;
449
+    clicking = true;
450
+    last_x = (mouse->pos().x() + this->pos().x()) / 16;
451
+    last_y = (mouse->pos().y() + this->pos().y()) / 16;
452
+    //qDebug() << QString("(%1, %2)").arg(event->get("x")).arg(event->get("y"));
453
+}
454
+
455
+void DraggablePixmapItem::move(int x, int y) {
456
+    event->setX(event->x() + x);
457
+    event->setY(event->y() + y);
458
+    updatePosition();
459
+    emitPositionChanged();
308 460
 }
309 461
 
310 462
 void DraggablePixmapItem::mouseMoveEvent(QGraphicsSceneMouseEvent *mouse) {
311 463
     if (active) {
312
-        int x = mouse->pos().x() / 16;
313
-        int y = mouse->pos().y() / 16;
464
+        int x = (mouse->pos().x() + this->pos().x()) / 16;
465
+        int y = (mouse->pos().y() + this->pos().y()) / 16;
314 466
         if (x != last_x || y != last_y) {
315
-            event->setX(event->x() + x - last_x);
316
-            event->setY(event->y() + y - last_y);
317
-            update();
467
+            clicking = false;
468
+            if (editor->selected_events->contains(this)) {
469
+                for (DraggablePixmapItem *item : *editor->selected_events) {
470
+                    item->move(x - last_x, y - last_y);
471
+                }
472
+            } else {
473
+                move(x - last_x, y - last_y);
474
+            }
475
+            last_x = x;
476
+            last_y = y;
477
+            //qDebug() << QString("(%1, %2)").arg(event->get("x")).arg(event->get("x"));
318 478
         }
319 479
     }
320 480
 }
321 481
 
322 482
 void DraggablePixmapItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouse) {
483
+    if (clicking) {
484
+        this->editor->selectMapObject(this, mouse->modifiers() & Qt::ControlModifier);
485
+        this->editor->updateSelectedObjects();
486
+    }
323 487
     active = false;
324 488
 }
489
+
490
+QList<DraggablePixmapItem *> *Editor::getObjects() {
491
+    QList<DraggablePixmapItem *> *list = new QList<DraggablePixmapItem *>;
492
+    for (Event *event : map->getAllEvents()) {
493
+        for (QGraphicsItem *child : objects_group->childItems()) {
494
+            DraggablePixmapItem *item = (DraggablePixmapItem *)child;
495
+            if (item->event == event) {
496
+                list->append(item);
497
+                break;
498
+            }
499
+        }
500
+    }
501
+    return list;
502
+}
503
+
504
+void Editor::redrawObject(DraggablePixmapItem *item) {
505
+    if (item) {
506
+        item->setPixmap(item->event->pixmap);
507
+        if (selected_events && selected_events->contains(item)) {
508
+            QImage image = item->pixmap().toImage();
509
+            QPainter painter(&image);
510
+            painter.setPen(QColor(250, 100, 25));
511
+            painter.drawRect(0, 0, image.width() - 1, image.height() - 1);
512
+            painter.end();
513
+            item->setPixmap(QPixmap::fromImage(image));
514
+        }
515
+    }
516
+}
517
+
518
+void Editor::updateSelectedObjects() {
519
+    for (DraggablePixmapItem *item : *(getObjects())) {
520
+        redrawObject(item);
521
+    }
522
+    emit selectedObjectsChanged();
523
+}
524
+
525
+void Editor::selectMapObject(DraggablePixmapItem *object) {
526
+    selectMapObject(object, false);
527
+}
528
+
529
+void Editor::selectMapObject(DraggablePixmapItem *object, bool toggle) {
530
+    if (selected_events && object) {
531
+        if (selected_events->contains(object)) {
532
+            if (toggle) {
533
+                selected_events->removeOne(object);
534
+            }
535
+        } else {
536
+            if (!toggle) {
537
+                selected_events->clear();
538
+            }
539
+            selected_events->append(object);
540
+        }
541
+        updateSelectedObjects();
542
+    }
543
+}
544
+
545
+DraggablePixmapItem* Editor::addNewEvent() {
546
+    return addNewEvent("object");
547
+}
548
+
549
+DraggablePixmapItem* Editor::addNewEvent(QString event_type) {
550
+    if (project && map) {
551
+        Event *event = new Event;
552
+        event->put("map_name", map->name);
553
+        event->put("event_type", event_type);
554
+        map->addEvent(event);
555
+        project->loadObjectPixmaps(map->getAllEvents());
556
+        DraggablePixmapItem *object = addMapObject(event);
557
+
558
+        return object;
559
+    }
560
+    return NULL;
561
+}
562
+
563
+void Editor::deleteEvent(Event *event) {
564
+    Map *map = project->getMap(event->get("map_name"));
565
+    if (map) {
566
+        map->removeEvent(event);
567
+    }
568
+    //selected_events->removeAll(event);
569
+    //updateSelectedObjects();
570
+}
571
+
572
+
573
+// dunno how to detect bubbling. QMouseEvent::isAccepted seems to always be true
574
+// check if selected_events changed instead. this has the side effect of deselecting
575
+// when you click on a selected event, since selected_events doesn't change.
576
+
577
+QList<DraggablePixmapItem *> selected_events_test;
578
+bool clicking = false;
579
+
580
+void Editor::objectsView_onMousePress(QMouseEvent *event) {
581
+    clicking = true;
582
+    selected_events_test = *selected_events;
583
+}
584
+
585
+void Editor::objectsView_onMouseMove(QMouseEvent *event) {
586
+    clicking = false;
587
+}
588
+
589
+void Editor::objectsView_onMouseRelease(QMouseEvent *event) {
590
+    if (clicking) {
591
+        if (selected_events_test.length()) {
592
+            if (selected_events_test.length() == selected_events->length()) {
593
+                bool deselect = true;
594
+                for (int i = 0; i < selected_events_test.length(); i++) {
595
+                    if (selected_events_test.at(i) != selected_events->at(i)) {
596
+                        deselect = false;
597
+                        break;
598
+                    }
599
+                }
600
+                if (deselect) {
601
+                    selected_events->clear();
602
+                    updateSelectedObjects();
603
+                }
604
+            }
605
+        }
606
+        clicking = false;
607
+    }
608
+}

+ 183
- 48
editor.h View File

@@ -4,24 +4,105 @@
4 4
 #include <QGraphicsScene>
5 5
 #include <QGraphicsItemGroup>
6 6
 #include <QGraphicsSceneMouseEvent>
7
+#include <QGraphicsItemAnimation>
8
+#include <QComboBox>
7 9
 
8 10
 #include "project.h"
9 11
 
12
+class DraggablePixmapItem;
13
+class MapPixmapItem;
14
+class CollisionPixmapItem;
15
+class MetatilesPixmapItem;
16
+class CollisionMetatilesPixmapItem;
17
+class ElevationMetatilesPixmapItem;
10 18
 
11
-class DraggablePixmapItem : public QGraphicsPixmapItem {
19
+class Editor : public QObject
20
+{
21
+    Q_OBJECT
22
+public:
23
+    Editor();
24
+public:
25
+    QObject *parent = NULL;
26
+    Project *project = NULL;
27
+    Map *map = NULL;
28
+    void saveProject();
29
+    void save();
30
+    void undo();
31
+    void redo();
32
+    void setMap(QString map_name);
33
+    void displayMap();
34
+    void displayMetatiles();
35
+    void displayCollisionMetatiles();
36
+    void displayElevationMetatiles();
37
+    void displayMapObjects();
38
+    void displayMapConnections();
39
+    void displayMapBorder();
40
+
41
+    void setEditingMap();
42
+    void setEditingCollision();
43
+    void setEditingObjects();
44
+
45
+    DraggablePixmapItem *addMapObject(Event *event);
46
+    void selectMapObject(DraggablePixmapItem *object);
47
+    void selectMapObject(DraggablePixmapItem *object, bool toggle);
48
+    DraggablePixmapItem *addNewEvent();
49
+    DraggablePixmapItem *addNewEvent(QString event_type);
50
+    void deleteEvent(Event *);
51
+    void updateSelectedObjects();
52
+    void redrawObject(DraggablePixmapItem *item);
53
+    QList<DraggablePixmapItem *> *getObjects();
54
+
55
+    QGraphicsScene *scene = NULL;
56
+    QGraphicsPixmapItem *current_view = NULL;
57
+    MapPixmapItem *map_item = NULL;
58
+    CollisionPixmapItem *collision_item = NULL;
59
+    QGraphicsItemGroup *objects_group = NULL;
60
+
61
+    QGraphicsScene *scene_metatiles = NULL;
62
+    QGraphicsScene *scene_collision_metatiles = NULL;
63
+    QGraphicsScene *scene_elevation_metatiles = NULL;
64
+    MetatilesPixmapItem *metatiles_item = NULL;
65
+    CollisionMetatilesPixmapItem *collision_metatiles_item = NULL;
66
+    ElevationMetatilesPixmapItem *elevation_metatiles_item = NULL;
67
+
68
+    QList<DraggablePixmapItem*> *events = NULL;
69
+    QList<DraggablePixmapItem*> *selected_events = NULL;
70
+
71
+    QString map_edit_mode;
72
+
73
+    void objectsView_onMousePress(QMouseEvent *event);
74
+    void objectsView_onMouseMove(QMouseEvent *event);
75
+    void objectsView_onMouseRelease(QMouseEvent *event);
76
+
77
+private slots:
78
+    void mouseEvent_map(QGraphicsSceneMouseEvent *event, MapPixmapItem *item);
79
+    void mouseEvent_collision(QGraphicsSceneMouseEvent *event, CollisionPixmapItem *item);
80
+
81
+signals:
82
+    void objectsChanged();
83
+    void selectedObjectsChanged();
84
+};
85
+
86
+
87
+
88
+class DraggablePixmapItem : public QObject, public QGraphicsPixmapItem {
89
+    Q_OBJECT
12 90
 public:
13 91
     DraggablePixmapItem(QPixmap pixmap): QGraphicsPixmapItem(pixmap) {
14 92
     }
15
-    Event *event;
93
+    Editor *editor = NULL;
94
+    Event *event = NULL;
95
+    QGraphicsItemAnimation *pos_anim = NULL;
16 96
     DraggablePixmapItem(Event *event_) : QGraphicsPixmapItem(event_->pixmap) {
17 97
         event = event_;
18
-        update();
98
+        updatePosition();
19 99
     }
20 100
     bool active;
21 101
     bool right_click;
102
+    bool clicking;
22 103
     int last_x;
23 104
     int last_y;
24
-    void update() {
105
+    void updatePosition() {
25 106
         int x = event->x() * 16;
26 107
         int y = event->y() * 16;
27 108
         x -= pixmap().width() / 32 * 16;
@@ -30,6 +111,62 @@ public:
30 111
         setY(y);
31 112
         setZValue(event->y());
32 113
     }
114
+    void move(int x, int y);
115
+    void emitPositionChanged() {
116
+        emit xChanged(event->x());
117
+        emit yChanged(event->y());
118
+        emit elevationChanged(event->elevation());
119
+    }
120
+    void updatePixmap() {
121
+        QList<Event*> objects;
122
+        objects.append(event);
123
+        event->pixmap = QPixmap();
124
+        editor->project->loadObjectPixmaps(objects);
125
+        editor->redrawObject(this);
126
+        emit spriteChanged(event->pixmap);
127
+    }
128
+    void bind(QComboBox *combo, QString key) {
129
+        connect(combo, static_cast<void (QComboBox::*)(const QString &)>(&QComboBox::activated),
130
+                this, [this, key](QString value){
131
+            this->event->put(key, value);
132
+        });
133
+        connect(this, &DraggablePixmapItem::onPropertyChanged,
134
+                this, [combo, key](QString key2, QString value){
135
+            if (key2 == key) {
136
+                combo->addItem(value);
137
+                combo->setCurrentText(value);
138
+            }
139
+        });
140
+    }
141
+
142
+signals:
143
+    void positionChanged(Event *event);
144
+    void xChanged(int);
145
+    void yChanged(int);
146
+    void elevationChanged(int);
147
+    void spriteChanged(QPixmap pixmap);
148
+    void onPropertyChanged(QString key, QString value);
149
+
150
+public slots:
151
+    void set_x(const QString &text) {
152
+        event->put("x", text);
153
+        updatePosition();
154
+    }
155
+    void set_y(const QString &text) {
156
+        event->put("y", text);
157
+        updatePosition();
158
+    }
159
+    void set_elevation(const QString &text) {
160
+        event->put("elevation", text);
161
+        updatePosition();
162
+    }
163
+    void set_sprite(const QString &text) {
164
+        event->put("sprite", text);
165
+        updatePixmap();
166
+    }
167
+    void set_script(const QString &text) {
168
+        event->put("script_label", text);
169
+    }
33 170
 
34 171
 protected:
35 172
     void mousePressEvent(QGraphicsSceneMouseEvent*);
@@ -37,22 +174,33 @@ protected:
37 174
     void mouseReleaseEvent(QGraphicsSceneMouseEvent*);
38 175
 };
39 176
 
40
-class MapPixmapItem : public QGraphicsPixmapItem {
177
+class EventGroup : public QGraphicsItemGroup {
178
+};
179
+
180
+class MapPixmapItem : public QObject, public QGraphicsPixmapItem {
181
+    Q_OBJECT
41 182
 public:
42 183
     MapPixmapItem(QPixmap pixmap): QGraphicsPixmapItem(pixmap) {
43 184
     }
44
-    Map *map;
185
+    Map *map = NULL;
45 186
     MapPixmapItem(Map *map_) {
46 187
         map = map_;
47 188
     }
48 189
     bool active;
49 190
     bool right_click;
191
+    QPoint selection_origin;
192
+    QList<QPoint> selection;
50 193
     virtual void paint(QGraphicsSceneMouseEvent*);
51 194
     virtual void floodFill(QGraphicsSceneMouseEvent*);
195
+    virtual void pick(QGraphicsSceneMouseEvent*);
196
+    virtual void select(QGraphicsSceneMouseEvent*);
52 197
     virtual void undo();
53 198
     virtual void redo();
54 199
     virtual void draw();
55 200
 
201
+signals:
202
+    void mouseEvent(QGraphicsSceneMouseEvent *, MapPixmapItem *);
203
+
56 204
 protected:
57 205
     void mousePressEvent(QGraphicsSceneMouseEvent*);
58 206
     void mouseMoveEvent(QGraphicsSceneMouseEvent*);
@@ -60,36 +208,51 @@ protected:
60 208
 };
61 209
 
62 210
 class CollisionPixmapItem : public MapPixmapItem {
211
+    Q_OBJECT
63 212
 public:
64 213
     CollisionPixmapItem(QPixmap pixmap): MapPixmapItem(pixmap) {
65 214
     }
66 215
     CollisionPixmapItem(Map *map_): MapPixmapItem(map_) {
67 216
     }
68
-
69
-public:
70 217
     virtual void paint(QGraphicsSceneMouseEvent*);
71 218
     virtual void floodFill(QGraphicsSceneMouseEvent*);
219
+    virtual void pick(QGraphicsSceneMouseEvent*);
72 220
     virtual void draw();
221
+
222
+signals:
223
+    void mouseEvent(QGraphicsSceneMouseEvent *, CollisionPixmapItem *);
224
+
225
+protected:
226
+    void mousePressEvent(QGraphicsSceneMouseEvent*);
227
+    void mouseMoveEvent(QGraphicsSceneMouseEvent*);
228
+    void mouseReleaseEvent(QGraphicsSceneMouseEvent*);
73 229
 };
74 230
 
75
-class MetatilesPixmapItem : public QGraphicsPixmapItem {
231
+class MetatilesPixmapItem : public QObject, public QGraphicsPixmapItem {
232
+    Q_OBJECT
76 233
 public:
77 234
     MetatilesPixmapItem(QPixmap pixmap): QGraphicsPixmapItem(pixmap) {
78 235
     }
79 236
     MetatilesPixmapItem(Map *map_) {
80 237
         map = map_;
238
+        connect(map, SIGNAL(paintTileChanged(Map*)), this, SLOT(paintTileChanged(Map *)));
81 239
     }
82
-    Map* map;
240
+    Map* map = NULL;
83 241
     virtual void pick(uint);
84 242
     virtual void draw();
243
+private slots:
244
+    void paintTileChanged(Map *map);
85 245
 protected:
86 246
     void mousePressEvent(QGraphicsSceneMouseEvent*);
247
+    void mouseMoveEvent(QGraphicsSceneMouseEvent*);
87 248
     void mouseReleaseEvent(QGraphicsSceneMouseEvent*);
88 249
 };
89 250
 
90 251
 class CollisionMetatilesPixmapItem : public MetatilesPixmapItem {
252
+    Q_OBJECT
91 253
 public:
92 254
     CollisionMetatilesPixmapItem(Map *map_): MetatilesPixmapItem(map_) {
255
+        connect(map, SIGNAL(paintCollisionChanged(Map*)), this, SLOT(paintCollisionChanged(Map *)));
93 256
     }
94 257
     virtual void pick(uint collision) {
95 258
         map->paint_collision = collision;
@@ -98,11 +261,17 @@ public:
98 261
     virtual void draw() {
99 262
         setPixmap(map->renderCollisionMetatiles());
100 263
     }
264
+private slots:
265
+    void paintCollisionChanged(Map *map) {
266
+        draw();
267
+    }
101 268
 };
102 269
 
103 270
 class ElevationMetatilesPixmapItem : public MetatilesPixmapItem {
271
+    Q_OBJECT
104 272
 public:
105 273
     ElevationMetatilesPixmapItem(Map *map_): MetatilesPixmapItem(map_) {
274
+        connect(map, SIGNAL(paintCollisionChanged(Map*)), this, SLOT(paintCollisionChanged(Map *)));
106 275
     }
107 276
     virtual void pick(uint elevation) {
108 277
         map->paint_elevation = elevation;
@@ -111,45 +280,11 @@ public:
111 280
     virtual void draw() {
112 281
         setPixmap(map->renderElevationMetatiles());
113 282
     }
283
+private slots:
284
+    void paintCollisionChanged(Map *map) {
285
+        draw();
286
+    }
114 287
 };
115 288
 
116 289
 
117
-class Editor
118
-{
119
-public:
120
-    Editor();
121
-public:
122
-    Project *project;
123
-    Map *map;
124
-    void saveProject();
125
-    void save();
126
-    void undo();
127
-    void redo();
128
-    void setMap(QString map_name);
129
-    void displayMap();
130
-    void displayMetatiles();
131
-    void displayCollisionMetatiles();
132
-    void displayElevationMetatiles();
133
-    void displayMapObjects();
134
-    void displayMapConnections();
135
-    void displayMapBorder();
136
-
137
-    void setEditingMap();
138
-    void setEditingCollision();
139
-    void setEditingObjects();
140
-
141
-    QGraphicsScene *scene;
142
-    QGraphicsPixmapItem *current_view;
143
-    MapPixmapItem *map_item;
144
-    CollisionPixmapItem *collision_item;
145
-    QGraphicsItemGroup *objects_group;
146
-
147
-    QGraphicsScene *scene_metatiles;
148
-    QGraphicsScene *scene_collision_metatiles;
149
-    QGraphicsScene *scene_elevation_metatiles;
150
-    MetatilesPixmapItem *metatiles_item;
151
-    CollisionMetatilesPixmapItem *collision_metatiles_item;
152
-    ElevationMetatilesPixmapItem *elevation_metatiles_item;
153
-};
154
-
155 290
 #endif // EDITOR_H

+ 0
- 47
event.cpp View File

@@ -2,51 +2,4 @@
2 2
 
3 3
 Event::Event()
4 4
 {
5
-
6
-}
7
-
8
-ObjectEvent::ObjectEvent()
9
-{
10
-
11
-}
12
-
13
-Warp::Warp()
14
-{
15
-
16
-}
17
-
18
-CoordEvent::CoordEvent()
19
-{
20
-
21
-}
22
-
23
-BGEvent::BGEvent()
24
-{
25
-
26
-}
27
-
28
-Sign::Sign()
29
-{
30
-
31
-}
32
-
33
-Sign::Sign(const BGEvent &bg)
34
-{
35
-    x_ = bg.x_;
36
-    y_ = bg.y_;
37
-    elevation_ = bg.elevation_;
38
-    type = bg.type;
39
-}
40
-
41
-HiddenItem::HiddenItem()
42
-{
43
-
44
-}
45
-
46
-HiddenItem::HiddenItem(const BGEvent &bg)
47
-{
48
-    x_ = bg.x_;
49
-    y_ = bg.y_;
50
-    elevation_ = bg.elevation_;
51
-    type = bg.type;
52 5
 }

+ 22
- 72
event.h View File

@@ -3,6 +3,7 @@
3 3
 
4 4
 #include <QString>
5 5
 #include <QPixmap>
6
+#include <QMap>
6 7
 
7 8
 class Event
8 9
 {
@@ -11,90 +12,39 @@ public:
11 12
 
12 13
 public:
13 14
     int x() {
14
-        return x_.toInt(nullptr, 0);
15
+        return getInt("x");
15 16
     }
16 17
     int y() {
17
-        return y_.toInt(nullptr, 0);
18
+        return getInt("y");
18 19
     }
19 20
     int elevation() {
20
-        return elevation_.toInt(nullptr, 0);
21
+        return getInt("elevation");
21 22
     }
22 23
     void setX(int x) {
23
-        x_ = QString("%1").arg(x);
24
+        put("x", x);
24 25
     }
25 26
     void setY(int y) {
26
-        y_ = QString("%1").arg(y);
27
+        put("y", y);
27 28
     }
28
-
29
-    QString x_;
30
-    QString y_;
31
-    QString elevation_;
32
-    QPixmap pixmap;
33
-};
34
-
35
-class ObjectEvent : public Event {
36
-public:
37
-    ObjectEvent();
38
-
39
-public:
40
-    QString sprite;
41
-    QString replacement; // ????
42
-    QString behavior;
43
-    QString radius_x;
44
-    QString radius_y;
45
-    QString property;
46
-    QString sight_radius;
47
-    QString script_label;
48
-    QString event_flag;
49
-};
50
-
51
-class Warp : public Event {
52
-public:
53
-    Warp();
54
-
55
-public:
56
-    QString destination_warp;
57
-    QString destination_map;
58
-};
59
-
60
-class CoordEvent : public Event {
61
-public:
62
-    CoordEvent();
63
-
64
-public:
65
-    QString unknown1;
66
-    QString unknown2;
67
-    QString unknown3;
68
-    QString unknown4;
69
-    QString script_label;
70
-};
71
-
72
-class BGEvent : public Event {
73
-public:
74
-    BGEvent();
75
-public:
76
-    bool is_item() {
77
-        return type.toInt(nullptr, 0) >= 5;
29
+    QString get(QString key) {
30
+        return values.value(key);
31
+    }
32
+    int getInt(QString key) {
33
+        return values.value(key).toInt(nullptr, 0);
34
+    }
35
+    void put(QString key, int value) {
36
+        put(key, QString("%1").arg(value));
37
+    }
38
+    void put(QString key, QString value) {
39
+        values.insert(key, value);
78 40
     }
79
-    QString type;
80
-};
81 41
 
82
-class Sign : public BGEvent {
83
-public:
84
-    Sign();
85
-    Sign(const BGEvent&);
86
-public:
87
-    QString script_label;
88
-};
42
+    bool is_hidden_item() {
43
+        return getInt("type") >= 5;
44
+    }
89 45
 
90
-class HiddenItem : public BGEvent {
91
-public:
92
-    HiddenItem();
93
-    HiddenItem(const BGEvent&);
94
-public:
95
-    QString item;
96
-    QString unknown5;
97
-    QString unknown6;
46
+    QMap<QString, QString> values;
47
+    QPixmap pixmap;
98 48
 };
99 49
 
100 50
 #endif // EVENT_H

+ 22
- 0
graphicsview.cpp View File

@@ -0,0 +1,22 @@
1
+#include "graphicsview.h"
2
+
3
+void GraphicsView::mousePressEvent(QMouseEvent *event) {
4
+    QGraphicsView::mousePressEvent(event);
5
+    if (editor) {
6
+        editor->objectsView_onMousePress(event);
7
+    }
8
+}
9
+
10
+void GraphicsView::mouseMoveEvent(QMouseEvent *event) {
11
+    QGraphicsView::mouseMoveEvent(event);
12
+    if (editor) {
13
+        editor->objectsView_onMouseMove(event);
14
+    }
15
+}
16
+
17
+void GraphicsView::mouseReleaseEvent(QMouseEvent *event) {
18
+    QGraphicsView::mouseReleaseEvent(event);
19
+    if (editor) {
20
+        editor->objectsView_onMouseRelease(event);
21
+    }
22
+}

+ 38
- 0
graphicsview.h View File

@@ -0,0 +1,38 @@
1
+#ifndef GRAPHICSVIEW_H
2
+#define GRAPHICSVIEW_H
3
+
4
+#include <QGraphicsView>
5
+#include <QMouseEvent>
6
+
7
+#include "editor.h"
8
+
9
+/*
10
+class GraphicsView_Object : public QObject
11
+{
12
+    Q_OBJECT
13
+
14
+signals:
15
+    void onMousePress(QMouseEvent *event);
16
+    void onMouseMove(QMouseEvent *event);
17
+    void onMouseRelease(QMouseEvent *event);
18
+};
19
+*/
20
+
21
+class GraphicsView : public QGraphicsView
22
+{
23
+public:
24
+    GraphicsView() : QGraphicsView() {}
25
+    GraphicsView(QWidget *parent) : QGraphicsView(parent) {}
26
+
27
+public:
28
+//    GraphicsView_Object object;
29
+    Editor *editor = NULL;
30
+protected:
31
+    void mousePressEvent(QMouseEvent *event);
32
+    void mouseMoveEvent(QMouseEvent *event);
33
+    void mouseReleaseEvent(QMouseEvent *event);
34
+};
35
+
36
+//Q_DECLARE_METATYPE(GraphicsView)
37
+
38
+#endif // GRAPHICSVIEW_H

+ 326
- 37
mainwindow.cpp View File

@@ -1,12 +1,20 @@
1 1
 #include "mainwindow.h"
2 2
 #include "ui_mainwindow.h"
3 3
 #include "project.h"
4
+#include "editor.h"
5
+#include "objectpropertiesframe.h"
6
+#include "ui_objectpropertiesframe.h"
4 7
 
5 8
 #include <QDebug>
6 9
 #include <QFileDialog>
7 10
 #include <QStandardItemModel>
8 11
 #include <QShortcut>
9 12
 #include <QSettings>
13
+#include <QSpinBox>
14
+#include <QTextEdit>
15
+#include <QSpacerItem>
16
+#include <QFont>
17
+#include <QScrollBar>
10 18
 
11 19
 MainWindow::MainWindow(QWidget *parent) :
12 20
     QMainWindow(parent),
@@ -15,16 +23,23 @@ MainWindow::MainWindow(QWidget *parent) :
15 23
     QCoreApplication::setOrganizationName("pret");
16 24
     QCoreApplication::setApplicationName("pretmap");
17 25
 
26
+    ui->setupUi(this);
27
+    new QShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Z), this, SLOT(redo()));
28
+
18 29
     editor = new Editor;
30
+    connect(editor, SIGNAL(objectsChanged()), this, SLOT(updateSelectedObjects()));
31
+    connect(editor, SIGNAL(selectedObjectsChanged()), this, SLOT(updateSelectedObjects()));
19 32
 
20
-    new QShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Z), this, SLOT(redo()));
21
-    ui->setupUi(this);
33
+    on_toolButton_Paint_clicked();
22 34
 
23 35
     QSettings settings;
24 36
     QString key = "recent_projects";
25 37
     if (settings.contains(key)) {
26 38
         QString default_dir = settings.value(key).toStringList().last();
27
-        openProject(default_dir);
39
+        if (!default_dir.isNull()) {
40
+            qDebug() << QString("default_dir: '%1'").arg(default_dir);
41
+            openProject(default_dir);
42
+        }
28 43
     }
29 44
 }
30 45
 
@@ -34,35 +49,53 @@ MainWindow::~MainWindow()
34 49
 }
35 50
 
36 51
 void MainWindow::openProject(QString dir) {
37
-    bool already_open = (editor->project != NULL) && (editor->project->root == dir);
52
+    if (dir.isNull()) {
53
+        return;
54
+    }
55
+    bool already_open = (
56
+        (editor != NULL && editor != nullptr)
57
+        && (editor->project != NULL && editor->project != nullptr)
58
+        && (editor->project->root == dir)
59
+    );
38 60
     if (!already_open) {
39 61
         editor->project = new Project;
40 62
         editor->project->root = dir;
63
+        setWindowTitle(editor->project->getProjectTitle() + " - pretmap");
41 64
         populateMapList();
42 65
         setMap(getDefaultMap());
43 66
     } else {
67
+        setWindowTitle(editor->project->getProjectTitle() + " - pretmap");
44 68
         populateMapList();
45 69
     }
46 70
 }
47 71
 
48 72
 QString MainWindow::getDefaultMap() {
49
-    QSettings settings;
50
-    QString key = "project:" + editor->project->root;
51
-    if (settings.contains(key)) {
52
-        QMap<QString, QVariant> qmap = settings.value(key).toMap();
53
-        if (qmap.contains("recent_map")) {
54
-            QString map_name = qmap.value("recent_map").toString();
55
-            return map_name;
56
-        }
57
-    }
58
-    // Failing that, just get the first map in the list.
59
-    for (int i = 0; i < editor->project->groupedMapNames->length(); i++) {
60
-        QStringList *list = editor->project->groupedMapNames->value(i);
61
-        if (list->length()) {
62
-            return list->value(0);
73
+    if (editor && editor->project) {
74
+        QList<QStringList*> *names = editor->project->groupedMapNames;
75
+        if (names) {
76
+            QSettings settings;
77
+            QString key = "project:" + editor->project->root;
78
+            if (settings.contains(key)) {
79
+                QMap<QString, QVariant> qmap = settings.value(key).toMap();
80
+                if (qmap.contains("recent_map")) {
81
+                    QString map_name = qmap.value("recent_map").toString();
82
+                    for (int i = 0; i < names->length(); i++) {
83
+                        if (names->value(i)->contains(map_name)) {
84
+                            return map_name;
85
+                        }
86
+                    }
87
+                }
88
+            }
89
+            // Failing that, just get the first map in the list.
90
+            for (int i = 0; i < names->length(); i++) {
91
+                QStringList *list = names->value(i);
92
+                if (list->length()) {
93
+                    return list->value(0);
94
+                }
95
+            }
63 96
         }
64 97
     }
65
-    return NULL;
98
+    return QString();
66 99
 }
67 100
 
68 101
 QString MainWindow::getExistingDirectory(QString dir) {
@@ -92,6 +125,7 @@ void MainWindow::on_action_Open_Project_triggered()
92 125
 }
93 126
 
94 127
 void MainWindow::setMap(QString map_name) {
128
+    qDebug() << QString("setMap(%1)").arg(map_name);
95 129
     if (map_name.isNull()) {
96 130
         return;
97 131
     }
@@ -114,6 +148,7 @@ void MainWindow::setMap(QString map_name) {
114 148
     ui->graphicsView_Objects_Map->setScene(editor->scene);
115 149
     ui->graphicsView_Objects_Map->setSceneRect(editor->scene->sceneRect());
116 150
     ui->graphicsView_Objects_Map->setFixedSize(editor->scene->width() + 2, editor->scene->height() + 2);
151
+    ui->graphicsView_Objects_Map->editor = editor;
117 152
 
118 153
     ui->graphicsView_Metatiles->setScene(editor->scene_metatiles);
119 154
     //ui->graphicsView_Metatiles->setSceneRect(editor->scene_metatiles->sceneRect());
@@ -129,6 +164,10 @@ void MainWindow::setMap(QString map_name) {
129 164
 
130 165
     displayMapProperties();
131 166
 
167
+    setWindowTitle(map_name + " - " + editor->project->getProjectTitle() + " - pretmap");
168
+
169
+    connect(editor->map, SIGNAL(mapChanged(Map*)), this, SLOT(onMapChanged(Map *)));
170
+
132 171
     setRecentMap(map_name);
133 172
     updateMapList();
134 173
 }
@@ -145,11 +184,22 @@ void MainWindow::setRecentMap(QString map_name) {
145 184
 }
146 185
 
147 186
 void MainWindow::displayMapProperties() {
187
+    ui->comboBox_Song->clear();
188
+    ui->comboBox_Location->clear();
189
+    ui->comboBox_Visibility->clear();
190
+    ui->comboBox_Weather->clear();
191
+    ui->comboBox_Type->clear();
192
+    ui->comboBox_BattleScene->clear();
193
+    ui->checkBox_ShowLocation->setChecked(false);
194
+    if (!editor || !editor->map || !editor->project) {
195
+        ui->frame_3->setEnabled(false);
196
+        return;
197
+    }
198
+    ui->frame_3->setEnabled(true);
148 199
     Map *map = editor->map;
149 200
     Project *project = editor->project;
150 201
 
151 202
     QStringList songs = project->getSongNames();
152
-    ui->comboBox_Song->clear();
153 203
     ui->comboBox_Song->addItems(songs);
154 204
     QString song = map->song;
155 205
     if (!songs.contains(song)) {
@@ -157,23 +207,18 @@ void MainWindow::displayMapProperties() {
157 207
     }
158 208
     ui->comboBox_Song->setCurrentText(song);
159 209
 
160
-    ui->comboBox_Location->clear();
161 210
     ui->comboBox_Location->addItems(project->getLocations());
162 211
     ui->comboBox_Location->setCurrentText(map->location);
163 212
 
164
-    ui->comboBox_Visibility->clear();
165 213
     ui->comboBox_Visibility->addItems(project->getVisibilities());
166 214
     ui->comboBox_Visibility->setCurrentText(map->visibility);
167 215
 
168
-    ui->comboBox_Weather->clear();
169 216
     ui->comboBox_Weather->addItems(project->getWeathers());
170 217
     ui->comboBox_Weather->setCurrentText(map->weather);
171 218
 
172
-    ui->comboBox_Type->clear();
173 219
     ui->comboBox_Type->addItems(project->getMapTypes());
174 220
     ui->comboBox_Type->setCurrentText(map->type);
175 221
 
176
-    ui->comboBox_BattleScene->clear();
177 222
     ui->comboBox_BattleScene->addItems(project->getBattleScenes());
178 223
     ui->comboBox_BattleScene->setCurrentText(map->battle_scene);
179 224
 
@@ -182,40 +227,54 @@ void MainWindow::displayMapProperties() {
182 227
 
183 228
 void MainWindow::on_comboBox_Song_activated(const QString &song)
184 229
 {
185
-    editor->map->song = song;
230
+    if (editor && editor->map) {
231
+        editor->map->song = song;
232
+    }
186 233
 }
187 234
 
188 235
 void MainWindow::on_comboBox_Location_activated(const QString &location)
189 236
 {
190
-    editor->map->location = location;
237
+    if (editor && editor->map) {
238
+        editor->map->location = location;
239
+    }
191 240
 }
192 241
 
193 242
 void MainWindow::on_comboBox_Visibility_activated(const QString &visibility)
194 243
 {
195
-    editor->map->visibility = visibility;
244
+    if (editor && editor->map) {
245
+        editor->map->visibility = visibility;
246
+    }
196 247
 }
197 248
 
198 249
 void MainWindow::on_comboBox_Weather_activated(const QString &weather)
199 250
 {
200
-    editor->map->weather = weather;
251
+    if (editor && editor->map) {
252
+        editor->map->weather = weather;
253
+    }
201 254
 }
202 255
 
203 256
 void MainWindow::on_comboBox_Type_activated(const QString &type)
204 257
 {
205
-    editor->map->type = type;
258
+    if (editor && editor->map) {
259
+        editor->map->type = type;
260
+    }
206 261
 }
207 262
 
208 263
 void MainWindow::on_comboBox_BattleScene_activated(const QString &battle_scene)
209 264
 {
210
-    editor->map->battle_scene = battle_scene;
265
+    if (editor && editor->map) {
266
+        editor->map->battle_scene = battle_scene;
267
+    }
211 268
 }
212 269
 
213 270
 void MainWindow::on_checkBox_ShowLocation_clicked(bool checked)
214 271
 {
215
-    if (checked) {
216
-        editor->map->show_location = "TRUE";
217
-    } else {
218
-        editor->map->show_location = "FALSE";
272
+    if (editor && editor->map) {
273
+        if (checked) {
274
+            editor->map->show_location = "TRUE";
275
+        } else {
276
+            editor->map->show_location = "FALSE";
277
+        }
219 278
     }
220 279
 }
221 280
 
@@ -281,7 +340,7 @@ void MainWindow::on_mapList_activated(const QModelIndex &index)
281 340
     if (!data.isNull()) {
282 341
         setMap(data.toString());
283 342
     }
284
-    updateMapList();
343
+    //updateMapList();
285 344
 }
286 345
 
287 346
 void MainWindow::markAllEdited(QAbstractItemModel *model) {
@@ -307,7 +366,8 @@ void MainWindow::markEdited(QModelIndex index) {
307 366
             if (editor->project->map_cache->contains(map_name)) {
308 367
                 // Just mark anything that's been opened for now.
309 368
                 // TODO if (project->getMap()->saved)
310
-                ui->mapList->setExpanded(index, true);
369
+                //ui->mapList->setExpanded(index, true);
370
+                ui->mapList->setExpanded(index, editor->project->map_cache->value(map_name)->hasUnsavedChanges());
311 371
             }
312 372
         }
313 373
     }
@@ -334,6 +394,7 @@ void MainWindow::redo() {
334 394
 
335 395
 void MainWindow::on_action_Save_triggered() {
336 396
     editor->save();
397
+    updateMapList();
337 398
 }
338 399
 
339 400
 void MainWindow::on_tabWidget_2_currentChanged(int index)
@@ -368,3 +429,231 @@ void MainWindow::on_actionRedo_triggered()
368 429
 {
369 430
     redo();
370 431
 }
432
+
433
+void MainWindow::on_toolButton_newObject_clicked()
434
+{
435
+    if (editor) {
436
+        DraggablePixmapItem *object = editor->addNewEvent();
437
+        if (object) {
438
+            //if (editor->selected_events->length()) {
439
+                editor->selectMapObject(object, true);
440
+            //}
441
+        }
442
+        updateSelectedObjects();
443
+    }
444
+}
445
+
446
+// Should probably just pass layout and let the editor work it out
447
+void MainWindow::updateSelectedObjects() {
448
+
449
+    QList<DraggablePixmapItem *> *all_events = editor->getObjects();
450
+    QList<DraggablePixmapItem *> *events = all_events;
451
+
452
+    if (editor->selected_events && editor->selected_events->length()) {
453
+        events = editor->selected_events;
454
+    }
455
+
456
+    QMap<QString, int> map_obj_gfx_constants = editor->project->getMapObjGfxConstants();
457
+
458
+    QList<ObjectPropertiesFrame *> frames;
459
+
460
+    for (DraggablePixmapItem *item : *events) {
461
+        ObjectPropertiesFrame *frame = new ObjectPropertiesFrame;
462
+//        frame->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
463
+
464
+        QSpinBox *x = frame->ui->spinBox_x;
465
+        QSpinBox *y = frame->ui->spinBox_y;
466
+        QSpinBox *z = frame->ui->spinBox_z;
467
+
468
+        x->setValue(item->event->x());
469
+        connect(x, SIGNAL(valueChanged(QString)), item, SLOT(set_x(QString)));
470
+        connect(item, SIGNAL(xChanged(int)), x, SLOT(setValue(int)));
471
+
472
+        y->setValue(item->event->y());
473
+        connect(y, SIGNAL(valueChanged(QString)), item, SLOT(set_y(QString)));
474
+        connect(item, SIGNAL(yChanged(int)), y, SLOT(setValue(int)));
475
+
476
+        z->setValue(item->event->elevation());
477
+        connect(z, SIGNAL(valueChanged(QString)), item, SLOT(set_elevation(QString)));
478
+        connect(item, SIGNAL(elevationChanged(int)), z, SLOT(setValue(int)));
479
+
480
+        QFont font;
481
+        font.setCapitalization(QFont::Capitalize);
482
+        frame->ui->label_name->setFont(font);
483
+        QString event_type = item->event->get("event_type");
484
+        QString map_name = item->event->get("map_name");
485
+        frame->ui->label_name->setText(
486
+            QString("%1 %2 %3")
487
+                .arg(map_name)
488
+                .arg(event_type)
489
+                .arg(editor->project->getMap(map_name)->events.value(event_type).indexOf(item->event) + 1)
490
+        );
491
+
492
+        frame->ui->label_spritePixmap->setPixmap(item->event->pixmap);
493
+        connect(item, SIGNAL(spriteChanged(QPixmap)), frame->ui->label_spritePixmap, SLOT(setPixmap(QPixmap)));
494
+
495
+        frame->ui->sprite->setVisible(false);
496
+
497
+        QMap<QString, QString> field_labels;
498
+        field_labels["script_label"] = "Script";
499
+        field_labels["event_flag"] = "Event Flag";
500
+        field_labels["replacement"] = "Replacement";
501
+        field_labels["property"] = "Property";
502
+        field_labels["sight_radius"] = "Sight Radius";
503
+        field_labels["destination_warp"] = "Destination Warp";
504
+        field_labels["destination_map"] = "Destination Map";
505
+        field_labels["coord_unknown1"] = "Unknown 1";
506
+        field_labels["coord_unknown2"] = "Unknown 2";
507
+        field_labels["type"] = "Type";
508
+        field_labels["item"] = "Item";
509
+        field_labels["item_unknown5"] = "Unknown 5";
510
+        field_labels["item_unknown6"] = "Unknown 6";
511
+
512
+        QStringList fields;
513
+
514
+        if (event_type == "object") {
515
+
516
+            frame->ui->sprite->setVisible(true);
517
+            frame->ui->comboBox_sprite->addItems(map_obj_gfx_constants.keys());
518
+            frame->ui->comboBox_sprite->setCurrentText(item->event->get("sprite"));
519
+            connect(frame->ui->comboBox_sprite, SIGNAL(activated(QString)), item, SLOT(set_sprite(QString)));
520
+
521
+            /*
522
+            frame->ui->script->setVisible(true);
523
+            frame->ui->comboBox_script->addItem(item->event->get("script_label"));
524
+            frame->ui->comboBox_script->setCurrentText(item->event->get("script_label"));
525
+            //item->bind(frame->ui->comboBox_script, "script_label");
526
+            connect(frame->ui->comboBox_script, SIGNAL(activated(QString)), item, SLOT(set_script(QString)));
527
+            //connect(frame->ui->comboBox_script, static_cast<void (QComboBox::*)(const QString&)>(&QComboBox::activated), item, [item](QString script_label){ item->event->put("script_label", script_label); });
528
+            //connect(item, SIGNAL(scriptChanged(QString)), frame->ui->comboBox_script, SLOT(setValue(QString)));
529
+            */
530
+
531
+            fields << "script_label";
532
+            fields << "event_flag";
533
+            fields << "replacement";
534
+            fields << "property";
535
+            fields << "sight_radius";
536
+        }
537
+        else if (event_type == "warp") {
538
+            fields << "destination_warp";
539
+            fields << "destination_map";
540
+        }
541
+        else if (event_type == "trap") {
542
+            fields << "script_label";
543
+            fields << "coord_unknown1";
544
+            fields << "coord_unknown2";
545
+        }
546
+        else if (event_type == "sign") {
547
+            fields << "type";
548
+            fields << "script_label";
549
+        }
550
+        else if (event_type == "hidden item") {
551
+            fields << "type";
552
+            fields << "item";
553
+            fields << "item_unknown5";
554
+            fields << "item_unknown6";
555
+        }
556
+
557
+        for (QString key : fields) {
558
+            QWidget *widget = new QWidget(frame);
559
+            QFormLayout *fl = new QFormLayout(widget);
560
+            fl->setContentsMargins(9, 0, 9, 0);
561
+            QComboBox *combo = new QComboBox(widget);
562
+            combo->setEditable(true);
563
+
564
+            QString value = item->event->get(key);
565
+            if (key == "destination_map") {
566
+                if (!editor->project->mapNames->contains(value)) {
567
+                    combo->addItem(value);
568
+                }
569
+                combo->addItems(*editor->project->mapNames);
570
+            } else {
571
+                combo->addItem(value);
572
+            }
573
+            combo->setCurrentText(value);
574
+
575
+            fl->addRow(new QLabel(field_labels[key], widget), combo);
576
+            widget->setLayout(fl);
577
+            frame->layout()->addWidget(widget);
578
+
579
+            item->bind(combo, key);
580
+        }
581
+
582
+        frames.append(frame);
583
+
584
+    }
585
+
586
+    //int scroll = ui->scrollArea_4->verticalScrollBar()->value();
587
+
588
+    QWidget *target = ui->scrollAreaWidgetContents;
589
+
590
+    if (target->children().length()) {
591
+        qDeleteAll(target->children());
592
+    }
593
+
594
+    QVBoxLayout *layout = new QVBoxLayout(target);
595
+    target->setLayout(layout);
596
+    ui->scrollArea_4->setWidgetResizable(true);
597
+    ui->scrollArea_4->setWidget(target);
598
+
599
+    for (ObjectPropertiesFrame *frame : frames) {
600
+        layout->addWidget(frame);
601
+    }
602
+
603
+    layout->addStretch(1);
604
+
605
+    // doesn't work
606
+    //QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
607
+    //ui->scrollArea_4->ensureVisible(0, scroll);
608
+}
609
+
610
+void MainWindow::on_toolButton_deleteObject_clicked()
611
+{
612
+    if (editor && editor->selected_events) {
613
+        if (editor->selected_events->length()) {
614
+            for (DraggablePixmapItem *item : *editor->selected_events) {
615
+                editor->deleteEvent(item->event);
616
+                if (editor->scene->items().contains(item)) {
617
+                    editor->scene->removeItem(item);
618
+                }
619
+                editor->selected_events->removeOne(item);
620
+            }
621
+            updateSelectedObjects();
622
+        }
623
+    }
624
+}
625
+
626
+void MainWindow::on_toolButton_Paint_clicked()
627
+{
628
+    editor->map_edit_mode = "paint";
629
+    checkToolButtons();
630
+}
631
+
632
+void MainWindow::on_toolButton_Select_clicked()
633
+{
634
+    editor->map_edit_mode = "select";
635
+    checkToolButtons();
636
+}
637
+
638
+void MainWindow::on_toolButton_Fill_clicked()
639
+{
640
+    editor->map_edit_mode = "fill";
641
+    checkToolButtons();
642
+}
643
+
644
+void MainWindow::on_toolButton_Dropper_clicked()
645
+{
646
+    editor->map_edit_mode = "pick";
647
+    checkToolButtons();
648
+}
649
+
650
+void MainWindow::checkToolButtons() {
651
+    ui->toolButton_Paint->setChecked(editor->map_edit_mode == "paint");
652
+    ui->toolButton_Select->setChecked(editor->map_edit_mode == "select");
653
+    ui->toolButton_Fill->setChecked(editor->map_edit_mode == "fill");
654
+    ui->toolButton_Dropper->setChecked(editor->map_edit_mode == "pick");
655
+}
656
+
657
+void MainWindow::onMapChanged(Map *map) {
658
+    updateMapList();
659
+}

+ 18
- 1
mainwindow.h View File

@@ -32,6 +32,8 @@ private slots:
32 32
     void undo();
33 33
     void redo();
34 34
 
35
+    void onMapChanged(Map *map);
36
+
35 37
     void on_action_Save_triggered();
36 38
     void on_tabWidget_2_currentChanged(int index);
37 39
     void on_action_Exit_triggered();
@@ -49,9 +51,23 @@ private slots:
49 51
 
50 52
     void on_actionRedo_triggered();
51 53
 
54
+    void on_toolButton_newObject_clicked();
55
+
56
+    void on_toolButton_deleteObject_clicked();
57
+
58
+    void updateSelectedObjects();
59
+
60
+    void on_toolButton_Paint_clicked();
61
+
62
+    void on_toolButton_Select_clicked();
63
+
64
+    void on_toolButton_Fill_clicked();
65
+
66
+    void on_toolButton_Dropper_clicked();
67
+
52 68
 private:
53 69
     Ui::MainWindow *ui;
54
-    Editor *editor;
70
+    Editor *editor = NULL;
55 71
     void setMap(QString);
56 72
     void populateMapList();
57 73
     QString getExistingDirectory(QString);
@@ -64,6 +80,7 @@ private:
64 80
     void updateMapList();
65 81
 
66 82
     void displayMapProperties();
83
+    void checkToolButtons();
67 84
 };
68 85
 
69 86
 #endif // MAINWINDOW_H

+ 694
- 339
mainwindow.ui
File diff suppressed because it is too large
View File


+ 166
- 53
map.cpp View File

@@ -3,9 +3,11 @@
3 3
 #include <QTime>
4 4
 #include <QDebug>
5 5
 #include <QPainter>
6
+#include <QImage>
6 7
 
7 8
 Map::Map(QObject *parent) : QObject(parent)
8 9
 {
10
+    blockdata = new Blockdata;
9 11
     cached_blockdata = new Blockdata;
10 12
     cached_collision = new Blockdata;
11 13
     cached_border = new Blockdata;
@@ -22,8 +24,8 @@ int Map::getHeight() {
22 24
     return height.toInt(nullptr, 0);
23 25
 }
24 26
 
25
-Tileset* Map::getBlockTileset(uint metatile_index) {
26
-    uint primary_size = 0x200;//tileset_primary->metatiles->length();
27
+Tileset* Map::getBlockTileset(int metatile_index) {
28
+    int primary_size = 0x200;//tileset_primary->metatiles->length();
27 29
     if (metatile_index < primary_size) {
28 30
         return tileset_primary;
29 31
     } else {
@@ -31,23 +33,43 @@ Tileset* Map::getBlockTileset(uint metatile_index) {
31 33
     }
32 34
 }
33 35
 
34
-QImage Map::getMetatileTile(uint tile) {
35
-    uint primary_size = 0x200;//tileset_primary->metatiles->length();
36
-    if (tile < primary_size) {
37
-        return tileset_primary->tiles->value(tile);
38
-    } else {
39
-        return tileset_secondary->tiles->value(tile - primary_size);
36
+QList<QList<QRgb>> Map::getBlockPalettes(int metatile_index) {
37
+    QList<QList<QRgb>> palettes;
38
+    for (int i = 0; i < 6; i++) {
39
+        palettes.append(tileset_primary->palettes->at(i));
40
+    }
41
+    for (int i = 6; i < tileset_secondary->palettes->length(); i++) {
42
+        palettes.append(tileset_secondary->palettes->at(i));
40 43
     }
44
+    return palettes;
41 45
 }
42 46
 
43
-Metatile* Map::getMetatile(uint index) {
44
-    uint primary_size = 0x200;//tileset_primary->metatiles->length();
47
+int Map::getBlockIndex(int index) {
48
+    int primary_size = 0x200;
45 49
     if (index < primary_size) {
46
-        return tileset_primary->metatiles->value(index);
50
+        return index;
47 51
     } else {
48
-        //qDebug() << QString("secondary tileset: %1").arg(index - primary_size, 0, 16);
49
-        return tileset_secondary->metatiles->value(index - primary_size);
52
+        return index - primary_size;
53
+    }
54
+}
55
+
56
+QImage Map::getMetatileTile(int tile) {
57
+    Tileset *tileset = getBlockTileset(tile);
58
+    int local_index = getBlockIndex(tile);
59
+    if (!tileset || !tileset->tiles) {
60
+        return QImage();
61
+    }
62
+    return tileset->tiles->value(local_index, QImage());
63
+}
64
+
65
+Metatile* Map::getMetatile(int index) {
66
+    Tileset *tileset = getBlockTileset(index);
67
+    int local_index = getBlockIndex(index);
68
+    if (!tileset || !tileset->metatiles) {
69
+        return NULL;
50 70
     }
71
+    Metatile *metatile = tileset->metatiles->value(local_index, NULL);
72
+    return metatile;
51 73
 }
52 74
 
53 75
 QImage Map::getCollisionMetatileImage(Block block) {
@@ -93,28 +115,38 @@ QImage Map::getElevationMetatileImage(int elevation) {
93 115
     return metatile_image;
94 116
 }
95 117
 
96
-QImage Map::getMetatileImage(uint tile) {
118
+QImage Map::getMetatileImage(int tile) {
97 119
 
98 120
     QImage metatile_image(16, 16, QImage::Format_RGBA8888);
99 121
 
100 122
     Metatile* metatile = getMetatile(tile);
101
-    if (metatile == NULL) {
123
+    if (!metatile || !metatile->tiles) {
102 124
         metatile_image.fill(0xffffffff);
103 125
         return metatile_image;
104 126
     }
105 127
 
106 128
     Tileset* blockTileset = getBlockTileset(tile);
129
+    if (!blockTileset) {
130
+        metatile_image.fill(0xffffffff);
131
+        return metatile_image;
132
+    }
133
+    QList<QList<QRgb>> palettes = getBlockPalettes(tile);
107 134
 
135
+    QPainter metatile_painter(&metatile_image);
108 136
     for (int layer = 0; layer < 2; layer++)
109 137
     for (int y = 0; y < 2; y++)
110 138
     for (int x = 0; x < 2; x++) {
111
-        //qDebug() << QString("x=%1 y=%2 layer=%3").arg(x).arg(y).arg(layer);
112
-        Tile tile = metatile->tiles->value((y * 2) + x + (layer * 4));
113
-        QImage tile_image = getMetatileTile(tile.tile);
114
-        QList<QRgb> palette = blockTileset->palettes->value(tile.palette);
115
-        for (int j = 0; j < palette.length(); j++) {
116
-            tile_image.setColor(j, palette.value(j));
117
-        }
139
+        Tile tile_ = metatile->tiles->value((y * 2) + x + (layer * 4));
140
+        QImage tile_image = getMetatileTile(tile_.tile);
141
+        //if (tile_image.isNull()) {
142
+        //    continue;
143
+        //}
144
+        //if (blockTileset->palettes) {
145
+            QList<QRgb> palette = palettes.value(tile_.palette);
146
+            for (int j = 0; j < palette.length(); j++) {
147
+                tile_image.setColor(j, palette.value(j));
148
+            }
149
+        //}
118 150
         //QVector<QRgb> vector = palette.toVector();
119 151
         //tile_image.setColorTable(vector);
120 152
         if (layer > 0) {
@@ -122,43 +154,66 @@ QImage Map::getMetatileImage(uint tile) {
122 154
             color.setAlpha(0);
123 155
             tile_image.setColor(15, color.rgba());
124 156
         }
125
-        QPainter metatile_painter(&metatile_image);
126 157
         QPoint origin = QPoint(x*8, y*8);
127
-        metatile_painter.drawImage(origin, tile_image.mirrored(tile.xflip == 1, tile.yflip == 1));
128
-        metatile_painter.end();
158
+        metatile_painter.drawImage(origin, tile_image.mirrored(tile_.xflip == 1, tile_.yflip == 1));
129 159
     }
160
+    metatile_painter.end();
130 161
 
131 162
     return metatile_image;
132 163
 }
133 164
 
134 165
 bool Map::blockChanged(int i, Blockdata *cache) {
166
+    if (cache == NULL || cache == nullptr) {
167
+        return true;
168
+    }
169
+    if (blockdata == NULL || blockdata == nullptr) {
170
+        return true;
171
+    }
172
+    if (cache->blocks == NULL || cache->blocks == nullptr) {
173
+        return true;
174
+    }
175
+    if (blockdata->blocks == NULL || blockdata->blocks == nullptr) {
176
+        return true;
177
+    }
135 178
     if (cache->blocks->length() <= i) {
136 179
         return true;
137 180
     }
181
+    if (blockdata->blocks->length() <= i) {
182
+        return true;
183
+    }
138 184
     return blockdata->blocks->value(i) != cache->blocks->value(i);
139 185
 }
140 186
 
141 187
 void Map::cacheBorder() {
188
+    if (cached_border) delete cached_border;
142 189
     cached_border = new Blockdata;
143
-    for (int i = 0; i < border->blocks->length(); i++) {
144
-        Block block = border->blocks->value(i);
145
-        cached_border->blocks->append(block);
190
+    if (border && border->blocks) {
191
+        for (int i = 0; i < border->blocks->length(); i++) {
192
+            Block block = border->blocks->value(i);
193
+            cached_border->blocks->append(block);
194
+        }
146 195
     }
147 196
 }
148 197
 
149 198
 void Map::cacheBlockdata() {
199
+    if (cached_blockdata) delete cached_blockdata;
150 200
     cached_blockdata = new Blockdata;
151
-    for (int i = 0; i < blockdata->blocks->length(); i++) {
152
-        Block block = blockdata->blocks->value(i);
153
-        cached_blockdata->blocks->append(block);
201
+    if (blockdata && blockdata->blocks) {
202
+        for (int i = 0; i < blockdata->blocks->length(); i++) {
203
+            Block block = blockdata->blocks->value(i);
204
+            cached_blockdata->blocks->append(block);
205
+        }
154 206
     }
155 207
 }
156 208
 
157 209
 void Map::cacheCollision() {
210
+    if (cached_collision) delete cached_collision;
158 211
     cached_collision = new Blockdata;
159
-    for (int i = 0; i < blockdata->blocks->length(); i++) {
160
-        Block block = blockdata->blocks->value(i);
161
-        cached_collision->blocks->append(block);
212
+    if (blockdata && blockdata->blocks) {
213
+        for (int i = 0; i < blockdata->blocks->length(); i++) {
214
+            Block block = blockdata->blocks->value(i);
215
+            cached_collision->blocks->append(block);
216
+        }
162 217
     }
163 218
 }
164 219
 
@@ -174,9 +229,13 @@ QPixmap Map::renderCollision() {
174 229
         collision_image = QImage(width_ * 16, height_ * 16, QImage::Format_RGBA8888);
175 230
         changed_any = true;
176 231
     }
232
+    if (!(blockdata && blockdata->blocks && width_ && height_)) {
233
+        collision_pixmap = collision_pixmap.fromImage(collision_image);
234
+        return collision_pixmap;
235
+    }
177 236
     QPainter painter(&collision_image);
178 237
     for (int i = 0; i < blockdata->blocks->length(); i++) {
179
-        if (!blockChanged(i, cached_collision)) {
238
+        if (cached_collision && !blockChanged(i, cached_collision)) {
180 239
             continue;
181 240
         }
182 241
         changed_any = true;
@@ -184,8 +243,8 @@ QPixmap Map::renderCollision() {
184 243
         QImage metatile_image = getMetatileImage(block.tile);
185 244
         QImage collision_metatile_image = getCollisionMetatileImage(block);
186 245
         QImage elevation_metatile_image = getElevationMetatileImage(block);
187
-        int map_y = i / width_;
188
-        int map_x = i % width_;
246
+        int map_y = width_ ? i / width_ : 0;
247
+        int map_x = width_ ? i % width_ : 0;
189 248
         QPoint metatile_origin = QPoint(map_x * 16, map_y * 16);
190 249
         painter.setOpacity(1);
191 250
         painter.drawImage(metatile_origin, metatile_image);
@@ -238,6 +297,11 @@ QPixmap Map::render() {
238 297
         image = QImage(width_ * 16, height_ * 16, QImage::Format_RGBA8888);
239 298
         changed_any = true;
240 299
     }
300
+    if (!(blockdata && blockdata->blocks && width_ && height_)) {
301
+        pixmap = pixmap.fromImage(image);
302
+        return pixmap;
303
+    }
304
+
241 305
     QPainter painter(&image);
242 306
     for (int i = 0; i < blockdata->blocks->length(); i++) {
243 307
         if (!blockChanged(i, cached_blockdata)) {
@@ -246,8 +310,8 @@ QPixmap Map::render() {
246 310
         changed_any = true;
247 311
         Block block = blockdata->blocks->value(i);
248 312
         QImage metatile_image = getMetatileImage(block.tile);
249
-        int map_y = i / width_;
250
-        int map_x = i % width_;
313
+        int map_y = width_ ? i / width_ : 0;
314
+        int map_x = width_ ? i % width_ : 0;
251 315
         QPoint metatile_origin = QPoint(map_x * 16, map_y * 16);
252 316
         painter.drawImage(metatile_origin, metatile_image);
253 317
     }
@@ -267,6 +331,10 @@ QPixmap Map::renderBorder() {
267 331
         border_image = QImage(width_ * 16, height_ * 16, QImage::Format_RGBA8888);
268 332
         changed_any = true;
269 333
     }
334
+    if (!(border && border->blocks)) {
335
+        border_pixmap = border_pixmap.fromImage(border_image);
336
+        return border_pixmap;
337
+    }
270 338
     QPainter painter(&border_image);
271 339
     for (int i = 0; i < border->blocks->length(); i++) {
272 340
         if (!blockChanged(i, cached_border)) {
@@ -371,6 +439,9 @@ void Map::drawSelection(int i, int w, QPainter *painter) {
371 439
 }
372 440
 
373 441
 QPixmap Map::renderMetatiles() {
442
+    if (!tileset_primary || !tileset_primary->metatiles || !tileset_secondary || !tileset_secondary->metatiles) {
443
+        return QPixmap();
444
+    }
374 445
     int primary_length = tileset_primary->metatiles->length();
375 446
     int length_ = primary_length + tileset_secondary->metatiles->length();
376 447
     int width_ = 8;
@@ -378,7 +449,7 @@ QPixmap Map::renderMetatiles() {
378 449
     QImage image(width_ * 16, height_ * 16, QImage::Format_RGBA8888);
379 450
     QPainter painter(&image);
380 451
     for (int i = 0; i < length_; i++) {
381
-        uint tile = i;
452
+        int tile = i;
382 453
         if (i >= primary_length) {
383 454
             tile += 0x200 - primary_length;
384 455
         }
@@ -396,17 +467,21 @@ QPixmap Map::renderMetatiles() {
396 467
 }
397 468
 
398 469
 Block* Map::getBlock(int x, int y) {
399
-    if (x >= 0 && x < getWidth())
400
-    if (y >= 0 && y < getHeight()) {
401
-        int i = y * getWidth() + x;
402
-        return new Block(blockdata->blocks->value(i));
470
+    if (blockdata && blockdata->blocks) {
471
+        if (x >= 0 && x < getWidth())
472
+        if (y >= 0 && y < getHeight()) {
473
+            int i = y * getWidth() + x;
474
+            return new Block(blockdata->blocks->value(i));
475
+        }
403 476
     }
404 477
     return NULL;
405 478
 }
406 479
 
407 480
 void Map::_setBlock(int x, int y, Block block) {
408 481
     int i = y * getWidth() + x;
409
-    blockdata->blocks->replace(i, block);
482
+    if (blockdata && blockdata->blocks) {
483
+        blockdata->blocks->replace(i, block);
484
+    }
410 485
 }
411 486
 
412 487
 void Map::_floodFill(int x, int y, uint tile) {
@@ -542,22 +617,33 @@ void Map::_floodFillCollisionElevation(int x, int y, uint collision, uint elevat
542 617
 
543 618
 
544 619
 void Map::undo() {
545
-    Blockdata *commit = history.pop();
546
-    if (commit != NULL) {
547
-        blockdata->copyFrom(commit);
620
+    if (blockdata) {
621
+        Blockdata *commit = history.pop();
622
+        if (commit != NULL) {
623
+            blockdata->copyFrom(commit);
624
+            emit mapChanged(this);
625
+        }
548 626
     }
549 627
 }
550 628
 
551 629
 void Map::redo() {
552
-    Blockdata *commit = history.next();
553
-    if (commit != NULL) {
554
-        blockdata->copyFrom(commit);
630
+    if (blockdata) {
631
+        Blockdata *commit = history.next();
632
+        if (commit != NULL) {
633
+            blockdata->copyFrom(commit);
634
+            emit mapChanged(this);
635
+        }
555 636
     }
556 637
 }
557 638
 
558 639
 void Map::commit() {
559
-    Blockdata* commit = blockdata->copy();
560
-    history.push(commit);
640
+    if (blockdata) {
641
+        if (!blockdata->equals(history.history.at(history.head))) {
642
+            Blockdata* commit = blockdata->copy();
643
+            history.push(commit);
644
+            emit mapChanged(this);
645
+        }
646
+    }
561 647
 }
562 648
 
563 649
 void Map::setBlock(int x, int y, Block block) {
@@ -598,3 +684,30 @@ void Map::floodFillCollisionElevation(int x, int y, uint collision, uint elevati
598 684
         commit();
599 685
     }
600 686
 }
687
+
688
+QList<Event *> Map::getAllEvents() {
689
+    QList<Event*> all;
690
+    for (QList<Event*> list : events.values()) {
691
+        all += list;
692
+    }
693
+    return all;
694
+}
695
+
696
+QList<Event *> Map::getEventsByType(QString type)
697
+{
698
+    return events.value(type);
699
+}
700
+
701
+void Map::removeEvent(Event *event) {
702
+    for (QString key : events.keys()) {
703
+        events[key].removeAll(event);
704
+    }
705
+}
706
+
707
+void Map::addEvent(Event *event) {
708
+    events[event->get("event_type")].append(event);
709
+}
710
+
711
+bool Map::hasUnsavedChanges() {
712
+    return !history.isSaved();
713
+}

+ 36
- 18
map.h View File

@@ -14,10 +14,11 @@ template <typename T>
14 14
 class History {
15 15
 public:
16 16
     QList<T> history;
17
-    int head;
17
+    int head = -1;
18
+    int saved = -1;
18 19
 
19 20
     History() {
20
-        head = -1;
21
+
21 22
     }
22 23
     T pop() {
23 24
         if (head > 0) {
@@ -35,9 +36,18 @@ public:
35 36
         while (head + 1 < history.length()) {
36 37
             history.removeLast();
37 38
         }
39
+        if (saved > head) {
40
+            saved = -1;
41
+        }
38 42
         history.append(commit);
39 43
         head++;
40 44
     }
45
+    void save() {
46
+        saved = head;
47
+    }
48
+    bool isSaved() {
49
+        return saved == head;
50
+    }
41 51
 };
42 52
 
43 53
 class Connection {
@@ -79,18 +89,19 @@ public:
79 89
     QString tileset_primary_label;
80 90
     QString tileset_secondary_label;
81 91
 
82
-    Tileset *tileset_primary;
83
-    Tileset *tileset_secondary;
92
+    Tileset *tileset_primary = NULL;
93
+    Tileset *tileset_secondary = NULL;
84 94
 
85
-    Blockdata* blockdata;
95
+    Blockdata* blockdata = NULL;
86 96
 
87 97
 public:
88 98
     int getWidth();
89 99
     int getHeight();
90
-    Tileset* getBlockTileset(uint);
91
-    Metatile* getMetatile(uint);
92
-    QImage getMetatileImage(uint);
93
-    QImage getMetatileTile(uint);
100
+    Tileset* getBlockTileset(int);
101
+    int getBlockIndex(int index);
102
+    Metatile* getMetatile(int);
103
+    QImage getMetatileImage(int);
104
+    QImage getMetatileTile(int);
94 105
     QPixmap render();
95 106
     QPixmap renderMetatiles();
96 107
 
@@ -107,9 +118,9 @@ public:
107 118
     void drawSelection(int i, int w, QPainter *painter);
108 119
 
109 120
     bool blockChanged(int, Blockdata*);
110
-    Blockdata* cached_blockdata;
121
+    Blockdata* cached_blockdata = NULL;
111 122
     void cacheBlockdata();
112
-    Blockdata* cached_collision;
123
+    Blockdata* cached_collision = NULL;
113 124
     void cacheCollision();
114 125
     QImage image;
115 126
     QPixmap pixmap;
@@ -141,23 +152,30 @@ public:
141 152
     QString coord_events_label;
142 153
     QString bg_events_label;
143 154
 
144
-    QList<ObjectEvent*> object_events;
145
-    QList<Warp*> warps;
146
-    QList<CoordEvent*> coord_events;
147
-    QList<Sign*> signs;
148
-    QList<HiddenItem*> hidden_items;
155
+    QList<Event*> getAllEvents();
156
+    QList<Event*> getEventsByType(QString type);
157
+    void removeEvent(Event *event);
158
+    void addEvent(Event *event);
159
+    QMap<QString, QList<Event*>> events;
149 160
 
150 161
     QList<Connection*> connections;
151 162
     QPixmap renderConnection(Connection);
152 163
 
153 164
     QImage border_image;
154 165
     QPixmap border_pixmap;
155
-    Blockdata *border;
156
-    Blockdata *cached_border;
166
+    Blockdata *border = NULL;
167
+    Blockdata *cached_border = NULL;
157 168
     QPixmap renderBorder();
158 169
     void cacheBorder();
159 170
 
171
+    bool hasUnsavedChanges();
172
+
173
+    QList<QList<QRgb> > getBlockPalettes(int metatile_index);
174
+
160 175
 signals:
176
+    void paintTileChanged(Map *map);
177
+    void paintCollisionChanged(Map *map);
178
+    void mapChanged(Map *map);
161 179
 
162 180
 public slots:
163 181
 };

+ 1
- 1
metatile.h View File

@@ -9,7 +9,7 @@ class Metatile
9 9
 public:
10 10
     Metatile();
11 11
 public:
12
-    QList<Tile> *tiles;
12
+    QList<Tile> *tiles = NULL;
13 13
     int attr;
14 14
 };
15 15
 

+ 14
- 0
objectpropertiesframe.cpp View File

@@ -0,0 +1,14 @@
1
+#include "objectpropertiesframe.h"
2
+#include "ui_objectpropertiesframe.h"
3
+
4
+ObjectPropertiesFrame::ObjectPropertiesFrame(QWidget *parent) :
5
+    QFrame(parent),
6
+    ui(new Ui::ObjectPropertiesFrame)
7
+{
8
+    ui->setupUi(this);
9
+}
10
+
11
+ObjectPropertiesFrame::~ObjectPropertiesFrame()
12
+{
13
+    delete ui;
14
+}

+ 22
- 0
objectpropertiesframe.h View File

@@ -0,0 +1,22 @@
1
+#ifndef OBJECTPROPERTIESFRAME_H
2
+#define OBJECTPROPERTIESFRAME_H
3
+
4
+#include <QFrame>
5
+
6
+namespace Ui {
7
+class ObjectPropertiesFrame;
8
+}
9
+
10
+class ObjectPropertiesFrame : public QFrame
11
+{
12
+    Q_OBJECT
13
+
14
+public:
15
+    explicit ObjectPropertiesFrame(QWidget *parent = 0);
16
+    ~ObjectPropertiesFrame();
17
+
18
+public:
19
+    Ui::ObjectPropertiesFrame *ui;
20
+};
21
+
22
+#endif // OBJECTPROPERTIESFRAME_H

+ 250
- 0
objectpropertiesframe.ui View File

@@ -0,0 +1,250 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<ui version="4.0">
3
+ <class>ObjectPropertiesFrame</class>
4
+ <widget class="QFrame" name="ObjectPropertiesFrame">
5
+  <property name="geometry">
6
+   <rect>
7
+    <x>0</x>
8
+    <y>0</y>
9
+    <width>284</width>
10
+    <height>146</height>
11
+   </rect>
12
+  </property>
13
+  <property name="sizePolicy">
14
+   <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
15
+    <horstretch>0</horstretch>
16
+    <verstretch>0</verstretch>
17
+   </sizepolicy>
18
+  </property>
19
+  <property name="minimumSize">
20
+   <size>
21
+    <width>284</width>
22
+    <height>90</height>
23
+   </size>
24
+  </property>
25
+  <property name="windowTitle">
26
+   <string>Frame</string>
27
+  </property>
28
+  <property name="layoutDirection">
29
+   <enum>Qt::LeftToRight</enum>
30
+  </property>
31
+  <property name="frameShape">
32
+   <enum>QFrame::Box</enum>
33
+  </property>
34
+  <property name="frameShadow">
35
+   <enum>QFrame::Raised</enum>
36
+  </property>
37
+  <property name="lineWidth">
38
+   <number>1</number>
39
+  </property>
40
+  <layout class="QVBoxLayout" name="verticalLayout_2">
41
+   <item>
42
+    <widget class="QWidget" name="widget" native="true">
43
+     <property name="sizePolicy">
44
+      <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
45
+       <horstretch>0</horstretch>
46
+       <verstretch>0</verstretch>
47
+      </sizepolicy>
48
+     </property>
49
+     <layout class="QHBoxLayout" name="horizontalLayout_2">
50
+      <item>
51
+       <widget class="QLabel" name="label_spritePixmap">
52
+        <property name="sizePolicy">
53
+         <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
54
+          <horstretch>0</horstretch>
55
+          <verstretch>0</verstretch>
56
+         </sizepolicy>
57
+        </property>
58
+        <property name="minimumSize">
59
+         <size>
60
+          <width>64</width>
61
+          <height>64</height>
62
+         </size>
63
+        </property>
64
+        <property name="frameShape">
65
+         <enum>QFrame::Box</enum>
66
+        </property>
67
+        <property name="frameShadow">
68
+         <enum>QFrame::Sunken</enum>
69
+        </property>
70
+        <property name="text">
71
+         <string/>
72
+        </property>
73
+        <property name="scaledContents">
74
+         <bool>false</bool>
75
+        </property>
76
+        <property name="alignment">
77
+         <set>Qt::AlignCenter</set>
78
+        </property>
79
+        <property name="indent">
80
+         <number>-1</number>
81
+        </property>
82
+       </widget>
83
+      </item>
84
+      <item>
85
+       <layout class="QVBoxLayout" name="verticalLayout">
86
+        <item>
87
+         <widget class="QLabel" name="label_name">
88
+          <property name="text">
89
+           <string>Object 1</string>
90
+          </property>
91
+         </widget>
92
+        </item>
93
+        <item>
94
+         <layout class="QHBoxLayout" name="horizontalLayout">
95
+          <item>
96
+           <layout class="QHBoxLayout" name="x">
97
+            <item>
98
+             <widget class="QLabel" name="label_x">
99
+              <property name="text">
100
+               <string>X</string>
101
+              </property>
102
+              <property name="alignment">
103
+               <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
104
+              </property>
105
+             </widget>
106
+            </item>
107
+            <item>
108
+             <widget class="QSpinBox" name="spinBox_x">
109
+              <property name="minimum">
110
+               <number>-32768</number>
111
+              </property>
112
+              <property name="maximum">
113
+               <number>32767</number>
114
+              </property>
115
+             </widget>
116
+            </item>
117
+           </layout>
118
+          </item>
119
+          <item>
120
+           <layout class="QHBoxLayout" name="y">
121
+            <item>
122
+             <widget class="QLabel" name="label_y">
123
+              <property name="text">
124
+               <string>Y</string>
125
+              </property>
126
+              <property name="alignment">
127
+               <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
128
+              </property>
129
+             </widget>
130
+            </item>
131
+            <item>
132
+             <widget class="QSpinBox" name="spinBox_y">
133
+              <property name="minimum">
134
+               <number>-32768</number>
135
+              </property>
136
+              <property name="maximum">
137
+               <number>32767</number>
138
+              </property>
139
+             </widget>
140
+            </item>
141
+           </layout>
142
+          </item>
143
+          <item>
144
+           <layout class="QHBoxLayout" name="z">
145
+            <item>
146
+             <widget class="QLabel" name="label">
147
+              <property name="text">
148
+               <string>Z</string>
149
+              </property>
150
+              <property name="alignment">
151
+               <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
152
+              </property>
153
+             </widget>
154
+            </item>
155
+            <item>
156
+             <widget class="QSpinBox" name="spinBox_z">
157
+              <property name="maximum">
158
+               <number>15</number>
159
+              </property>
160
+             </widget>
161
+            </item>
162
+           </layout>
163
+          </item>
164
+          <item>
165
+           <spacer name="horizontalSpacer">
166
+            <property name="orientation">
167
+             <enum>Qt::Horizontal</enum>
168
+            </property>
169
+            <property name="sizeHint" stdset="0">
170
+             <size>
171
+              <width>40</width>
172
+              <height>20</height>
173
+             </size>
174
+            </property>
175
+           </spacer>
176
+          </item>
177
+         </layout>
178
+        </item>
179
+       </layout>
180
+      </item>
181
+     </layout>
182
+    </widget>
183
+   </item>
184
+   <item>
185
+    <widget class="QWidget" name="sprite" native="true">
186
+     <property name="sizePolicy">
187
+      <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
188
+       <horstretch>0</horstretch>
189
+       <verstretch>0</verstretch>
190
+      </sizepolicy>
191
+     </property>
192
+     <layout class="QFormLayout" name="formLayout_sprite">
193
+      <property name="leftMargin">
194
+       <number>9</number>
195
+      </property>
196
+      <property name="topMargin">
197
+       <number>0</number>
198
+      </property>
199
+      <property name="bottomMargin">
200
+       <number>0</number>
201
+      </property>
202
+      <item row="0" column="0">
203
+       <widget class="QLabel" name="label_sprite">
204
+        <property name="text">
205
+         <string>Sprite</string>
206
+        </property>
207
+        <property name="buddy">
208
+         <cstring>comboBox_sprite</cstring>
209
+        </property>
210
+       </widget>
211
+      </item>
212
+      <item row="0" column="1">
213
+       <widget class="QComboBox" name="comboBox_sprite">
214
+        <property name="enabled">
215
+         <bool>true</bool>
216
+        </property>
217
+        <property name="sizePolicy">
218
+         <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
219
+          <horstretch>0</horstretch>
220
+          <verstretch>0</verstretch>
221
+         </sizepolicy>
222
+        </property>
223
+        <property name="editable">
224
+         <bool>true</bool>
225
+        </property>
226
+        <property name="currentText">
227
+         <string/>
228
+        </property>
229
+        <property name="maxVisibleItems">
230
+         <number>25</number>
231
+        </property>
232
+        <property name="sizeAdjustPolicy">
233
+         <enum>QComboBox::AdjustToContentsOnFirstShow</enum>
234
+        </property>
235
+       </widget>
236
+      </item>
237
+     </layout>
238
+    </widget>
239
+   </item>
240
+  </layout>
241
+ </widget>
242
+ <tabstops>
243
+  <tabstop>spinBox_x</tabstop>
244
+  <tabstop>spinBox_y</tabstop>
245
+  <tabstop>spinBox_z</tabstop>
246
+  <tabstop>comboBox_sprite</tabstop>
247
+ </tabstops>
248
+ <resources/>
249
+ <connections/>
250
+</ui>

+ 8
- 3
pretmap.pro View File

@@ -23,7 +23,9 @@ SOURCES += main.cpp\
23 23
     metatile.cpp \
24 24
     tile.cpp \
25 25
     event.cpp \
26
-    editor.cpp
26
+    editor.cpp \
27
+    objectpropertiesframe.cpp \
28
+    graphicsview.cpp
27 29
 
28 30
 HEADERS  += mainwindow.h \
29 31
     project.h \
@@ -35,9 +37,12 @@ HEADERS  += mainwindow.h \
35 37
     metatile.h \
36 38
     tile.h \
37 39
     event.h \
38
-    editor.h
40
+    editor.h \
41
+    objectpropertiesframe.h \
42
+    graphicsview.h
39 43
 
40
-FORMS    += mainwindow.ui
44
+FORMS    += mainwindow.ui \
45
+    objectpropertiesframe.ui
41 46
 
42 47
 RESOURCES += \
43 48
     resources/images.qrc

+ 305
- 121
project.cpp View File

@@ -15,12 +15,17 @@ Project::Project()
15 15
 {
16 16
     groupNames = new QStringList;
17 17
     groupedMapNames = new QList<QStringList*>;
18
+    mapNames = new QStringList;
18 19
     map_cache = new QMap<QString, Map*>;
19 20
     tileset_cache = new QMap<QString, Tileset*>;
20 21
 }
21 22
 
22 23
 QString Project::getProjectTitle() {
23
-    return root.section('/', -1);
24
+    if (!root.isNull()) {
25
+        return root.section('/', -1);
26
+    } else {
27
+        return QString();
28
+    }
24 29
 }
25 30
 
26 31
 Map* Project::loadMap(QString map_name) {
@@ -35,6 +40,7 @@ Map* Project::loadMap(QString map_name) {
35 40
     readMapEvents(map);
36 41
     loadMapConnections(map);
37 42
     map->commit();
43
+    map->history.save();
38 44
 
39 45
     map_cache->insert(map_name, map);
40 46
     return map;
@@ -43,9 +49,9 @@ Map* Project::loadMap(QString map_name) {
43 49
 void Project::loadMapConnections(Map *map) {
44 50
     map->connections.clear();
45 51
     if (!map->connections_label.isNull()) {
46
-        QString path = root + QString("/data/maps/%1/connections.s").arg(map->name);
52
+        QString path = root + QString("/data/maps/%1/connections.inc").arg(map->name);
47 53
         QString text = readTextFile(path);
48
-        if (text != NULL) {
54
+        if (!text.isNull()) {
49 55
             QList<QStringList> *commands = parse(text);
50 56
             QStringList *list = getLabelValues(commands, map->connections_label);
51 57
 
@@ -114,7 +120,10 @@ void Project::readMapHeader(Map* map) {
114 120
     QString label = map->name;
115 121
     Asm *parser = new Asm;
116 122
 
117
-    QString header_text = readTextFile(root + "/data/maps/" + label + "/header.s");
123
+    QString header_text = readTextFile(root + "/data/maps/" + label + "/header.inc");
124
+    if (header_text.isNull()) {
125
+        return;
126
+    }
118 127
     QStringList *header = getLabelValues(parser->parse(header_text), label);
119 128
     map->attributes_label = header->value(0);
120 129
     map->events_label = header->value(1);
@@ -133,7 +142,7 @@ void Project::readMapHeader(Map* map) {
133 142
 
134 143
 void Project::saveMapHeader(Map *map) {
135 144
     QString label = map->name;
136
-    QString header_path = root + "/data/maps/" + label + "/header.s";
145
+    QString header_path = root + "/data/maps/" + label + "/header.inc";
137 146
     QString text = "";
138 147
     text += QString("%1::\n").arg(label);
139 148
     text += QString("\t.4byte %1\n").arg(map->attributes_label);
@@ -155,7 +164,10 @@ void Project::saveMapHeader(Map *map) {
155 164
 void Project::readMapAttributes(Map* map) {
156 165
     Asm *parser = new Asm;
157 166
 
158
-    QString assets_text = readTextFile(root + "/data/maps/_assets.s");
167
+    QString assets_text = readTextFile(root + "/data/maps/_assets.inc");
168
+    if (assets_text.isNull()) {
169
+        return;
170
+    }
159 171
     QStringList *attributes = getLabelValues(parser->parse(assets_text), map->attributes_label);
160 172
     map->width = attributes->value(0);
161 173
     map->height = attributes->value(1);
@@ -173,7 +185,7 @@ void Project::getTilesets(Map* map) {
173 185
 Tileset* Project::loadTileset(QString label) {
174 186
     Asm *parser = new Asm;
175 187
 
176
-    QString headers_text = readTextFile(root + "/data/tilesets/headers.s");
188
+    QString headers_text = readTextFile(root + "/data/tilesets/headers.inc");
177 189
     QStringList *values = getLabelValues(parser->parse(headers_text), label);
178 190
     Tileset *tileset = new Tileset;
179 191
     tileset->name = label;
@@ -193,7 +205,7 @@ Tileset* Project::loadTileset(QString label) {
193 205
 }
194 206
 
195 207
 QString Project::getBlockdataPath(Map* map) {
196
-    QString text = readTextFile(root + "/data/maps/_assets.s");
208
+    QString text = readTextFile(root + "/data/maps/_assets.inc");
197 209
     QStringList *values = getLabelValues(parse(text), map->blockdata_label);
198 210
     QString path;
199 211
     if (!values->isEmpty()) {
@@ -205,7 +217,7 @@ QString Project::getBlockdataPath(Map* map) {
205 217
 }
206 218
 
207 219
 QString Project::getMapBorderPath(Map *map) {
208
-    QString text = readTextFile(root + "/data/maps/_assets.s");
220
+    QString text = readTextFile(root + "/data/maps/_assets.inc");
209 221
     QStringList *values = getLabelValues(parse(text), map->border_label);
210 222
     QString path;
211 223
     if (!values->isEmpty()) {
@@ -229,6 +241,7 @@ void Project::loadMapBorder(Map *map) {
229 241
 void Project::saveBlockdata(Map* map) {
230 242
     QString path = getBlockdataPath(map);
231 243
     writeBlockdata(path, map->blockdata);
244
+    map->history.save();
232 245
 }
233 246
 
234 247
 void Project::writeBlockdata(QString path, Blockdata *blockdata) {
@@ -251,14 +264,18 @@ void Project::saveAllMaps() {
251 264
 void Project::saveMap(Map *map) {
252 265
     saveBlockdata(map);
253 266
     saveMapHeader(map);
267
+    saveMapEvents(map);
254 268
 }
255 269
 
256 270
 void Project::loadTilesetAssets(Tileset* tileset) {
257 271
     Asm* parser = new Asm;
258 272
     QString category = (tileset->is_secondary == "TRUE") ? "secondary" : "primary";
273
+    if (tileset->name.isNull()) {
274
+        return;
275
+    }
259 276
     QString dir_path = root + "/data/tilesets/" + category + "/" + tileset->name.replace("gTileset_", "").toLower();
260 277
 
261
-    QString graphics_text = readTextFile(root + "/data/tilesets/graphics.s");
278
+    QString graphics_text = readTextFile(root + "/data/tilesets/graphics.inc");
262 279
     QList<QStringList> *graphics = parser->parse(graphics_text);
263 280
     QStringList *tiles_values = getLabelValues(graphics, tileset->tiles_label);
264 281
     QStringList *palettes_values = getLabelValues(graphics, tileset->palettes_label);
@@ -288,7 +305,7 @@ void Project::loadTilesetAssets(Tileset* tileset) {
288 305
 
289 306
     QString metatiles_path;
290 307
     QString metatile_attrs_path;
291
-    QString metatiles_text = readTextFile(root + "/data/tilesets/metatiles.s");
308
+    QString metatiles_text = readTextFile(root + "/data/tilesets/metatiles.inc");
292 309
     QList<QStringList> *metatiles_macros = parser->parse(metatiles_text);
293 310
     QStringList *metatiles_values = getLabelValues(metatiles_macros, tileset->metatiles_label);
294 311
     if (!metatiles_values->isEmpty()) {
@@ -328,7 +345,7 @@ void Project::loadTilesetAssets(Tileset* tileset) {
328 345
         QList<Metatile*> *metatiles = new QList<Metatile*>;
329 346
         for (int i = 0; i < num_metatiles; i++) {
330 347
             Metatile *metatile = new Metatile;
331
-            int index = i * 16;
348
+            int index = i * (2 * 4 * num_layers);
332 349
             for (int j = 0; j < 4 * num_layers; j++) {
333 350
                 uint16_t word = data[index++] & 0xff;
334 351
                 word += (data[index++] & 0xff) << 8;
@@ -342,6 +359,9 @@ void Project::loadTilesetAssets(Tileset* tileset) {
342 359
             metatiles->append(metatile);
343 360
         }
344 361
         tileset->metatiles = metatiles;
362
+    } else {
363
+        tileset->metatiles = new QList<Metatile*>;
364
+        qDebug() << QString("Could not open '%1'").arg(metatiles_path);
345 365
     }
346 366
 
347 367
     QFile attrs_file(metatile_attrs_path);
@@ -354,6 +374,8 @@ void Project::loadTilesetAssets(Tileset* tileset) {
354 374
             word += (data[i*2 + 1] & 0xff) << 8;
355 375
             tileset->metatiles->value(i)->attr = word;
356 376
         }
377
+    } else {
378
+        qDebug() << QString("Could not open '%1'").arg(metatile_attrs_path);
357 379
     }
358 380
 
359 381
     // palettes
@@ -377,6 +399,11 @@ void Project::loadTilesetAssets(Tileset* tileset) {
377 399
                 QRgb color = qRgb(red * 8, green * 8, blue * 8);
378 400
                 palette.prepend(color);
379 401
             }
402
+        } else {
403
+            for (int j = 0; j < 16; j++) {
404
+                palette.append(qRgb(j * 16, j * 16, j * 16));
405
+            }
406
+            qDebug() << QString("Could not open '%1'").arg(path);
380 407
         }
381 408
         //qDebug() << path;
382 409
         palettes->append(palette);
@@ -420,7 +447,8 @@ QString Project::readTextFile(QString path) {
420 447
     QFile file(path);
421 448
     if (!file.open(QIODevice::ReadOnly)) {
422 449
         //QMessageBox::information(0, "Error", QString("Could not open '%1': ").arg(path) + file.errorString());
423
-        return NULL;
450
+        qDebug() << QString("Could not open '%1': ").arg(path) + file.errorString();
451
+        return QString();
424 452
     }
425 453
     QTextStream in(&file);
426 454
     QString text = "";
@@ -434,12 +462,14 @@ void Project::saveTextFile(QString path, QString text) {
434 462
     QFile file(path);
435 463
     if (file.open(QIODevice::WriteOnly)) {
436 464
         file.write(text.toUtf8());
465
+    } else {
466
+        qDebug() << QString("Could not open '%1' for writing: ").arg(path) + file.errorString();
437 467
     }
438 468
 }
439 469
 
440 470
 void Project::readMapGroups() {
441
-    QString text = readTextFile(root + "/data/maps/_groups.s");
442
-    if (text == NULL) {
471
+    QString text = readTextFile(root + "/data/maps/_groups.inc");
472
+    if (text.isNull()) {
443 473
         return;
444 474
     }
445 475
     Asm *parser = new Asm;
@@ -466,12 +496,13 @@ void Project::readMapGroups() {
466 496
         }
467 497
     }
468 498
 
469
-    QList<QStringList*> *maps = new QList<QStringList*>;
499
+    QList<QStringList*> *groupedMaps = new QList<QStringList*>;
470 500
     for (int i = 0; i < groups->length(); i++) {
471 501
         QStringList *list = new QStringList;
472
-        maps->append(list);
502
+        groupedMaps->append(list);
473 503
     }
474 504
 
505
+    QStringList *maps = new QStringList;
475 506
     int group = -1;
476 507
     for (int i = 0; i < commands->length(); i++) {
477 508
         QStringList params = commands->value(i);
@@ -481,15 +512,17 @@ void Project::readMapGroups() {
481 512
         } else if (macro == ".4byte") {
482 513
             if (group != -1) {
483 514
                 for (int j = 1; j < params.length(); j++) {
484
-                    QStringList *list = maps->value(group);
515
+                    QStringList *list = groupedMaps->value(group);
485 516
                     list->append(params.value(j));
517
+                    maps->append(params.value(j));
486 518
                 }
487 519
             }
488 520
         }
489 521
     }
490 522
 
491 523
     groupNames = groups;
492
-    groupedMapNames = maps;
524
+    groupedMapNames = groupedMaps;
525
+    mapNames = maps;
493 526
 }
494 527
 
495 528
 QList<QStringList>* Project::parse(QString text) {
@@ -544,8 +577,8 @@ QStringList Project::getBattleScenes() {
544 577
 
545 578
 QStringList Project::getSongNames() {
546 579
     QStringList names;
547
-    QString text = readTextFile(root + "/constants/songs.s");
548
-    if (text != NULL) {
580
+    QString text = readTextFile(root + "/constants/songs.inc");
581
+    if (!text.isNull()) {
549 582
         QList<QStringList> *commands = parse(text);
550 583
         for (int i = 0; i < commands->length(); i++) {
551 584
             QStringList params = commands->value(i);
@@ -560,8 +593,8 @@ QStringList Project::getSongNames() {
560 593
 
561 594
 QString Project::getSongName(int value) {
562 595
     QStringList names;
563
-    QString text = readTextFile(root + "/constants/songs.s");
564
-    if (text != NULL) {
596
+    QString text = readTextFile(root + "/constants/songs.inc");
597
+    if (!text.isNull()) {
565 598
         QList<QStringList> *commands = parse(text);
566 599
         for (int i = 0; i < commands->length(); i++) {
567 600
             QStringList params = commands->value(i);
@@ -578,8 +611,8 @@ QString Project::getSongName(int value) {
578 611
 
579 612
 QMap<QString, int> Project::getMapObjGfxConstants() {
580 613
     QMap<QString, int> constants;
581
-    QString text = readTextFile(root + "/constants/map_object_constants.s");
582
-    if (text != NULL) {
614
+    QString text = readTextFile(root + "/constants/map_object_constants.inc");
615
+    if (!text.isNull()) {
583 616
         QList<QStringList> *commands = parse(text);
584 617
         for (int i = 0; i < commands->length(); i++) {
585 618
             QStringList params = commands->value(i);
@@ -602,9 +635,9 @@ QString Project::fixGraphicPath(QString path) {
602 635
     return path;
603 636
 }
604 637
 
605
-void Project::loadObjectPixmaps(QList<ObjectEvent*> objects) {
638
+void Project::loadObjectPixmaps(QList<Event*> objects) {
606 639
     bool needs_update = false;
607
-    for (ObjectEvent *object : objects) {
640
+    for (Event *object : objects) {
608 641
         if (object->pixmap.isNull()) {
609 642
             needs_update = true;
610 643
             break;
@@ -616,62 +649,152 @@ void Project::loadObjectPixmaps(QList<ObjectEvent*> objects) {
616 649
 
617 650
     QMap<QString, int> constants = getMapObjGfxConstants();
618 651
 
619
-    QString pointers_path = root + "/data/graphics/field_objects/map_object_graphics_info_pointers.s";
620
-    QString pointers_text = readTextFile(pointers_path);
621
-    if (pointers_text == NULL) {
622
-        return;
623
-    }
624
-    QString info_path = root + "/data/graphics/field_objects/map_object_graphics_info.s";
625
-    QString info_text = readTextFile(info_path);
626
-    if (info_text == NULL) {
627
-        return;
628
-    }
629
-    QString pic_path = root + "/data/graphics/field_objects/map_object_pic_tables.s";
630
-    QString pic_text = readTextFile(pic_path);
631
-    if (pic_text == NULL) {
632
-        return;
633
-    }
634
-    QString assets_path = root + "/data/graphics/field_objects/map_object_graphics.s";
635
-    QString assets_text = readTextFile(assets_path);
636
-    if (assets_text == NULL) {
637
-        return;
638
-    }
652
+    QString pointers_text = readTextFile(root + "/include/data/field_map_obj/map_object_graphics_info_pointers.h");
653
+    QString info_text = readTextFile(root + "/include/data/field_map_obj/map_object_graphics_info.h");
654
+    QString pic_text = readTextFile(root + "/include/data/field_map_obj/map_object_pic_tables.h");
655
+    QString assets_text = readTextFile(root + "/src/field_map_obj.c");
639 656
 
640
-    QStringList *pointers = getLabelValues(parse(pointers_text), "gMapObjectGraphicsInfoPointers");
641
-    QList<QStringList> *info_commands = parse(info_text);
642
-    QList<QStringList> *asset_commands = parse(assets_text);
643
-    QList<QStringList> *pic_commands = parse(pic_text);
657
+    QStringList pointers = readCArray(pointers_text, "gMapObjectGraphicsInfoPointers");
644 658
 
645
-    for (ObjectEvent *object : objects) {
659
+    for (Event *object : objects) {
646 660
         if (!object->pixmap.isNull()) {
647 661
             continue;
648 662
         }
649
-        int id = constants.value(object->sprite);
650
-        QString info_label = pointers->value(id);
651
-        QStringList *info = getLabelValues(info_commands, info_label);
652
-        QString pic_label = info->value(12);
653
-
654
-        QList<QStringList> *pic = getLabelMacros(pic_commands, pic_label);
655
-        for (int i = 0; i < pic->length(); i++) {
656
-            QStringList command = pic->value(i);
657
-            QString macro = command.value(0);
658
-            if (macro == "obj_frame_tiles") {
659
-                QString label = command.value(1);
660
-                QStringList *incbins = getLabelValues(asset_commands, label);
661
-                QString path = incbins->value(0).section('"', 1, 1);
663
+        QString event_type = object->get("event_type");
664
+        if (event_type == "object") {
665
+            object->pixmap = QPixmap(":/images/Entities_16x16.png").copy(0, 0, 16, 16);
666
+        } else if (event_type == "warp") {
667
+            object->pixmap = QPixmap(":/images/Entities_16x16.png").copy(16, 0, 16, 16);
668
+        } else if (event_type == "trap") {
669
+            object->pixmap = QPixmap(":/images/Entities_16x16.png").copy(32, 0, 16, 16);
670
+        } else if (event_type == "sign" || event_type == "hidden item") {
671
+            object->pixmap = QPixmap(":/images/Entities_16x16.png").copy(48, 0, 16, 16);
672
+        }
673
+
674
+        if (event_type == "object") {
675
+
676
+            int sprite_id = constants.value(object->get("sprite"));
677
+
678
+            QString info_label = pointers.value(sprite_id).replace("&", "");
679
+            QString pic_label = readCArray(info_text, info_label).value(14);
680
+            QString gfx_label = readCArray(pic_text, pic_label).value(0);
681
+            gfx_label = gfx_label.section(QRegExp("[\\(\\)]"), 1, 1);
682
+            QString path = readCIncbin(assets_text, gfx_label);
683
+
684
+            if (!path.isNull()) {
662 685
                 path = fixGraphicPath(path);
663 686
                 QPixmap pixmap(root + "/" + path);
664
-                object->pixmap = pixmap;
665
-                break;
687
+                if (!pixmap.isNull()) {
688
+                    object->pixmap = pixmap;
689
+                }
666 690
             }
691
+
667 692
         }
668 693
     }
694
+
695
+}
696
+
697
+void Project::saveMapEvents(Map *map) {
698
+    QString path = root + QString("/data/maps/events/%1.inc").arg(map->name);
699
+    QString text = "";
700
+
701
+    text += QString("%1::\n").arg(map->object_events_label);
702
+    for (int i = 0; i < map->events["object"].length(); i++) {
703
+        Event *object_event = map->events["object"].value(i);
704
+        int radius_x = object_event->getInt("radius_x");
705
+        int radius_y = object_event->getInt("radius_y");
706
+        QString radius = QString("%1").arg((radius_x & 0xf) + ((radius_y & 0xf) << 4));
707
+        uint16_t x = object_event->getInt("x");
708
+        uint16_t y = object_event->getInt("y");
709
+
710
+        text += QString("\tobject_event %1").arg(i + 1);
711
+        text += QString(", %1").arg(object_event->get("sprite"));
712
+        text += QString(", %1").arg(object_event->get("replacement"));
713
+        text += QString(", %1").arg(x & 0xff);
714
+        text += QString(", %1").arg((x >> 8) & 0xff);
715
+        text += QString(", %1").arg(y & 0xff);
716
+        text += QString(", %1").arg((y >> 8) & 0xff);
717
+        text += QString(", %1").arg(object_event->get("elevation"));
718
+        text += QString(", %1").arg(object_event->get("behavior"));
719
+        text += QString(", %1").arg(radius);
720
+        text += QString(", 0");
721
+        text += QString(", %1").arg(object_event->get("property"));
722
+        text += QString(", 0");
723
+        text += QString(", %1").arg(object_event->get("sight_radius"));
724
+        text += QString(", 0");
725
+        text += QString(", %1").arg(object_event->get("script_label"));
726
+        text += QString(", %1").arg(object_event->get("event_flag"));
727
+        text += QString(", 0");
728
+        text += QString(", 0");
729
+        text += "\n";
730
+    }
731
+    text += "\n";
732
+
733
+    text += QString("%1::\n").arg(map->warps_label);
734
+    for (Event *warp : map->events["warp"]) {
735
+        text += QString("\twarp_def %1").arg(warp->get("x"));
736
+        text += QString(", %1").arg(warp->get("y"));
737
+        text += QString(", %1").arg(warp->get("elevation"));
738
+        text += QString(", %1").arg(warp->get("destination_warp"));
739
+        text += QString(", %1").arg(warp->get("destination_map"));
740
+        text += "\n";
741
+    }
742
+    text += "\n";
743
+
744
+    text += QString("%1::\n").arg(map->coord_events_label);
745
+    for (Event *coords : map->events["trap"]) {
746
+        text += QString("\tcoord_event %1").arg(coords->get("x"));
747
+        text += QString(", %1").arg(coords->get("y"));
748
+        text += QString(", %1").arg(coords->get("elevation"));
749
+        text += QString(", 0");
750
+        text += QString(", %1").arg(coords->get("coord_unknown1"));
751
+        text += QString(", %1").arg(coords->get("coord_unknown2"));
752
+        text += QString(", 0");
753
+        text += QString(", %1").arg(coords->get("script_label"));
754
+        text += "\n";
755
+    }
756
+    text += "\n";
757
+
758
+    text += QString("%1::\n").arg(map->bg_events_label);
759
+    for (Event *sign : map->events["sign"]) {
760
+        text += QString("\tbg_event %1").arg(sign->get("x"));
761
+        text += QString(", %1").arg(sign->get("y"));
762
+        text += QString(", %1").arg(sign->get("elevation"));
763
+        text += QString(", %1").arg(sign->get("type"));
764
+        text += QString(", 0");
765
+        text += QString(", %1").arg(sign->get("script_label"));
766
+        text += "\n";
767
+    }
768
+    for (Event *item : map->events["hidden item"]) {
769
+        text += QString("\tbg_event %1").arg(item->get("x"));
770
+        text += QString(", %1").arg(item->get("y"));
771
+        text += QString(", %1").arg(item->get("elevation"));
772
+        text += QString(", %1").arg(item->get("type"));
773
+        text += QString(", 0");
774
+        text += QString(", %1").arg(item->get("item"));
775
+        text += QString(", %1").arg(item->get("item_unknown5"));
776
+        text += QString(", %1").arg(item->get("item_unknown6"));
777
+        text += "\n";
778
+    }
779
+    text += "\n";
780
+
781
+    text += QString("%1::\n").arg(map->events_label);
782
+    text += QString("\tmap_events %1, %2, %3, %4\n")
783
+            .arg(map->object_events_label)
784
+            .arg(map->warps_label)
785
+            .arg(map->coord_events_label)
786
+            .arg(map->bg_events_label);
787
+
788
+    saveTextFile(path, text);
669 789
 }
670 790
 
671 791
 void Project::readMapEvents(Map *map) {
672 792
     // lazy
673
-    QString path = root + QString("/data/maps/events/%1.s").arg(map->name);
793
+    QString path = root + QString("/data/maps/events/%1.inc").arg(map->name);
674 794
     QString text = readTextFile(path);
795
+    if (text.isNull()) {
796
+        return;
797
+    }
675 798
 
676 799
     QStringList *labels = getLabelValues(parse(text), map->events_label);
677 800
     map->object_events_label = labels->value(0);
@@ -680,10 +803,11 @@ void Project::readMapEvents(Map *map) {
680 803
     map->bg_events_label = labels->value(3);
681 804
 
682 805
     QList<QStringList> *object_events = getLabelMacros(parse(text), map->object_events_label);
683
-    map->object_events.clear();
806
+    map->events["object"].clear();
684 807
     for (QStringList command : *object_events) {
685 808
         if (command.value(0) == "object_event") {
686
-            ObjectEvent *object = new ObjectEvent;
809
+            Event *object = new Event;
810
+            object->put("map_name", map->name);
687 811
             // This macro is not fixed as of writing, but it should take fewer args.
688 812
             bool old_macro = false;
689 813
             if (command.length() >= 20) {
@@ -692,96 +816,156 @@ void Project::readMapEvents(Map *map) {
692 816
                 command.removeAt(15);
693 817
                 command.removeAt(13);
694 818
                 command.removeAt(11);
695
-                command.removeAt(7);
696
-                command.removeAt(5);
697 819
                 command.removeAt(1); // id. not 0, but is just the index in the list of objects
698 820
                 old_macro = true;
699 821
             }
700 822
             int i = 1;
701
-            object->sprite = command.value(i++);
702
-            object->replacement = command.value(i++);
703
-            object->x_ = command.value(i++);
704
-            object->y_ = command.value(i++);
705
-            object->elevation_ = command.value(i++);
706
-            object->behavior = command.value(i++);
823
+            object->put("sprite", command.value(i++));
824
+            object->put("replacement", command.value(i++));
825
+            int16_t x = command.value(i++).toInt(nullptr, 0) | (command.value(i++).toInt(nullptr, 0) << 8);
826
+            int16_t y = command.value(i++).toInt(nullptr, 0) | (command.value(i++).toInt(nullptr, 0) << 8);
827
+            object->put("x", x);
828
+            object->put("y", y);
829
+            object->put("elevation", command.value(i++));
830
+            object->put("behavior", command.value(i++));
707 831
             if (old_macro) {
708 832
                 int radius = command.value(i++).toInt(nullptr, 0);
709
-                object->radius_x = QString("%1").arg(radius & 0xf);
710
-                object->radius_y = QString("%1").arg((radius >> 4) & 0xf);
833
+                object->put("radius_x", radius & 0xf);
834
+                object->put("radius_y", (radius >> 4) & 0xf);
711 835
             } else {
712
-                object->radius_x = command.value(i++);
713
-                object->radius_y = command.value(i++);
836
+                object->put("radius_x", command.value(i++));
837
+                object->put("radius_y", command.value(i++));
714 838
             }
715
-            object->property = command.value(i++);
716
-            object->sight_radius = command.value(i++);
717
-            object->script_label = command.value(i++);
718
-            object->event_flag = command.value(i++);
839
+            object->put("property", command.value(i++));
840
+            object->put("sight_radius", command.value(i++));
841
+            object->put("script_label", command.value(i++));
842
+            object->put("event_flag", command.value(i++));
719 843
 
720
-            map->object_events.append(object);
844
+            object->put("event_type", "object");
845
+            map->events["object"].append(object);
721 846
         }
722 847
     }
723 848
 
724 849
     QList<QStringList> *warps = getLabelMacros(parse(text), map->warps_label);
725
-    map->warps.clear();
850
+    map->events["warp"].clear();
726 851
     for (QStringList command : *warps) {
727 852
         if (command.value(0) == "warp_def") {
728
-            Warp *warp = new Warp;
853
+            Event *warp = new Event;
854
+            warp->put("map_name", map->name);
729 855
             int i = 1;
730
-            warp->x_ = command.value(i++);
731
-            warp->y_ = command.value(i++);
732
-            warp->elevation_ = command.value(i++);
733
-            warp->destination_warp = command.value(i++);
734
-            warp->destination_map = command.value(i++);
735
-            map->warps.append(warp);
856
+            warp->put("x", command.value(i++));
857
+            warp->put("y", command.value(i++));
858
+            warp->put("elevation", command.value(i++));
859
+            warp->put("destination_warp", command.value(i++));
860
+            warp->put("destination_map", command.value(i++));
861
+
862
+            warp->put("event_type", "warp");
863
+            map->events["warp"].append(warp);
736 864
         }
737 865
     }
738 866
 
739 867
     QList<QStringList> *coords = getLabelMacros(parse(text), map->coord_events_label);
740
-    map->coord_events.clear();
868
+    map->events["trap"].clear();
741 869
     for (QStringList command : *coords) {
742 870
         if (command.value(0) == "coord_event") {
743
-            CoordEvent *coord = new CoordEvent;
871
+            Event *coord = new Event;
872
+            coord->put("map_name", map->name);
744 873
             bool old_macro = false;
745 874
             if (command.length() >= 9) {
746 875
                 command.removeAt(7);
747
-                command.removeAt(6);
748 876
                 command.removeAt(4);
749 877
                 old_macro = true;
750 878
             }
751 879
             int i = 1;
752
-            coord->x_ = command.value(i++);
753
-            coord->y_ = command.value(i++);
754
-            coord->elevation_ = command.value(i++);
755
-            coord->unknown1 = command.value(i++);
756
-            coord->script_label = command.value(i++);
757
-            map->coord_events.append(coord);
880
+            coord->put("x", command.value(i++));
881
+            coord->put("y", command.value(i++));
882
+            coord->put("elevation", command.value(i++));
883
+            coord->put("coord_unknown1", command.value(i++));
884
+            coord->put("coord_unknown2", command.value(i++));
885
+            coord->put("script_label", command.value(i++));
886
+            //coord_unknown3
887
+            //coord_unknown4
888
+
889
+            coord->put("event_type", "trap");
890
+            map->events["trap"].append(coord);
758 891
         }
759 892
     }
760 893
 
761
-    QList<QStringList> *bgs = getLabelMacros(parse(text), map->warps_label);
762
-    map->hidden_items.clear();
763
-    map->signs.clear();
894
+    QList<QStringList> *bgs = getLabelMacros(parse(text), map->bg_events_label);
895
+    map->events["hidden item"].clear();
896
+    map->events["sign"].clear();
764 897
     for (QStringList command : *bgs) {
765 898
         if (command.value(0) == "bg_event") {
766
-            BGEvent *bg = new BGEvent;
899
+            Event *bg = new Event;
900
+            bg->put("map_name", map->name);
767 901
             int i = 1;
768
-            bg->x_ = command.value(i++);
769
-            bg->y_ = command.value(i++);
770
-            bg->elevation_ = command.value(i++);
771
-            bg->type = command.value(i++);
902
+            bg->put("x", command.value(i++));
903
+            bg->put("y", command.value(i++));
904
+            bg->put("elevation", command.value(i++));
905
+            bg->put("type", command.value(i++));
772 906
             i++;
773
-            if (bg->is_item()) {
774
-                HiddenItem *item = new HiddenItem(*bg);
775
-                item->item = command.value(i++);
776
-                item->unknown5 = command.value(i++);
777
-                item->unknown6 = command.value(i++);
778
-                map->hidden_items.append(item);
907
+            if (bg->is_hidden_item()) {
908
+                bg->put("item", command.value(i++));
909
+                bg->put("item_unknown5", command.value(i++));
910
+                bg->put("item_unknown6", command.value(i++));
911
+
912
+                bg->put("event_type", "hidden item");
913
+                map->events["hidden item"].append(bg);
779 914
             } else {
780
-                Sign *sign = new Sign(*bg);
781
-                sign->script_label = command.value(i++);
782
-                map->signs.append(sign);
915
+                bg->put("script_label", command.value(i++));
916
+                //sign_unknown7
917
+
918
+                bg->put("event_type", "sign");
919
+                map->events["sign"].append(bg);
783 920
             }
784 921
         }
785 922
     }
786 923
 
787 924
 }
925
+
926
+QStringList Project::readCArray(QString text, QString label) {
927
+    QStringList list;
928
+
929
+    if (label.isNull()) {
930
+        return list;
931
+    }
932
+
933
+    QRegExp *re = new QRegExp(QString("\\b%1\\b\\s*\\[?\\s*\\]?\\s*=\\s*\\{([^\\}]*)\\}").arg(label));
934
+    int pos = re->indexIn(text);
935
+    if (pos != -1) {
936
+        QString body = re->cap(1);
937
+        body = body.replace(QRegExp("\\s*"), "");
938
+        list = body.split(',');
939
+        /*
940
+        QRegExp *inner = new QRegExp("&?\\b([A-Za-z0-9_\\(\\)]*)\\b,");
941
+        int pos = 0;
942
+        while ((pos = inner->indexIn(body, pos)) != -1) {
943
+            list << inner->cap(1);
944
+            pos += inner->matchedLength();
945
+        }
946
+        */
947
+    }
948
+
949
+    return list;
950
+}
951
+
952
+QString Project::readCIncbin(QString text, QString label) {
953
+    QString path;
954
+
955
+    if (label.isNull()) {
956
+        return path;
957
+    }
958
+
959
+    QRegExp *re = new QRegExp(QString(
960
+        "\\b%1\\b"
961
+        "\\s*\\[?\\s*\\]?\\s*=\\s*"
962
+        "INCBIN_[US][0-9][0-9]?"
963
+        "\\(\"([^\"]*)\"\\)").arg(label));
964
+
965
+    int pos = re->indexIn(text);
966
+    if (pos != -1) {
967
+        path = re->cap(1);
968
+    }
969
+
970
+    return path;
971
+}

+ 10
- 4
project.h View File

@@ -12,14 +12,15 @@ class Project
12 12
 public:
13 13
     Project();
14 14
     QString root;
15
-    QStringList *groupNames;
16
-    QList<QStringList*> *groupedMapNames;
15
+    QStringList *groupNames = NULL;
16
+    QList<QStringList*> *groupedMapNames = NULL;
17
+    QStringList *mapNames = NULL;
17 18
 
18 19
     QMap<QString, Map*> *map_cache;
19 20
     Map* loadMap(QString);
20 21
     Map* getMap(QString);
21 22
 
22
-    QMap<QString, Tileset*> *tileset_cache;
23
+    QMap<QString, Tileset*> *tileset_cache = NULL;
23 24
     Tileset* loadTileset(QString);
24 25
     Tileset* getTileset(QString);
25 26
 
@@ -55,7 +56,7 @@ public:
55 56
     QStringList getMapTypes();
56 57
     QStringList getBattleScenes();
57 58
 
58
-    void loadObjectPixmaps(QList<ObjectEvent*> objects);
59
+    void loadObjectPixmaps(QList<Event*> objects);
59 60
     QMap<QString, int> getMapObjGfxConstants();
60 61
     QString fixGraphicPath(QString path);
61 62
 
@@ -64,6 +65,11 @@ public:
64 65
 
65 66
     void loadMapBorder(Map *map);
66 67
     QString getMapBorderPath(Map *map);
68
+
69
+    void saveMapEvents(Map *map);
70
+
71
+    QStringList readCArray(QString text, QString label);
72
+    QString readCIncbin(QString text, QString label);
67 73
 };
68 74
 
69 75
 #endif // PROJECT_H

BIN
resources/icons/add.ico View File


BIN
resources/icons/cursor.ico View File


BIN
resources/icons/delete.ico View File


BIN
resources/icons/fill_color.ico View File


BIN
resources/icons/pencil.ico View File


BIN
resources/icons/pipette.ico View File


BIN
resources/icons/viewsprites.ico View File


+ 8
- 0
resources/images.qrc View File

@@ -7,5 +7,13 @@
7 7
         <file>icons/folder_map.ico</file>
8 8
         <file>icons/image.ico</file>
9 9
         <file>icons/map.ico</file>
10
+        <file>icons/cursor.ico</file>
11
+        <file>icons/fill_color.ico</file>
12
+        <file>icons/pencil.ico</file>
13
+        <file>icons/pipette.ico</file>
14
+        <file>images/Entities_16x16.png</file>
15
+        <file>icons/add.ico</file>
16
+        <file>icons/delete.ico</file>
17
+        <file>icons/viewsprites.ico</file>
10 18
     </qresource>
11 19
 </RCC>

BIN
resources/images/Entities_16x16.png View File


+ 3
- 3
tileset.h View File

@@ -19,9 +19,9 @@ public:
19 19
     QString callback_label;
20 20
     QString metatile_attrs_label;
21 21
 
22
-    QList<QImage> *tiles;
23
-    QList<Metatile*> *metatiles;
24
-    QList<QList<QRgb>> *palettes;
22
+    QList<QImage> *tiles = NULL;
23
+    QList<Metatile*> *metatiles = NULL;
24
+    QList<QList<QRgb>> *palettes = NULL;
25 25
 };
26 26
 
27 27
 #endif // TILESET_H