diff --git a/CHANGELOG.md b/CHANGELOG.md index 50007ef5..5d489b17 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,10 +21,12 @@ The **"Breaking Changes"** listed below are changes that have been made in the d - Add an input field to the Tileset Editor for editing the full metatile attributes value directly, including unused bits. - An alert will be displayed when attempting to open a seemingly invalid project. - Add support for defining project values with `enum` where `#define` was expected. +- Add support for referring to object events and warps with named IDs, rather than referring to them with their index number. - Add a setting to specify the tile values to use for the unused metatile layer. - Add a setting to specify the maximum number of events in a group. A warning will be shown if too many events are added. - Add a setting to customize the size and position of the player view distance. - Add `onLayoutOpened` to the scripting API. +- Add a splash loading screen for project openings. ### Changed - `Change Dimensions` now has an interactive resizing rectangle. @@ -67,9 +69,13 @@ The **"Breaking Changes"** listed below are changes that have been made in the d - Fix config files being written before the project is opened successfully. - Fix the map and other project info still displaying if a new project fails to open. - Fix unsaved changes being ignored when quitting (such as with Cmd+Q on macOS). -- Fix selections with multiple Events not always clearing when making a new selection. +- Fix selections with multiple events not always clearing when making a new selection. - Fix the new event button not updating correctly when selecting object events. - Fix duplicated `Hidden Item` events not copying the `Requires Itemfinder` field. +- Fix event sprites disappearing in certain areas outside the map boundaries. +- Fix deselecting an event still allowing you to drag the event around. +- Fix events rendering on top of the ruler at very high y values. +- Fix new map names not appearing in event dropdowns that have already been populated. - Fix `About porymap` opening a new window each time it's activated. - Fix the `Edit History` window not raising to the front when reactivated. - New maps are now always inserted in map dropdowns at the correct position, rather than at the bottom of the list until the project is reloaded. @@ -97,6 +103,7 @@ The **"Breaking Changes"** listed below are changes that have been made in the d - Fix exporting a timelapse sometimes altering the state of the current map's edit history. - Stop sliders in the Palette Editor from creating a bunch of edit history when used. - Fix scrolling on some containers locking up when the mouse stops over a spin box or combo box. +- Fix the selection index for some combo boxes differing from their displayed text. - Fix some file dialogs returning to an incorrect window when closed. - Fix bug where reloading a layout would overwrite all unsaved changes. - Fix bug where layout json and blockdata could be saved separately leading to inconsistent data. diff --git a/docsrc/manual/scripting-capabilities.rst b/docsrc/manual/scripting-capabilities.rst index ac1cf521..0651f7d9 100644 --- a/docsrc/manual/scripting-capabilities.rst +++ b/docsrc/manual/scripting-capabilities.rst @@ -204,7 +204,7 @@ Callbacks Called when the mouse exits the map. -.. js:function:: onMapResized(oldWidth, oldHeight, newWidth, newHeight) +.. js:function:: onMapResized(oldWidth, oldHeight, delta) Called when the dimensions of the map are changed. @@ -212,10 +212,8 @@ Callbacks :type oldWidth: number :param oldHeight: the height of the map before the change :type oldHeight: number - :param newWidth: the width of the map after the change - :type newWidth: number - :param newHeight: the height of the map after the change - :type newHeight: number + :param delta: the amount the map size changed in each direction. The object's shape is ``{left, right, top, bottom}`` + :type prevBlock: delta .. js:function:: onBorderResized(oldWidth, oldHeight, newWidth, newHeight) diff --git a/forms/loadingscreen.ui b/forms/loadingscreen.ui new file mode 100644 index 00000000..4ed06b9f --- /dev/null +++ b/forms/loadingscreen.ui @@ -0,0 +1,157 @@ + + + LoadingScreen + + + Qt::WindowModality::ApplicationModal + + + + 0 + 0 + 366 + 255 + + + + BusyCursor + + + Qt::ContextMenuPolicy::NoContextMenu + + + Form + + + + + + + 20 + true + + + + porymap + + + Qt::AlignmentFlag::AlignCenter + + + + + + + + 12 + + + + Version X.x.x + + + Qt::AlignmentFlag::AlignCenter + + + + + + + Qt::Orientation::Vertical + + + + 20 + 40 + + + + + + + + QFrame::Shape::NoFrame + + + QFrame::Shadow::Raised + + + + + + Qt::Orientation::Horizontal + + + + 40 + 20 + + + + + + + + + 64 + 64 + + + + IMAGE + + + + + + + Qt::Orientation::Horizontal + + + + 40 + 20 + + + + + + + + + + + Qt::Orientation::Vertical + + + + 20 + 40 + + + + + + + + QFrame::Shape::NoFrame + + + QFrame::Shadow::Plain + + + + + + Loading.... + + + + + + + + + + + diff --git a/forms/mainwindow.ui b/forms/mainwindow.ui index bf0d2608..c75c8328 100644 --- a/forms/mainwindow.ui +++ b/forms/mainwindow.ui @@ -2733,7 +2733,10 @@ - + + + false + QComboBox::SizeAdjustPolicy::AdjustToContents diff --git a/forms/mapheaderform.ui b/forms/mapheaderform.ui index 08552e2c..d4fc36f3 100644 --- a/forms/mapheaderform.ui +++ b/forms/mapheaderform.ui @@ -10,6 +10,9 @@ 380 + + Qt::FocusPolicy::ClickFocus + Form diff --git a/forms/newdefinedialog.ui b/forms/newdefinedialog.ui new file mode 100644 index 00000000..c816c6e3 --- /dev/null +++ b/forms/newdefinedialog.ui @@ -0,0 +1,89 @@ + + + NewDefineDialog + + + + 0 + 0 + 252 + 124 + + + + true + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Name + + + + + + + true + + + + + + + false + + + color: rgb(255, 0, 0) + + + + + + + + + + + + + Value + + + + + + + + + + Qt::Orientation::Horizontal + + + QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok + + + false + + + + + + + + diff --git a/forms/projectsettingseditor.ui b/forms/projectsettingseditor.ui index 4cf06515..05598b8f 100644 --- a/forms/projectsettingseditor.ui +++ b/forms/projectsettingseditor.ui @@ -1582,19 +1582,21 @@ 499 - - - - - ... + + + + + Qt::Orientation::Horizontal - - - :/icons/help.ico:/icons/help.ico + + + 40 + 20 + - + - + @@ -1626,7 +1628,7 @@ 0 0 544 - 437 + 338 @@ -1646,6 +1648,34 @@ + + + + <html><head/><body><p>Add additional C files containing #defines or enums. These will be used to resolve unknown symbols during project launch.</p></body></html> + + + Add Global Constants File... + + + + :/icons/add.ico:/icons/add.ico + + + + + + + ... + + + + :/icons/help.ico:/icons/help.ico + + + + + + @@ -1671,8 +1701,8 @@ 499 - - + + ... @@ -1683,7 +1713,7 @@ - + @@ -1715,7 +1745,7 @@ 0 0 544 - 437 + 421 @@ -1735,6 +1765,36 @@ + + + + <html><head/><body><p>Add an additional #define name and expression. This may be used to evaluate other #defines during project launch.</p></body></html> + + + Add Global Constant... + + + + :/icons/add.ico:/icons/add.ico + + + + + + + Qt::Orientation::Horizontal + + + + 40 + 20 + + + + + + + diff --git a/forms/wildmonchart.ui b/forms/wildmonchart.ui index 8d6668e4..05c0ba44 100644 --- a/forms/wildmonchart.ui +++ b/forms/wildmonchart.ui @@ -197,7 +197,7 @@ - + true @@ -237,6 +237,11 @@ QGraphicsView
QtCharts
+ + NoScrollComboBox + QComboBox +
noscrollcombobox.h
+
diff --git a/include/config.h b/include/config.h index 67a8b507..26d2a353 100644 --- a/include/config.h +++ b/include/config.h @@ -345,6 +345,8 @@ public: this->unusedTileCovered = 0x0000; this->unusedTileSplit = 0x0000; this->maxEventsPerGroup = 255; + this->globalConstantsFilepaths.clear(); + this->globalConstants.clear(); this->identifiers.clear(); this->readKeys.clear(); } @@ -417,6 +419,8 @@ public: QMargins playerViewDistance; QList warpBehaviors; int maxEventsPerGroup; + QStringList globalConstantsFilepaths; + QMap globalConstants; protected: virtual QString getConfigFilepath() override; diff --git a/include/core/maplayout.h b/include/core/maplayout.h index 6e82604a..3e67af18 100644 --- a/include/core/maplayout.h +++ b/include/core/maplayout.h @@ -107,8 +107,8 @@ public: void setBlock(int x, int y, Block block, bool enableScriptCallback = false); void setBlockdata(Blockdata blockdata, bool enableScriptCallback = false); - void adjustDimensions(QMargins margins, bool setNewBlockdata = true); - void setDimensions(int newWidth, int newHeight, bool setNewBlockdata = true, bool enableScriptCallback = false); + void adjustDimensions(const QMargins &margins, bool setNewBlockdata = true); + void setDimensions(int newWidth, int newHeight, bool setNewBlockdata = true); void setBorderDimensions(int newWidth, int newHeight, bool setNewBlockdata = true, bool enableScriptCallback = false); void cacheBlockdata(); diff --git a/include/core/parseutil.h b/include/core/parseutil.h index e02d0504..2edb9f78 100644 --- a/include/core/parseutil.h +++ b/include/core/parseutil.h @@ -43,8 +43,13 @@ class ParseUtil { public: ParseUtil(); - void set_root(const QString &dir); + + void setRoot(const QString &dir) { this->root = dir; } + void setUpdatesSplashScreen(bool updates) { this->updatesSplashScreen = updates; } + static QString readTextFile(const QString &path, QString *error = nullptr); + QString loadTextFile(const QString &path, QString *error = nullptr); + bool cacheFile(const QString &path, QString *error = nullptr); void clearFileCache() { this->fileCache.clear(); } static int textFileLineCount(const QString &path); @@ -55,9 +60,13 @@ public: QString readCIncbin(const QString &text, const QString &label); QMap readCIncbinMulti(const QString &filepath); QStringList readCIncbinArray(const QString &filename, const QString &label); - QMap readCDefinesByRegex(const QString &filename, const QSet ®exList, QString *error = nullptr); - QMap readCDefinesByName(const QString &filename, const QSet &names, QString *error = nullptr); + QHash readCDefinesByRegex(const QString &filename, const QSet ®exList, QString *error = nullptr); + QHash readCDefinesByName(const QString &filename, const QSet &names, QString *error = nullptr); QStringList readCDefineNames(const QString &filename, const QSet ®exList, QString *error = nullptr); + void loadGlobalCDefinesFromFile(const QString &filename, QString *error = nullptr); + void loadGlobalCDefines(const QMap &defines); + void loadGlobalCDefines(const QHash &defines); + void resetCDefines(); OrderedMap> readCStructs(const QString &, const QString & = "", const QHash& = {}); QList getLabelMacros(const QList&, const QString&); QStringList getLabelValues(const QList&, const QString&); @@ -90,24 +99,38 @@ private: QString curDefine; QHash fileCache; QHash errorMap; - int evaluateDefine(const QString&, const QString &, QMap*, QMap*); - QList tokenizeExpression(QString, QMap*, QMap*); + + // The maps of define names to values/expressions that are available while parsing C defines. + // As the parser reads and evaluates more defines it will update these maps accordingly. + QHash knownDefineValues; + QHash knownDefineExpressions; + + // Maps of special define names to values/expressions that take precedence over defines encountered while parsing. + // Some (like 'TRUE'/'FALSE') are always present in these maps, others may be specified by the user with 'loadGlobalCDefines' / 'loadGlobalCDefinesFromFile'. + QHash globalDefineValues; + QHash globalDefineExpressions; + + bool updatesSplashScreen = false; + + int evaluateDefine(const QString &identifier, bool *ok = nullptr); + int evaluateExpression(const QString &expression); + QList tokenizeExpression(QString expression); QList generatePostfix(const QList &tokens); int evaluatePostfix(const QList &postfix); void recordError(const QString &message); void recordErrors(const QStringList &errors); void logRecordedErrors(); QString createErrorMessage(const QString &message, const QString &expression); + void updateSplashScreen(QString path); struct ParsedDefines { - QMap expressions; // Map of all define names encountered to their expressions + QHash expressions; // Map of all define names encountered to their expressions QStringList filteredNames; // List of define names that matched the search text, in the order that they were encountered }; ParsedDefines readCDefines(const QString &filename, const QSet &filterList, bool useRegex, QString *error); - QMap evaluateCDefines(const QString &filename, const QSet &filterList, bool useRegex, QString *error); + QHash evaluateCDefines(const QString &filename, const QSet &filterList, bool useRegex, QString *error); bool defineNameMatchesFilter(const QString &name, const QSet &filterList) const; bool defineNameMatchesFilter(const QString &name, const QSet &filterList) const; - QString loadTextFile(const QString &path, QString *error = nullptr); QString pathWithRoot(const QString &path); static const QRegularExpression re_incScriptLabel; diff --git a/include/core/tileset.h b/include/core/tileset.h index a05afdc3..abb31ab1 100644 --- a/include/core/tileset.h +++ b/include/core/tileset.h @@ -67,9 +67,9 @@ public: bool saveTilesImage(); bool savePalettes(); - bool appendToHeaders(QString root, QString friendlyName, bool usingAsm); - bool appendToGraphics(QString root, QString friendlyName, bool usingAsm); - bool appendToMetatiles(QString root, QString friendlyName, bool usingAsm); + bool appendToHeaders(const QString &filepath, const QString &friendlyName, bool usingAsm); + bool appendToGraphics(const QString &filepath, const QString &friendlyName, bool usingAsm); + bool appendToMetatiles(const QString &filepath, const QString &friendlyName, bool usingAsm); void setTilesImage(const QImage &image); diff --git a/include/mainwindow.h b/include/mainwindow.h index 683df61f..c65cac79 100644 --- a/include/mainwindow.h +++ b/include/mainwindow.h @@ -52,6 +52,8 @@ public: MainWindow(const MainWindow &) = delete; MainWindow & operator = (const MainWindow &) = delete; + void initialize(); + // Scripting API Q_INVOKABLE QJSValue getBlock(int x, int y); void tryRedrawMapArea(bool forceRedraw); diff --git a/include/project.h b/include/project.h index 1031640b..3c11009f 100644 --- a/include/project.h +++ b/include/project.h @@ -76,7 +76,7 @@ public: int maxEncounterRate; bool wildEncountersLoaded; - void set_root(QString); + void setRoot(const QString&); void clearMaps(); void clearTilesetCache(); @@ -203,6 +203,7 @@ public: bool readEventGraphics(); bool readFieldmapProperties(); bool readFieldmapMasks(); + bool readGlobalConstants(); QMap> readObjEventGfxInfo(); QPixmap getEventPixmap(const QString &gfxName, const QString &movementName); @@ -307,7 +308,10 @@ private: void setNewLayoutBlockdata(Layout *layout); void setNewLayoutBorder(Layout *layout); - void ignoreWatchedFileTemporarily(QString filepath); + void watchFile(const QString &filename); + void watchFiles(const QStringList &filenames); + void ignoreWatchedFileTemporarily(const QString &filepath); + void ignoreWatchedFilesTemporarily(const QStringList &filepaths); void recordFileChange(const QString &filepath); void resetFileCache(); diff --git a/include/scripting.h b/include/scripting.h index 6870f159..b85e9e26 100644 --- a/include/scripting.h +++ b/include/scripting.h @@ -39,6 +39,7 @@ public: static void populateGlobalObject(MainWindow *mainWindow); static QJSEngine *getEngine(); static void invokeAction(int actionIndex); + static void cb_ProjectOpened(QString projectPath); static void cb_ProjectClosed(QString projectPath); static void cb_MetatileChanged(int x, int y, Block prevBlock, Block newBlock); @@ -47,18 +48,20 @@ public: static void cb_BlockHoverCleared(); static void cb_MapOpened(QString mapName); static void cb_LayoutOpened(QString layoutName); - static void cb_MapResized(int oldWidth, int oldHeight, int newWidth, int newHeight); + static void cb_MapResized(int oldWidth, int oldHeight, const QMargins &delta); static void cb_BorderResized(int oldWidth, int oldHeight, int newWidth, int newHeight); static void cb_MapShifted(int xDelta, int yDelta); static void cb_TilesetUpdated(QString tilesetName); static void cb_MainTabChanged(int oldTab, int newTab); static void cb_MapViewTabChanged(int oldTab, int newTab); static void cb_BorderVisibilityToggled(bool visible); + static bool tryErrorJS(QJSValue js); static QJSValue fromBlock(Block block); static QJSValue fromTile(Tile tile); static Tile toTile(QJSValue obj); static QJSValue dimensions(int width, int height); + static QJSValue margins(const QMargins &margins); static QJSValue position(int x, int y); static const QImage * getImage(const QString &filepath, bool useCache); static QJSValue dialogInput(QJSValue input, bool selectedOk); diff --git a/include/ui/aboutporymap.h b/include/ui/aboutporymap.h index 6bd0ed32..3a760f44 100644 --- a/include/ui/aboutporymap.h +++ b/include/ui/aboutporymap.h @@ -13,6 +13,8 @@ class AboutPorymap : public QDialog public: explicit AboutPorymap(QWidget *parent = nullptr); ~AboutPorymap(); + + static QString getVersionString(); private: Ui::AboutPorymap *ui; }; diff --git a/include/ui/divingmappixmapitem.h b/include/ui/divingmappixmapitem.h index 7eceba07..0a4a32c1 100644 --- a/include/ui/divingmappixmapitem.h +++ b/include/ui/divingmappixmapitem.h @@ -2,6 +2,7 @@ #define DIVINGMAPPIXMAPITEM_H #include "mapconnection.h" +#include "noscrollcombobox.h" #include #include @@ -10,7 +11,7 @@ class DivingMapPixmapItem : public QObject, public QGraphicsPixmapItem { Q_OBJECT public: - DivingMapPixmapItem(MapConnection *connection, QComboBox *combo); + DivingMapPixmapItem(MapConnection *connection, NoScrollComboBox *combo); ~DivingMapPixmapItem(); MapConnection* connection() const { return m_connection; } @@ -18,7 +19,7 @@ public: private: QPointer m_connection; - QPointer m_combo; + QPointer m_combo; void setComboText(const QString &text); static QPixmap getBasePixmap(MapConnection* connection); diff --git a/include/ui/loadingscreen.h b/include/ui/loadingscreen.h new file mode 100644 index 00000000..ff88e87c --- /dev/null +++ b/include/ui/loadingscreen.h @@ -0,0 +1,43 @@ +#include "qgifimage.h" + +#include +#include +#include + + + +namespace Ui { +class LoadingScreen; +} + +class PorymapLoadingScreen : public QWidget { + + Q_OBJECT + +public: + explicit PorymapLoadingScreen(QWidget *parent = nullptr); + ~PorymapLoadingScreen(); + + void setPixmap(const QPixmap &pixmap); + void showMessage(const QString &text); + void showMessage(const QString &prefix, const QString &text); + void showLoadingMessage(const QString &text); + + void start(); + void stop (); + +private: + void setupUi(); + +public slots: + void updateFrame(); + +private: + Ui::LoadingScreen *ui; + + QGifImage splashImage; + int frame = 0; + QTimer timer; +}; + +extern PorymapLoadingScreen *porysplash; diff --git a/include/ui/mapheaderform.h b/include/ui/mapheaderform.h index 4f3dc775..fb4f7aa9 100644 --- a/include/ui/mapheaderform.h +++ b/include/ui/mapheaderform.h @@ -12,6 +12,7 @@ #include "mapheader.h" #include "project.h" +#include "noscrollcombobox.h" namespace Ui { class MapHeaderForm; @@ -64,7 +65,7 @@ private: QPointer m_project = nullptr; bool m_allowProjectChanges = true; - void setText(QComboBox *combo, const QString &text) const; + void setText(NoScrollComboBox *combo, const QString &text) const; void setText(QLineEdit *lineEdit, const QString &text) const; void setLocations(const QStringList &locations); void updateLocationName(); diff --git a/include/ui/message.h b/include/ui/message.h index 8e36372d..1756c48d 100644 --- a/include/ui/message.h +++ b/include/ui/message.h @@ -24,21 +24,21 @@ public: class ErrorMessage : public Message { public: ErrorMessage(const QString &message, QWidget *parent); - static int show(const QString &message, QWidget *parent); + static void show(const QString &message, QWidget *parent); }; // Basic warning message with an 'Ok' button. class WarningMessage : public Message { public: WarningMessage(const QString &message, QWidget *parent); - static int show(const QString &message, QWidget *parent); + static void show(const QString &message, QWidget *parent); }; // Basic informational message with a 'Close' button. class InfoMessage : public Message { public: InfoMessage(const QString &message, QWidget *parent); - static int show(const QString &message, QWidget *parent); + static void show(const QString &message, QWidget *parent); }; // Basic question message with a 'Yes' and 'No' button. @@ -53,7 +53,7 @@ public: class RecentErrorMessage : public ErrorMessage { public: RecentErrorMessage(const QString &message, QWidget *parent); - static int show(const QString &message, QWidget *parent); + static void show(const QString &message, QWidget *parent); }; diff --git a/include/ui/movablerect.h b/include/ui/movablerect.h index 21edd21d..92dd43f7 100644 --- a/include/ui/movablerect.h +++ b/include/ui/movablerect.h @@ -20,7 +20,7 @@ public: } void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) override { - if (!(*enabled)) return; + if (!isVisible()) return; painter->setPen(this->color); painter->drawRect(this->rect() + QMargins(1,1,1,1)); // Fill painter->setPen(Qt::black); @@ -28,11 +28,17 @@ public: painter->drawRect(this->rect()); // Inner border } void updateLocation(int x, int y); - bool *enabled; + + void setActive(bool active); + bool getActive() const { return this->active; } protected: + bool *enabled = nullptr; + bool active = true; QRectF baseRect; QRgb color; + + void updateVisibility(); }; diff --git a/include/ui/newdefinedialog.h b/include/ui/newdefinedialog.h new file mode 100644 index 00000000..2107dcec --- /dev/null +++ b/include/ui/newdefinedialog.h @@ -0,0 +1,32 @@ +#ifndef NEWDEFINEDIALOG_H +#define NEWDEFINEDIALOG_H + +#include +#include + +namespace Ui { +class NewDefineDialog; +} + +class NewDefineDialog : public QDialog +{ + Q_OBJECT + +public: + explicit NewDefineDialog(QWidget *parent = nullptr); + ~NewDefineDialog(); + + virtual void accept() override; + +signals: + void createdDefine(const QString &name, const QString &expression); + +private: + Ui::NewDefineDialog *ui; + + bool validateName(bool allowEmpty = false); + void onNameChanged(const QString &name); + void dialogButtonClicked(QAbstractButton *button); +}; + +#endif // NEWDEFINEDIALOG_H diff --git a/include/ui/projectsettingseditor.h b/include/ui/projectsettingseditor.h index e4a6ae94..579aec21 100644 --- a/include/ui/projectsettingseditor.h +++ b/include/ui/projectsettingseditor.h @@ -67,6 +67,12 @@ private: void setWarpBehaviorsList(QStringList list); void openFilesHelp(); void openIdentifiersHelp(); + void addNewGlobalConstantsFilepath(); + void addGlobalConstantsFilepath(const QString &filepath); + QStringList getGlobalConstantsFilepaths(); + void addNewGlobalConstant(); + void addGlobalConstant(const QString &name, const QString &expression); + QMap getGlobalConstants(); private slots: void dialogButtonClicked(QAbstractButton *button); diff --git a/porymap.pro b/porymap.pro index d8505e11..ff894f39 100644 --- a/porymap.pro +++ b/porymap.pro @@ -104,6 +104,7 @@ SOURCES += src/core/advancemapparser.cpp \ src/ui/metatileselector.cpp \ src/ui/movablerect.cpp \ src/ui/movementpermissionsselector.cpp \ + src/ui/newdefinedialog.cpp \ src/ui/neweventtoolbutton.cpp \ src/ui/newlayoutdialog.cpp \ src/ui/newlayoutform.cpp \ @@ -133,6 +134,7 @@ SOURCES += src/core/advancemapparser.cpp \ src/ui/preferenceeditor.cpp \ src/ui/regionmappropertiesdialog.cpp \ src/ui/colorpicker.cpp \ + src/ui/loadingscreen.cpp \ src/config.cpp \ src/editor.cpp \ src/main.cpp \ @@ -216,6 +218,7 @@ HEADERS += include/core/advancemapparser.h \ include/ui/metatileselector.h \ include/ui/movablerect.h \ include/ui/movementpermissionsselector.h \ + include/ui/newdefinedialog.h \ include/ui/neweventtoolbutton.h \ include/ui/newlayoutdialog.h \ include/ui/newlayoutform.h \ @@ -248,6 +251,7 @@ HEADERS += include/core/advancemapparser.h \ include/ui/preferenceeditor.h \ include/ui/regionmappropertiesdialog.h \ include/ui/colorpicker.h \ + include/ui/loadingscreen.h \ include/config.h \ include/editor.h \ include/mainwindow.h \ @@ -267,8 +271,10 @@ FORMS += forms/mainwindow.ui \ forms/connectionslistitem.ui \ forms/customattributesframe.ui \ forms/gridsettingsdialog.ui \ + forms/loadingscreen.ui \ forms/mapheaderform.ui \ forms/maplisttoolbar.ui \ + forms/newdefinedialog.ui \ forms/newlayoutdialog.ui \ forms/newlayoutform.ui \ forms/newlocationdialog.ui \ diff --git a/resources/images.qrc b/resources/images.qrc index e1253139..41789a6e 100644 --- a/resources/images.qrc +++ b/resources/images.qrc @@ -94,6 +94,7 @@ images/collisions_unknown.png images/Entities_16x16.png images/pokemon_icon_placeholder.png + images/porysplash.gif icons/clipboard.ico icons/map_go.ico diff --git a/resources/images/porysplash.gif b/resources/images/porysplash.gif new file mode 100644 index 00000000..900874d4 Binary files /dev/null and b/resources/images/porysplash.gif differ diff --git a/resources/text/script_template.txt b/resources/text/script_template.txt index 4b5134d1..bee6e56e 100644 --- a/resources/text/script_template.txt +++ b/resources/text/script_template.txt @@ -39,7 +39,7 @@ export function onBlockHoverCleared() { } // Called when the dimensions of the map are changed. -export function onMapResized(oldWidth, oldHeight, newWidth, newHeight) { +export function onMapResized(oldWidth, oldHeight, delta) { } diff --git a/src/config.cpp b/src/config.cpp index 7e7422c7..0e22840e 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -234,7 +234,7 @@ void KeyValueConfigBase::load() { continue; } - this->parseConfigKeyValue(match.captured("key").trimmed().toLower(), match.captured("value").trimmed()); + this->parseConfigKeyValue(match.captured("key").trimmed(), match.captured("value").trimmed()); } this->setUnreadKeys(); @@ -840,6 +840,10 @@ void ProjectConfig::parseConfigKeyValue(QString key, QString value) { } else { logWarn(QString("Invalid config key found in config file %1: '%2'").arg(this->getConfigFilepath()).arg(key)); } + } else if (key.startsWith("global_constant/")) { + this->globalConstants.insert(key.mid(QStringLiteral("global_constant/").length()), value); + } else if (key == "global_constants_filepaths") { + this->globalConstantsFilepaths = value.split(",", Qt::SkipEmptyParts); } else if (key == "prefabs_filepath") { this->prefabFilepath = value; } else if (key == "prefabs_import_prompted") { @@ -863,7 +867,7 @@ void ProjectConfig::parseConfigKeyValue(QString key, QString value) { } else if (key == "event_icon_path_heal") { this->eventIconPaths[Event::Group::Heal] = value; } else if (key.startsWith("pokemon_icon_path/")) { - this->pokemonIconPaths.insert(key.mid(QStringLiteral("pokemon_icon_path/").length()).toUpper(), value); + this->pokemonIconPaths.insert(key.mid(QStringLiteral("pokemon_icon_path/").length()), value); } else if (key == "collision_sheet_path") { this->collisionSheetPath = value; } else if (key == "collision_sheet_width") { @@ -970,12 +974,16 @@ QMap ProjectConfig::getKeyValueMap() { map.insert("event_icon_path_coord", this->eventIconPaths[Event::Group::Coord]); map.insert("event_icon_path_bg", this->eventIconPaths[Event::Group::Bg]); map.insert("event_icon_path_heal", this->eventIconPaths[Event::Group::Heal]); - for (auto i = this->pokemonIconPaths.cbegin(), end = this->pokemonIconPaths.cend(); i != end; i++){ - const QString path = i.value(); - if (!path.isEmpty()) map.insert("pokemon_icon_path/" + i.key(), path); + for (auto it = this->pokemonIconPaths.constBegin(); it != this->pokemonIconPaths.constEnd(); it++) { + const QString path = it.value(); + if (!path.isEmpty()) map.insert("pokemon_icon_path/" + it.key(), path); } - for (auto i = this->identifiers.cbegin(), end = this->identifiers.cend(); i != end; i++) { - map.insert("ident/"+defaultIdentifiers.value(i.key()).first, i.value()); + for (auto it = this->globalConstants.constBegin(); it != this->globalConstants.constEnd(); it++) { + map.insert("global_constant/" + it.key(), it.value()); + } + map.insert("global_constants_filepaths", this->globalConstantsFilepaths.join(",")); + for (auto it = this->identifiers.constBegin(); it != this->identifiers.constEnd(); it++) { + map.insert("ident/"+defaultIdentifiers.value(it.key()).first, it.value()); } map.insert("collision_sheet_path", this->collisionSheetPath); map.insert("collision_sheet_width", QString::number(this->collisionSheetSize.width())); diff --git a/src/core/maplayout.cpp b/src/core/maplayout.cpp index fb0f714c..c3e91ba3 100644 --- a/src/core/maplayout.cpp +++ b/src/core/maplayout.cpp @@ -189,46 +189,38 @@ void Layout::setBorderBlockData(Blockdata newBlockdata, bool enableScriptCallbac } } -void Layout::setDimensions(int newWidth, int newHeight, bool setNewBlockdata, bool enableScriptCallback) { +void Layout::setDimensions(int newWidth, int newHeight, bool setNewBlockdata) { if (setNewBlockdata) { setNewDimensionsBlockdata(newWidth, newHeight); } - - int oldWidth = this->width; - int oldHeight = this->height; this->width = newWidth; this->height = newHeight; - - if (enableScriptCallback && (oldWidth != newWidth || oldHeight != newHeight)) { - Scripting::cb_MapResized(oldWidth, oldHeight, newWidth, newHeight); - } - - emit dimensionsChanged(QSize(getWidth(), getHeight())); + emit dimensionsChanged(QSize(this->width, this->height)); } -void Layout::adjustDimensions(QMargins margins, bool setNewBlockdata) { - int newWidth = this->width + margins.left() + margins.right(); - int newHeight = this->height + margins.top() + margins.bottom(); +void Layout::adjustDimensions(const QMargins &margins, bool setNewBlockdata) { + int oldWidth = this->width; + int oldHeight = this->height; + this->width = oldWidth + margins.left() + margins.right(); + this->height = oldHeight + margins.top() + margins.bottom(); if (setNewBlockdata) { // Fill new blockdata Blockdata newBlockdata; - for (int y = 0; y < newHeight; y++) - for (int x = 0; x < newWidth; x++) { - if ((x < margins.left()) || (x >= newWidth - margins.right()) || (y < margins.top()) || (y >= newHeight - margins.bottom())) { + for (int y = 0; y < this->height; y++) + for (int x = 0; x < this->width; x++) { + if ((x < margins.left()) || (x >= this->width - margins.right()) || (y < margins.top()) || (y >= this->height - margins.bottom())) { newBlockdata.append(0); } else { - int index = (y - margins.top()) * this->width + (x - margins.left()); + int index = (y - margins.top()) * oldWidth + (x - margins.left()); newBlockdata.append(this->blockdata.value(index)); } } this->blockdata = newBlockdata; } - this->width = newWidth; - this->height = newHeight; - - emit dimensionsChanged(QSize(getWidth(), getHeight())); + Scripting::cb_MapResized(oldWidth, oldHeight, margins); + emit dimensionsChanged(QSize(this->width, this->height)); } void Layout::setBorderDimensions(int newWidth, int newHeight, bool setNewBlockdata, bool enableScriptCallback) { diff --git a/src/core/parseutil.cpp b/src/core/parseutil.cpp index da2a8f8e..80252c13 100644 --- a/src/core/parseutil.cpp +++ b/src/core/parseutil.cpp @@ -1,5 +1,6 @@ #include "log.h" #include "parseutil.h" +#include "loadingscreen.h" #include #include @@ -15,26 +16,8 @@ const QRegularExpression ParseUtil::re_poryScriptLabel("\\b(script)(\\((global|l const QRegularExpression ParseUtil::re_globalPoryScriptLabel("\\b(script)(\\((global)\\))?\\s*\\b(?