From cd9b8b12a54c6f6133bb94c18a9c0134af0fe9e0 Mon Sep 17 00:00:00 2001 From: Marcus Huderle Date: Wed, 12 Feb 2020 10:22:40 -0600 Subject: [PATCH] Validate map layout and tileset loading --- include/editor.h | 2 +- include/mainwindow.h | 2 +- include/project.h | 10 +++---- src/editor.cpp | 9 ++++-- src/mainwindow.cpp | 28 ++++++++--------- src/project.cpp | 68 +++++++++++++++++++++++++++++------------- src/ui/newmappopup.cpp | 4 ++- 7 files changed, 78 insertions(+), 45 deletions(-) diff --git a/include/editor.h b/include/editor.h index bfb0ee95..45706daf 100644 --- a/include/editor.h +++ b/include/editor.h @@ -45,7 +45,7 @@ public: bool setMap(QString map_name); void saveUiFields(); void saveEncounterTabData(); - void displayMap(); + bool displayMap(); void displayMetatileSelector(); void displayMapMetatiles(); void displayMapMovementPermissions(); diff --git a/include/mainwindow.h b/include/mainwindow.h index 7224f485..8d5d3e20 100644 --- a/include/mainwindow.h +++ b/include/mainwindow.h @@ -187,7 +187,7 @@ private: bool setMap(QString, bool scrollTreeView = false); void redrawMapScene(); bool loadDataStructures(); - void populateMapList(); + bool populateMapList(); void sortMapList(); QString getExistingDirectory(QString); bool openProject(QString dir); diff --git a/include/project.h b/include/project.h index 51bec9a0..4948b7e0 100644 --- a/include/project.h +++ b/include/project.h @@ -74,13 +74,13 @@ public: QMap tilesetLabels; Blockdata* readBlockdata(QString); - void loadBlockdata(Map*); + bool loadBlockdata(Map*); void saveTextFile(QString path, QString text); void appendTextFile(QString path, QString text); void deleteFile(QString path); - void readMapGroups(); + bool readMapGroups(); Map* addNewMapToGroup(QString mapName, int groupNum); Map* addNewMapToGroup(QString, int, Map*, bool); QString getNewMapName(); @@ -101,8 +101,8 @@ public: QMap getTopLevelMapFields(); bool loadMapData(Map*); bool readMapLayouts(); - void loadMapLayout(Map*); - void loadMapTilesets(Map*); + bool loadMapLayout(Map*); + bool loadMapTilesets(Map*); void loadTilesetAssets(Tileset*); void loadTilesetTiles(Tileset*, QImage); void loadTilesetMetatiles(Tileset*); @@ -154,7 +154,7 @@ public: QString getScriptFileExtension(bool usePoryScript); QString getScriptDefaultString(bool usePoryScript, QString mapName); - void loadMapBorder(Map *map); + bool loadMapBorder(Map *map); void saveMapHealEvents(Map *map); diff --git a/src/editor.cpp b/src/editor.cpp index f634494b..6083299d 100644 --- a/src/editor.cpp +++ b/src/editor.cpp @@ -908,7 +908,7 @@ void Editor::setConnectionsVisibility(bool visible) { } bool Editor::setMap(QString map_name) { - if (map_name.isNull()) { + if (map_name.isEmpty()) { return false; } @@ -920,7 +920,9 @@ bool Editor::setMap(QString map_name) { map = loadedMap; selected_events->clear(); - displayMap(); + if (!displayMap()) { + return false; + } updateSelectedEvents(); } @@ -1045,7 +1047,7 @@ void Editor::mouseEvent_collision(QGraphicsSceneMouseEvent *event, CollisionPixm } } -void Editor::displayMap() { +bool Editor::displayMap() { if (!scene) { scene = new QGraphicsScene; MapSceneEventFilter *filter = new MapSceneEventFilter(); @@ -1086,6 +1088,7 @@ void Editor::displayMap() { if (events_group) { events_group->setVisible(false); } + return true; } void Editor::displayMetatileSelector() { diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 62d9362b..d0ed74ed 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -281,16 +281,11 @@ bool MainWindow::openProject(QString dir) { if (!already_open) { editor->project = new Project; editor->project->set_root(dir); - success = loadDataStructures(); - if (success) { - populateMapList(); - success = setMap(getDefaultMap(), true); - } + success = loadDataStructures() + && populateMapList() + && setMap(getDefaultMap(), true); } else { - success = loadDataStructures(); - if (success) { - populateMapList(); - } + success = loadDataStructures() && populateMapList(); } if (success) { @@ -350,7 +345,7 @@ void MainWindow::on_action_Open_Project_triggered() bool MainWindow::setMap(QString map_name, bool scrollTreeView) { logInfo(QString("Setting map to '%1'").arg(map_name)); - if (map_name.isNull()) { + if (map_name.isEmpty()) { return false; } @@ -388,7 +383,9 @@ bool MainWindow::setMap(QString map_name, bool scrollTreeView) { void MainWindow::redrawMapScene() { - editor->displayMap(); + if (!editor->displayMap()) + return; + on_tabWidget_currentChanged(ui->tabWidget->currentIndex()); double base = editor->scale_base; @@ -644,9 +641,12 @@ bool MainWindow::loadDataStructures() { return true; } -void MainWindow::populateMapList() { - editor->project->readMapGroups(); - sortMapList(); +bool MainWindow::populateMapList() { + bool success = editor->project->readMapGroups(); + if (success) { + sortMapList(); + } + return success; } void MainWindow::sortMapList() { diff --git a/src/project.cpp b/src/project.cpp index fc7154d7..29d14df5 100644 --- a/src/project.cpp +++ b/src/project.cpp @@ -74,10 +74,9 @@ Map* Project::loadMap(QString map_name) { map->setName(map_name); } - if (!loadMapData(map)) + if (!(loadMapData(map) && loadMapLayout(map))) return nullptr; - loadMapLayout(map); map->commit(); map->metatileHistory.save(); map_cache->insert(map_name, map); @@ -387,21 +386,21 @@ void Project::setNewMapHeader(Map* map, int mapIndex) { map->battle_scene = "MAP_BATTLE_SCENE_NORMAL"; } -void Project::loadMapLayout(Map* map) { +bool Project::loadMapLayout(Map* map) { if (!map->isPersistedToFile) { - return; + return true; } - if (!mapLayouts.contains(map->layoutId)) { - logError(QString("Error: Map '%1' has an unknown layout '%2'").arg(map->name).arg(map->layoutId)); - return; - } else { + if (mapLayouts.contains(map->layoutId)) { map->layout = mapLayouts[map->layoutId]; + } else { + logError(QString("Error: Map '%1' has an unknown layout '%2'").arg(map->name).arg(map->layoutId)); + return false; } - loadMapTilesets(map); - loadBlockdata(map); - loadMapBorder(map); + return loadMapTilesets(map) + && loadBlockdata(map) + && loadMapBorder(map); } bool Project::readMapLayouts() { @@ -906,13 +905,23 @@ void Project::saveTilesetPalettes(Tileset *tileset, bool /*primary*/) { } } -void Project::loadMapTilesets(Map* map) { +bool Project::loadMapTilesets(Map* map) { if (map->layout->has_unsaved_changes) { - return; + return true; } map->layout->tileset_primary = getTileset(map->layout->tileset_primary_label); + if (!map->layout->tileset_primary) { + logError(QString("Map layout %1 has invalid primary tileset '%2'").arg(map->layout->id).arg(map->layout->tileset_primary_label)); + return false; + } + map->layout->tileset_secondary = getTileset(map->layout->tileset_secondary_label); + if (!map->layout->tileset_secondary) { + logError(QString("Map layout %1 has invalid secondary tileset '%2'").arg(map->layout->id).arg(map->layout->tileset_secondary_label)); + return false; + } + return true; } Tileset* Project::loadTileset(QString label, Tileset *tileset) { @@ -939,9 +948,9 @@ Tileset* Project::loadTileset(QString label, Tileset *tileset) { return tileset; } -void Project::loadBlockdata(Map* map) { +bool Project::loadBlockdata(Map* map) { if (!map->isPersistedToFile || map->layout->has_unsaved_changes) { - return; + return true; } QString path = QString("%1/%2").arg(root).arg(map->layout->blockdata_path); @@ -955,6 +964,7 @@ void Project::loadBlockdata(Map* map) { .arg(map->getWidth() * map->getHeight())); map->layout->blockdata->blocks->resize(map->getWidth() * map->getHeight()); } + return true; } void Project::setNewMapBlockdata(Map* map) { @@ -965,13 +975,21 @@ void Project::setNewMapBlockdata(Map* map) { map->layout->blockdata = blockdata; } -void Project::loadMapBorder(Map *map) { +bool Project::loadMapBorder(Map *map) { if (!map->isPersistedToFile || map->layout->has_unsaved_changes) { - return; + return true; } QString path = QString("%1/%2").arg(root).arg(map->layout->border_path); map->layout->border = readBlockdata(path); + int borderLength = 4; + if (map->layout->border->blocks->count() != borderLength) { + logWarn(QString("Layout border blockdata length %1 must be %2. Resizing border blockdata.") + .arg(map->layout->border->blocks->count()) + .arg(borderLength)); + map->layout->border->blocks->resize(borderLength); + } + return true; } void Project::setNewMapBorder(Map *map) { @@ -1265,7 +1283,12 @@ void Project::loadTilesetAssets(Tileset* tileset) { tiles_path = fixGraphicPath(tiles_path); tileset->tilesImagePath = tiles_path; - QImage image = QImage(tileset->tilesImagePath); + QImage image; + if (QFile::exists(tileset->tilesImagePath)) { + image = QImage(tileset->tilesImagePath); + } else { + image = QImage(8, 8, QImage::Format_Indexed8); + } this->loadTilesetTiles(tileset, image); this->loadTilesetMetatiles(tileset); this->loadTilesetMetatileLabels(tileset); @@ -1518,12 +1541,16 @@ bool Project::readWildMonData() { return true; } -void Project::readMapGroups() { +bool Project::readMapGroups() { + mapConstantsToMapNames->clear(); + mapNamesToMapConstants->clear(); + map_groups->clear(); + QString mapGroupsFilepath = QString("%1/data/maps/map_groups.json").arg(root); QJsonDocument mapGroupsDoc; if (!parser.tryParseJsonFile(&mapGroupsDoc, mapGroupsFilepath)) { logError(QString("Failed to read map groups from %1").arg(mapGroupsFilepath)); - return; + return false; } QJsonObject mapGroupsObj = mapGroupsDoc.object(); @@ -1557,6 +1584,7 @@ void Project::readMapGroups() { groupNames = groups; groupedMapNames = groupedMaps; mapNames = maps; + return true; } Map* Project::addNewMapToGroup(QString mapName, int groupNum) { diff --git a/src/ui/newmappopup.cpp b/src/ui/newmappopup.cpp index 53cac7d2..e0938227 100644 --- a/src/ui/newmappopup.cpp +++ b/src/ui/newmappopup.cpp @@ -157,7 +157,9 @@ void NewMapPopup::on_pushButton_NewMap_Accept_clicked() { group = project->groupNames->indexOf(this->ui->comboBox_NewMap_Group->currentText()); newMap->layout = layout; newMap->layoutId = layout->id; - if (this->existingLayout) project->loadMapLayout(newMap); + if (this->existingLayout) { + project->loadMapLayout(newMap); + } newMap->group_num = QString::number(group); map = newMap; emit applied();