diff --git a/forms/mainwindow.ui b/forms/mainwindow.ui index 98d03ba3..b35225a6 100644 --- a/forms/mainwindow.ui +++ b/forms/mainwindow.ui @@ -14,8 +14,8 @@ porymap - - + + Qt::Horizontal @@ -1856,209 +1856,337 @@ + + + 0 + 0 + + Header - - - false + + + 0 - - - 10 - 10 - 381 - 311 - + + 0 - - - 0 - 0 - + + 0 - - QFrame::StyledPanel + + 0 - - QFrame::Raised + + 0 - - - 12 - - - - - Song + + + + false + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + QFormLayout::FieldsStayAtSizeHint - - - - - - <html><head/><body><p>The default background music for this map.</p></body></html> + + 12 - - true + + 9 - - - - - - Location - - - - - - - <html><head/><body><p>The section of the region map which the map is grouped under. This also determines the name of the map that is display when the player enters it.</p></body></html> - - - true - - - - - - - Requires Flash - - - - - - - <html><head/><body><p>Whether or not the map is dark and requires Flash to illuminate.</p></body></html> - - - - - - - - - - Weather - - - - - - - <html><head/><body><p>The default weather for this map.</p></body></html> - - - true - - - - - - - Type - - - - - - - <html><head/><body><p>The map type is a general attribute, which is used for many different things. For example. it determines whether biking or running is allowed.</p></body></html> - - - true - - - - - - - Battle scene - - - - - - - <html><head/><body><p>Determines the type of battle scene graphics to use.</p></body></html> - - - true - - - - - - - Show Location Name - - - - - - - <html><head/><body><p>Whether or not to display the location name when the player enters the map.</p></body></html> - - - - - - - - - - Allow Running - - - - - - - <html><head/><body><p>Allows the player to use Running Shoes</p></body></html> - - - - - - - - - - Allow Biking - - - - - - - <html><head/><body><p>Allows the player to use a Bike</p></body></html> - - - - - - - - - - Allow Dig & Escape Rope - - - - - - - <html><head/><body><p>Allows the player to use Dig or Escape Rope</p></body></html> - - - - - - - - + + + + Song + + + + + + + <html><head/><body><p>The default background music for this map.</p></body></html> + + + true + + + + + + + Location + + + + + + + <html><head/><body><p>The section of the region map which the map is grouped under. This also determines the name of the map that is display when the player enters it.</p></body></html> + + + true + + + + + + + Requires Flash + + + + + + + <html><head/><body><p>Whether or not the map is dark and requires Flash to illuminate.</p></body></html> + + + + + + + + + + Weather + + + + + + + <html><head/><body><p>The default weather for this map.</p></body></html> + + + true + + + + + + + Type + + + + + + + <html><head/><body><p>The map type is a general attribute, which is used for many different things. For example. it determines whether biking or running is allowed.</p></body></html> + + + true + + + + + + + Battle scene + + + + + + + <html><head/><body><p>Determines the type of battle scene graphics to use.</p></body></html> + + + true + + + + + + + Show Location Name + + + + + + + <html><head/><body><p>Whether or not to display the location name when the player enters the map.</p></body></html> + + + + + + + + + + Allow Running + + + + + + + <html><head/><body><p>Allows the player to use Running Shoes</p></body></html> + + + + + + + + + + Allow Biking + + + + + + + <html><head/><body><p>Allows the player to use a Bike</p></body></html> + + + + + + + + + + Allow Dig & Escape Rope + + + + + + + <html><head/><body><p>Allows the player to use Dig or Escape Rope</p></body></html> + + + + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + Custom Fields + + + + + + + QFrame::NoFrame + + + QFrame::Plain + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Add + + + + + + + Delete + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + Custom fields will be added to the map.json file for the current map. + + + true + + + false + + + true + + + false + + + true + + + false + + + + Key + + + + + Value + + + + + + + + diff --git a/include/core/map.h b/include/core/map.h index 038f6321..d50c7b7e 100644 --- a/include/core/map.h +++ b/include/core/map.h @@ -38,6 +38,7 @@ public: QString battle_scene; QString sharedEventsMap = ""; QString sharedScriptsMap = ""; + QMap customHeaders; MapLayout *layout; bool isPersistedToFile = true; bool needsLayoutDir = true; diff --git a/include/editor.h b/include/editor.h index 57131830..4b7f71a0 100644 --- a/include/editor.h +++ b/include/editor.h @@ -74,6 +74,7 @@ public: void updatePrimaryTileset(QString tilesetLabel, bool forceLoad = false); void updateSecondaryTileset(QString tilesetLabel, bool forceLoad = false); void toggleBorderVisibility(bool visible); + void updateCustomMapHeaderValues(QTableWidget *); Tileset *getCurrentMapPrimaryTileset(); DraggablePixmapItem *addMapEvent(Event *event); diff --git a/include/mainwindow.h b/include/mainwindow.h index 924e12ad..06ab1999 100644 --- a/include/mainwindow.h +++ b/include/mainwindow.h @@ -152,12 +152,12 @@ private slots: void selectedEventIndexChanged(int index); void on_horizontalSlider_CollisionTransparency_valueChanged(int value); - void on_toolButton_ExpandAll_clicked(); - void on_toolButton_CollapseAll_clicked(); - void on_actionAbout_Porymap_triggered(); + void on_pushButton_AddCustomHeaderField_clicked(); + void on_pushButton_DeleteCustomHeaderField_clicked(); + void on_tableWidget_CustomHeaderFields_cellChanged(int row, int column); private: Ui::MainWindow *ui; diff --git a/include/project.h b/include/project.h index 1d05d2b2..89306895 100644 --- a/include/project.h +++ b/include/project.h @@ -70,6 +70,7 @@ public: QList* getLabelMacros(QList*, QString); QStringList* getLabelValues(QList*, QString); + QMap getTopLevelMapFields(); bool loadMapData(Map*); void readMapLayouts(); void loadMapLayout(Map*); diff --git a/src/editor.cpp b/src/editor.cpp index b9465bee..5674721b 100644 --- a/src/editor.cpp +++ b/src/editor.cpp @@ -1109,6 +1109,21 @@ void Editor::toggleBorderVisibility(bool visible) this->setConnectionsVisibility(visible); } +void Editor::updateCustomMapHeaderValues(QTableWidget *table) +{ + QMap fields; + for (int row = 0; row < table->rowCount(); row++) { + QString keyStr = ""; + QString valueStr = ""; + QTableWidgetItem *key = table->item(row, 0); + QTableWidgetItem *value = table->item(row, 1); + if (key) keyStr = key->text(); + if (value) valueStr = value->text(); + fields[keyStr] = valueStr; + } + map->customHeaders = fields; +} + Tileset* Editor::getCurrentMapPrimaryTileset() { QString tilesetLabel = map->layout->tileset_primary_label; diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 1d62e951..fdee69ba 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -486,6 +486,17 @@ void MainWindow::displayMapProperties() { ui->checkBox_AllowRunning->setChecked(map->allowRunning.toInt() > 0 || map->allowRunning == "TRUE"); ui->checkBox_AllowBiking->setChecked(map->allowBiking.toInt() > 0 || map->allowBiking == "TRUE"); ui->checkBox_AllowEscapeRope->setChecked(map->allowEscapeRope.toInt() > 0 || map->allowEscapeRope == "TRUE"); + + // Custom fields table. + ui->tableWidget_CustomHeaderFields->blockSignals(true); + ui->tableWidget_CustomHeaderFields->setRowCount(0); + for (auto it = map->customHeaders.begin(); it != map->customHeaders.end(); it++) { + int rowIndex = ui->tableWidget_CustomHeaderFields->rowCount(); + ui->tableWidget_CustomHeaderFields->insertRow(rowIndex); + ui->tableWidget_CustomHeaderFields->setItem(rowIndex, 0, new QTableWidgetItem(it.key())); + ui->tableWidget_CustomHeaderFields->setItem(rowIndex, 1, new QTableWidgetItem(it.value())); + } + ui->tableWidget_CustomHeaderFields->blockSignals(false); } void MainWindow::on_comboBox_Song_activated(const QString &song) @@ -1903,6 +1914,42 @@ void MainWindow::on_actionAbout_Porymap_triggered() window->show(); } +void MainWindow::on_pushButton_AddCustomHeaderField_clicked() +{ + int rowIndex = this->ui->tableWidget_CustomHeaderFields->rowCount(); + this->ui->tableWidget_CustomHeaderFields->insertRow(rowIndex); + this->ui->tableWidget_CustomHeaderFields->selectRow(rowIndex); + this->editor->updateCustomMapHeaderValues(this->ui->tableWidget_CustomHeaderFields); +} + +void MainWindow::on_pushButton_DeleteCustomHeaderField_clicked() +{ + int rowCount = this->ui->tableWidget_CustomHeaderFields->rowCount(); + if (rowCount > 0) { + QModelIndexList indexList = ui->tableWidget_CustomHeaderFields->selectionModel()->selectedIndexes(); + QList persistentIndexes; + for (QModelIndex index : indexList) { + QPersistentModelIndex persistentIndex(index); + persistentIndexes.append(persistentIndex); + } + + for (QPersistentModelIndex index : persistentIndexes) { + this->ui->tableWidget_CustomHeaderFields->removeRow(index.row()); + } + + if (this->ui->tableWidget_CustomHeaderFields->rowCount() > 0) { + this->ui->tableWidget_CustomHeaderFields->selectRow(0); + } + + this->editor->updateCustomMapHeaderValues(this->ui->tableWidget_CustomHeaderFields); + } +} + +void MainWindow::on_tableWidget_CustomHeaderFields_cellChanged(int row, int column) +{ + this->editor->updateCustomMapHeaderValues(this->ui->tableWidget_CustomHeaderFields); +} + void MainWindow::closeEvent(QCloseEvent *event) { porymapConfig.setGeometry( this->saveGeometry(), diff --git a/src/project.cpp b/src/project.cpp index 488aa31e..473df657 100644 --- a/src/project.cpp +++ b/src/project.cpp @@ -128,6 +128,58 @@ QStringList* Project::getLabelValues(QList *list, QString label) { return values; } +QMap Project::getTopLevelMapFields() { + if (projectConfig.getBaseGameVersion() == BaseGameVersion::pokeemerald) { + return QMap + { + {"id", true}, + {"name", true}, + {"layout", true}, + {"music", true}, + {"region_map_section", true}, + {"requires_flash", true}, + {"weather", true}, + {"map_type", true}, + {"allow_bike", true}, + {"allow_escape_rope", true}, + {"allow_running", true}, + {"show_map_name", true}, + {"battle_scene", true}, + {"connections", true}, + {"object_events", true}, + {"warp_events", true}, + {"coord_events", true}, + {"bg_events", true}, + {"shared_events_map", true}, + {"shared_scripts_map", true}, + }; + } else if (projectConfig.getBaseGameVersion() == BaseGameVersion::pokeruby) { + return QMap + { + {"id", true}, + {"name", true}, + {"layout", true}, + {"music", true}, + {"region_map_section", true}, + {"requires_flash", true}, + {"weather", true}, + {"map_type", true}, + {"show_map_name", true}, + {"battle_scene", true}, + {"connections", true}, + {"object_events", true}, + {"warp_events", true}, + {"coord_events", true}, + {"bg_events", true}, + {"shared_events_map", true}, + {"shared_scripts_map", true}, + }; + } else { + logError("Invalid game version"); + return QMap(); + } +} + bool Project::loadMapData(Map* map) { if (!map->isPersistedToFile) { return true; @@ -322,6 +374,14 @@ bool Project::loadMapData(Map* map) { } } + // Check for custom fields + QMap baseFields = this->getTopLevelMapFields(); + for (QString key : mapObj.keys()) { + if (!baseFields.contains(key)) { + map->customHeaders.insert(key, mapObj[key].toString()); + } + } + return true; } @@ -954,6 +1014,11 @@ void Project::saveMap(Map *map) { mapObj["shared_scripts_map"] = map->sharedScriptsMap; } + // Custom header fields. + for (QString key : map->customHeaders.keys()) { + mapObj[key] = map->customHeaders[key]; + } + QJsonDocument mapDoc(mapObj); mapFile.write(mapDoc.toJson());