Pārlūkot izejas kodu

Merge pull request #3 from huderlem/maps

Fix map connections, warps, and map event saving
yenatch 6 gadus atpakaļ
vecāks
revīzija
7f761a5051
Revīzijas autora e-pasta adrese nav piesaistīta nevienam kontam
7 mainītis faili ar 210 papildinājumiem un 117 dzēšanām
  1. 1
    0
      .gitignore
  2. 0
    4
      event.h
  3. 14
    7
      mainwindow.cpp
  4. 34
    11
      map.cpp
  5. 3
    0
      map.h
  6. 156
    95
      project.cpp
  7. 2
    0
      project.h

+ 1
- 0
.gitignore Parādīt failu

@@ -1 +1,2 @@
1 1
 pretmap.pro.user
2
+*.autosave

+ 0
- 4
event.h Parādīt failu

@@ -39,10 +39,6 @@ public:
39 39
         values.insert(key, value);
40 40
     }
41 41
 
42
-    bool is_hidden_item() {
43
-        return getInt("type") >= 5;
44
-    }
45
-
46 42
     QMap<QString, QString> values;
47 43
     QPixmap pixmap;
48 44
 };

+ 14
- 7
mainwindow.cpp Parādīt failu

@@ -504,13 +504,16 @@ void MainWindow::updateSelectedObjects() {
504 504
         field_labels["property"] = "Property";
505 505
         field_labels["sight_radius"] = "Sight Radius";
506 506
         field_labels["destination_warp"] = "Destination Warp";
507
-        field_labels["destination_map"] = "Destination Map";
507
+        field_labels["destination_map_name"] = "Destination Map";
508 508
         field_labels["coord_unknown1"] = "Unknown 1";
509 509
         field_labels["coord_unknown2"] = "Unknown 2";
510 510
         field_labels["type"] = "Type";
511 511
         field_labels["item"] = "Item";
512 512
         field_labels["item_unknown5"] = "Unknown 5";
513 513
         field_labels["item_unknown6"] = "Unknown 6";
514
+        field_labels["weather"] = "Weather";
515
+        field_labels["flag"] = "Flag";
516
+        field_labels["secret_base_map"] = "Secret Base Map";
514 517
 
515 518
         QStringList fields;
516 519
 
@@ -542,22 +545,26 @@ void MainWindow::updateSelectedObjects() {
542 545
         }
543 546
         else if (event_type == "warp") {
544 547
             fields << "destination_warp";
545
-            fields << "destination_map";
548
+            fields << "destination_map_name";
546 549
         }
547 550
         else if (event_type == "trap") {
548 551
             fields << "script_label";
549 552
             fields << "coord_unknown1";
550 553
             fields << "coord_unknown2";
551 554
         }
555
+        else if (event_type == "trap_weather") {
556
+            fields << "weather";
557
+        }
552 558
         else if (event_type == "sign") {
553 559
             fields << "type";
554 560
             fields << "script_label";
555 561
         }
556
-        else if (event_type == "hidden item") {
557
-            fields << "type";
562
+        else if (event_type == "event_hidden_item") {
558 563
             fields << "item";
559
-            fields << "item_unknown5";
560
-            fields << "item_unknown6";
564
+            fields << "flag";
565
+        }
566
+        else if (event_type == "event_secret_base") {
567
+            fields << "secret_base_map";
561 568
         }
562 569
 
563 570
         for (QString key : fields) {
@@ -568,7 +575,7 @@ void MainWindow::updateSelectedObjects() {
568 575
             combo->setEditable(true);
569 576
 
570 577
             QString value = item->event->get(key);
571
-            if (key == "destination_map") {
578
+            if (key == "destination_map_name") {
572 579
                 if (!editor->project->mapNames->contains(value)) {
573 580
                     combo->addItem(value);
574 581
                 }

+ 34
- 11
map.cpp Parādīt failu

@@ -4,6 +4,7 @@
4 4
 #include <QDebug>
5 5
 #include <QPainter>
6 6
 #include <QImage>
7
+#include <QRegularExpression>
7 8
 
8 9
 Map::Map(QObject *parent) : QObject(parent)
9 10
 {
@@ -16,6 +17,24 @@ Map::Map(QObject *parent) : QObject(parent)
16 17
     paint_elevation = 3;
17 18
 }
18 19
 
20
+void Map::setName(QString mapName) {
21
+    name = mapName;
22
+    constantName = mapConstantFromName(mapName);
23
+}
24
+
25
+QString Map::mapConstantFromName(QString mapName) {
26
+    // Transform map names of the form 'GraniteCave_B1F` into map constants like 'MAP_GRANITE_CAVE_B1F'.
27
+    QString nameWithUnderscores = mapName.replace(QRegularExpression("([a-z])([A-Z])"), "\\1_\\2");
28
+    QString withMapAndUppercase = "MAP_" + nameWithUnderscores.toUpper();
29
+    QString constantName = withMapAndUppercase.replace(QRegularExpression("_+"), "_");
30
+
31
+    // Handle special cases.
32
+    // SSTidal needs to be SS_TIDAL, rather than SSTIDAL
33
+    constantName = constantName.replace("SSTIDAL", "SS_TIDAL");
34
+
35
+    return constantName;
36
+}
37
+
19 38
 int Map::getWidth() {
20 39
     return width.toInt(nullptr, 0);
21 40
 }
@@ -138,22 +157,26 @@ QImage Map::getMetatileImage(int tile) {
138 157
     for (int x = 0; x < 2; x++) {
139 158
         Tile tile_ = metatile->tiles->value((y * 2) + x + (layer * 4));
140 159
         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
-        //}
150
-        //QVector<QRgb> vector = palette.toVector();
151
-        //tile_image.setColorTable(vector);
160
+        if (tile_image.isNull()) {
161
+            // Some metatiles specify tiles that are outside the valid range.
162
+            // These are treated as completely transparent, so they can be skipped without
163
+            // being drawn.
164
+            continue;
165
+        }
166
+
167
+        // Colorize the metatile tiles with its palette.
168
+        QList<QRgb> palette = palettes.value(tile_.palette);
169
+        for (int j = 0; j < palette.length(); j++) {
170
+            tile_image.setColor(j, palette.value(j));
171
+        }
172
+
173
+        // The top layer of the metatile has its last color displayed at transparent.
152 174
         if (layer > 0) {
153 175
             QColor color(tile_image.color(15));
154 176
             color.setAlpha(0);
155 177
             tile_image.setColor(15, color.rgba());
156 178
         }
179
+
157 180
         QPoint origin = QPoint(x*8, y*8);
158 181
         metatile_painter.drawImage(origin, tile_image.mirrored(tile_.xflip == 1, tile_.yflip == 1));
159 182
     }

+ 3
- 0
map.h Parādīt failu

@@ -75,6 +75,7 @@ public:
75 75
 
76 76
 public:
77 77
     QString name;
78
+    QString constantName;
78 79
     QString attributes_label;
79 80
     QString events_label;
80 81
     QString scripts_label;
@@ -102,6 +103,8 @@ public:
102 103
     Blockdata* blockdata = NULL;
103 104
 
104 105
 public:
106
+    void setName(QString mapName);
107
+    static QString mapConstantFromName(QString mapName);
105 108
     int getWidth();
106 109
     int getHeight();
107 110
     Tileset* getBlockTileset(int);

+ 156
- 95
project.cpp Parādīt failu

@@ -31,7 +31,7 @@ QString Project::getProjectTitle() {
31 31
 Map* Project::loadMap(QString map_name) {
32 32
     Map *map = new Map;
33 33
 
34
-    map->name = map_name;
34
+    map->setName(map_name);
35 35
     readMapHeader(map);
36 36
     readMapAttributes(map);
37 37
     getTilesets(map);
@@ -66,8 +66,13 @@ void Project::loadMapConnections(Map *map) {
66 66
                     Connection *connection = new Connection;
67 67
                     connection->direction = command.value(1);
68 68
                     connection->offset = command.value(2);
69
-                    connection->map_name = command.value(3);
70
-                    map->connections.append(connection);
69
+                    QString mapConstant = command.value(3);
70
+                    if (mapConstantsToMapNames.contains(mapConstant)) {
71
+                        connection->map_name = mapConstantsToMapNames[mapConstant];
72
+                        map->connections.append(connection);
73
+                    } else {
74
+                        qDebug() << QString("Failed to find connected map for map constant '%1'").arg(mapConstant);
75
+                    }
71 76
                 }
72 77
             }
73 78
         }
@@ -512,9 +517,15 @@ void Project::readMapGroups() {
512 517
         } else if (macro == ".4byte") {
513 518
             if (group != -1) {
514 519
                 for (int j = 1; j < params.length(); j++) {
520
+                    QString mapName = params.value(j);
515 521
                     QStringList *list = groupedMaps->value(group);
516
-                    list->append(params.value(j));
517
-                    maps->append(params.value(j));
522
+                    list->append(mapName);
523
+                    maps->append(mapName);
524
+
525
+                    // Build the mapping and reverse mapping between map constants and map names.
526
+                    QString mapConstant = Map::mapConstantFromName(mapName);
527
+                    mapConstantsToMapNames.insert(mapConstant, mapName);
528
+                    mapNamesToMapConstants.insert(mapName, mapConstant);
518 529
                 }
519 530
             }
520 531
         }
@@ -654,9 +665,9 @@ void Project::loadObjectPixmaps(QList<Event*> objects) {
654 665
             object->pixmap = QPixmap(":/images/Entities_16x16.png").copy(0, 0, 16, 16);
655 666
         } else if (event_type == "warp") {
656 667
             object->pixmap = QPixmap(":/images/Entities_16x16.png").copy(16, 0, 16, 16);
657
-        } else if (event_type == "trap") {
668
+        } else if (event_type == "trap" || event_type == "trap_weather") {
658 669
             object->pixmap = QPixmap(":/images/Entities_16x16.png").copy(32, 0, 16, 16);
659
-        } else if (event_type == "sign" || event_type == "hidden item") {
670
+        } else if (event_type == "sign" || event_type == "event_hidden_item" || event_type == "event_secret_base") {
660 671
             object->pixmap = QPixmap(":/images/Entities_16x16.png").copy(48, 0, 16, 16);
661 672
         }
662 673
 
@@ -687,85 +698,107 @@ void Project::saveMapEvents(Map *map) {
687 698
     QString path = root + QString("/data/maps/events/%1.inc").arg(map->name);
688 699
     QString text = "";
689 700
 
690
-    text += QString("%1::\n").arg(map->object_events_label);
691
-    for (int i = 0; i < map->events["object"].length(); i++) {
692
-        Event *object_event = map->events["object"].value(i);
693
-        int radius_x = object_event->getInt("radius_x");
694
-        int radius_y = object_event->getInt("radius_y");
695
-        QString radius = QString("%1").arg((radius_x & 0xf) + ((radius_y & 0xf) << 4));
696
-        uint16_t x = object_event->getInt("x");
697
-        uint16_t y = object_event->getInt("y");
698
-
699
-        text += QString("\tobject_event %1").arg(i + 1);
700
-        text += QString(", %1").arg(object_event->get("sprite"));
701
-        text += QString(", %1").arg(object_event->get("replacement"));
702
-        text += QString(", %1").arg(x & 0xff);
703
-        text += QString(", %1").arg((x >> 8) & 0xff);
704
-        text += QString(", %1").arg(y & 0xff);
705
-        text += QString(", %1").arg((y >> 8) & 0xff);
706
-        text += QString(", %1").arg(object_event->get("elevation"));
707
-        text += QString(", %1").arg(object_event->get("behavior"));
708
-        text += QString(", %1").arg(radius);
709
-        text += QString(", 0");
710
-        text += QString(", %1").arg(object_event->get("property"));
711
-        text += QString(", 0");
712
-        text += QString(", %1").arg(object_event->get("sight_radius"));
713
-        text += QString(", 0");
714
-        text += QString(", %1").arg(object_event->get("script_label"));
715
-        text += QString(", %1").arg(object_event->get("event_flag"));
716
-        text += QString(", 0");
717
-        text += QString(", 0");
701
+    if (map->events["object"].length() > 0) {
702
+        text += QString("%1::\n").arg(map->object_events_label);
703
+        for (int i = 0; i < map->events["object"].length(); i++) {
704
+            Event *object_event = map->events["object"].value(i);
705
+            int radius_x = object_event->getInt("radius_x");
706
+            int radius_y = object_event->getInt("radius_y");
707
+            QString radius = QString("%1").arg((radius_x & 0xf) + ((radius_y & 0xf) << 4));
708
+            uint16_t x = object_event->getInt("x");
709
+            uint16_t y = object_event->getInt("y");
710
+
711
+            text += QString("\tobject_event %1").arg(i + 1);
712
+            text += QString(", %1").arg(object_event->get("sprite"));
713
+            text += QString(", %1").arg(object_event->get("replacement"));
714
+            text += QString(", %1").arg(x & 0xff);
715
+            text += QString(", %1").arg((x >> 8) & 0xff);
716
+            text += QString(", %1").arg(y & 0xff);
717
+            text += QString(", %1").arg((y >> 8) & 0xff);
718
+            text += QString(", %1").arg(object_event->get("elevation"));
719
+            text += QString(", %1").arg(object_event->get("behavior"));
720
+            text += QString(", %1").arg(radius);
721
+            text += QString(", 0");
722
+            text += QString(", %1").arg(object_event->get("property"));
723
+            text += QString(", 0");
724
+            text += QString(", %1").arg(object_event->get("sight_radius"));
725
+            text += QString(", 0");
726
+            text += QString(", %1").arg(object_event->get("script_label"));
727
+            text += QString(", %1").arg(object_event->get("event_flag"));
728
+            text += QString(", 0");
729
+            text += QString(", 0");
730
+            text += "\n";
731
+        }
718 732
         text += "\n";
719 733
     }
720
-    text += "\n";
721 734
 
722
-    text += QString("%1::\n").arg(map->warps_label);
723
-    for (Event *warp : map->events["warp"]) {
724
-        text += QString("\twarp_def %1").arg(warp->get("x"));
725
-        text += QString(", %1").arg(warp->get("y"));
726
-        text += QString(", %1").arg(warp->get("elevation"));
727
-        text += QString(", %1").arg(warp->get("destination_warp"));
728
-        text += QString(", %1").arg(warp->get("destination_map"));
729
-        text += "\n";
730
-    }
731
-    text += "\n";
732
-
733
-    text += QString("%1::\n").arg(map->coord_events_label);
734
-    for (Event *coords : map->events["trap"]) {
735
-        text += QString("\tcoord_event %1").arg(coords->get("x"));
736
-        text += QString(", %1").arg(coords->get("y"));
737
-        text += QString(", %1").arg(coords->get("elevation"));
738
-        text += QString(", 0");
739
-        text += QString(", %1").arg(coords->get("coord_unknown1"));
740
-        text += QString(", %1").arg(coords->get("coord_unknown2"));
741
-        text += QString(", 0");
742
-        text += QString(", %1").arg(coords->get("script_label"));
735
+    if (map->events["warp"].length() > 0) {
736
+        text += QString("%1::\n").arg(map->warps_label);
737
+        for (Event *warp : map->events["warp"]) {
738
+            text += QString("\twarp_def %1").arg(warp->get("x"));
739
+            text += QString(", %1").arg(warp->get("y"));
740
+            text += QString(", %1").arg(warp->get("elevation"));
741
+            text += QString(", %1").arg(warp->get("destination_warp"));
742
+            text += QString(", %1").arg(mapNamesToMapConstants[warp->get("destination_map_name")]);
743
+            text += "\n";
744
+        }
743 745
         text += "\n";
744 746
     }
745
-    text += "\n";
746 747
 
747
-    text += QString("%1::\n").arg(map->bg_events_label);
748
-    for (Event *sign : map->events["sign"]) {
749
-        text += QString("\tbg_event %1").arg(sign->get("x"));
750
-        text += QString(", %1").arg(sign->get("y"));
751
-        text += QString(", %1").arg(sign->get("elevation"));
752
-        text += QString(", %1").arg(sign->get("type"));
753
-        text += QString(", 0");
754
-        text += QString(", %1").arg(sign->get("script_label"));
748
+    if (map->events["trap"].length() + map->events["trap_weather"].length() > 0) {
749
+        text += QString("%1::\n").arg(map->coord_events_label);
750
+        for (Event *coords : map->events["trap"]) {
751
+            text += QString("\tcoord_event %1").arg(coords->get("x"));
752
+            text += QString(", %1").arg(coords->get("y"));
753
+            text += QString(", %1").arg(coords->get("elevation"));
754
+            text += QString(", 0");
755
+            text += QString(", %1").arg(coords->get("coord_unknown1"));
756
+            text += QString(", %1").arg(coords->get("coord_unknown2"));
757
+            text += QString(", 0");
758
+            text += QString(", %1").arg(coords->get("script_label"));
759
+            text += "\n";
760
+        }
761
+        for (Event *coords : map->events["trap_weather"]) {
762
+            text += QString("\tcoord_weather_event %1").arg(coords->get("x"));
763
+            text += QString(", %1").arg(coords->get("y"));
764
+            text += QString(", %1").arg(coords->get("elevation"));
765
+            text += QString(", %1").arg(coords->get("weather"));
766
+            text += "\n";
767
+        }
755 768
         text += "\n";
756 769
     }
757
-    for (Event *item : map->events["hidden item"]) {
758
-        text += QString("\tbg_event %1").arg(item->get("x"));
759
-        text += QString(", %1").arg(item->get("y"));
760
-        text += QString(", %1").arg(item->get("elevation"));
761
-        text += QString(", %1").arg(item->get("type"));
762
-        text += QString(", 0");
763
-        text += QString(", %1").arg(item->get("item"));
764
-        text += QString(", %1").arg(item->get("item_unknown5"));
765
-        text += QString(", %1").arg(item->get("item_unknown6"));
770
+
771
+    if (map->events["sign"].length() +
772
+        map->events["event_hidden_item"].length() +
773
+        map->events["event_secret_base"].length() > 0)
774
+    {
775
+        text += QString("%1::\n").arg(map->bg_events_label);
776
+        for (Event *sign : map->events["sign"]) {
777
+            text += QString("\tbg_event %1").arg(sign->get("x"));
778
+            text += QString(", %1").arg(sign->get("y"));
779
+            text += QString(", %1").arg(sign->get("elevation"));
780
+            text += QString(", %1").arg(sign->get("type"));
781
+            text += QString(", 0");
782
+            text += QString(", %1").arg(sign->get("script_label"));
783
+            text += "\n";
784
+        }
785
+        for (Event *item : map->events["event_hidden_item"]) {
786
+            text += QString("\tbg_hidden_item_event %1").arg(item->get("x"));
787
+            text += QString(", %1").arg(item->get("y"));
788
+            text += QString(", %1").arg(item->get("elevation"));
789
+            text += QString(", %1").arg(item->get("item"));
790
+            text += QString(", %1").arg(item->get("flag"));
791
+            text += "\n";
792
+        }
793
+        for (Event *item : map->events["event_secret_base"]) {
794
+            text += QString("\tbg_secret_base_event %1").arg(item->get("x"));
795
+            text += QString(", %1").arg(item->get("y"));
796
+            text += QString(", %1").arg(item->get("elevation"));
797
+            text += QString(", %1").arg(item->get("secret_base_map"));
798
+            text += "\n";
799
+        }
766 800
         text += "\n";
767 801
     }
768
-    text += "\n";
769 802
 
770 803
     text += QString("%1::\n").arg(map->events_label);
771 804
     text += QString("\tmap_events %1, %2, %3, %4\n")
@@ -846,15 +879,22 @@ void Project::readMapEvents(Map *map) {
846 879
             warp->put("y", command.value(i++));
847 880
             warp->put("elevation", command.value(i++));
848 881
             warp->put("destination_warp", command.value(i++));
849
-            warp->put("destination_map", command.value(i++));
850 882
 
851
-            warp->put("event_type", "warp");
852
-            map->events["warp"].append(warp);
883
+            // Ensure the warp destination map constant is valid before adding it to the warps.
884
+            QString mapConstant = command.value(i++);
885
+            if (mapConstantsToMapNames.contains(mapConstant)) {
886
+                warp->put("destination_map_name", mapConstantsToMapNames[mapConstant]);
887
+                warp->put("event_type", "warp");
888
+                map->events["warp"].append(warp);
889
+            } else {
890
+                qDebug() << QString("Destination map constant '%1' is invalid for warp").arg(mapConstant);
891
+            }
853 892
         }
854 893
     }
855 894
 
856 895
     QList<QStringList> *coords = getLabelMacros(parse(text), map->coord_events_label);
857 896
     map->events["trap"].clear();
897
+    map->events["trap_weather"].clear();
858 898
     for (QStringList command : *coords) {
859 899
         if (command.value(0) == "coord_event") {
860 900
             Event *coord = new Event;
@@ -877,12 +917,23 @@ void Project::readMapEvents(Map *map) {
877 917
 
878 918
             coord->put("event_type", "trap");
879 919
             map->events["trap"].append(coord);
920
+        } else if (command.value(0) == "coord_weather_event") {
921
+            Event *coord = new Event;
922
+            coord->put("map_name", map->name);
923
+            int i = 1;
924
+            coord->put("x", command.value(i++));
925
+            coord->put("y", command.value(i++));
926
+            coord->put("elevation", command.value(i++));
927
+            coord->put("weather", command.value(i++));
928
+            coord->put("event_type", "trap_weather");
929
+            map->events["trap_weather"].append(coord);
880 930
         }
881 931
     }
882 932
 
883 933
     QList<QStringList> *bgs = getLabelMacros(parse(text), map->bg_events_label);
884
-    map->events["hidden item"].clear();
885 934
     map->events["sign"].clear();
935
+    map->events["event_hidden_item"].clear();
936
+    map->events["event_secret_base"].clear();
886 937
     for (QStringList command : *bgs) {
887 938
         if (command.value(0) == "bg_event") {
888 939
             Event *bg = new Event;
@@ -893,23 +944,33 @@ void Project::readMapEvents(Map *map) {
893 944
             bg->put("elevation", command.value(i++));
894 945
             bg->put("type", command.value(i++));
895 946
             i++;
896
-            if (bg->is_hidden_item()) {
897
-                bg->put("item", command.value(i++));
898
-                bg->put("item_unknown5", command.value(i++));
899
-                bg->put("item_unknown6", command.value(i++));
900
-
901
-                bg->put("event_type", "hidden item");
902
-                map->events["hidden item"].append(bg);
903
-            } else {
904
-                bg->put("script_label", command.value(i++));
905
-                //sign_unknown7
906
-
907
-                bg->put("event_type", "sign");
908
-                map->events["sign"].append(bg);
909
-            }
947
+            bg->put("script_label", command.value(i++));
948
+            //sign_unknown7
949
+            bg->put("event_type", "sign");
950
+            map->events["sign"].append(bg);
951
+        } else if (command.value(0) == "bg_hidden_item_event") {
952
+            Event *bg = new Event;
953
+            bg->put("map_name", map->name);
954
+            int i = 1;
955
+            bg->put("x", command.value(i++));
956
+            bg->put("y", command.value(i++));
957
+            bg->put("elevation", command.value(i++));
958
+            bg->put("item", command.value(i++));
959
+            bg->put("flag", command.value(i++));
960
+            bg->put("event_type", "event_hidden_item");
961
+            map->events["event_hidden_item"].append(bg);
962
+        } else if (command.value(0) == "bg_secret_base_event") {
963
+            Event *bg = new Event;
964
+            bg->put("map_name", map->name);
965
+            int i = 1;
966
+            bg->put("x", command.value(i++));
967
+            bg->put("y", command.value(i++));
968
+            bg->put("elevation", command.value(i++));
969
+            bg->put("secret_base_map", command.value(i++));
970
+            bg->put("event_type", "event_secret_base");
971
+            map->events["event_secret_base"].append(bg);
910 972
         }
911 973
     }
912
-
913 974
 }
914 975
 
915 976
 QStringList Project::readCArray(QString text, QString label) {

+ 2
- 0
project.h Parādīt failu

@@ -15,6 +15,8 @@ public:
15 15
     QStringList *groupNames = NULL;
16 16
     QList<QStringList*> *groupedMapNames = NULL;
17 17
     QStringList *mapNames = NULL;
18
+    QMap<QString, QString> mapConstantsToMapNames;
19
+    QMap<QString, QString> mapNamesToMapConstants;
18 20
 
19 21
     QMap<QString, Map*> *map_cache;
20 22
     Map* loadMap(QString);