diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0d64777f..5e78fe5e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -21,20 +21,23 @@ 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.
- Redesigned the new map dialog, including better error checking and a collapsible section for header data.
- New maps/layouts are no longer saved automatically, and can be fully discarded by closing without saving.
- Map groups and ``MAPSEC`` names specified when creating a new map will be added automatically if they don't already exist.
+- Custom fields in JSON files that Porymap writes are no longer discarded.
- Edits to map connections now have Undo/Redo and can be viewed in exported timelapses.
- Changes to the "Mirror to Connecting Maps" setting will now be saved between sessions.
- A notice will be displayed when attempting to open the "Dynamic" map, rather than nothing happening.
- The base game version is now auto-detected if the project name contains only one of "emerald", "firered/leafgreen", or "ruby/sapphire".
-- The max encounter rate is now read from the project, rather than assuming the default value from RSE.
- It's now possible to cancel quitting if there are unsaved changes in sub-windows.
- The triple-layer metatiles setting can now be set automatically using a project constant.
- `Export Map Stitch Image` and `Export Map Timelapse Image` now show a preview of the full image/gif, not just the current map.
@@ -49,6 +52,10 @@ The **"Breaking Changes"** listed below are changes that have been made in the d
- `Script` dropdowns now autocomplete only with scripts from the current map, rather than every script in the project. The old behavior is available via a new setting.
- The options for `Encounter Type` and `Terrain Type` in the Tileset Editor are not hardcoded anymore, they're now read from the project.
- The `symbol_wild_encounters` setting was replaced; this value is now read from the project.
+- The max encounter rate is now read from the project, rather than assuming the default value from RSE.
+- `MAP_OFFSET_W` and `MAP_OFFSET_H` (used to limit the maximum map size) are now read from the project.
+- The rendered area of the map border is now limited to the maximum player view distance (prior to this it included two extra rows on the top and bottom).
+- An error message will now be shown when Porymap is unable to save changes (e.g. if Porymap doesn't have write permissions for your project).
- A project may now be opened even if it has no maps or map groups. A minimum of one map layout is required.
- The file extensions that are expected for `.png` and `.pal` data files and the extensions outputted when creating a new tileset can now be customized.
- Miscellaneous performance improvements, especially for opening projects.
@@ -57,12 +64,18 @@ The **"Breaking Changes"** listed below are changes that have been made in the d
- Fix `Add Region Map...` not updating the region map settings file.
- Fix some crashes on invalid region map tilesets.
- Improve error reporting for invalid region map editor settings.
+- Fix the region map editor's palette resetting between region maps.
+- Fix the region map editor's h-flip and v-flip settings being swapped.
- 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.
diff --git a/docsrc/manual/project-files.rst b/docsrc/manual/project-files.rst
index caac85c2..93715d86 100644
--- a/docsrc/manual/project-files.rst
+++ b/docsrc/manual/project-files.rst
@@ -97,6 +97,8 @@ In addition to these files, there are some specific symbol and macro names that
``define_pals_total``, ``NUM_PALS_TOTAL``,
``define_tiles_per_metatile``, ``NUM_TILES_PER_METATILE``, to determine if triple-layer metatiles are in use. Values other than 8 or 12 are ignored
``define_map_size``, ``MAX_MAP_DATA_SIZE``, to limit map dimensions
+ ``define_map_offset_width``, ``MAP_OFFSET_W``, to limit map dimensions
+ ``define_map_offset_height``, ``MAP_OFFSET_H``, to limit map dimensions
``define_mask_metatile``, ``MAPGRID_METATILE_ID_MASK``, optionally read to get settings on ``Maps`` tab
``define_mask_collision``, ``MAPGRID_COLLISION_MASK``, optionally read to get settings on ``Maps`` tab
``define_mask_elevation``, ``MAPGRID_ELEVATION_MASK``, optionally read to get settings on ``Maps`` tab
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/connectionslistitem.ui b/forms/connectionslistitem.ui
index bf04e8be..116da983 100644
--- a/forms/connectionslistitem.ui
+++ b/forms/connectionslistitem.ui
@@ -6,7 +6,7 @@
0
0
- 178
+ 188
157
@@ -20,7 +20,7 @@
.ConnectionsListItem { border-width: 1px; }
- QFrame::StyledPanel
+ QFrame::Shape::StyledPanel
-
@@ -65,7 +65,7 @@
-
- Remove this connection.
+ <html><head/><body><p>Remove this connection.</p></body></html>
...
@@ -79,28 +79,28 @@
-
- Where the connected map should be positioned relative to the current map.
+ <html><head/><body><p>Where the connected map should be positioned relative to the current map.</p></body></html>
-
- The name of the map to connect to the current map.
+ <html><head/><body><p>The name of the map to connect to the current map.</p></body></html>
-
- The number of spaces to move the connected map perpendicular to its connected direction.
+ <html><head/><body><p>The number of spaces to move the connected map perpendicular to its connected direction.</p></body></html>
-
- Open the connected map.
+ <html><head/><body><p>Open the connected map.</p></body></html>
...
diff --git a/forms/customattributesdialog.ui b/forms/customattributesdialog.ui
index b1f1ee4b..90dfba6e 100644
--- a/forms/customattributesdialog.ui
+++ b/forms/customattributesdialog.ui
@@ -33,7 +33,7 @@
-
- The key name for the new JSON field
+ <html><head/><body><p>The key name for the new JSON field</p></body></html>
true
@@ -50,7 +50,7 @@
-
- The data type for the new JSON field
+ <html><head/><body><p>The data type for the new JSON field</p></body></html>
@@ -70,7 +70,7 @@
- The value for the new JSON field
+ <html><head/><body><p>The value for the new JSON field</p></body></html>
diff --git a/forms/customscriptseditor.ui b/forms/customscriptseditor.ui
index e2efa2af..7db3b208 100644
--- a/forms/customscriptseditor.ui
+++ b/forms/customscriptseditor.ui
@@ -60,7 +60,7 @@
-
- Create a new Porymap script file with a default template
+ <html><head/><body><p>Create a new Porymap script file with a default template</p></body></html>
Create New Script...
@@ -74,7 +74,7 @@
-
- Add an existing script file to the list below
+ <html><head/><body><p>Add an existing script file to the list below</p></body></html>
Load Script...
@@ -88,7 +88,7 @@
-
- Refresh all loaded scripts to account for any recent edits
+ <html><head/><body><p>Refresh all loaded scripts to account for any recent edits</p></body></html>
Refresh Scripts
diff --git a/forms/loadingscreen.ui b/forms/loadingscreen.ui
new file mode 100644
index 00000000..d6f52430
--- /dev/null
+++ b/forms/loadingscreen.ui
@@ -0,0 +1,164 @@
+
+
+ LoadingScreen
+
+
+ Qt::ApplicationModal
+
+
+
+ 0
+ 0
+ 366
+ 255
+
+
+
+ BusyCursor
+
+
+ Qt::NoContextMenu
+
+
+ Form
+
+
+
-
+
+
+
+ 20
+ true
+
+
+
+ porymap
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 12
+
+
+
+ Version X.x.x
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+
+ QFrame::NoFrame
+
+
+ QFrame::Raised
+
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 64
+ 64
+
+
+
+ IMAGE
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+
+ QFrame::NoFrame
+
+
+ QFrame::Plain
+
+
+
-
+
+
+ Loading.....
+
+
+
+ -
+
+
+ TextLabel
+
+
+
+
+
+
+
+
+
+
+
diff --git a/forms/mainwindow.ui b/forms/mainwindow.ui
index 86f50047..bf0d2608 100644
--- a/forms/mainwindow.ui
+++ b/forms/mainwindow.ui
@@ -260,9 +260,6 @@
false
-
-
-
0
@@ -351,12 +348,6 @@
false
-
- QGraphicsView::ViewportAnchor::AnchorUnderMouse
-
-
- QGraphicsView::ViewportAnchor::AnchorUnderMouse
-
@@ -2386,7 +2377,7 @@
-
- If enabled, connections will automatically be updated on the connected map.
+ <html><head/><body><p>If enabled, the connected Emerge and/or Dive maps will be displayed with an opacity set using the slider.</p></body></html>
Mirror to Connecting Maps
@@ -2435,8 +2426,11 @@
-
+
+ false
+
- Open the selected Dive Map
+ <html><head/><body><p>Open the selected Dive Map</p></body></html>
...
@@ -2450,7 +2444,7 @@
-
- If enabled, the connected Emerge and/or Dive maps will be displayed with an opacity set using the slider.
+ <html><head/><body><p>If enabled, the connected Emerge and/or Dive maps will be displayed with an opacity set using the slider.</p></body></html>
Show Emerge/Dive Maps
@@ -2569,8 +2563,11 @@
-
+
+ false
+
- Open the selected Emerge Map
+ <html><head/><body><p>Open the selected Emerge Map</p></body></html>
...
@@ -2589,7 +2586,7 @@
Qt::Orientation::Horizontal
-
+
0
@@ -2863,6 +2860,7 @@
+
@@ -2887,8 +2885,10 @@
+
+
@@ -3076,45 +3076,6 @@
Ctrl+T
-
-
- true
-
-
-
- :/icons/sort_alphabet.ico:/icons/sort_alphabet.ico
-
-
- Sort by &Location
-
-
-
-
- true
-
-
-
- :/icons/sort_number.ico:/icons/sort_number.ico
-
-
- Sort by &Group
-
-
- Sort by Group
-
-
-
-
- true
-
-
-
- :/icons/sort_map.ico:/icons/sort_map.ico
-
-
- Sort by &Layout
-
-
About Porymap...
@@ -3310,9 +3271,14 @@
MapView
- QWidget
+ QGraphicsView
+
+ ConnectionsView
+ QGraphicsView
+
+
MapTree
QTreeView
@@ -3321,7 +3287,7 @@
NoScrollGraphicsView
QGraphicsView
-
+
MapListToolBar
diff --git a/forms/mapheaderform.ui b/forms/mapheaderform.ui
index 8faba290..08552e2c 100644
--- a/forms/mapheaderform.ui
+++ b/forms/mapheaderform.ui
@@ -7,7 +7,7 @@
0
0
407
- 349
+ 380
@@ -224,7 +224,11 @@
-
-
+
+
+ <html><head/><body><p>The name that will be displayed in-game for this Location. This name will be shared with any other map that has the same Location.</p></body></html>
+
+
diff --git a/forms/maplisttoolbar.ui b/forms/maplisttoolbar.ui
index 54eb48d0..07878f0a 100644
--- a/forms/maplisttoolbar.ui
+++ b/forms/maplisttoolbar.ui
@@ -32,7 +32,7 @@
-
- Add a new folder to the list.
+ <html><head/><body><p>Add a new folder to the list.</p></body></html>
@@ -73,7 +73,7 @@
-
- Expand all folders in the list.
+ <html><head/><body><p>Expand all folders in the list.</p></body></html>
@@ -93,7 +93,7 @@
-
- Collapse all folders in the list.
+ <html><head/><body><p>Collapse all folders in the list.</p></body></html>
@@ -113,7 +113,7 @@
-
- If enabled, folders may be renamed and items in the list may be rearranged.
+ <html><head/><body><p>If enabled, folders may be renamed and items in the list may be rearranged.</p></body></html>
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/newmapconnectiondialog.ui b/forms/newmapconnectiondialog.ui
index 9b3a3b6e..85aeec72 100644
--- a/forms/newmapconnectiondialog.ui
+++ b/forms/newmapconnectiondialog.ui
@@ -17,10 +17,10 @@
-
- QFrame::NoFrame
+ QFrame::Shape::NoFrame
- QFrame::Plain
+ QFrame::Shadow::Plain
@@ -45,7 +45,7 @@
-
- The name of the map to connect to the current map.
+ <html><head/><body><p>The name of the map to connect to the current map.</p></body></html>
@@ -59,7 +59,7 @@
-
- Where the connected map should be positioned relative to the current map.
+ <html><head/><body><p>Where the connected map should be positioned relative to the current map.</p></body></html>
@@ -82,10 +82,10 @@
-
- Qt::Horizontal
+ Qt::Orientation::Horizontal
- QDialogButtonBox::Cancel|QDialogButtonBox::Ok
+ QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok
diff --git a/forms/preferenceeditor.ui b/forms/preferenceeditor.ui
index 2ce37cbe..83de6f18 100644
--- a/forms/preferenceeditor.ui
+++ b/forms/preferenceeditor.ui
@@ -40,7 +40,7 @@
-
- If checked, a prompt to reload your project will appear if relevant project files are edited
+ <html><head/><body><p>If checked, a prompt to reload your project will appear if relevant project files are edited</p></body></html>
Monitor project files
@@ -50,7 +50,7 @@
-
- If checked, Porymap will automatically open your most recently opened project on startup
+ <html><head/><body><p>If checked, Porymap will automatically open your most recently opened project on startup</p></body></html>
Open recent project on launch
@@ -60,7 +60,7 @@
-
- If checked, Porymap will automatically alert you on startup if a new release is available
+ <html><head/><body><p>If checked, Porymap will automatically alert you on startup if a new release is available</p></body></html>
Automatically check for updates
@@ -112,7 +112,7 @@
-
- If checked, no warning will be shown when deleting an event that has an associated #define that may also be deleted.
+ <html><head/><body><p>If checked, no warning will be shown when deleting an event that has an associated #define that may also be deleted.</p></body></html>
Disable warning when deleting events with IDs
@@ -138,7 +138,7 @@
-
- If enabled, an event can be selected by clicking directly on the opaque pixels of its sprite. This may be preferable when events are overlapping.
+ <html><head/><body><p>If enabled, an event can be selected by clicking directly on the opaque pixels of its sprite. This may be preferable when events are overlapping.</p></body></html>
Select by clicking on sprite
@@ -148,7 +148,7 @@
-
- If enabled, an event can be selected by clicking anywhere within its sprite dimensions. This may be preferable for events with small or mostly transparent sprites.
+ <html><head/><body><p>If enabled, an event can be selected by clicking anywhere within its sprite dimensions. This may be preferable for events with small or mostly transparent sprites.</p></body></html>
Select by clicking within bounding rectangle
@@ -231,7 +231,7 @@
-
- The shell command for your preferred text editor (possibly an absolute path if the program doesn't exist in your PATH).
+ <html><head/><body><p>The shell command for your preferred text editor (possibly an absolute path if the program doesn't exist in your PATH).</p></body></html>
e.g. code %D
@@ -264,7 +264,7 @@
-
- The shell command for your preferred text editor to open a file to a specific line number (possibly an absolute path if the program doesn't exist in your PATH).
+ <html><head/><body><p>The shell command for your preferred text editor to open a file to a specific line number (possibly an absolute path if the program doesn't exist in your PATH).</p></body></html>
e.g. code --goto %F:%L
diff --git a/forms/projectsettingseditor.ui b/forms/projectsettingseditor.ui
index a088d87e..05598b8f 100644
--- a/forms/projectsettingseditor.ui
+++ b/forms/projectsettingseditor.ui
@@ -6,8 +6,8 @@
0
0
- 631
- 600
+ 642
+ 609
@@ -38,8 +38,8 @@
0
0
- 559
- 568
+ 570
+ 692
@@ -52,7 +52,7 @@
-
- Whether map script files should prefer using .pory
+ <html><head/><body><p>Whether map script files should prefer using .pory</p></body></html>
Use Poryscript
@@ -61,11 +61,24 @@
-
+
+ <html><head/><body><p>If enabled, Porymap will display wild encounter data on the Wild Pokémon tab.</p></body></html>
+
Show Wild Encounter Tables
+ -
+
+
+ <html><head/><body><p>If enabled, Porymap will not discard data like "connections_include_order" or "name_clone", which serve no purpose other than recreating the original game.</p></body></html>
+
+
+ Preserve data only needed to match the original game
+
+
+
@@ -89,7 +102,7 @@
-
- Restore the data in the prefabs file to the version defaults. Will create a new file if one doesn't exist.
+ <html><head/><body><p>Restore the data in the prefabs file to the version defaults. Will create a new file if one doesn't exist.</p></body></html>
Import Defaults
@@ -99,7 +112,7 @@
-
- The file that will be used to populate the Prefabs tab
+ <html><head/><body><p>The file that will be used to populate the Prefabs tab</p></body></html>
prefabs.json
@@ -138,7 +151,7 @@
-
- The image sheet that will be used to represent elevation and collision on the Collision tab
+ <html><head/><body><p>The image sheet that will be used to represent elevation and collision on the Collision tab</p></body></html>
true
@@ -166,7 +179,7 @@
-
- The maximum collision value represented with an icon on the image sheet
+ <html><head/><body><p>The maximum collision value represented with an icon on the image sheet</p></body></html>
@@ -187,7 +200,7 @@
-
- The maximum elevation value represented with an icon on the image sheet
+ <html><head/><body><p>The maximum elevation value represented with an icon on the image sheet</p></body></html>
@@ -260,7 +273,7 @@
-
- The icon that will be displayed on the Wild Pokémon tab for the above species
+ <html><head/><body><p>The icon that will be displayed on the Wild Pokémon tab for the above species</p></body></html>
true
@@ -270,6 +283,91 @@
+ -
+
+
+ Player View Distance
+
+
+
-
+
+
-
+
+
+ North
+
+
+
+ -
+
+
+ South
+
+
+
+ -
+
+
+ <html><head/><body><p>The distance (in pixels) that a player is able to see North of their character's position in-game. By default this is the distance from the center 16x16 to the edge of the 160 pixel tall GBA screen.</p></body></html>
+
+
+ 0
+
+
+
+ -
+
+
+ <html><head/><body><p>The distance (in pixels) that a player is able to see South of their character's position in-game. By default this is the distance from the center 16x16 to the edge of the 160 pixel tall GBA screen.</p></body></html>
+
+
+ 0
+
+
+
+
+
+ -
+
+
-
+
+
+ West
+
+
+
+ -
+
+
+ East
+
+
+
+ -
+
+
+ <html><head/><body><p>The distance (in pixels) that a player is able to see West of their character's position in-game. By default this is the distance from the center 16x16 to the edge of the 240 pixel wide GBA screen.</p></body></html>
+
+
+ 0
+
+
+
+ -
+
+
+ <html><head/><body><p>The distance (in pixels) that a player is able to see East of their character's position in-game. By default this is the distance from the center 16x16 to the edge of the 240 pixel wide GBA screen.</p></body></html>
+
+
+ 0
+
+
+
+
+
+
+
+
-
@@ -368,8 +466,8 @@
0
0
- 559
- 560
+ 570
+ 622
@@ -379,37 +477,6 @@
Map Data Defaults
- -
-
-
-
- 0
-
-
- 0
-
-
- 0
-
-
- 0
-
-
-
-
- -
-
-
- The default metatile value that will be used to fill new maps
-
-
- 0x
-
-
- 16
-
-
-
-
@@ -417,6 +484,50 @@
+ -
+
+
+ Width
+
+
+
+ -
+
+
+ <html><head/><body><p>The default elevation that will be used to fill new maps</p></body></html>
+
+
+
+ -
+
+
+ <html><head/><body><p>Whether a separate text.inc or text.pory file will be created for new maps, alongside the scripts file</p></body></html>
+
+
+ Create separate text file
+
+
+
+ -
+
+
+ <html><head/><body><p>The default layout width for new maps</p></body></html>
+
+
+ 1
+
+
+
+ -
+
+
+ <html><head/><body><p>The default layout height for new maps</p></body></html>
+
+
+ 1
+
+
+
-
@@ -424,13 +535,10 @@
- -
-
-
- Whether a separate text.inc or text.pory file will be created for new maps, alongside the scripts file
-
+
-
+
- Create separate text file
+ Collision
@@ -441,6 +549,20 @@
+ -
+
+
+ <html><head/><body><p>The default metatile value that will be used to fill new maps</p></body></html>
+
+
+
+ -
+
+
+ <html><head/><body><p>The default collision that will be used to fill new maps</p></body></html>
+
+
+
-
@@ -460,7 +582,7 @@
-
- A comma-separated list of metatile values that will be used to fill new map borders
+ <html><head/><body><p>A comma-separated list of metatile values that will be used to fill new map borders</p></body></html>
@@ -481,54 +603,30 @@
0
-
-
+
- The default metatile value that will be used for the top-left border metatile on new maps.
-
-
- 0x
-
-
- 16
+ <html><head/><body><p>The default metatile value that will be used for the top-left border metatile on new maps.</p></body></html>
-
-
+
- The default metatile value that will be used for the top-right border metatile on new maps.
-
-
- 0x
-
-
- 16
+ <html><head/><body><p>The default metatile value that will be used for the top-right border metatile on new maps.</p></body></html>
-
-
+
- The default metatile value that will be used for the bottom-left border metatile on new maps.
-
-
- 0x
-
-
- 16
+ <html><head/><body><p>The default metatile value that will be used for the bottom-left border metatile on new maps.</p></body></html>
-
-
+
- The default metatile value that will be used for the bottom-right border metatile on new maps.
-
-
- 0x
-
-
- 16
+ <html><head/><body><p>The default metatile value that will be used for the bottom-right border metatile on new maps.</p></body></html>
@@ -536,24 +634,28 @@
- -
-
-
- The default elevation that will be used to fill new maps
-
+
-
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
- -
-
+
-
+
- Collision
-
-
-
- -
-
-
- The default collision that will be used to fill new maps
+ Height
@@ -604,7 +706,7 @@
-
- The mask used to read/write metatile IDs in map data.
+ <html><head/><body><p>The mask used to read/write metatile IDs in map data.</p></body></html>
@@ -618,7 +720,7 @@
-
- The mask used to read/write collision values in map data.
+ <html><head/><body><p>The mask used to read/write collision values in map data.</p></body></html>
@@ -632,7 +734,7 @@
-
- The mask used to read/write elevation values in map data.
+ <html><head/><body><p>The mask used to read/write elevation values in map data.</p></body></html>
@@ -661,7 +763,7 @@
-
- Whether "Allow Running", "Allow Biking" and "Allow Dig & Escape Rope" are default options for Map Headers
+ <html><head/><body><p>Whether "Allow Running", "Allow Biking" and "Allow Dig & Escape Rope" are default options for Map Headers</p></body></html>
Enable 'Allow Running/Biking/Escaping'
@@ -671,7 +773,7 @@
-
- Whether "Floor Number" is a default option for Map Headers
+ <html><head/><body><p>Whether "Floor Number" is a default option for Map Headers</p></body></html>
Enable 'Floor Number'
@@ -681,7 +783,7 @@
-
- Whether the dimensions of the border can be changed. If not set, all borders are 2x2
+ <html><head/><body><p>Whether the dimensions of the border can be changed. If not set, all borders are 2x2</p></body></html>
Enable Custom Border Size
@@ -741,7 +843,7 @@
0
0
- 559
+ 570
798
@@ -760,7 +862,11 @@
-
-
+
+
+ <html><head/><body><p>The default primary tileset to use for new maps/layouts.</p></body></html>
+
+
-
@@ -770,7 +876,11 @@
-
-
+
+
+ <html><head/><body><p>The default secondary tileset to use for new maps/layouts.</p></body></html>
+
+
@@ -784,7 +894,7 @@
-
- Fully transparent pixels will be rendered as black pixels (the Pokémon games do this by default)
+ <html><head/><body><p>Fully transparent pixels will be rendered as black pixels (the Pokémon games do this by default)</p></body></html>
Render as black
@@ -794,7 +904,7 @@
-
- Fully transparent pixels will be rendered using the first palette color (this the default behavior for the GBA)
+ <html><head/><body><p>Fully transparent pixels will be rendered using the first palette color (this the default behavior for the GBA)</p></body></html>
Render using first palette color
@@ -820,7 +930,7 @@
-
- This raw tile value will be used to fill the unused bottom layer of Normal metatiles
+ <html><head/><body><p>This raw tile value will be used to fill the unused bottom layer of Normal metatiles</p></body></html>
@@ -834,7 +944,7 @@
-
- This raw tile value will be used to fill the unused top layer of Covered metatiles
+ <html><head/><body><p>This raw tile value will be used to fill the unused top layer of Covered metatiles</p></body></html>
@@ -848,7 +958,7 @@
-
- This raw tile value will be used to fill the unused middle layer of Split metatiles
+ <html><head/><body><p>This raw tile value will be used to fill the unused middle layer of Split metatiles</p></body></html>
@@ -892,22 +1002,19 @@
-
- The mask used to read/write Layer Type from the metatile's attributes data. If 0, this attribute is disabled.
+ <html><head/><body><p>The mask used to read/write Layer Type from the metatile's attributes data. If 0, this attribute is disabled.</p></body></html>
-
- The mask used to read/write Metatile Behavior from the metatile's attributes data. If 0, this attribute is disabled.
+ <html><head/><body><p>The mask used to read/write Metatile Behavior from the metatile's attributes data. If 0, this attribute is disabled.</p></body></html>
-
-
- The number of bytes used per metatile for metatile attributes
-
Attributes size (in bytes)
@@ -938,6 +1045,9 @@
-
+
+ <html><head/><body><p>If checked, metatiles will be interpreted as having 3 layers of 4 tiles each (12 tiles total) as opposed to the default 2 layers of 4 tiles each (8 total).</p></body></html>
+
Enable Triple Layer Metatiles
@@ -946,7 +1056,7 @@
-
- The mask used to read/write Terrain Type from the metatile's attributes data. If 0, this attribute is disabled.
+ <html><head/><body><p>The mask used to read/write Terrain Type from the metatile's attributes data. If 0, this attribute is disabled.</p></body></html>
@@ -973,7 +1083,7 @@
-
- The mask used to read/write Encounter Type from the metatile's attributes data. If 0, this attribute is disabled.
+ <html><head/><body><p>The mask used to read/write Encounter Type from the metatile's attributes data. If 0, this attribute is disabled.</p></body></html>
@@ -986,6 +1096,9 @@
-
+
+ <html><head/><body><p>The number of bytes each metatile has for metatile attributes. This is the metadata about each metatile like behvior, layer type, etc.</p></body></html>
+
false
@@ -1026,7 +1139,7 @@
-
- Whether the C data outputted for new tilesets will include the "callback" field
+ <html><head/><body><p>Whether the C data outputted for new tilesets will include the "callback" field</p></body></html>
Output 'callback' field
@@ -1036,7 +1149,7 @@
-
- Whether the C data outputted for new tilesets will include the "isCompressed" field
+ <html><head/><body><p>Whether the C data outputted for new tilesets will include the "isCompressed" field</p></body></html>
Output 'isCompressed' field
@@ -1083,8 +1196,8 @@
0
0
- 559
- 788
+ 570
+ 840
@@ -1111,7 +1224,7 @@
-
- The icon that will be used to represent Warp events
+ <html><head/><body><p>The icon that will be used to represent Warp events</p></body></html>
true
@@ -1121,7 +1234,7 @@
-
- The icon that will be used to represent Heal Location events
+ <html><head/><body><p>The icon that will be used to represent Heal Location events</p></body></html>
true
@@ -1145,7 +1258,7 @@
-
- The icon that will be used to represent Object events that don't have their own sprite
+ <html><head/><body><p>The icon that will be used to represent Object events that don't have their own sprite</p></body></html>
true
@@ -1162,7 +1275,7 @@
-
- The icon that will be used to represent Trigger events
+ <html><head/><body><p>The icon that will be used to represent Trigger events</p></body></html>
true
@@ -1172,7 +1285,7 @@
-
- The icon that will be used to represent BG events
+ <html><head/><body><p>The icon that will be used to represent BG events</p></body></html>
true
@@ -1246,7 +1359,7 @@
-
- Remove the current text from the list
+ <html><head/><body><p>Remove the current text from the list</p></body></html>
...
@@ -1270,7 +1383,7 @@
-
- If checked, Warp Events will not display a warning about incompatible metatile behaviors
+ <html><head/><body><p>If checked, Warp Events will not display a warning about incompatible metatile behaviors</p></body></html>
Disable Warning
@@ -1281,9 +1394,9 @@
-
-
+
- Metatile Behaviors on this list won't trigger warnings for Warp Events
+ <html><head/><body><p>Metatile Behaviors on this list won't trigger warnings for Warp Events</p></body></html>
true
@@ -1299,7 +1412,7 @@
-
- Add the current text to the list
+ <html><head/><body><p>Add the current text to the list</p></body></html>
...
@@ -1465,23 +1578,25 @@
0
0
- 559
- 490
+ 570
+ 499
-
-
-
-
-
- ...
+
+
-
+
+
+ Qt::Orientation::Horizontal
-
-
- :/icons/help.ico:/icons/help.ico
+
+
+ 40
+ 20
+
-
+
- -
+
-
@@ -1512,8 +1627,8 @@
0
0
- 533
- 428
+ 544
+ 338
@@ -1533,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
+
+
+
+ -
+
+
@@ -1554,12 +1697,12 @@
0
0
- 559
- 490
+ 570
+ 499
-
- -
+
+
-
...
@@ -1570,7 +1713,7 @@
- -
+
-
@@ -1601,8 +1744,8 @@
0
0
- 533
- 428
+ 544
+ 421
@@ -1622,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
+
+
+
+
+ -
+
+
@@ -1651,6 +1824,11 @@
QSpinBox
+
+ NoScrollTextEdit
+ QTextEdit
+
+
UIntSpinBox
QAbstractSpinBox
diff --git a/forms/regionmappropertiesdialog.ui b/forms/regionmappropertiesdialog.ui
index 80e7020a..88b465f4 100644
--- a/forms/regionmappropertiesdialog.ui
+++ b/forms/regionmappropertiesdialog.ui
@@ -21,7 +21,7 @@
- QFormLayout::AllNonFixedFieldsGrow
+ QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow
-
@@ -33,7 +33,7 @@
-
- A nickname for this region map that will differentiate it from others (should be unique).
+ <html><head/><body><p>A nickname for this region map that will differentiate it from others (should be unique).</p></body></html>
@@ -131,7 +131,7 @@
- The height of the tilemap
+ <html><head/><body><p>The height of the tilemap</p></body></html>
255
@@ -148,10 +148,10 @@
-
- QFrame::NoFrame
+ QFrame::Shape::NoFrame
- QFrame::Raised
+ QFrame::Shadow::Raised
@@ -218,10 +218,10 @@
<html><head/><body><p>Path to the tilemap binary relative to the project root.</p></body></html>
- QFrame::NoFrame
+ QFrame::Shape::NoFrame
- QFrame::Raised
+ QFrame::Shadow::Raised
@@ -269,10 +269,10 @@
-
- QFrame::NoFrame
+ QFrame::Shape::NoFrame
- QFrame::Plain
+ QFrame::Shadow::Plain
@@ -392,10 +392,10 @@
-
- QFrame::NoFrame
+ QFrame::Shape::NoFrame
- QFrame::Raised
+ QFrame::Shadow::Raised
@@ -487,7 +487,7 @@
-
- Qt::Horizontal
+ Qt::Orientation::Horizontal
@@ -517,7 +517,7 @@
-
- Qt::Horizontal
+ Qt::Orientation::Horizontal
@@ -590,7 +590,7 @@
-
- Qt::Horizontal
+ Qt::Orientation::Horizontal
@@ -617,7 +617,7 @@
-
- Qt::Horizontal
+ Qt::Orientation::Horizontal
@@ -646,7 +646,7 @@
-
- Qt::Horizontal
+ Qt::Orientation::Horizontal
@@ -659,10 +659,10 @@
-
- Qt::Horizontal
+ Qt::Orientation::Horizontal
- QDialogButtonBox::Cancel|QDialogButtonBox::Ok
+ QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok
diff --git a/forms/wildmonchart.ui b/forms/wildmonchart.ui
index 488e066e..8d6668e4 100644
--- a/forms/wildmonchart.ui
+++ b/forms/wildmonchart.ui
@@ -145,7 +145,7 @@
false
- QComboBox::AdjustToMinimumContentsLength
+ QComboBox::AdjustToMinimumContentsLengthWithIcon
8
diff --git a/include/config.h b/include/config.h
index 4bfc2bc5..3f441229 100644
--- a/include/config.h
+++ b/include/config.h
@@ -14,19 +14,20 @@
#include
#include "events.h"
+#include "gridsettings.h"
-static const QVersionNumber porymapVersion = QVersionNumber::fromString(PORYMAP_VERSION);
+extern const QVersionNumber porymapVersion;
-// In both versions the default new map border is a generic tree
-#define DEFAULT_BORDER_RSE (QList{0x1D4, 0x1D5, 0x1DC, 0x1DD})
-#define DEFAULT_BORDER_FRLG (QList{0x14, 0x15, 0x1C, 0x1D})
+// Distance in pixels from the edge of a GBA screen (240x160) to the center 16x16 pixels.
+#define GBA_H_DIST_TO_CENTER ((240-16)/2)
+#define GBA_V_DIST_TO_CENTER ((160-16)/2)
#define CONFIG_BACKWARDS_COMPATABILITY
class KeyValueConfigBase
{
public:
- void save();
+ bool save();
void load();
virtual ~KeyValueConfigBase();
virtual void reset() = 0;
@@ -36,9 +37,11 @@ protected:
virtual QMap getKeyValueMap() = 0;
virtual void init() = 0;
virtual void setUnreadKeys() = 0;
- bool getConfigBool(QString key, QString value);
- int getConfigInteger(QString key, QString value, int min = INT_MIN, int max = INT_MAX, int defaultValue = 0);
- uint32_t getConfigUint32(QString key, QString value, uint32_t min = 0, uint32_t max = UINT_MAX, uint32_t defaultValue = 0);
+
+ static bool getConfigBool(const QString &key, const QString &value);
+ static int getConfigInteger(const QString &key, const QString &value, int min = INT_MIN, int max = INT_MAX, int defaultValue = 0);
+ static uint32_t getConfigUint32(const QString &key, const QString &value, uint32_t min = 0, uint32_t max = UINT_MAX, uint32_t defaultValue = 0);
+ static QColor getConfigColor(const QString &key, const QString &value, const QColor &defaultValue = Qt::black);
};
class PorymapConfig: public KeyValueConfigBase
@@ -92,6 +95,7 @@ public:
this->rateLimitTimes.clear();
this->eventSelectionShapeMode = QGraphicsPixmapItem::MaskShape;
this->shownInGameReloadMessage = false;
+ this->gridSettings = GridSettings();
}
void addRecentProject(QString project);
void setRecentProjects(QStringList projects);
@@ -156,6 +160,7 @@ public:
QByteArray newMapDialogGeometry;
QByteArray newLayoutDialogGeometry;
bool shownInGameReloadMessage;
+ GridSettings gridSettings;
protected:
virtual QString getConfigFilepath() override;
@@ -214,6 +219,8 @@ enum ProjectIdentifier {
define_pals_total,
define_tiles_per_metatile,
define_map_size,
+ define_map_offset_width,
+ define_map_offset_height,
define_mask_metatile,
define_mask_collision,
define_mask_elevation,
@@ -317,18 +324,20 @@ public:
this->defaultMetatileId = 1;
this->defaultElevation = 3;
this->defaultCollision = 0;
+ this->defaultMapSize = QSize(20,20);
this->defaultPrimaryTileset = "gTileset_General";
this->prefabFilepath = QString();
this->prefabImportPrompted = false;
this->tilesetsHaveCallback = true;
this->tilesetsHaveIsCompressed = true;
this->setTransparentPixelsBlack = true;
+ this->preserveMatchingOnlyData = false;
this->filePaths.clear();
this->eventIconPaths.clear();
this->pokemonIconPaths.clear();
this->collisionSheetPath = QString();
- this->collisionSheetWidth = 2;
- this->collisionSheetHeight = 16;
+ this->collisionSheetSize = QSize(2, 16);
+ this->playerViewDistance = QMargins(GBA_H_DIST_TO_CENTER, GBA_V_DIST_TO_CENTER, GBA_H_DIST_TO_CENTER, GBA_V_DIST_TO_CENTER);
this->blockMetatileIdMask = 0x03FF;
this->blockCollisionMask = 0x0C00;
this->blockElevationMask = 0xF000;
@@ -337,6 +346,8 @@ public:
this->unusedTileSplit = 0x0000;
this->maxEventsPerGroup = 255;
this->forcedMajorVersion = 0;
+ this->globalConstantsFilepaths.clear();
+ this->globalConstants.clear();
this->identifiers.clear();
this->readKeys.clear();
}
@@ -382,6 +393,7 @@ public:
uint16_t defaultMetatileId;
uint16_t defaultElevation;
uint16_t defaultCollision;
+ QSize defaultMapSize;
QList newMapBorderMetatileIds;
QString defaultPrimaryTileset;
QString defaultSecondaryTileset;
@@ -390,6 +402,7 @@ public:
bool tilesetsHaveCallback;
bool tilesetsHaveIsCompressed;
bool setTransparentPixelsBlack;
+ bool preserveMatchingOnlyData;
int metatileAttributesSize;
uint32_t metatileBehaviorMask;
uint32_t metatileTerrainTypeMask;
@@ -403,11 +416,13 @@ public:
uint16_t unusedTileSplit;
bool mapAllowFlagsEnabled;
QString collisionSheetPath;
- int collisionSheetWidth;
- int collisionSheetHeight;
+ QSize collisionSheetSize;
+ QMargins playerViewDistance;
QList warpBehaviors;
int maxEventsPerGroup;
int forcedMajorVersion;
+ QStringList globalConstantsFilepaths;
+ QMap globalConstants;
protected:
virtual QString getConfigFilepath() override;
diff --git a/include/core/editcommands.h b/include/core/editcommands.h
index 9a54063c..5dc4bf0c 100644
--- a/include/core/editcommands.h
+++ b/include/core/editcommands.h
@@ -14,7 +14,7 @@ class Map;
class Layout;
class Blockdata;
class Event;
-class DraggablePixmapItem;
+class EventPixmapItem;
class Editor;
enum CommandId {
diff --git a/include/core/events.h b/include/core/events.h
index 85116860..9da9b531 100644
--- a/include/core/events.h
+++ b/include/core/events.h
@@ -10,6 +10,7 @@
#include
#include "orderedjson.h"
+#include "parseutil.h"
class Project;
@@ -18,7 +19,7 @@ class EventFrame;
class ObjectFrame;
class CloneObjectFrame;
class WarpFrame;
-class DraggablePixmapItem;
+class EventPixmapItem;
class Event;
class ObjectEvent;
@@ -78,9 +79,13 @@ public:
None,
};
- // all event groups except warps have IDs that start at 1
+ // Normally we refer to events using their index in the list of that group's events.
+ // Object events often get referred to with a special "local ID", which is really just the index + 1.
+ // We use this local ID number in the index spinner for object events instead of the actual index.
+ // This distinction is only really important for object and warp events, because these are normally
+ // the only two groups of events that need to be explicitly referred to.
static int getIndexOffset(Event::Group group) {
- return (group == Event::Group::Warp) ? 0 : 1;
+ return (group == Event::Group::Object) ? 1 : 0;
}
static Event::Group typeToGroup(Event::Type type) {
@@ -139,23 +144,22 @@ public:
Event::Type getEventType() const { return this->eventType; }
virtual OrderedJson::object buildEventJson(Project *project) = 0;
- virtual bool loadFromJson(const QJsonObject &json, Project *project) = 0;
+ virtual bool loadFromJson(QJsonObject json, Project *project) = 0;
virtual void setDefaultValues(Project *project);
virtual QSet getExpectedFields() = 0;
- void readCustomAttributes(const QJsonObject &json);
- void addCustomAttributesTo(OrderedJson::object *obj) const;
- const QMap getCustomAttributes() const { return this->customAttributes; }
- void setCustomAttributes(const QMap newCustomAttributes) { this->customAttributes = newCustomAttributes; }
- virtual void loadPixmap(Project *project);
+ QJsonObject getCustomAttributes() const { return this->customAttributes; }
+ void setCustomAttributes(const QJsonObject &newCustomAttributes) { this->customAttributes = newCustomAttributes; }
+
+ virtual QPixmap loadPixmap(Project *project);
void setPixmap(QPixmap newPixmap) { this->pixmap = newPixmap; }
QPixmap getPixmap() const { return this->pixmap; }
- void setPixmapItem(DraggablePixmapItem *item);
- DraggablePixmapItem *getPixmapItem() const { return this->pixmapItem; }
+ void setPixmapItem(EventPixmapItem *item);
+ EventPixmapItem *getPixmapItem() const { return this->pixmapItem; }
void setUsesDefaultPixmap(bool newUsesDefaultPixmap) { this->usesDefaultPixmap = newUsesDefaultPixmap; }
bool getUsesDefaultPixmap() const { return this->usesDefaultPixmap; }
@@ -191,12 +195,16 @@ protected:
// When deleting events like this we want to warn the user that the #define may also be deleted.
QString idName;
- QMap customAttributes;
+ QJsonObject customAttributes;
QPixmap pixmap;
- DraggablePixmapItem *pixmapItem = nullptr;
+ EventPixmapItem *pixmapItem = nullptr;
QPointer eventFrame;
+
+ static QString readString(QJsonObject *object, const QString &key) { return ParseUtil::jsonToQString(object->take(key)); }
+ static int readInt(QJsonObject *object, const QString &key) { return ParseUtil::jsonToInt(object->take(key)); }
+ static bool readBool(QJsonObject *object, const QString &key) { return ParseUtil::jsonToBool(object->take(key)); }
};
@@ -219,13 +227,13 @@ public:
virtual EventFrame *createEventFrame() override;
virtual OrderedJson::object buildEventJson(Project *project) override;
- virtual bool loadFromJson(const QJsonObject &json, Project *project) override;
+ virtual bool loadFromJson(QJsonObject json, Project *project) override;
virtual void setDefaultValues(Project *project) override;
virtual QSet getExpectedFields() override;
- virtual void loadPixmap(Project *project) override;
+ virtual QPixmap loadPixmap(Project *project) override;
void setGfx(QString newGfx) { this->gfx = newGfx; }
QString getGfx() const { return this->gfx; }
@@ -286,23 +294,23 @@ public:
virtual EventFrame *createEventFrame() override;
virtual OrderedJson::object buildEventJson(Project *project) override;
- virtual bool loadFromJson(const QJsonObject &json, Project *project) override;
+ virtual bool loadFromJson(QJsonObject json, Project *project) override;
virtual void setDefaultValues(Project *project) override;
virtual QSet getExpectedFields() override;
- virtual void loadPixmap(Project *project) override;
+ virtual QPixmap loadPixmap(Project *project) override;
void setTargetMap(QString newTargetMap) { this->targetMap = newTargetMap; }
QString getTargetMap() const { return this->targetMap; }
- void setTargetID(int newTargetID) { this->targetID = newTargetID; }
- int getTargetID() const { return this->targetID; }
+ void setTargetID(QString newTargetID) { this->targetID = newTargetID; }
+ QString getTargetID() const { return this->targetID; }
private:
QString targetMap;
- int targetID = 0;
+ QString targetID;
};
@@ -324,7 +332,7 @@ public:
virtual EventFrame *createEventFrame() override;
virtual OrderedJson::object buildEventJson(Project *project) override;
- virtual bool loadFromJson(const QJsonObject &json, Project *project) override;
+ virtual bool loadFromJson(QJsonObject json, Project *project) override;
virtual void setDefaultValues(Project *project) override;
@@ -361,7 +369,7 @@ public:
virtual EventFrame *createEventFrame() override = 0;
virtual OrderedJson::object buildEventJson(Project *project) override = 0;
- virtual bool loadFromJson(const QJsonObject &json, Project *project) override = 0;
+ virtual bool loadFromJson(QJsonObject json, Project *project) override = 0;
virtual void setDefaultValues(Project *project) override = 0;
@@ -389,7 +397,7 @@ public:
virtual EventFrame *createEventFrame() override;
virtual OrderedJson::object buildEventJson(Project *project) override;
- virtual bool loadFromJson(const QJsonObject &json, Project *project) override;
+ virtual bool loadFromJson(QJsonObject json, Project *project) override;
virtual void setDefaultValues(Project *project) override;
@@ -429,7 +437,7 @@ public:
virtual EventFrame *createEventFrame() override;
virtual OrderedJson::object buildEventJson(Project *project) override;
- virtual bool loadFromJson(const QJsonObject &json, Project *project) override;
+ virtual bool loadFromJson(QJsonObject json, Project *project) override;
virtual void setDefaultValues(Project *project) override;
@@ -460,7 +468,7 @@ public:
virtual EventFrame *createEventFrame() override = 0;
virtual OrderedJson::object buildEventJson(Project *project) override = 0;
- virtual bool loadFromJson(const QJsonObject &json, Project *project) override = 0;
+ virtual bool loadFromJson(QJsonObject json, Project *project) override = 0;
virtual void setDefaultValues(Project *project) override = 0;
@@ -487,7 +495,7 @@ public:
virtual EventFrame *createEventFrame() override;
virtual OrderedJson::object buildEventJson(Project *project) override;
- virtual bool loadFromJson(const QJsonObject &json, Project *project) override;
+ virtual bool loadFromJson(QJsonObject json, Project *project) override;
virtual void setDefaultValues(Project *project) override;
@@ -522,7 +530,7 @@ public:
virtual EventFrame *createEventFrame() override;
virtual OrderedJson::object buildEventJson(Project *project) override;
- virtual bool loadFromJson(const QJsonObject &json, Project *project) override;
+ virtual bool loadFromJson(QJsonObject json, Project *project) override;
virtual void setDefaultValues(Project *project) override;
@@ -567,7 +575,7 @@ public:
virtual EventFrame *createEventFrame() override;
virtual OrderedJson::object buildEventJson(Project *project) override;
- virtual bool loadFromJson(const QJsonObject &json, Project *project) override;
+ virtual bool loadFromJson(QJsonObject json, Project *project) override;
virtual void setDefaultValues(Project *project) override;
@@ -599,12 +607,15 @@ public:
virtual EventFrame *createEventFrame() override;
virtual OrderedJson::object buildEventJson(Project *project) override;
- virtual bool loadFromJson(const QJsonObject &, Project *) override;
+ virtual bool loadFromJson(QJsonObject json, Project *project) override;
virtual void setDefaultValues(Project *project) override;
virtual QSet getExpectedFields() override;
+ void setHostMapName(QString newHostMapName) { this->hostMapName = newHostMapName; }
+ QString getHostMapName() const;
+
void setRespawnMapName(QString newRespawnMapName) { this->respawnMapName = newRespawnMapName; }
QString getRespawnMapName() const { return this->respawnMapName; }
@@ -614,6 +625,7 @@ public:
private:
QString respawnMapName;
QString respawnNPC;
+ QString hostMapName; // Only needed if the host map fails to load.
};
diff --git a/include/core/map.h b/include/core/map.h
index 9a4c2185..84791fa3 100644
--- a/include/core/map.h
+++ b/include/core/map.h
@@ -22,10 +22,6 @@
#define MAX_BORDER_WIDTH 255
#define MAX_BORDER_HEIGHT 255
-// Number of metatiles to draw out from edge of map. Could allow modification of this in the future.
-// porymap will reflect changes to it, but the value is hard-coded in the projects at the moment
-#define BORDER_DISTANCE 7
-
class LayoutPixmapItem;
class CollisionPixmapItem;
class BorderMetatilesPixmapItem;
@@ -76,6 +72,8 @@ public:
void resetEvents();
QList getEvents(Event::Group group = Event::Group::None) const;
Event* getEvent(Event::Group group, int index) const;
+ Event* getEvent(Event::Group group, const QString &idName) const;
+ QStringList getEventIdNames(Event::Group group) const;
int getNumEvents(Event::Group group = Event::Group::None) const;
QStringList getScriptLabels(Event::Group group = Event::Group::None);
QString getScriptsFilePath() const;
@@ -87,6 +85,7 @@ public:
void deleteConnections();
QList getConnections() const { return m_connections; }
+ MapConnection* getConnection(const QString &direction) const;
void removeConnection(MapConnection *);
void addConnection(MapConnection *);
void loadConnection(MapConnection *);
@@ -100,8 +99,8 @@ public:
bool hasUnsavedChanges() const;
void pruneEditHistory();
- void setCustomAttributes(const QMap &attributes) { m_customAttributes = attributes; }
- QMap customAttributes() const { return m_customAttributes; }
+ void setCustomAttributes(const QJsonObject &attributes) { m_customAttributes = attributes; }
+ QJsonObject customAttributes() const { return m_customAttributes; }
private:
QString m_name;
@@ -110,7 +109,7 @@ private:
QString m_sharedScriptsMap = "";
QStringList m_scriptsFileLabels;
- QMap m_customAttributes;
+ QJsonObject m_customAttributes;
MapHeader *m_header = nullptr;
Layout *m_layout = nullptr;
diff --git a/include/core/mapconnection.h b/include/core/mapconnection.h
index 496e884f..5df071bd 100644
--- a/include/core/mapconnection.h
+++ b/include/core/mapconnection.h
@@ -5,6 +5,7 @@
#include
#include
#include
+#include
class Project;
class Map;
@@ -34,6 +35,9 @@ public:
int offset() const { return m_offset; }
void setOffset(int offset, bool mirror = true);
+ QJsonObject customData() const { return m_customData; }
+ void setCustomData(const QJsonObject &customData) { m_customData = customData; }
+
MapConnection* findMirror();
MapConnection* createMirror();
@@ -55,6 +59,7 @@ private:
QString m_targetMapName;
QString m_direction;
int m_offset;
+ QJsonObject m_customData;
void markMapEdited();
Map* getMap(const QString& mapName) const;
diff --git a/include/core/maplayout.h b/include/core/maplayout.h
index 3b6bbf12..3e67af18 100644
--- a/include/core/maplayout.h
+++ b/include/core/maplayout.h
@@ -42,6 +42,8 @@ public:
Tileset *tileset_primary = nullptr;
Tileset *tileset_secondary = nullptr;
+ QJsonObject customData;
+
Blockdata blockdata;
QImage image;
@@ -94,8 +96,8 @@ public:
int getHeight() const { return height; }
int getBorderWidth() const { return border_width; }
int getBorderHeight() const { return border_height; }
- int getBorderDrawWidth() const;
- int getBorderDrawHeight() const;
+ QMargins getBorderMargins() const;
+ QRect getVisibleRect() const;
bool isWithinBounds(int x, int y) const;
bool isWithinBounds(const QRect &rect) const;
@@ -105,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();
@@ -114,9 +116,12 @@ public:
void clearBorderCache();
void cacheBorder();
- void setClean();
bool hasUnsavedChanges() const;
+ bool save(const QString &root);
+ bool saveBorder(const QString &root);
+ bool saveBlockdata(const QString &root);
+
bool layoutBlockChanged(int i, const Blockdata &cache);
uint16_t getBorderMetatileId(int x, int y);
@@ -141,6 +146,7 @@ public:
private:
void setNewDimensionsBlockdata(int newWidth, int newHeight);
void setNewBorderDimensionsBlockdata(int newWidth, int newHeight);
+ bool writeBlockdata(const QString &path, const Blockdata &blockdata) const;
static int getBorderDrawDistance(int dimension, qreal minimum);
diff --git a/include/core/paletteutil.h b/include/core/paletteutil.h
index ce221026..34e9ae3f 100644
--- a/include/core/paletteutil.h
+++ b/include/core/paletteutil.h
@@ -7,7 +7,7 @@
namespace PaletteUtil {
QList parse(QString filepath, bool *error);
- void writeJASC(QString filepath, QVector colors, int offset, int nColors);
+ bool writeJASC(const QString &filepath, const QVector &colors, int offset, int nColors);
}
#endif // PALETTEUTIL_H
diff --git a/include/core/parseutil.h b/include/core/parseutil.h
index 4c19a27c..aae86a88 100644
--- a/include/core/parseutil.h
+++ b/include/core/parseutil.h
@@ -43,7 +43,7 @@ class ParseUtil
{
public:
ParseUtil();
- void set_root(const QString &dir);
+ void setRoot(const QString &dir) { this->root = dir; }
static QString readTextFile(const QString &path, QString *error = nullptr);
bool cacheFile(const QString &path, QString *error = nullptr);
void clearFileCache() { this->fileCache.clear(); }
@@ -55,10 +55,14 @@ 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);
- tsl::ordered_map> readCStructs(const QString &, const QString & = "", const QHash& = {});
+ 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&);
bool tryParseJsonFile(QJsonDocument *out, const QString &filepath, QString *error = nullptr);
@@ -90,8 +94,20 @@ 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;
+
+ 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);
@@ -100,11 +116,11 @@ private:
QString createErrorMessage(const QString &message, const QString &expression);
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);
diff --git a/include/core/regionmap.h b/include/core/regionmap.h
index 18362663..c8afb1b2 100644
--- a/include/core/regionmap.h
+++ b/include/core/regionmap.h
@@ -56,8 +56,8 @@ public:
bool loadLayout(poryjson::Json);
bool loadEntries();
- void setEntries(QMap *entries) { this->region_map_entries = entries; }
- void setEntries(const QMap &entries) { *(this->region_map_entries) = entries; }
+ void setEntries(QHash *entries) { this->region_map_entries = entries; }
+ void setEntries(const QHash &entries) { *(this->region_map_entries) = entries; }
void clearEntries() { this->region_map_entries->clear(); }
MapSectionEntry getEntry(QString section);
void setEntry(QString section, MapSectionEntry entry);
@@ -151,7 +151,7 @@ signals:
void mapNeedsDisplaying();
private:
- QMap *region_map_entries = nullptr;
+ QHash *region_map_entries = nullptr;
QString alias = "";
diff --git a/include/core/regionmapeditcommands.h b/include/core/regionmapeditcommands.h
index 05b12bc3..e47fdb7b 100644
--- a/include/core/regionmapeditcommands.h
+++ b/include/core/regionmapeditcommands.h
@@ -153,7 +153,7 @@ private:
/// ClearEntries
class ClearEntries : public QUndoCommand {
public:
- ClearEntries(RegionMap *map, QMap, QUndoCommand *parent = nullptr);
+ ClearEntries(RegionMap *map, QHash, QUndoCommand *parent = nullptr);
void undo() override;
void redo() override;
@@ -163,7 +163,7 @@ public:
private:
RegionMap *map;
- QMap entries;
+ QHash entries;
};
#endif // REGIONMAPEDITCOMMANDS_H
diff --git a/include/core/tileset.h b/include/core/tileset.h
index 32d18858..a05afdc3 100644
--- a/include/core/tileset.h
+++ b/include/core/tileset.h
@@ -55,17 +55,17 @@ public:
static QString getExpectedDir(QString tilesetName, bool isSecondary);
QString getExpectedDir();
- void load();
- void loadMetatiles();
- void loadMetatileAttributes();
- void loadTilesImage(QImage *importedImage = nullptr);
- void loadPalettes();
+ bool load();
+ bool loadMetatiles();
+ bool loadMetatileAttributes();
+ bool loadTilesImage(QImage *importedImage = nullptr);
+ bool loadPalettes();
- void save();
- void saveMetatileAttributes();
- void saveMetatiles();
- void saveTilesImage();
- void savePalettes();
+ bool save();
+ bool saveMetatileAttributes();
+ bool saveMetatiles();
+ bool saveTilesImage();
+ bool savePalettes();
bool appendToHeaders(QString root, QString friendlyName, bool usingAsm);
bool appendToGraphics(QString root, QString friendlyName, bool usingAsm);
diff --git a/include/core/utility.h b/include/core/utility.h
index 1b9277ab..09caebce 100644
--- a/include/core/utility.h
+++ b/include/core/utility.h
@@ -9,6 +9,8 @@ namespace Util {
int roundUp(int numToRound, int multiple);
QString toDefineCase(QString input);
QString toHexString(uint32_t value, int minLength = 0);
+ QString toHtmlParagraph(const QString &text);
+ Qt::Orientations getOrientation(bool xflip, bool yflip);
}
#endif // UTILITY_H
diff --git a/include/core/wildmoninfo.h b/include/core/wildmoninfo.h
index 3c94fb17..a3665b7d 100644
--- a/include/core/wildmoninfo.h
+++ b/include/core/wildmoninfo.h
@@ -3,7 +3,7 @@
#define GUARD_WILDMONINFO_H
#include
-#include "orderedmap.h"
+#include "orderedjson.h"
class WildPokemon {
public:
@@ -13,22 +13,26 @@ public:
int minLevel;
int maxLevel;
QString species;
+ OrderedJson::object customData;
};
struct WildMonInfo {
bool active = false;
int encounterRate = 0;
QVector wildPokemon;
+ OrderedJson::object customData;
};
struct WildPokemonHeader {
- tsl::ordered_map wildMons;
+ OrderedMap wildMons;
+ OrderedJson::object customData;
};
struct EncounterField {
QString name; // Ex: "fishing_mons"
QVector encounterRates;
- tsl::ordered_map> groups; // Ex: "good_rod", {2, 3, 4}
+ OrderedMap> groups; // Ex: "good_rod", {2, 3, 4}
+ OrderedJson::object customData;
};
typedef QVector EncounterFields;
diff --git a/include/editor.h b/include/editor.h
index 48fdfc0d..432084e8 100644
--- a/include/editor.h
+++ b/include/editor.h
@@ -30,7 +30,7 @@
#include "mapruler.h"
#include "encountertablemodel.h"
-class DraggablePixmapItem;
+class EventPixmapItem;
class MetatilesPixmapItem;
class Editor : public QObject
@@ -57,8 +57,8 @@ public:
GridSettings gridSettings;
void setProject(Project * project);
- void saveAll();
- void saveCurrent();
+ bool saveAll();
+ bool saveCurrent();
void saveEncounterTabData();
void closeProject();
@@ -92,14 +92,16 @@ public:
void setConnectionsVisibility(bool visible);
void updateDivingMapsVisibility();
void renderDivingConnections();
- void addConnection(MapConnection* connection);
+ void addNewConnection(const QString &mapName, const QString &direction);
+ void replaceConnection(const QString &mapName, const QString &direction);
void removeConnection(MapConnection* connection);
+ void removeSelectedConnection();
void addNewWildMonGroup(QWidget *window);
void deleteWildMonGroup();
void configureEncounterJSON(QWidget *);
EncounterTableModel* getCurrentWildMonTable();
- void updateDiveMap(QString mapName);
- void updateEmergeMap(QString mapName);
+ bool setDivingMapName(const QString &mapName, const QString &direction);
+ QString getDivingMapName(const QString &direction) const;
void setSelectedConnection(MapConnection *connection);
void updatePrimaryTileset(QString tilesetLabel, bool forceLoad = false);
@@ -107,7 +109,7 @@ public:
void toggleBorderVisibility(bool visible, bool enableScriptCallback = true);
void updateCustomMapAttributes();
- DraggablePixmapItem *addEventPixmapItem(Event *event);
+ EventPixmapItem *addEventPixmapItem(Event *event);
void removeEventPixmapItem(Event *event);
bool canAddEvents(const QList &events);
void selectMapEvent(Event *event, bool toggle = false);
@@ -116,12 +118,16 @@ public:
void duplicateSelectedEvents();
void redrawAllEvents();
void redrawEvents(const QList &events);
- void redrawEventPixmapItem(DraggablePixmapItem *item);
+ void redrawEventPixmapItem(EventPixmapItem *item);
+ void updateEventPixmapItemZValue(EventPixmapItem *item);
qreal getEventOpacity(const Event *event) const;
+ void setPlayerViewRect(const QRectF &rect);
void updateCursorRectPos(int x, int y);
void setCursorRectVisible(bool visible);
+ void onEventDragged(Event *event, const QPoint &oldPosition, const QPoint &newPosition);
+ void onEventReleased(Event *event, const QPoint &position);
void updateWarpEventWarning(Event *event);
void updateWarpEventWarnings();
@@ -172,10 +178,7 @@ public:
static QList> collisionIcons;
int eventShiftActionId = 0;
-
- void eventsView_onMousePress(QMouseEvent *event);
-
- bool selectingEvent = false;
+ int eventMoveActionId = 0;
void deleteSelectedEvents();
void shouldReselectEvents();
@@ -183,6 +186,22 @@ public:
static void openInTextEditor(const QString &path, int lineNum = 0);
void setCollisionGraphics();
+ enum ZValue {
+ MapBorder = -4,
+ MapConnectionInactive = -3,
+ MapConnectionActive = -2,
+ MapConnectionMask = -1,
+
+ // Event pixmaps set their z value to be their y position on the map.
+ // Their y value is int16_t, so we have enough space to allocate the
+ // full range + 1 for the selected event (which should always be on top).
+ EventMinimum = 1,
+ EventMaximum = EventMinimum + 0x10000,
+
+ Ruler,
+ ResizeLayoutPopup
+ };
+
public slots:
void openMapScripts() const;
void openScript(const QString &scriptLabel) const;
@@ -199,7 +218,7 @@ private:
EditMode editMode = EditMode::None;
- void save(bool currentOnly);
+ bool save(bool currentOnly);
void clearMap();
void clearMetatileSelector();
void clearMovementPermissionSelector();
@@ -218,8 +237,9 @@ private:
void removeConnectionPixmap(MapConnection *connection);
void displayConnection(MapConnection *connection);
void displayDivingConnection(MapConnection *connection);
- void setDivingMapName(QString mapName, QString direction);
void removeDivingMapPixmap(MapConnection *connection);
+ void onDivingMapEditingFinished(NoScrollComboBox* combo, const QString &direction);
+ void updateDivingMapButton(QToolButton* button, const QString &mapName);
void updateEncounterFields(EncounterFields newFields);
QString getMovementPermissionText(uint16_t collision, uint16_t elevation);
QString getMetatileDisplayMessage(uint16_t metatileId);
@@ -249,11 +269,11 @@ private slots:
signals:
void eventsChanged();
+ void openEventMap(Event*);
void openConnectedMap(MapConnection*);
void wildMonTableOpened(EncounterTableModel*);
void wildMonTableClosed();
void wildMonTableEdited();
- void warpEventDoubleClicked(QString, int, Event::Group);
void currentMetatilesSelectionChanged();
void mapRulerStatusChanged(const QString &);
void tilesetUpdated(QString);
diff --git a/include/lib/orderedjson.h b/include/lib/orderedjson.h
index 544112f1..cb5139d3 100644
--- a/include/lib/orderedjson.h
+++ b/include/lib/orderedjson.h
@@ -99,7 +99,7 @@ public:
// Array and object typedefs
typedef QVector array;
- typedef tsl::ordered_map object;
+ typedef OrderedMap object;
// Constructors for the various types of JSON value.
Json() noexcept; // NUL
@@ -132,7 +132,22 @@ public:
int>::type = 0>
Json(const V & v) : Json(array(v.begin(), v.end())) {}
- static const Json fromQJsonValue(QJsonValue value);
+ static Json fromQJsonValue(const QJsonValue &value);
+
+ static void append(Json::array *array, const QJsonArray &addendum) {
+ for (const auto &i : addendum) array->push_back(fromQJsonValue(i));
+ }
+ static void append(Json::array *array, const Json::array &addendum) {
+ for (const auto &i : addendum) array->push_back(i);
+ }
+ static void append(Json::object *object, const QJsonObject &addendum) {
+ for (auto it = addendum.constBegin(); it != addendum.constEnd(); it++)
+ (*object)[it.key()] = fromQJsonValue(it.value());
+ }
+ static void append(Json::object *object, const Json::object &addendum) {
+ for (auto it = addendum.cbegin(); it != addendum.cend(); it++)
+ (*object)[it.key()] = it.value();
+ }
// This prevents Json(some_pointer) from accidentally producing a bool. Use
// Json(bool(some_pointer)) if that behavior is desired.
diff --git a/include/lib/orderedmap.h b/include/lib/orderedmap.h
index 40882d9f..33fcfc50 100644
--- a/include/lib/orderedmap.h
+++ b/include/lib/orderedmap.h
@@ -1977,6 +1977,14 @@ public:
size_type erase(const K& key, std::size_t precalculated_hash) {
return m_ht.erase(key, precalculated_hash);
}
+
+ // Naive solution for take, should probably be replaced with one that does a single lookup and no unnecessary insertion.
+ // We want to mirror the behavior of QMap::take, which returns a default-constructed value if the key is not present.
+ T take(const key_type& key) {
+ typename ValueSelect::value_type value = m_ht[key];
+ m_ht.erase(key);
+ return value;
+ }
@@ -2404,4 +2412,7 @@ private:
} // end namespace tsl
+template
+using OrderedMap = tsl::ordered_map;
+
#endif
diff --git a/include/mainwindow.h b/include/mainwindow.h
index b3df2e9b..b2bba6ca 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);
@@ -175,9 +177,9 @@ private slots:
void on_action_Reload_Project_triggered();
void on_action_Close_Project_triggered();
void on_action_Save_Project_triggered();
- void save(bool currentOnly = false);
+ bool save(bool currentOnly = false);
- void openWarpMap(QString map_name, int event_id, Event::Group event_group);
+ void openEventMap(Event *event);
void duplicate();
void setClipboardData(poryjson::Json::object);
@@ -197,8 +199,7 @@ private slots:
void onMapLoaded(Map *map);
void onMapRulerStatusChanged(const QString &);
void applyUserShortcuts();
- void markMapEdited();
- void markSpecificMapEdited(Map*);
+ void markMapEdited(Map*);
void markLayoutEdited();
void on_actionNew_Tileset_triggered();
@@ -243,13 +244,9 @@ private slots:
void on_pushButton_AddConnection_clicked();
void on_button_OpenDiveMap_clicked();
void on_button_OpenEmergeMap_clicked();
- void on_comboBox_DiveMap_currentTextChanged(const QString &mapName);
- void on_comboBox_EmergeMap_currentTextChanged(const QString &mapName);
void on_comboBox_PrimaryTileset_currentTextChanged(const QString &arg1);
void on_comboBox_SecondaryTileset_currentTextChanged(const QString &arg1);
void on_pushButton_ChangeDimensions_clicked();
- void on_checkBox_smartPaths_stateChanged(int selected);
- void on_checkBox_ToggleBorder_stateChanged(int selected);
void resetMapViewScale();
@@ -260,7 +257,6 @@ private slots:
void eventTabChanged(int index);
- void on_checkBox_MirrorConnections_stateChanged(int selected);
void on_actionDive_Emerge_Map_triggered();
void on_actionShow_Events_In_Map_View_triggered();
void on_groupBox_DiveMapOpacity_toggled(bool on);
@@ -437,6 +433,10 @@ private:
void checkForUpdates(bool requestedByUser);
void setDivingMapsVisible(bool visible);
+
+ void setSmartPathsEnabled(bool enabled);
+ void setBorderVisibility(bool visible);
+ void setMirrorConnectionsEnabled(bool enabled);
};
// These are namespaced in a struct to avoid colliding with e.g. class Map.
diff --git a/include/project.h b/include/project.h
index 554fb3c7..99c7d7b7 100644
--- a/include/project.h
+++ b/include/project.h
@@ -62,7 +62,6 @@ public:
QStringList mapSectionIdNames;
QMap encounterTypeToName;
QMap terrainTypeToName;
- QMap regionMapEntries;
QMap> metatileLabelsMap;
QMap unusedMetatileLabels;
QMap metatileBehaviorMap;
@@ -72,13 +71,12 @@ public:
QSet modifiedFiles;
bool usingAsmTilesets;
QSet disabledSettingsNames;
- QSet topLevelMapFields;
int pokemonMinLevel;
int pokemonMaxLevel;
int maxEncounterRate;
bool wildEncountersLoaded;
- void set_root(QString);
+ void setRoot(const QString&);
void clearMaps();
void clearTilesetCache();
@@ -111,10 +109,6 @@ public:
bool loadBlockdata(Layout *);
bool loadLayoutBorder(Layout *);
- void saveTextFile(QString path, QString text);
- void appendTextFile(QString path, QString text);
- void deleteFile(QString path);
-
bool readMapGroups();
void addNewMapGroup(const QString &groupName);
QString mapNameToMapGroup(const QString &mapName) const;
@@ -145,12 +139,11 @@ public:
QString getNewHealLocationName(const Map* map) const;
bool readWildMonData();
- tsl::ordered_map> wildMonData;
+ OrderedMap> wildMonData;
QString wildMonTableName;
QVector wildMonFields;
QVector encounterGroupLabels;
- QVector extraEncounterGroups;
bool readSpeciesIconPaths();
QString getDefaultSpeciesIconPath(const QString &species);
@@ -158,40 +151,34 @@ public:
bool addNewMapsec(const QString &idName, const QString &displayName = QString());
void removeMapsec(const QString &idName);
- QString getMapsecDisplayName(const QString &idName) const { return this->mapSectionDisplayNames.value(idName); }
+ QString getMapsecDisplayName(const QString &idName) const { return this->locationData.value(idName).displayName; }
void setMapsecDisplayName(const QString &idName, const QString &displayName);
bool hasUnsavedChanges();
bool hasUnsavedDataChanges = false;
- void initTopLevelMapFields();
bool readMapJson(const QString &mapName, QJsonDocument * out);
- bool loadMapEvent(Map *map, const QJsonObject &json, Event::Type defaultType = Event::Type::None);
+ bool loadMapEvent(Map *map, QJsonObject json, Event::Type defaultType = Event::Type::None);
bool loadMapData(Map*);
bool readMapLayouts();
Layout *loadLayout(QString layoutId);
bool loadLayout(Layout *);
bool loadMapLayout(Map*);
bool loadLayoutTilesets(Layout *);
- void loadTilesetAssets(Tileset*);
+ bool loadTilesetAssets(Tileset*);
void loadTilesetMetatileLabels(Tileset*);
void readTilesetPaths(Tileset* tileset);
- void saveAll();
- void saveGlobalData();
- void saveLayout(Layout *);
- void saveLayoutBlockdata(Layout *);
- void saveLayoutBorder(Layout *);
- void writeBlockdata(QString, const Blockdata &);
- void saveMap(Map *map, bool skipLayout = false);
- void saveConfig();
- void saveMapLayouts();
- void saveMapGroups();
- void saveRegionMapSections();
- void saveWildMonData();
- void saveHealLocations();
- void saveTilesets(Tileset*, Tileset*);
- void saveTilesetMetatileLabels(Tileset*, Tileset*);
+ bool saveAll();
+ bool saveGlobalData();
+ bool saveConfig();
+ bool saveLayout(Layout *layout);
+ bool saveMap(Map *map, bool skipLayout = false);
+ bool saveTextFile(const QString &path, const QString &text);
+ bool saveRegionMapSections();
+ bool saveTilesets(Tileset*, Tileset*);
+ bool saveTilesetMetatileLabels(Tileset*, Tileset*);
+
void appendTilesetLabel(const QString &label, const QString &isSecondaryStr);
bool readTilesetLabels();
bool readTilesetMetatileLabels();
@@ -217,6 +204,7 @@ public:
bool readEventGraphics();
bool readFieldmapProperties();
bool readFieldmapMasks();
+ bool readGlobalConstants();
QMap> readObjEventGfxInfo();
QPixmap getEventPixmap(const QString &gfxName, const QString &movementName);
@@ -240,35 +228,52 @@ public:
static QString getExistingFilepath(QString filepath);
void applyParsedLimits();
+
+ void setRegionMapEntries(const QHash &entries);
+ QHash getRegionMapEntries() const;
+
+ QSet getTopLevelMapFields() const;
+
+ int getMapDataSize(int width, int height) const;
+ int getMaxMapDataSize() const { return this->maxMapDataSize; }
+ int getMaxMapWidth() const;
+ int getMaxMapHeight() const;
+ bool mapDimensionsValid(int width, int height) const;
+ bool calculateDefaultMapSize();
+ QSize getDefaultMapSize() const { return this->defaultMapSize; }
+ QSize getMapSizeAddition() const { return this->mapSizeAddition; }
+
+ int getMaxEvents(Event::Group group) const;
static QString getEmptyMapDefineName();
static QString getDynamicMapDefineName();
static QString getDynamicMapName();
static QString getEmptySpeciesName();
- static int getNumTilesPrimary();
- static int getNumTilesTotal();
- static int getNumMetatilesPrimary();
- static int getNumMetatilesTotal();
- static int getNumPalettesPrimary();
- static int getNumPalettesTotal();
- static int getMaxMapDataSize();
- static int getDefaultMapDimension();
- static int getMaxMapWidth();
- static int getMaxMapHeight();
- static int getMapDataSize(int width, int height);
- static bool mapDimensionsValid(int width, int height);
- bool calculateDefaultMapSize();
- int getMaxEvents(Event::Group group);
+ static QMargins getMetatileViewDistance();
+ static int getNumTilesPrimary() { return num_tiles_primary; }
+ static int getNumTilesTotal() { return num_tiles_total; }
+ static int getNumMetatilesPrimary() { return num_metatiles_primary; }
+ static int getNumMetatilesTotal() { return Block::getMaxMetatileId() + 1; }
+ static int getNumPalettesPrimary(){ return num_pals_primary; }
+ static int getNumPalettesTotal() { return num_pals_total; }
static QString getEmptyMapsecName();
static QString getMapGroupPrefix();
private:
- QHash mapSectionDisplayNames;
QMap modifiedFileTimestamps;
QMap facingDirections;
QHash speciesToIconPath;
QHash maps;
+ // Fields for preserving top-level JSON data that Porymap isn't expecting.
+ QJsonObject customLayoutsData;
+ QJsonObject customMapSectionsData;
+ QJsonObject customMapGroupsData;
+ QJsonObject customHealLocationsData;
+ OrderedJson::object customWildMonData;
+ OrderedJson::object customWildMonGroupData;
+ OrderedJson::array extraEncounterGroups;
+
// Maps/layouts represented in these sets have been fully loaded from the project.
// If a valid map name / layout id is not in these sets, a Map / Layout object exists
// for it in Project::maps / Project::mapLayouts, but it has been minimally populated
@@ -292,7 +297,14 @@ private:
};
QMap eventGraphicsMap;
- void updateLayout(Layout *);
+ // The extra data that can be associated with each MAPSEC name.
+ struct LocationData
+ {
+ MapSectionEntry map;
+ QString displayName;
+ QJsonObject custom;
+ };
+ QHash locationData;
void setNewLayoutBlockdata(Layout *layout);
void setNewLayoutBorder(Layout *layout);
@@ -301,17 +313,27 @@ private:
void recordFileChange(const QString &filepath);
void resetFileCache();
+ bool saveMapLayouts();
+ bool saveMapGroups();
+ bool saveWildMonData();
+ bool saveHealLocations();
+ bool appendTextFile(const QString &path, const QString &text);
+
QString findSpeciesIconPath(const QStringList &names) const;
- int maxEventsPerGroup;
int maxObjectEvents;
+ int maxMapDataSize;
+ QSize defaultMapSize;
+ QSize mapSizeAddition;
+
+ // TODO: These really shouldn't be static, they're specific to a single project.
+ // We're making an assumption here that we only have one project open at a single time
+ // (which is true, but then if that's the case we should have some global Project instance instead)
static int num_tiles_primary;
static int num_tiles_total;
static int num_metatiles_primary;
static int num_pals_primary;
static int num_pals_total;
- static int max_map_data_size;
- static int default_map_dimension;
signals:
void fileChanged(const QString &filepath);
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/connectionpixmapitem.h b/include/ui/connectionpixmapitem.h
index 26b83aa6..32e309f9 100644
--- a/include/ui/connectionpixmapitem.h
+++ b/include/ui/connectionpixmapitem.h
@@ -43,8 +43,6 @@ protected:
virtual void mousePressEvent(QGraphicsSceneMouseEvent*) override;
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent*) override;
virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent*) override;
- virtual void keyPressEvent(QKeyEvent*) override;
- virtual void focusInEvent(QFocusEvent*) override;
signals:
void connectionItemDoubleClicked(MapConnection*);
diff --git a/include/ui/connectionslistitem.h b/include/ui/connectionslistitem.h
index b63922a9..1b9713cf 100644
--- a/include/ui/connectionslistitem.h
+++ b/include/ui/connectionslistitem.h
@@ -36,19 +36,17 @@ private:
protected:
virtual void mousePressEvent(QMouseEvent*) override;
- virtual void focusInEvent(QFocusEvent*) override;
- virtual void keyPressEvent(QKeyEvent*) override;
+ virtual bool eventFilter(QObject*, QEvent *event) override;
signals:
void selected();
void openMapClicked(MapConnection*);
-private slots:
- void on_comboBox_Direction_currentTextChanged(QString direction);
- void on_comboBox_Map_currentTextChanged(QString mapName);
- void on_spinBox_Offset_valueChanged(int offset);
- void on_button_Delete_clicked();
- void on_button_OpenMap_clicked();
+private:
+ void commitDirection();
+ void commitMap(const QString &mapName);
+ void commitMove(int offset);
+ void commitRemove();
};
#endif // CONNECTIONSLISTITEM_H
diff --git a/include/ui/customattributestable.h b/include/ui/customattributestable.h
index 21cac4de..780f441d 100644
--- a/include/ui/customattributestable.h
+++ b/include/ui/customattributestable.h
@@ -13,8 +13,8 @@ public:
explicit CustomAttributesTable(QWidget *parent = nullptr);
~CustomAttributesTable() {};
- QMap getAttributes() const;
- void setAttributes(const QMap &attributes);
+ QJsonObject getAttributes() const;
+ void setAttributes(const QJsonObject &attributes);
void addNewAttribute(const QString &key, const QJsonValue &value);
bool deleteSelectedAttributes();
diff --git a/include/ui/draggablepixmapitem.h b/include/ui/draggablepixmapitem.h
deleted file mode 100644
index aeda4daf..00000000
--- a/include/ui/draggablepixmapitem.h
+++ /dev/null
@@ -1,70 +0,0 @@
-#ifndef DRAGGABLEPIXMAPITEM_H
-#define DRAGGABLEPIXMAPITEM_H
-
-#include
-#include
-#include
-#include
-
-#include
-
-#include "events.h"
-
-class Editor;
-
-class DraggablePixmapItem : public QObject, public QGraphicsPixmapItem {
- Q_OBJECT
-public:
- DraggablePixmapItem(QPixmap pixmap): QGraphicsPixmapItem(pixmap) {}
-
- DraggablePixmapItem(Event *event, Editor *editor) : QGraphicsPixmapItem(event->getPixmap()) {
- this->event = event;
- event->setPixmapItem(this);
- this->editor = editor;
- updatePosition();
- }
-
- Event *event = nullptr;
-
- void updatePosition();
- void move(int dx, int dy);
- void moveTo(const QPoint &pos);
- void emitPositionChanged();
- void updatePixmap();
-
-private:
- Editor *editor = nullptr;
- QPoint lastPos;
- bool active = false;
- bool releaseSelectionQueued = false;
-
-signals:
- void positionChanged(Event *event);
- void xChanged(int);
- void yChanged(int);
- void elevationChanged(int);
- void spriteChanged(QPixmap pixmap);
- void onPropertyChanged(QString key, QString value);
-
-public slots:
- void set_x(int x) {
- event->setX(x);
- updatePosition();
- }
- void set_y(int y) {
- event->setY(y);
- updatePosition();
- }
- void set_elevation(int z) {
- event->setElevation(z);
- updatePosition();
- }
-
-protected:
- void mousePressEvent(QGraphicsSceneMouseEvent*);
- void mouseMoveEvent(QGraphicsSceneMouseEvent*);
- void mouseReleaseEvent(QGraphicsSceneMouseEvent*);
- void mouseDoubleClickEvent(QGraphicsSceneMouseEvent*);
-};
-
-#endif // DRAGGABLEPIXMAPITEM_H
diff --git a/include/ui/eventframes.h b/include/ui/eventframes.h
index 763d6baf..09eae50b 100644
--- a/include/ui/eventframes.h
+++ b/include/ui/eventframes.h
@@ -57,7 +57,9 @@ protected:
bool initialized = false;
bool connected = false;
+ void populateDropdown(NoScrollComboBox * combo, const QStringList &items);
void populateScriptDropdown(NoScrollComboBox * combo, Project * project);
+ void populateIdNameDropdown(NoScrollComboBox * combo, Project * project, const QString &mapName, Event::Group group);
private:
Event *event;
@@ -78,6 +80,7 @@ public:
virtual void populate(Project *project) override;
public:
+ QLineEdit *line_edit_local_id;
NoScrollComboBox *combo_sprite;
NoScrollComboBox *combo_movement;
NoScrollSpinBox *spinner_radius_x;
@@ -108,12 +111,15 @@ public:
virtual void populate(Project *project) override;
public:
+ QLineEdit *line_edit_local_id;
NoScrollComboBox *combo_sprite;
- NoScrollSpinBox *spinner_target_id;
+ NoScrollComboBox *combo_target_id;
NoScrollComboBox *combo_target_map;
private:
CloneObjectEvent *clone;
+
+ void tryInvalidateIdDropdown(Map *map);
};
@@ -131,12 +137,15 @@ public:
virtual void populate(Project *project) override;
public:
+ QLineEdit *line_edit_id;
NoScrollComboBox *combo_dest_map;
NoScrollComboBox *combo_dest_warp;
QPushButton *warning;
private:
WarpEvent *warp;
+
+ void tryInvalidateIdDropdown(Map *map);
};
@@ -275,6 +284,8 @@ public:
private:
HealLocationEvent *healLocation;
+
+ void tryInvalidateIdDropdown(Map *map);
};
#endif // EVENTRAMES_H
diff --git a/include/ui/eventpixmapitem.h b/include/ui/eventpixmapitem.h
new file mode 100644
index 00000000..a28232ba
--- /dev/null
+++ b/include/ui/eventpixmapitem.h
@@ -0,0 +1,58 @@
+#ifndef EVENTPIXMAPITEM_H
+#define EVENTPIXMAPITEM_H
+
+#include
+#include
+#include
+#include
+
+#include
+
+#include "events.h"
+
+class Project;
+
+class EventPixmapItem : public QObject, public QGraphicsPixmapItem {
+ Q_OBJECT
+public:
+ explicit EventPixmapItem(Event *event);
+
+ void render(Project *project);
+
+ bool isSelected() const { return m_selected; }
+ void setSelected(bool selected) { m_selected = selected; }
+
+ Event * getEvent() const { return m_event; }
+
+ void move(int dx, int dy);
+ void moveTo(int x, int y);
+ void moveTo(const QPoint &pos);
+
+private:
+ QPixmap m_basePixmap;
+ Event *const m_event = nullptr;
+ QPoint m_lastPos;
+ bool m_active = false;
+ bool m_selected = false;
+ bool m_releaseSelectionQueued = false;
+
+ void updatePixelPosition();
+
+signals:
+ void xChanged(int x);
+ void yChanged(int y);
+ void posChanged(int x, int y);
+ void rendered(const QPixmap &pixmap);
+ void selected(Event *event, bool toggle);
+ void dragged(Event *event, const QPoint &oldPosition, const QPoint &newPosition);
+ void released(Event *event, const QPoint &position);
+ void doubleClicked(Event *event);
+
+protected:
+ virtual void mousePressEvent(QGraphicsSceneMouseEvent*) override;
+ virtual void mouseMoveEvent(QGraphicsSceneMouseEvent*) override;
+ virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent*) override;
+ virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent*) override { emit doubleClicked(m_event); }
+};
+
+#endif // EVENTPIXMAPITEM_H
diff --git a/include/ui/graphicsview.h b/include/ui/graphicsview.h
index 92771cf7..c587d2a9 100644
--- a/include/ui/graphicsview.h
+++ b/include/ui/graphicsview.h
@@ -32,25 +32,17 @@ signals:
void clicked(QMouseEvent *event);
};
-class Editor;
-
-// TODO: This should just be MapView. It makes map-based assumptions, and no other class inherits GraphicsView.
-class GraphicsView : public QGraphicsView
+class ConnectionsView : public QGraphicsView
{
+ Q_OBJECT
public:
- GraphicsView() : QGraphicsView() {}
- GraphicsView(QWidget *parent) : QGraphicsView(parent) {}
+ ConnectionsView(QWidget *parent = nullptr) : QGraphicsView(parent) {}
+
+signals:
+ void pressedDelete();
-public:
-// GraphicsView_Object object;
- Editor *editor;
protected:
- virtual void mousePressEvent(QMouseEvent *event) override;
- virtual void mouseMoveEvent(QMouseEvent *event) override;
- virtual void mouseReleaseEvent(QMouseEvent *event) override;
- virtual void moveEvent(QMoveEvent *event) override;
+ virtual void keyPressEvent(QKeyEvent *event) override;
};
-//Q_DECLARE_METATYPE(GraphicsView)
-
#endif // GRAPHICSVIEW_H
diff --git a/include/ui/loadingscreen.h b/include/ui/loadingscreen.h
new file mode 100644
index 00000000..df55b01c
--- /dev/null
+++ b/include/ui/loadingscreen.h
@@ -0,0 +1,41 @@
+#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(QPixmap pixmap);
+ void showMessage(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 79f4f6c8..4f3dc775 100644
--- a/include/ui/mapheaderform.h
+++ b/include/ui/mapheaderform.h
@@ -64,6 +64,8 @@ private:
QPointer m_project = nullptr;
bool m_allowProjectChanges = true;
+ void setText(QComboBox *combo, const QString &text) const;
+ void setText(QLineEdit *lineEdit, const QString &text) const;
void setLocations(const QStringList &locations);
void updateLocationName();
@@ -73,11 +75,11 @@ private:
void onWeatherChanged(const QString &weather);
void onTypeChanged(const QString &type);
void onBattleSceneChanged(const QString &battleScene);
- void onRequiresFlashChanged(int selected);
- void onShowLocationNameChanged(int selected);
- void onAllowRunningChanged(int selected);
- void onAllowBikingChanged(int selected);
- void onAllowEscapingChanged(int selected);
+ void onRequiresFlashChanged(bool enabled);
+ void onShowLocationNameChanged(bool enabled);
+ void onAllowRunningChanged(bool enabled);
+ void onAllowBikingChanged(bool enabled);
+ void onAllowEscapingChanged(bool enabled);
void onFloorNumberChanged(int offset);
};
diff --git a/include/ui/mapimageexporter.h b/include/ui/mapimageexporter.h
index ffc4d272..51c1afe3 100644
--- a/include/ui/mapimageexporter.h
+++ b/include/ui/mapimageexporter.h
@@ -91,30 +91,27 @@ protected:
virtual void showEvent(QShowEvent *) override;
virtual void resizeEvent(QResizeEvent *) override;
-private slots:
- void on_checkBox_Objects_stateChanged(int state);
- void on_checkBox_Warps_stateChanged(int state);
- void on_checkBox_BGs_stateChanged(int state);
- void on_checkBox_Triggers_stateChanged(int state);
- void on_checkBox_HealLocations_stateChanged(int state);
- void on_checkBox_AllEvents_stateChanged(int state);
-
- void on_checkBox_ConnectionUp_stateChanged(int state);
- void on_checkBox_ConnectionDown_stateChanged(int state);
- void on_checkBox_ConnectionLeft_stateChanged(int state);
- void on_checkBox_ConnectionRight_stateChanged(int state);
- void on_checkBox_AllConnections_stateChanged(int state);
-
- void on_checkBox_Collision_stateChanged(int state);
- void on_checkBox_Grid_stateChanged(int state);
- void on_checkBox_Border_stateChanged(int state);
+private:
+ void setShowGrid(bool checked);
+ void setShowBorder(bool checked);
+ void setShowObjects(bool checked);
+ void setShowWarps(bool checked);
+ void setShowBgs(bool checked);
+ void setShowTriggers(bool checked);
+ void setShowHealLocations(bool checked);
+ void setShowAllEvents(bool checked);
+ void setShowConnectionUp(bool checked);
+ void setShowConnectionDown(bool checked);
+ void setShowConnectionLeft(bool checked);
+ void setShowConnectionRight(bool checked);
+ void setShowAllConnections(bool checked);
+ void setShowCollision(bool checked);
+ void setDisablePreviewScaling(bool checked);
+ void setDisablePreviewUpdates(bool checked);
void on_pushButton_Reset_pressed();
void on_spinBox_TimelapseDelay_editingFinished();
void on_spinBox_FrameSkip_editingFinished();
-
- void on_checkBox_DisablePreviewScaling_stateChanged(int state);
- void on_checkBox_DisablePreviewUpdates_stateChanged(int state);
};
#endif // MAPIMAGEEXPORTER_H
diff --git a/include/ui/mapview.h b/include/ui/mapview.h
index aa271757..d53e5cce 100644
--- a/include/ui/mapview.h
+++ b/include/ui/mapview.h
@@ -5,13 +5,17 @@
#include "graphicsview.h"
#include "overlay.h"
-class MapView : public GraphicsView
+class Editor;
+
+class MapView : public QGraphicsView
{
Q_OBJECT
public:
- MapView() : GraphicsView() {}
- MapView(QWidget *parent) : GraphicsView(parent) {}
+ MapView() : QGraphicsView() {}
+ MapView(QWidget *parent) : QGraphicsView(parent) {}
+
+ Editor *editor;
Overlay * getOverlay(int layer);
void clearOverlayMap();
@@ -73,6 +77,7 @@ public:
protected:
virtual void drawForeground(QPainter *painter, const QRectF &rect) override;
virtual void keyPressEvent(QKeyEvent*) override;
+ virtual void moveEvent(QMoveEvent *event) override;
private:
QMap overlayMap;
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 56798a0c..92dd43f7 100644
--- a/include/ui/movablerect.h
+++ b/include/ui/movablerect.h
@@ -10,28 +10,35 @@
class MovableRect : public QGraphicsRectItem
{
public:
- MovableRect(bool *enabled, int width, int height, QRgb color);
+ MovableRect(bool *enabled, const QRectF &rect, const QRgb &color);
QRectF boundingRect() const override {
qreal penWidth = 4;
return QRectF(-penWidth,
-penWidth,
- 30 * 8 + penWidth * 2,
- 20 * 8 + penWidth * 2);
+ this->rect().width() + penWidth * 2,
+ this->rect().height() + penWidth * 2);
}
void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) override {
- if (!(*enabled)) return;
+ if (!isVisible()) return;
painter->setPen(this->color);
- painter->drawRect(this->rect().x() - 2, this->rect().y() - 2, this->rect().width() + 3, this->rect().height() + 3);
- painter->setPen(QColor(0, 0, 0));
- painter->drawRect(this->rect().x() - 3, this->rect().y() - 3, this->rect().width() + 5, this->rect().height() + 5);
- painter->drawRect(this->rect().x() - 1, this->rect().y() - 1, this->rect().width() + 1, this->rect().height() + 1);
+ painter->drawRect(this->rect() + QMargins(1,1,1,1)); // Fill
+ painter->setPen(Qt::black);
+ painter->drawRect(this->rect() + QMargins(2,2,2,2)); // Outer border
+ 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/newmapconnectiondialog.h b/include/ui/newmapconnectiondialog.h
index 4781c971..db9eee49 100644
--- a/include/ui/newmapconnectiondialog.h
+++ b/include/ui/newmapconnectiondialog.h
@@ -20,13 +20,16 @@ public:
virtual void accept() override;
signals:
- void accepted(MapConnection *result);
+ void newConnectionedAdded(const QString &mapName, const QString &direction);
+ void connectionReplaced(const QString &mapName, const QString &direction);
private:
Ui::NewMapConnectionDialog *ui;
+ Map *m_map;
bool mapNameIsValid();
void setWarningVisible(bool visible);
+ bool askReplaceConnection(MapConnection *connection, const QString &newMapName);
};
#endif // NEWMAPCONNECTIONDIALOG_H
diff --git a/include/ui/noscrollcombobox.h b/include/ui/noscrollcombobox.h
index 32966b3a..0ae2487c 100644
--- a/include/ui/noscrollcombobox.h
+++ b/include/ui/noscrollcombobox.h
@@ -18,6 +18,9 @@ public:
void setLineEdit(QLineEdit *edit);
void setFocusedScrollingEnabled(bool enabled);
+signals:
+ void editingFinished();
+
private:
void setItem(int index, const QString &text);
diff --git a/include/ui/noscrolltextedit.h b/include/ui/noscrolltextedit.h
new file mode 100644
index 00000000..dfc66789
--- /dev/null
+++ b/include/ui/noscrolltextedit.h
@@ -0,0 +1,25 @@
+#ifndef NOSCROLLTEXTEDIT_H
+#define NOSCROLLTEXTEDIT_H
+
+#include
+#include
+
+class NoScrollTextEdit : public QTextEdit
+{
+ Q_OBJECT
+public:
+ explicit NoScrollTextEdit(const QString &text, QWidget *parent = nullptr) : QTextEdit(text, parent) {
+ setFocusPolicy(Qt::StrongFocus);
+ };
+ explicit NoScrollTextEdit(QWidget *parent = nullptr) : NoScrollTextEdit(QString(), parent) {};
+
+ virtual void wheelEvent(QWheelEvent *event) override {
+ if (hasFocus()) {
+ QTextEdit::wheelEvent(event);
+ } else {
+ event->ignore();
+ }
+ };
+};
+
+#endif // NOSCROLLTEXTEDIT_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/include/ui/regionmapeditor.h b/include/ui/regionmapeditor.h
index 9a838827..432eaab6 100644
--- a/include/ui/regionmapeditor.h
+++ b/include/ui/regionmapeditor.h
@@ -54,7 +54,7 @@ private:
Project *project;
RegionMap *region_map = nullptr;
- tsl::ordered_map region_maps;
+ OrderedMap region_maps;
QString configFilepath;
@@ -95,7 +95,7 @@ private:
void saveConfig();
bool loadRegionMapEntries();
bool saveRegionMapEntries();
- QMap region_map_entries;
+ QHash region_map_entries;
bool buildConfigDialog();
poryjson::Json configRegionMapDialog();
@@ -121,6 +121,9 @@ private:
void restoreWindowState();
void closeEvent(QCloseEvent* event);
+ void setTileHFlip(bool enabled);
+ void setTileVFlip(bool enabled);
+
private slots:
void on_action_RegionMap_Save_triggered();
void on_actionSave_All_triggered();
@@ -145,8 +148,6 @@ private slots:
void on_spinBox_RM_LayoutWidth_valueChanged(int);
void on_spinBox_RM_LayoutHeight_valueChanged(int);
void on_spinBox_tilePalette_valueChanged(int);
- void on_checkBox_tileHFlip_stateChanged(int);
- void on_checkBox_tileVFlip_stateChanged(int);
void on_verticalSlider_Zoom_Map_Image_valueChanged(int);
void on_verticalSlider_Zoom_Image_Tiles_valueChanged(int);
void onHoveredRegionMapTileChanged(int x, int y);
diff --git a/include/ui/shortcut.h b/include/ui/shortcut.h
index 8989401d..5fdbfaee 100644
--- a/include/ui/shortcut.h
+++ b/include/ui/shortcut.h
@@ -49,9 +49,6 @@ public:
void setAutoRepeat(bool on);
bool autoRepeat() const;
- int id() const;
- QList ids() const;
-
inline QWidget *parentWidget() const
{ return static_cast(QObject::parent()); }
diff --git a/include/ui/tilemaptileselector.h b/include/ui/tilemaptileselector.h
index 5c3b8dac..155957a6 100644
--- a/include/ui/tilemaptileselector.h
+++ b/include/ui/tilemaptileselector.h
@@ -149,10 +149,10 @@ public:
void select(unsigned tileId);
unsigned selectedTile = 0;
- void selectVFlip(bool hFlip) { this->tile_hFlip = hFlip; }
+ void selectHFlip(bool hFlip) { this->tile_hFlip = hFlip; }
bool tile_hFlip = false;
- void selectHFlip(bool vFlip) { this->tile_vFlip = vFlip; }
+ void selectVFlip(bool vFlip) { this->tile_vFlip = vFlip; }
bool tile_vFlip = false;
void selectPalette(int palette) {
diff --git a/include/ui/tileseteditor.h b/include/ui/tileseteditor.h
index d659390a..b6a60a61 100644
--- a/include/ui/tileseteditor.h
+++ b/include/ui/tileseteditor.h
@@ -71,12 +71,6 @@ private slots:
void on_spinBox_paletteSelector_valueChanged(int arg1);
- void on_checkBox_xFlip_stateChanged(int arg1);
-
- void on_checkBox_yFlip_stateChanged(int arg1);
-
- void on_actionSave_Tileset_triggered();
-
void on_actionImport_Primary_Tiles_triggered();
void on_actionImport_Secondary_Tiles_triggered();
@@ -149,6 +143,8 @@ private:
void commitTerrainType();
void commitLayerType();
void setRawAttributesVisible(bool visible);
+ void setXFlip(bool enabled);
+ void setYFlip(bool enabled);
Ui::TilesetEditor *ui;
History metatileHistory;
@@ -175,6 +171,8 @@ private:
bool lockSelection = false;
QSet metatileReloadQueue;
+ bool save();
+
signals:
void tilesetsSaved(QString, QString);
};
diff --git a/porymap.pro b/porymap.pro
index 35fd6af2..ff894f39 100644
--- a/porymap.pro
+++ b/porymap.pro
@@ -73,7 +73,7 @@ SOURCES += src/core/advancemapparser.cpp \
src/ui/customscriptseditor.cpp \
src/ui/customscriptslistitem.cpp \
src/ui/divingmappixmapitem.cpp \
- src/ui/draggablepixmapitem.cpp \
+ src/ui/eventpixmapitem.cpp \
src/ui/bordermetatilespixmapitem.cpp \
src/ui/collisionpixmapitem.cpp \
src/ui/connectionpixmapitem.cpp \
@@ -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 \
@@ -184,7 +186,7 @@ HEADERS += include/core/advancemapparser.h \
include/ui/customscriptseditor.h \
include/ui/customscriptslistitem.h \
include/ui/divingmappixmapitem.h \
- include/ui/draggablepixmapitem.h \
+ include/ui/eventpixmapitem.h \
include/ui/bordermetatilespixmapitem.h \
include/ui/collisionpixmapitem.h \
include/ui/connectionpixmapitem.h \
@@ -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 \
@@ -223,6 +226,7 @@ HEADERS += include/core/advancemapparser.h \
include/ui/newmapgroupdialog.h \
include/ui/noscrollcombobox.h \
include/ui/noscrollspinbox.h \
+ include/ui/noscrolltextedit.h \
include/ui/montabwidget.h \
include/ui/encountertablemodel.h \
include/ui/encountertabledelegates.h \
@@ -247,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 \
@@ -266,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 8a17a45c..45144a2d 100644
--- a/src/config.cpp
+++ b/src/config.cpp
@@ -18,6 +18,12 @@
#include
#include
+const QVersionNumber porymapVersion = QVersionNumber::fromString(PORYMAP_VERSION);
+
+// In both versions the default new map border is a generic tree
+const QList defaultBorder_RSE = {0x1D4, 0x1D5, 0x1DC, 0x1DD};
+const QList defaultBorder_FRLG = {0x14, 0x15, 0x1C, 0x1D};
+
const QList defaultWarpBehaviors_RSE = {
0x0E, // MB_MOSSDEEP_GYM_WARP
0x0F, // MB_MT_PYRE_HOLE
@@ -89,6 +95,8 @@ const QMap> ProjectConfig::defaultIde
{ProjectIdentifier::define_pals_total, {"define_pals_total", "NUM_PALS_TOTAL"}},
{ProjectIdentifier::define_tiles_per_metatile, {"define_tiles_per_metatile", "NUM_TILES_PER_METATILE"}},
{ProjectIdentifier::define_map_size, {"define_map_size", "MAX_MAP_DATA_SIZE"}},
+ {ProjectIdentifier::define_map_offset_width, {"define_map_offset_width", "MAP_OFFSET_W"}},
+ {ProjectIdentifier::define_map_offset_height, {"define_map_offset_height", "MAP_OFFSET_H"}},
{ProjectIdentifier::define_mask_metatile, {"define_mask_metatile", "MAPGRID_METATILE_ID_MASK"}},
{ProjectIdentifier::define_mask_collision, {"define_mask_collision", "MAPGRID_COLLISION_MASK"}},
{ProjectIdentifier::define_mask_elevation, {"define_mask_elevation", "MAPGRID_ELEVATION_MASK"}},
@@ -226,14 +234,14 @@ 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();
file.close();
}
-void KeyValueConfigBase::save() {
+bool KeyValueConfigBase::save() {
QString text = "";
QMap map = this->getKeyValueMap();
for (QMap::iterator it = map.begin(); it != map.end(); it++) {
@@ -241,15 +249,17 @@ void KeyValueConfigBase::save() {
}
QFile file(this->getConfigFilepath());
- if (file.open(QIODevice::WriteOnly)) {
- file.write(text.toUtf8());
- file.close();
- } else {
+ if (!file.open(QIODevice::WriteOnly)) {
logError(QString("Could not open config file '%1' for writing: ").arg(this->getConfigFilepath()) + file.errorString());
+ return false;
}
+
+ file.write(text.toUtf8());
+ file.close();
+ return true;
}
-bool KeyValueConfigBase::getConfigBool(QString key, QString value) {
+bool KeyValueConfigBase::getConfigBool(const QString &key, const QString &value) {
bool ok;
int result = value.toInt(&ok, 0);
if (!ok || (result != 0 && result != 1)) {
@@ -258,26 +268,35 @@ bool KeyValueConfigBase::getConfigBool(QString key, QString value) {
return (result != 0);
}
-int KeyValueConfigBase::getConfigInteger(QString key, QString value, int min, int max, int defaultValue) {
+int KeyValueConfigBase::getConfigInteger(const QString &key, const QString &value, int min, int max, int defaultValue) {
bool ok;
int result = value.toInt(&ok, 0);
if (!ok) {
- logWarn(QString("Invalid config value for %1: '%2'. Must be an integer.").arg(key).arg(value));
- return defaultValue;
+ logWarn(QString("Invalid config value for %1: '%2'. Must be an integer. Using default value '%3'.").arg(key).arg(value).arg(defaultValue));
+ result = defaultValue;
}
return qMin(max, qMax(min, result));
}
-uint32_t KeyValueConfigBase::getConfigUint32(QString key, QString value, uint32_t min, uint32_t max, uint32_t defaultValue) {
+uint32_t KeyValueConfigBase::getConfigUint32(const QString &key, const QString &value, uint32_t min, uint32_t max, uint32_t defaultValue) {
bool ok;
uint32_t result = value.toUInt(&ok, 0);
if (!ok) {
- logWarn(QString("Invalid config value for %1: '%2'. Must be an integer.").arg(key).arg(value));
- return defaultValue;
+ logWarn(QString("Invalid config value for %1: '%2'. Must be an integer. Using default value '%3'.").arg(key).arg(value).arg(defaultValue));
+ result = defaultValue;
}
return qMin(max, qMax(min, result));
}
+QColor KeyValueConfigBase::getConfigColor(const QString &key, const QString &value, const QColor &defaultValue) {
+ QColor color = QColor("#" + value);
+ if (!color.isValid()) {
+ logWarn(QString("Invalid config value for %1: '%2'. Must be a color in the format 'RRGGBB'. Using default value '%3'.").arg(key).arg(value).arg(defaultValue.name()));
+ color = defaultValue;
+ }
+ return color;
+}
+
PorymapConfig porymapConfig;
QString PorymapConfig::getConfigFilepath() {
@@ -445,6 +464,18 @@ void PorymapConfig::parseConfigKeyValue(QString key, QString value) {
}
} else if (key == "shown_in_game_reload_message") {
this->shownInGameReloadMessage = getConfigBool(key, value);
+ } else if (key == "grid_width") {
+ this->gridSettings.width = getConfigUint32(key, value);
+ } else if (key == "grid_height") {
+ this->gridSettings.height = getConfigUint32(key, value);
+ } else if (key == "grid_x") {
+ this->gridSettings.offsetX = getConfigInteger(key, value, 0, 999);
+ } else if (key == "grid_y") {
+ this->gridSettings.offsetY = getConfigInteger(key, value, 0, 999);
+ } else if (key == "grid_style") {
+ this->gridSettings.style = GridSettings::getStyleFromName(value);
+ } else if (key == "grid_color") {
+ this->gridSettings.color = getConfigColor(key, value);
} else {
logWarn(QString("Invalid config key found in config file %1: '%2'").arg(this->getConfigFilepath()).arg(key));
}
@@ -522,6 +553,12 @@ QMap PorymapConfig::getKeyValueMap() {
}
map.insert("event_selection_shape_mode", (this->eventSelectionShapeMode == QGraphicsPixmapItem::MaskShape) ? "mask" : "bounding_rect");
map.insert("shown_in_game_reload_message", this->shownInGameReloadMessage ? "1" : "0");
+ map.insert("grid_width", QString::number(this->gridSettings.width));
+ map.insert("grid_height", QString::number(this->gridSettings.height));
+ map.insert("grid_x", QString::number(this->gridSettings.offsetX));
+ map.insert("grid_y", QString::number(this->gridSettings.offsetY));
+ map.insert("grid_style", GridSettings::getStyleName(this->gridSettings.style));
+ map.insert("grid_color", this->gridSettings.color.name().remove("#")); // Our text config treats '#' as the start of a comment.
return map;
}
@@ -737,6 +774,10 @@ void ProjectConfig::parseConfigKeyValue(QString key, QString value) {
this->defaultElevation = getConfigUint32(key, value, 0, Block::maxValue);
} else if (key == "default_collision") {
this->defaultCollision = getConfigUint32(key, value, 0, Block::maxValue);
+ } else if (key == "default_map_width") {
+ this->defaultMapSize.setWidth(getConfigInteger(key, value, 1));
+ } else if (key == "default_map_height") {
+ this->defaultMapSize.setHeight(getConfigInteger(key, value, 1));
} else if (key == "new_map_border_metatiles") {
this->newMapBorderMetatileIds.clear();
QList metatileIds = value.split(",");
@@ -799,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") {
@@ -809,6 +854,8 @@ void ProjectConfig::parseConfigKeyValue(QString key, QString value) {
this->tilesetsHaveIsCompressed = getConfigBool(key, value);
} else if (key == "set_transparent_pixels_black") {
this->setTransparentPixelsBlack = getConfigBool(key, value);
+ } else if (key == "preserve_matching_only_data") {
+ this->preserveMatchingOnlyData = getConfigBool(key, value);
} else if (key == "event_icon_path_object") {
this->eventIconPaths[Event::Group::Object] = value;
} else if (key == "event_icon_path_warp") {
@@ -820,13 +867,21 @@ 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") {
- this->collisionSheetWidth = getConfigUint32(key, value, 1, Block::maxValue);
+ this->collisionSheetSize.setWidth(getConfigInteger(key, value, 1, Block::maxValue));
} else if (key == "collision_sheet_height") {
- this->collisionSheetHeight = getConfigUint32(key, value, 1, Block::maxValue);
+ this->collisionSheetSize.setHeight(getConfigInteger(key, value, 1, Block::maxValue));
+ } else if (key == "player_view_north") {
+ this->playerViewDistance.setTop(getConfigInteger(key, value, 0, INT_MAX, GBA_V_DIST_TO_CENTER));
+ } else if (key == "player_view_south") {
+ this->playerViewDistance.setBottom(getConfigInteger(key, value, 0, INT_MAX, GBA_V_DIST_TO_CENTER));
+ } else if (key == "player_view_west") {
+ this->playerViewDistance.setLeft(getConfigInteger(key, value, 0, INT_MAX, GBA_H_DIST_TO_CENTER));
+ } else if (key == "player_view_east") {
+ this->playerViewDistance.setRight(getConfigInteger(key, value, 0, INT_MAX, GBA_H_DIST_TO_CENTER));
} else if (key == "warp_behaviors") {
this->warpBehaviors.clear();
value.remove(" ");
@@ -862,7 +917,7 @@ void ProjectConfig::setUnreadKeys() {
if (!readKeys.contains("enable_event_clone_object")) this->eventCloneObjectEnabled = isPokefirered;
if (!readKeys.contains("enable_floor_number")) this->floorNumberEnabled = isPokefirered;
if (!readKeys.contains("create_map_text_file")) this->createMapTextFileEnabled = (this->baseGameVersion != BaseGameVersion::pokeemerald);
- if (!readKeys.contains("new_map_border_metatiles")) this->newMapBorderMetatileIds = isPokefirered ? DEFAULT_BORDER_FRLG : DEFAULT_BORDER_RSE;
+ if (!readKeys.contains("new_map_border_metatiles")) this->newMapBorderMetatileIds = isPokefirered ? defaultBorder_FRLG : defaultBorder_RSE;
if (!readKeys.contains("default_secondary_tileset")) this->defaultSecondaryTileset = isPokefirered ? "gTileset_PalletTown" : "gTileset_Petalburg";
if (!readKeys.contains("metatile_attributes_size")) this->metatileAttributesSize = Metatile::getDefaultAttributesSize(this->baseGameVersion);
if (!readKeys.contains("metatile_behavior_mask")) this->metatileBehaviorMask = Metatile::getDefaultAttributesMask(this->baseGameVersion, Metatile::Attr::Behavior);
@@ -890,6 +945,8 @@ QMap ProjectConfig::getKeyValueMap() {
map.insert("default_metatile", Metatile::getMetatileIdString(this->defaultMetatileId));
map.insert("default_elevation", QString::number(this->defaultElevation));
map.insert("default_collision", QString::number(this->defaultCollision));
+ map.insert("default_map_width", QString::number(this->defaultMapSize.width()));
+ map.insert("default_map_height", QString::number(this->defaultMapSize.height()));
map.insert("new_map_border_metatiles", Metatile::getMetatileIdStrings(this->newMapBorderMetatileIds));
map.insert("default_primary_tileset", this->defaultPrimaryTileset);
map.insert("default_secondary_tileset", this->defaultSecondaryTileset);
@@ -901,6 +958,7 @@ QMap ProjectConfig::getKeyValueMap() {
map.insert("tilesets_have_callback", QString::number(this->tilesetsHaveCallback));
map.insert("tilesets_have_is_compressed", QString::number(this->tilesetsHaveIsCompressed));
map.insert("set_transparent_pixels_black", QString::number(this->setTransparentPixelsBlack));
+ map.insert("preserve_matching_only_data", QString::number(this->preserveMatchingOnlyData));
map.insert("metatile_attributes_size", QString::number(this->metatileAttributesSize));
map.insert("metatile_behavior_mask", Util::toHexString(this->metatileBehaviorMask));
map.insert("metatile_terrain_type_mask", Util::toHexString(this->metatileTerrainTypeMask));
@@ -918,16 +976,24 @@ 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->collisionSheetWidth));
- map.insert("collision_sheet_height", QString::number(this->collisionSheetHeight));
+ map.insert("collision_sheet_width", QString::number(this->collisionSheetSize.width()));
+ map.insert("collision_sheet_height", QString::number(this->collisionSheetSize.height()));
+ map.insert("player_view_north", QString::number(this->playerViewDistance.top()));
+ map.insert("player_view_south", QString::number(this->playerViewDistance.bottom()));
+ map.insert("player_view_west", QString::number(this->playerViewDistance.left()));
+ map.insert("player_view_east", QString::number(this->playerViewDistance.right()));
QStringList warpBehaviorStrs;
for (const auto &value : this->warpBehaviors)
warpBehaviorStrs.append("0x" + QString("%1").arg(value, 2, 16, QChar('0')).toUpper());
diff --git a/src/core/editcommands.cpp b/src/core/editcommands.cpp
index 8850448d..684d98c7 100644
--- a/src/core/editcommands.cpp
+++ b/src/core/editcommands.cpp
@@ -1,5 +1,5 @@
#include "editcommands.h"
-#include "draggablepixmapitem.h"
+#include "eventpixmapitem.h"
#include "bordermetatilespixmapitem.h"
#include "editor.h"
diff --git a/src/core/events.cpp b/src/core/events.cpp
index 164cc34d..22315211 100644
--- a/src/core/events.cpp
+++ b/src/core/events.cpp
@@ -20,8 +20,7 @@ Event* Event::create(Event::Type type) {
}
Event::~Event() {
- if (this->eventFrame)
- this->eventFrame->deleteLater();
+ delete this->eventFrame;
}
EventFrame *Event::getEventFrame() {
@@ -34,7 +33,7 @@ void Event::destroyEventFrame() {
this->eventFrame = nullptr;
}
-void Event::setPixmapItem(DraggablePixmapItem *item) {
+void Event::setPixmapItem(EventPixmapItem *item) {
this->pixmapItem = item;
if (this->eventFrame) {
this->eventFrame->invalidateConnections();
@@ -51,24 +50,6 @@ void Event::setDefaultValues(Project *) {
this->setElevation(projectConfig.defaultElevation);
}
-void Event::readCustomAttributes(const QJsonObject &json) {
- this->customAttributes.clear();
- const QSet expectedFields = this->getExpectedFields();
- for (auto i = json.constBegin(); i != json.constEnd(); i++) {
- if (!expectedFields.contains(i.key())) {
- this->customAttributes[i.key()] = i.value();
- }
- }
-}
-
-void Event::addCustomAttributesTo(OrderedJson::object *obj) const {
- for (auto i = this->customAttributes.constBegin(); i != this->customAttributes.constEnd(); i++) {
- if (!obj->contains(i.key())) {
- (*obj)[i.key()] = OrderedJson::fromQJsonValue(i.value());
- }
- }
-}
-
void Event::modify() {
this->map->modify();
}
@@ -123,7 +104,7 @@ QString Event::typeToString(Event::Type type) {
{Event::Type::CloneObject, "Clone Object"},
{Event::Type::Warp, "Warp"},
{Event::Type::Trigger, "Trigger"},
- {Event::Type::WeatherTrigger, "Weather"},
+ {Event::Type::WeatherTrigger, "Weather Trigger"},
{Event::Type::Sign, "Sign"},
{Event::Type::HiddenItem, "Hidden Item"},
{Event::Type::SecretBase, "Secret Base"},
@@ -132,9 +113,10 @@ QString Event::typeToString(Event::Type type) {
return typeToStringMap.value(type);
}
-void Event::loadPixmap(Project *project) {
+QPixmap Event::loadPixmap(Project *project) {
this->pixmap = project->getEventPixmap(this->getEventGroup());
this->usesDefaultPixmap = true;
+ return this->pixmap;
}
@@ -170,12 +152,13 @@ EventFrame *ObjectEvent::createEventFrame() {
OrderedJson::object ObjectEvent::buildEventJson(Project *) {
OrderedJson::object objectJson;
- if (projectConfig.eventCloneObjectEnabled) {
- objectJson["type"] = Event::typeToJsonKey(Event::Type::Object);
- }
QString idName = this->getIdName();
if (!idName.isEmpty())
objectJson["local_id"] = idName;
+
+ if (projectConfig.eventCloneObjectEnabled) {
+ objectJson["type"] = Event::typeToJsonKey(Event::Type::Object);
+ }
objectJson["graphics_id"] = this->getGfx();
objectJson["x"] = this->getX();
objectJson["y"] = this->getY();
@@ -187,27 +170,26 @@ OrderedJson::object ObjectEvent::buildEventJson(Project *) {
objectJson["trainer_sight_or_berry_tree_id"] = this->getSightRadiusBerryTreeID();
objectJson["script"] = this->getScript();
objectJson["flag"] = this->getFlag();
- this->addCustomAttributesTo(&objectJson);
+ OrderedJson::append(&objectJson, this->getCustomAttributes());
return objectJson;
}
-bool ObjectEvent::loadFromJson(const QJsonObject &json, Project *) {
- this->setX(ParseUtil::jsonToInt(json["x"]));
- this->setY(ParseUtil::jsonToInt(json["y"]));
- this->setElevation(ParseUtil::jsonToInt(json["elevation"]));
- this->setIdName(ParseUtil::jsonToQString(json["local_id"]));
- this->setGfx(ParseUtil::jsonToQString(json["graphics_id"]));
- this->setMovement(ParseUtil::jsonToQString(json["movement_type"]));
- this->setRadiusX(ParseUtil::jsonToInt(json["movement_range_x"]));
- this->setRadiusY(ParseUtil::jsonToInt(json["movement_range_y"]));
- this->setTrainerType(ParseUtil::jsonToQString(json["trainer_type"]));
- this->setSightRadiusBerryTreeID(ParseUtil::jsonToQString(json["trainer_sight_or_berry_tree_id"]));
- this->setScript(ParseUtil::jsonToQString(json["script"]));
- this->setFlag(ParseUtil::jsonToQString(json["flag"]));
+bool ObjectEvent::loadFromJson(QJsonObject json, Project *) {
+ this->setX(readInt(&json, "x"));
+ this->setY(readInt(&json, "y"));
+ this->setElevation(readInt(&json, "elevation"));
+ this->setIdName(readString(&json, "local_id"));
+ this->setGfx(readString(&json, "graphics_id"));
+ this->setMovement(readString(&json, "movement_type"));
+ this->setRadiusX(readInt(&json, "movement_range_x"));
+ this->setRadiusY(readInt(&json, "movement_range_y"));
+ this->setTrainerType(readString(&json, "trainer_type"));
+ this->setSightRadiusBerryTreeID(readString(&json, "trainer_sight_or_berry_tree_id"));
+ this->setScript(readString(&json, "script"));
+ this->setFlag(readString(&json, "flag"));
- this->readCustomAttributes(json);
-
+ this->setCustomAttributes(json);
return true;
}
@@ -222,36 +204,34 @@ void ObjectEvent::setDefaultValues(Project *project) {
this->setSightRadiusBerryTreeID("0");
}
-const QSet expectedObjectFields = {
- "local_id",
- "graphics_id",
- "elevation",
- "movement_type",
- "movement_range_x",
- "movement_range_y",
- "trainer_type",
- "trainer_sight_or_berry_tree_id",
- "script",
- "flag",
-};
-
QSet ObjectEvent::getExpectedFields() {
- QSet expectedFields = QSet();
- expectedFields = expectedObjectFields;
+ QSet expectedFields = {
+ "x",
+ "y",
+ "local_id",
+ "graphics_id",
+ "elevation",
+ "movement_type",
+ "movement_range_x",
+ "movement_range_y",
+ "trainer_type",
+ "trainer_sight_or_berry_tree_id",
+ "script",
+ "flag",
+ };
if (projectConfig.eventCloneObjectEnabled) {
expectedFields.insert("type");
}
- expectedFields << "x" << "y";
return expectedFields;
}
-void ObjectEvent::loadPixmap(Project *project) {
+QPixmap ObjectEvent::loadPixmap(Project *project) {
this->pixmap = project->getEventPixmap(this->gfx, this->movement);
if (!this->pixmap.isNull()) {
this->usesDefaultPixmap = false;
- } else {
- Event::loadPixmap(project);
+ return this->pixmap;
}
+ return Event::loadPixmap(project);
}
@@ -282,65 +262,62 @@ EventFrame *CloneObjectEvent::createEventFrame() {
OrderedJson::object CloneObjectEvent::buildEventJson(Project *project) {
OrderedJson::object cloneJson;
- cloneJson["type"] = Event::typeToJsonKey(Event::Type::CloneObject);
QString idName = this->getIdName();
if (!idName.isEmpty())
cloneJson["local_id"] = idName;
+
+ cloneJson["type"] = Event::typeToJsonKey(Event::Type::CloneObject);
cloneJson["graphics_id"] = this->getGfx();
cloneJson["x"] = this->getX();
cloneJson["y"] = this->getY();
cloneJson["target_local_id"] = this->getTargetID();
const QString mapName = this->getTargetMap();
cloneJson["target_map"] = project->getMapConstant(mapName, mapName);
- this->addCustomAttributesTo(&cloneJson);
+ OrderedJson::append(&cloneJson, this->getCustomAttributes());
return cloneJson;
}
-bool CloneObjectEvent::loadFromJson(const QJsonObject &json, Project *project) {
- this->setX(ParseUtil::jsonToInt(json["x"]));
- this->setY(ParseUtil::jsonToInt(json["y"]));
- this->setIdName(ParseUtil::jsonToQString(json["local_id"]));
- this->setGfx(ParseUtil::jsonToQString(json["graphics_id"]));
- this->setTargetID(ParseUtil::jsonToInt(json["target_local_id"]));
+bool CloneObjectEvent::loadFromJson(QJsonObject json, Project *project) {
+ this->setX(readInt(&json, "x"));
+ this->setY(readInt(&json, "y"));
+ this->setIdName(readString(&json, "local_id"));
+ this->setGfx(readString(&json, "graphics_id"));
+ this->setTargetID(readString(&json, "target_local_id"));
// Log a warning if "target_map" isn't a known map ID, but don't overwrite user data.
- const QString mapConstant = ParseUtil::jsonToQString(json["target_map"]);
+ const QString mapConstant = readString(&json, "target_map");
if (!project->mapConstantsToMapNames.contains(mapConstant))
logWarn(QString("Unknown Target Map constant '%1'.").arg(mapConstant));
this->setTargetMap(project->mapConstantsToMapNames.value(mapConstant, mapConstant));
- this->readCustomAttributes(json);
-
+ this->setCustomAttributes(json);
return true;
}
void CloneObjectEvent::setDefaultValues(Project *project) {
this->setGfx(project->gfxDefines.key(0, "0"));
- this->setTargetID(1);
+ this->setTargetID(QString::number(Event::getIndexOffset(Event::Group::Object)));
if (this->getMap()) this->setTargetMap(this->getMap()->name());
}
-const QSet expectedCloneObjectFields = {
- "type",
- "local_id",
- "graphics_id",
- "target_local_id",
- "target_map",
-};
-
QSet CloneObjectEvent::getExpectedFields() {
- QSet expectedFields = QSet();
- expectedFields = expectedCloneObjectFields;
- expectedFields << "x" << "y";
+ static const QSet expectedFields = {
+ "x",
+ "y",
+ "type",
+ "local_id",
+ "graphics_id",
+ "target_local_id",
+ "target_map",
+ };
return expectedFields;
}
-void CloneObjectEvent::loadPixmap(Project *project) {
+QPixmap CloneObjectEvent::loadPixmap(Project *project) {
// Try to get the targeted object to clone
- int eventIndex = this->targetID - 1;
Map *clonedMap = project->loadMap(this->targetMap);
- Event *clonedEvent = clonedMap ? clonedMap->getEvent(Event::Group::Object, eventIndex) : nullptr;
+ Event *clonedEvent = clonedMap ? clonedMap->getEvent(Event::Group::Object, this->targetID) : nullptr;
if (clonedEvent && clonedEvent->getEventType() == Event::Type::Object) {
// Get graphics data from cloned object
@@ -352,7 +329,7 @@ void CloneObjectEvent::loadPixmap(Project *project) {
this->gfx = project->gfxDefines.key(0, "0");
this->movement = project->movementTypes.value(0, "0");
}
- ObjectEvent::loadPixmap(project);
+ return ObjectEvent::loadPixmap(project);
}
@@ -389,25 +366,23 @@ OrderedJson::object WarpEvent::buildEventJson(Project *project) {
warpJson["dest_map"] = project->getMapConstant(mapName, mapName);
warpJson["dest_warp_id"] = this->getDestinationWarpID();
- this->addCustomAttributesTo(&warpJson);
-
+ OrderedJson::append(&warpJson, this->getCustomAttributes());
return warpJson;
}
-bool WarpEvent::loadFromJson(const QJsonObject &json, Project *project) {
- this->setX(ParseUtil::jsonToInt(json["x"]));
- this->setY(ParseUtil::jsonToInt(json["y"]));
- this->setElevation(ParseUtil::jsonToInt(json["elevation"]));
- this->setDestinationWarpID(ParseUtil::jsonToQString(json["dest_warp_id"]));
+bool WarpEvent::loadFromJson(QJsonObject json, Project *project) {
+ this->setX(readInt(&json, "x"));
+ this->setY(readInt(&json, "y"));
+ this->setElevation(readInt(&json, "elevation"));
+ this->setDestinationWarpID(readString(&json, "dest_warp_id"));
// Log a warning if "dest_map" isn't a known map ID, but don't overwrite user data.
- const QString mapConstant = ParseUtil::jsonToQString(json["dest_map"]);
+ const QString mapConstant = readString(&json, "dest_map");
if (!project->mapConstantsToMapNames.contains(mapConstant))
logWarn(QString("Unknown Destination Map constant '%1'.").arg(mapConstant));
this->setDestinationMap(project->mapConstantsToMapNames.value(mapConstant, mapConstant));
- this->readCustomAttributes(json);
-
+ this->setCustomAttributes(json);
return true;
}
@@ -417,16 +392,14 @@ void WarpEvent::setDefaultValues(Project *) {
this->setElevation(0);
}
-const QSet expectedWarpFields = {
- "elevation",
- "dest_map",
- "dest_warp_id",
-};
-
QSet WarpEvent::getExpectedFields() {
- QSet expectedFields = QSet();
- expectedFields = expectedWarpFields;
- expectedFields << "x" << "y";
+ static const QSet expectedFields = {
+ "x",
+ "y",
+ "elevation",
+ "dest_map",
+ "dest_warp_id",
+ };
return expectedFields;
}
@@ -476,21 +449,19 @@ OrderedJson::object TriggerEvent::buildEventJson(Project *) {
triggerJson["var_value"] = this->getScriptVarValue();
triggerJson["script"] = this->getScriptLabel();
- this->addCustomAttributesTo(&triggerJson);
-
+ OrderedJson::append(&triggerJson, this->getCustomAttributes());
return triggerJson;
}
-bool TriggerEvent::loadFromJson(const QJsonObject &json, Project *) {
- this->setX(ParseUtil::jsonToInt(json["x"]));
- this->setY(ParseUtil::jsonToInt(json["y"]));
- this->setElevation(ParseUtil::jsonToInt(json["elevation"]));
- this->setScriptVar(ParseUtil::jsonToQString(json["var"]));
- this->setScriptVarValue(ParseUtil::jsonToQString(json["var_value"]));
- this->setScriptLabel(ParseUtil::jsonToQString(json["script"]));
-
- this->readCustomAttributes(json);
+bool TriggerEvent::loadFromJson(QJsonObject json, Project *) {
+ this->setX(readInt(&json, "x"));
+ this->setY(readInt(&json, "y"));
+ this->setElevation(readInt(&json, "elevation"));
+ this->setScriptVar(readString(&json, "var"));
+ this->setScriptVarValue(readString(&json, "var_value"));
+ this->setScriptLabel(readString(&json, "script"));
+ this->setCustomAttributes(json);
return true;
}
@@ -501,18 +472,16 @@ void TriggerEvent::setDefaultValues(Project *project) {
this->setElevation(0);
}
-const QSet expectedTriggerFields = {
- "type",
- "elevation",
- "var",
- "var_value",
- "script",
-};
-
QSet TriggerEvent::getExpectedFields() {
- QSet expectedFields = QSet();
- expectedFields = expectedTriggerFields;
- expectedFields << "x" << "y";
+ static const QSet expectedFields = {
+ "x",
+ "y",
+ "type",
+ "elevation",
+ "var",
+ "var_value",
+ "script",
+ };
return expectedFields;
}
@@ -548,19 +517,17 @@ OrderedJson::object WeatherTriggerEvent::buildEventJson(Project *) {
weatherJson["elevation"] = this->getElevation();
weatherJson["weather"] = this->getWeather();
- this->addCustomAttributesTo(&weatherJson);
-
+ OrderedJson::append(&weatherJson, this->getCustomAttributes());
return weatherJson;
}
-bool WeatherTriggerEvent::loadFromJson(const QJsonObject &json, Project *) {
- this->setX(ParseUtil::jsonToInt(json["x"]));
- this->setY(ParseUtil::jsonToInt(json["y"]));
- this->setElevation(ParseUtil::jsonToInt(json["elevation"]));
- this->setWeather(ParseUtil::jsonToQString(json["weather"]));
-
- this->readCustomAttributes(json);
+bool WeatherTriggerEvent::loadFromJson(QJsonObject json, Project *) {
+ this->setX(readInt(&json, "x"));
+ this->setY(readInt(&json, "y"));
+ this->setElevation(readInt(&json, "elevation"));
+ this->setWeather(readString(&json, "weather"));
+ this->setCustomAttributes(json);
return true;
}
@@ -569,16 +536,14 @@ void WeatherTriggerEvent::setDefaultValues(Project *project) {
this->setElevation(0);
}
-const QSet expectedWeatherTriggerFields = {
- "type",
- "elevation",
- "weather",
-};
-
QSet WeatherTriggerEvent::getExpectedFields() {
- QSet expectedFields = QSet();
- expectedFields = expectedWeatherTriggerFields;
- expectedFields << "x" << "y";
+ static const QSet expectedFields = {
+ "x",
+ "y",
+ "type",
+ "elevation",
+ "weather",
+ };
return expectedFields;
}
@@ -616,20 +581,18 @@ OrderedJson::object SignEvent::buildEventJson(Project *) {
signJson["player_facing_dir"] = this->getFacingDirection();
signJson["script"] = this->getScriptLabel();
- this->addCustomAttributesTo(&signJson);
-
+ OrderedJson::append(&signJson, this->getCustomAttributes());
return signJson;
}
-bool SignEvent::loadFromJson(const QJsonObject &json, Project *) {
- this->setX(ParseUtil::jsonToInt(json["x"]));
- this->setY(ParseUtil::jsonToInt(json["y"]));
- this->setElevation(ParseUtil::jsonToInt(json["elevation"]));
- this->setFacingDirection(ParseUtil::jsonToQString(json["player_facing_dir"]));
- this->setScriptLabel(ParseUtil::jsonToQString(json["script"]));
-
- this->readCustomAttributes(json);
+bool SignEvent::loadFromJson(QJsonObject json, Project *) {
+ this->setX(readInt(&json, "x"));
+ this->setY(readInt(&json, "y"));
+ this->setElevation(readInt(&json, "elevation"));
+ this->setFacingDirection(readString(&json, "player_facing_dir"));
+ this->setScriptLabel(readString(&json, "script"));
+ this->setCustomAttributes(json);
return true;
}
@@ -639,17 +602,15 @@ void SignEvent::setDefaultValues(Project *project) {
this->setElevation(0);
}
-const QSet