diff --git a/forms/projectsettingseditor.ui b/forms/projectsettingseditor.ui index 26813862..fe50edd7 100644 --- a/forms/projectsettingseditor.ui +++ b/forms/projectsettingseditor.ui @@ -6,7 +6,7 @@ 0 0 - 600 + 631 600 @@ -38,7 +38,7 @@ 0 0 - 528 + 559 607 @@ -178,7 +178,7 @@ - + Image Path @@ -369,7 +369,7 @@ 0 0 - 531 + 559 587 @@ -743,7 +743,7 @@ 0 0 - 528 + 559 568 @@ -1007,7 +1007,7 @@ 0 0 559 - 490 + 827 @@ -1160,6 +1160,82 @@ + + + + Warp Behaviors + + + + + + Remove the current text from the list + + + ... + + + + :/icons/delete.ico:/icons/delete.ico + + + + + + + <html><head/><body><p>Porymap will display a warning on Warp Events if they are not positioned on a metatile with one of these behaviors. This list is purely for the warning and <b>will have no effect on your game</b>.</p></body></html> + + + true + + + + + + + If checked, Warp Events will not display a warning about incompatible metatile behaviors + + + Disable Warning + + + + + + + + + + Metatile Behaviors on this list won't trigger warnings for Warp Events + + + true + + + Qt::NoTextInteraction + + + Use the dropbown and buttons to add behaviors to the list... + + + + + + + Add the current text to the list + + + ... + + + + :/icons/add.ico:/icons/add.ico + + + + + + @@ -1290,7 +1366,7 @@ 0 0 - 528 + 559 490 @@ -1342,7 +1418,7 @@ 0 0 - 502 + 533 440 diff --git a/include/config.h b/include/config.h index 1a6e0ae8..7937361d 100644 --- a/include/config.h +++ b/include/config.h @@ -248,10 +248,13 @@ public: this->blockMetatileIdMask = 0x03FF; this->blockCollisionMask = 0x0C00; this->blockElevationMask = 0xF000; + this->warpBehaviors = defaultWarpBehaviors; + this->warpBehaviorWarningDisabled = false; this->readKeys.clear(); } static const QMap> defaultPaths; static const QStringList versionStrings; + static const QStringList defaultWarpBehaviors; void reset(BaseGameVersion baseGameVersion); void setBaseGameVersion(BaseGameVersion baseGameVersion); BaseGameVersion getBaseGameVersion(); @@ -329,7 +332,7 @@ public: void setEventIconPath(Event::Group group, const QString &path); QString getEventIconPath(Event::Group group); void setPokemonIconPath(const QString &species, const QString &path); - QString getPokemonIconPath(const QString & species); + QString getPokemonIconPath(const QString &species); QHash getPokemonIconPaths(); void setCollisionSheetPath(const QString &path); QString getCollisionSheetPath(); @@ -337,6 +340,10 @@ public: int getCollisionSheetWidth(); void setCollisionSheetHeight(int height); int getCollisionSheetHeight(); + void setWarpBehaviors(const QStringList &behaviors); + QStringList getWarpBehaviors(); + void setWarpBehaviorWarningDisabled(bool disabled); + bool getWarpBehaviorWarningDisabled(); // TODO: Replace these once there's generic support for editing project names static const QString metatileIdMaskName; @@ -396,6 +403,8 @@ private: QString collisionSheetPath; int collisionSheetWidth; int collisionSheetHeight; + QStringList warpBehaviors; + bool warpBehaviorWarningDisabled; }; extern ProjectConfig projectConfig; diff --git a/include/editor.h b/include/editor.h index ac1f8e4c..f684b491 100644 --- a/include/editor.h +++ b/include/editor.h @@ -190,7 +190,6 @@ private: static bool startDetachedProcess(const QString &command, const QString &workingDirectory = QString(), qint64 *pid = nullptr); - void constructBehaviorValueList(); // TODO: Remove private slots: void onMapStartPaint(QGraphicsSceneMouseEvent *event, MapPixmapItem *item); diff --git a/include/mainwindow.h b/include/mainwindow.h index 2eaedeab..1b1b9123 100644 --- a/include/mainwindow.h +++ b/include/mainwindow.h @@ -159,7 +159,7 @@ public: public slots: void on_mainTabBar_tabBarClicked(int index); void on_mapViewTab_tabBarClicked(int index); - void openProjectSettingsEditor(int tab); + void onWarpBehaviorWarningClicked(); private slots: void on_action_Open_Project_triggered(); @@ -390,7 +390,7 @@ private: void initShortcutsEditor(); void initCustomScriptsEditor(); void connectSubEditorsToShortcutsEditor(); - + void openProjectSettingsEditor(int tab); bool isProjectOpen(); void showExportMapImageWindow(ImageExporterMode mode); void redrawMetatileSelection(); diff --git a/include/project.h b/include/project.h index 2428aa89..c9cf0a0e 100644 --- a/include/project.h +++ b/include/project.h @@ -79,6 +79,7 @@ public: QMap> metatileLabelsMap; QMap metatileBehaviorMap; QMap metatileBehaviorMapInverse; + QSet warpBehaviorValues; QMap facingDirections; ParseUtil parser; QFileSystemWatcher fileWatcher; diff --git a/include/ui/projectsettingseditor.h b/include/ui/projectsettingseditor.h index 35ff95f3..d4fcea11 100644 --- a/include/ui/projectsettingseditor.h +++ b/include/ui/projectsettingseditor.h @@ -21,7 +21,7 @@ public: explicit ProjectSettingsEditor(QWidget *parent = nullptr, Project *project = nullptr); ~ProjectSettingsEditor(); - static const int warpBehaviorsTab; + static const int eventsTab; void setTab(int index); signals: @@ -60,6 +60,8 @@ private: QString stripProjectDir(QString s); void disableParsedSetting(QWidget * widget, const QString &name, const QString &filepath); void updateMaskOverlapWarning(QLabel * warning, QList masks); + QStringList getWarpBehaviorsList(); + void setWarpBehaviorsList(QStringList list); private slots: void dialogButtonClicked(QAbstractButton *button); @@ -70,6 +72,7 @@ private slots: void on_mainTabs_tabBarClicked(int index); void updateBlockMaskOverlapWarning(); void updateAttributeMaskOverlapWarning(); + void updateWarpBehaviorsList(bool adding); }; #endif // PROJECTSETTINGSEDITOR_H diff --git a/src/config.cpp b/src/config.cpp index 48bb9e95..7b90a5c0 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -16,6 +16,37 @@ #include #include +const QStringList ProjectConfig::defaultWarpBehaviors = { + "MB_NORTH_ARROW_WARP", + "MB_SOUTH_ARROW_WARP", + "MB_WEST_ARROW_WARP", + "MB_EAST_ARROW_WARP", + "MB_STAIRS_OUTSIDE_ABANDONED_SHIP", + "MB_WATER_SOUTH_ARROW_WARP", + "MB_SHOAL_CAVE_ENTRANCE", + "MB_SECRET_BASE_SPOT_RED_CAVE_OPEN", + "MB_SECRET_BASE_SPOT_BROWN_CAVE_OPEN", + "MB_SECRET_BASE_SPOT_YELLOW_CAVE_OPEN", + "MB_SECRET_BASE_SPOT_BLUE_CAVE_OPEN", + "MB_SECRET_BASE_SPOT_TREE_LEFT_OPEN", + "MB_SECRET_BASE_SPOT_TREE_RIGHT_OPEN", + "MB_SECRET_BASE_SPOT_SHRUB_OPEN", + "MB_ANIMATED_DOOR", + "MB_NON_ANIMATED_DOOR", + "MB_PETALBURG_GYM_DOOR", + "MB_WATER_DOOR", + "MB_LADDER", + "MB_UP_ESCALATOR", + "MB_DOWN_ESCALATOR", + "MB_DEEP_SOUTH_WARP", + "MB_LAVARIDGE_GYM_B1F_WARP", + "MB_LAVARIDGE_GYM_1F_WARP", + "MB_AQUA_HIDEOUT_WARP", + "MB_MT_PYRE_HOLE", + "MB_MOSSDEEP_GYM_WARP", + "MB_BRIDGE_OVER_OCEAN", +}; + const QString ProjectConfig::metatileIdMaskName = "MAPGRID_METATILE_ID_MASK"; const QString ProjectConfig::collisionMaskName = "MAPGRID_COLLISION_MASK"; const QString ProjectConfig::elevationMaskName = "MAPGRID_ELEVATION_MASK"; @@ -746,6 +777,12 @@ void ProjectConfig::parseConfigKeyValue(QString key, QString value) { this->collisionSheetWidth = getConfigUint32(key, value, 1, Block::maxValue); } else if (key == "collision_sheet_height") { this->collisionSheetHeight = getConfigUint32(key, value, 1, Block::maxValue); + } else if (key == "warp_behaviors") { + value.remove(" "); + this->warpBehaviors = value.split(",", Qt::SkipEmptyParts); + this->warpBehaviors.removeDuplicates(); + } else if (key == "warp_behavior_warning_disabled") { + this->warpBehaviorWarningDisabled = getConfigBool(key, value); } else { logWarn(QString("Invalid config key found in config file %1: '%2'").arg(this->getConfigFilepath()).arg(key)); } @@ -829,6 +866,9 @@ QMap ProjectConfig::getKeyValueMap() { map.insert("collision_sheet_path", this->collisionSheetPath); map.insert("collision_sheet_width", QString::number(this->collisionSheetWidth)); map.insert("collision_sheet_height", QString::number(this->collisionSheetHeight)); + map.insert("warp_behaviors", this->warpBehaviors.join(",")); + map.insert("warp_behavior_warning_disabled", QString::number(this->warpBehaviorWarningDisabled)); + return map; } @@ -1254,6 +1294,24 @@ int ProjectConfig::getCollisionSheetHeight() { return this->collisionSheetHeight; } +void ProjectConfig::setWarpBehaviors(const QStringList &behaviors) { + this->warpBehaviors = behaviors; + this->save(); +} + +QStringList ProjectConfig::getWarpBehaviors() { + return this->warpBehaviors; +} + +void ProjectConfig::setWarpBehaviorWarningDisabled(bool disabled) { + this->warpBehaviorWarningDisabled = disabled; + this->save(); +} + +bool ProjectConfig::getWarpBehaviorWarningDisabled() { + return this->warpBehaviorWarningDisabled; +} + UserConfig userConfig; diff --git a/src/editor.cpp b/src/editor.cpp index 5c3bd7b3..b64dfb09 100644 --- a/src/editor.cpp +++ b/src/editor.cpp @@ -106,7 +106,6 @@ void Editor::setEditingMap() { this->cursorMapTileRect->setActive(true); setMapEditingButtonsEnabled(true); - this->constructBehaviorValueList(); // TODO: Remove } void Editor::setEditingCollision() { @@ -1989,58 +1988,11 @@ void Editor::redrawObject(DraggablePixmapItem *item) { } } -/* TODO: Add tab to PSE for warp behaviors, containing: - - A description of what it means - - A check box to enable/disable the warning - - An editable list of warp behavior names - -*/ -// TODO: Relocate to file handling the "warp behaviors" window, make static list below a config default -const QStringList warpBehaviorNames = { - "MB_NORTH_ARROW_WARP", - "MB_SOUTH_ARROW_WARP", - "MB_WEST_ARROW_WARP", - "MB_EAST_ARROW_WARP", - "MB_STAIRS_OUTSIDE_ABANDONED_SHIP", - "MB_WATER_SOUTH_ARROW_WARP", - "MB_SHOAL_CAVE_ENTRANCE", - "MB_SECRET_BASE_SPOT_RED_CAVE_OPEN", - "MB_SECRET_BASE_SPOT_BROWN_CAVE_OPEN", - "MB_SECRET_BASE_SPOT_YELLOW_CAVE_OPEN", - "MB_SECRET_BASE_SPOT_BLUE_CAVE_OPEN", - "MB_SECRET_BASE_SPOT_TREE_LEFT_OPEN", - "MB_SECRET_BASE_SPOT_TREE_RIGHT_OPEN", - "MB_SECRET_BASE_SPOT_SHRUB_OPEN", - "MB_ANIMATED_DOOR", - "MB_NON_ANIMATED_DOOR", - "MB_PETALBURG_GYM_DOOR", - "MB_WATER_DOOR", - "MB_LADDER", - "MB_UP_ESCALATOR", - "MB_DOWN_ESCALATOR", - "MB_DEEP_SOUTH_WARP", - "MB_LAVARIDGE_GYM_B1F_WARP", - "MB_LAVARIDGE_GYM_1F_WARP", - "MB_AQUA_HIDEOUT_WARP", - "MB_MT_PYRE_HOLE", - "MB_MOSSDEEP_GYM_WARP", - "MB_BRIDGE_OVER_OCEAN", -}; -QSet warpBehaviorValues; -void Editor::constructBehaviorValueList() { - if (!project) return; - warpBehaviorValues.clear(); - //warpBehaviorNames.removeDuplicates(); // TODO: Uncomment when list is actually dynamic - for (auto name : warpBehaviorNames) { - if (project->metatileBehaviorMap.contains(name)) { - warpBehaviorValues.insert(project->metatileBehaviorMap[name]); - } - } -} - // Warp events display a warning if they're not positioned on a metatile with a warp behavior. void Editor::updateWarpEventWarning(Event *event) { - if (!map || !event || event->getEventType() != Event::Type::Warp) + if (projectConfig.getWarpBehaviorWarningDisabled()) + return; + if (!project || !map || !event || event->getEventType() != Event::Type::Warp) return; Block block; Metatile * metatile = nullptr; @@ -2049,16 +2001,18 @@ void Editor::updateWarpEventWarning(Event *event) { metatile = Tileset::getMetatile(block.metatileId(), map->layout->tileset_primary, map->layout->tileset_secondary); } // metatile may be null if the warp is in the map border. Display the warning in this case - bool validWarpBehavior = metatile && warpBehaviorValues.contains(metatile->behavior()); + bool validWarpBehavior = metatile && project->warpBehaviorValues.contains(metatile->behavior()); warpEvent->setWarningEnabled(!validWarpBehavior); } // The warp event behavior warning is updated whenever the event moves or the event selection changes. // It does not respond to changes in the underlying metatile. To capture the common case of a user painting -// metatiles on the Map tab then returning to the Events tab we update the warings for all selected warp +// metatiles on the Map tab then returning to the Events tab we update the warnings for all selected warp // events when the Events tab is opened. This does not cover the case where metatiles are painted while // still on the Events tab, such as by Undo/Redo or the scripting API. void Editor::updateWarpEventWarnings() { + if (projectConfig.getWarpBehaviorWarningDisabled()) + return; if (selected_events) { for (auto selection : *selected_events) updateWarpEventWarning(selection->event); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 355fcdb3..73158270 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -2744,6 +2744,33 @@ void MainWindow::on_actionProject_Settings_triggered() { this->openProjectSettingsEditor(porymapConfig.getProjectSettingsTab()); } +void MainWindow::onWarpBehaviorWarningClicked() { + static const QString text = QString( + "By default, Warp Events only function as exits if they're positioned on a metatile " + "whose Metatile Behavior is treated specially in your project's code." + ); + static const QString informative = QString( + "

" + "For instance, most floor metatiles in a cave have the behavior MB_CAVE, but the floor space in front of an " + "exit will have MB_SOUTH_ARROW_WARP, which is treated specially and will allow a Warp Event to warp the player. " + "You can see in the status bar what behavior a metatile has when you mouse over it, or by selecting it in the Tileset Editor." + "

" + "Note: Not all Warp Events that show this warning are incorrect! For example some warps may function " + "as a 1-way entrance, and others may have the metatile underneath them changed programmatically." + "

" + "You can disable this warning or edit the list of behaviors that silence this warning under Options -> Project Settings..." + "

" + ); + QMessageBox msgBox(QMessageBox::Information, "porymap", text, QMessageBox::Close, this); + QPushButton *settings = msgBox.addButton("Open Settings...", QMessageBox::ActionRole); + msgBox.setDefaultButton(QMessageBox::Close); + msgBox.setTextFormat(Qt::RichText); + msgBox.setInformativeText(informative); + msgBox.exec(); + if (msgBox.clickedButton() == settings) + this->openProjectSettingsEditor(ProjectSettingsEditor::eventsTab); +} + void MainWindow::on_actionCustom_Scripts_triggered() { if (!this->customScriptsEditor) initCustomScriptsEditor(); diff --git a/src/project.cpp b/src/project.cpp index 3e487efa..856bf2a2 100644 --- a/src/project.cpp +++ b/src/project.cpp @@ -2291,6 +2291,17 @@ bool Project::readMetatileBehaviors() { for (QString defineName : this->metatileBehaviorMap.keys()) { this->metatileBehaviorMapInverse.insert(this->metatileBehaviorMap[defineName], defineName); } + + // Construct warp behavior value list for the warp metatile behavior warning + const QStringList warpBehaviorNames = projectConfig.getWarpBehaviors(); + this->warpBehaviorValues.clear(); + for (auto name : warpBehaviorNames) { + if (this->metatileBehaviorMap.contains(name)) { + int value = this->metatileBehaviorMap.value(name); + this->warpBehaviorValues.insert(static_cast(value)); + } + } + return true; } diff --git a/src/ui/eventframes.cpp b/src/ui/eventframes.cpp index 7da0a977..3002569a 100644 --- a/src/ui/eventframes.cpp +++ b/src/ui/eventframes.cpp @@ -525,9 +525,7 @@ void WarpFrame::connectSignals(MainWindow *window) { // warning this->warning->disconnect(); - connect(this->warning, &QPushButton::clicked, [window]() { - window->openProjectSettingsEditor(ProjectSettingsEditor::warpBehaviorsTab); - }); + connect(this->warning, &QPushButton::clicked, window, &MainWindow::onWarpBehaviorWarningClicked); } void WarpFrame::initialize() { diff --git a/src/ui/projectsettingseditor.cpp b/src/ui/projectsettingseditor.cpp index 44930598..09a94981 100644 --- a/src/ui/projectsettingseditor.cpp +++ b/src/ui/projectsettingseditor.cpp @@ -10,7 +10,7 @@ Editor for the settings in a user's porymap.project.cfg file (and 'use_encounter_json' in porymap.user.cfg). */ -const int ProjectSettingsEditor::warpBehaviorsTab = 4; +const int ProjectSettingsEditor::eventsTab = 3; ProjectSettingsEditor::ProjectSettingsEditor(QWidget *parent, Project *project) : QMainWindow(parent), @@ -45,6 +45,8 @@ void ProjectSettingsEditor::connectSignals() { this->setBorderMetatileIds(customSize, this->getBorderMetatileIds(!customSize)); this->setBorderMetatilesUi(customSize); }); + connect(ui->button_AddWarpBehavior, &QAbstractButton::clicked, [this](bool) { this->updateWarpBehaviorsList(true); }); + connect(ui->button_RemoveWarpBehavior, &QAbstractButton::clicked, [this](bool) { this->updateWarpBehaviorsList(false); }); // Connect file selection buttons connect(ui->button_ChoosePrefabs, &QAbstractButton::clicked, [this](bool) { this->choosePrefabsFile(); }); @@ -56,6 +58,7 @@ void ProjectSettingsEditor::connectSignals() { connect(ui->button_HealspotsIcon, &QAbstractButton::clicked, [this](bool) { this->chooseImageFile(ui->lineEdit_HealspotsIcon); }); connect(ui->button_PokemonIcon, &QAbstractButton::clicked, [this](bool) { this->chooseImageFile(ui->lineEdit_PokemonIcon); }); + // Display a warning if a mask value overlaps with another mask in its group. connect(ui->spinBox_MetatileIdMask, &UIntSpinBox::textChanged, this, &ProjectSettingsEditor::updateBlockMaskOverlapWarning); connect(ui->spinBox_CollisionMask, &UIntSpinBox::textChanged, this, &ProjectSettingsEditor::updateBlockMaskOverlapWarning); @@ -67,7 +70,8 @@ void ProjectSettingsEditor::connectSignals() { // Record that there are unsaved changes if any of the settings are modified for (auto combo : ui->centralwidget->findChildren()){ - if (combo != ui->comboBox_IconSpecies) // Changes to the icon species combo box are just for info display, don't mark as unsaved + // Changes to these two combo boxes are just for info display, don't mark as unsaved + if (combo != ui->comboBox_IconSpecies && combo != ui->comboBox_WarpBehaviors) connect(combo, &QComboBox::currentTextChanged, this, &ProjectSettingsEditor::markEdited); } for (auto checkBox : ui->centralwidget->findChildren()) @@ -92,17 +96,25 @@ void ProjectSettingsEditor::initUi() { ui->comboBox_DefaultPrimaryTileset->addItems(project->primaryTilesetLabels); ui->comboBox_DefaultSecondaryTileset->addItems(project->secondaryTilesetLabels); ui->comboBox_IconSpecies->addItems(project->speciesToIconPath.keys()); + ui->comboBox_WarpBehaviors->addItems(project->metatileBehaviorMap.keys()); } ui->comboBox_BaseGameVersion->addItems(ProjectConfig::versionStrings); ui->comboBox_AttributesSize->addItems({"1", "2", "4"}); // Validate that the border metatiles text is a comma-separated list of metatile values static const QString regex_Hex = "(0[xX])?[A-Fa-f0-9]+"; - static const QRegularExpression expression(QString("^(%1,)*%1$").arg(regex_Hex)); // Comma-separated list of hex values - QRegularExpressionValidator *validator = new QRegularExpressionValidator(expression); - ui->lineEdit_BorderMetatiles->setValidator(validator); + static const QRegularExpression expression_HexList(QString("^(%1,)*%1$").arg(regex_Hex)); // Comma-separated list of hex values + QRegularExpressionValidator *validator_HexList = new QRegularExpressionValidator(expression_HexList); + ui->lineEdit_BorderMetatiles->setValidator(validator_HexList); this->setBorderMetatilesUi(projectConfig.getUseCustomBorderSize()); + // Validate that the text added to the warp behavior list could be a valid define + // (we don't care whether it actually is a metatile behavior define) + static const QRegularExpression expression_Word("^[A-Za-z0-9_]*$"); + QRegularExpressionValidator *validator_Word = new QRegularExpressionValidator(expression_Word); + ui->comboBox_WarpBehaviors->setValidator(validator_Word); + ui->textEdit_WarpBehaviors->setTextColor(Qt::gray); + // Set spin box limits uint16_t maxMetatileId = Block::getMaxMetatileId(); ui->spinBox_FillMetatile->setMaximum(maxMetatileId); @@ -272,6 +284,38 @@ void ProjectSettingsEditor::updatePokemonIconPath(const QString &newSpecies) { this->prevIconSpecies = newSpecies; } +QStringList ProjectSettingsEditor::getWarpBehaviorsList() { + return ui->textEdit_WarpBehaviors->toPlainText().split("\n"); +} + +void ProjectSettingsEditor::setWarpBehaviorsList(QStringList list) { + ui->textEdit_WarpBehaviors->setText(list.join("\n")); +} + +void ProjectSettingsEditor::updateWarpBehaviorsList(bool adding) { + const QString input = ui->comboBox_WarpBehaviors->currentText(); + if (input.isEmpty()) + return; + + QStringList list = this->getWarpBehaviorsList(); + int pos = list.indexOf(input); + + if (adding && pos < 0) { + // Add text to list + list.prepend(input); + } else if (!adding && pos >= 0) { + // Remove text from list + list.removeAt(pos); + } else { + // Trying to add text already in list, + // or trying to remove text not in list + return; + } + + this->setWarpBehaviorsList(list); + this->hasUnsavedChanges = true; +} + void ProjectSettingsEditor::createProjectPathsTable() { auto pathPairs = ProjectConfig::defaultPaths.values(); for (auto pathPair : pathPairs) { @@ -366,6 +410,7 @@ void ProjectSettingsEditor::refresh() { ui->checkBox_EnableCustomBorderSize->setChecked(projectConfig.getUseCustomBorderSize()); ui->checkBox_OutputCallback->setChecked(projectConfig.getTilesetsHaveCallback()); ui->checkBox_OutputIsCompressed->setChecked(projectConfig.getTilesetsHaveIsCompressed()); + ui->checkBox_DisableWarning->setChecked(projectConfig.getWarpBehaviorWarningDisabled()); // Set spin box values ui->spinBox_Elevation->setValue(projectConfig.getDefaultElevation()); @@ -396,6 +441,7 @@ void ProjectSettingsEditor::refresh() { ui->lineEdit_HealspotsIcon->setText(projectConfig.getEventIconPath(Event::Group::Heal)); for (auto lineEdit : ui->scrollAreaContents_ProjectPaths->findChildren()) lineEdit->setText(projectConfig.getFilePath(lineEdit->objectName(), true)); + this->setWarpBehaviorsList(projectConfig.getWarpBehaviors()); this->refreshing = false; // Allow signals } @@ -429,6 +475,7 @@ void ProjectSettingsEditor::save() { projectConfig.setUseCustomBorderSize(ui->checkBox_EnableCustomBorderSize->isChecked()); projectConfig.setTilesetsHaveCallback(ui->checkBox_OutputCallback->isChecked()); projectConfig.setTilesetsHaveIsCompressed(ui->checkBox_OutputIsCompressed->isChecked()); + projectConfig.setWarpBehaviorWarningDisabled(ui->checkBox_DisableWarning->isChecked()); // Save spin box settings projectConfig.setDefaultElevation(ui->spinBox_Elevation->value()); @@ -455,6 +502,8 @@ void ProjectSettingsEditor::save() { for (auto lineEdit : ui->scrollAreaContents_ProjectPaths->findChildren()) projectConfig.setFilePath(lineEdit->objectName(), lineEdit->text()); + projectConfig.setWarpBehaviors(this->getWarpBehaviorsList()); + // Save border metatile IDs projectConfig.setNewMapBorderMetatileIds(this->getBorderMetatileIds(ui->checkBox_EnableCustomBorderSize->isChecked()));