diff --git a/docs/_sources/manual/project-files.rst.txt b/docs/_sources/manual/project-files.rst.txt
index e9e0e652..bbc71d70 100644
--- a/docs/_sources/manual/project-files.rst.txt
+++ b/docs/_sources/manual/project-files.rst.txt
@@ -47,6 +47,7 @@ The filepath that Porymap expects for each file can be overridden on the ``Files
src/data/object_events/object_event_graphics.h, yes, no, ``data_obj_event_gfx``, "to locate object event sprites using data from ``data_obj_event_pic_tables``"
src/data/graphics/pokemon.h, yes, no, ``data_pokemon_gfx``, "if ``symbol_pokemon_icon_table`` is read this file will be searched for filepaths to species icon"
src/data/region_map/region_map_sections.json, yes, yes, ``json_region_map_entries``, "for populating the locations list and for region map data"
+ src/data/region_map/regions.json, yes, yes, ``json_region_entries``, "For populating the regions list and for region map data"
src/data/region_map/porymap_config.json, yes, yes, ``json_region_porymap_cfg``, "Porymap's config file for the region map editor"
include/constants/global.h, yes, no, ``constants_global``, "to evaluate ``define_obj_event_count``"
include/constants/items.h, yes, no, ``constants_items``, "to find ``regex_items`` names"
diff --git a/docs/manual/project-files.html b/docs/manual/project-files.html
index d220769e..d326e86d 100644
--- a/docs/manual/project-files.html
+++ b/docs/manual/project-files.html
@@ -596,145 +596,151 @@ to a file, it probably is not a good idea to edit yourself unless otherwise note
json_region_map_entries
|
for populating the locations list and for region map data |
-src/data/region_map/porymap_config.json |
+
src/data/region_map/regions.json |
+yes |
+yes |
+json_region_entries
|
+For populating the regions list and for region map data |
+
+src/data/region_map/porymap_config.json |
yes |
yes |
json_region_porymap_cfg
|
Porymap’s config file for the region map editor |
-include/constants/global.h |
+
include/constants/global.h |
yes |
no |
constants_global
|
to evaluate define_obj_event_count |
-include/constants/items.h |
+
include/constants/items.h |
yes |
no |
constants_items
|
to find regex_items names |
-include/constants/flags.h |
+
include/constants/flags.h |
yes |
no |
constants_flags
|
to find regex_flags names |
-include/constants/vars.h |
+
include/constants/vars.h |
yes |
no |
constants_vars
|
to find regex_vars names |
-include/constants/weather.h |
+
include/constants/weather.h |
yes |
no |
constants_weather
|
to find regex_weather names |
-include/constants/songs.h |
+
include/constants/songs.h |
yes |
no |
constants_songs
|
to find regex_music names |
-include/constants/pokemon.h |
+
include/constants/pokemon.h |
yes |
no |
constants_pokemon
|
to evaluate define_min_level and define_max_level |
-include/constants/map_types.h |
+
include/constants/map_types.h |
yes |
no |
constants_map_types
|
to find regex_map_types and regex_battle_scenes names |
-include/constants/trainer_types.h |
+
include/constants/trainer_types.h |
yes |
no |
constants_trainer_types
|
to find regex_trainer_types names |
-include/constants/secret_bases.h |
+
include/constants/secret_bases.h |
yes |
no |
constants_secret_bases
|
to find regex_secret_bases names |
-include/constants/event_object_movement.h |
+
include/constants/event_object_movement.h |
yes |
no |
constants_obj_event_movement
|
to find regex_movement_types names |
-include/constants/event_objects.h |
+
include/constants/event_objects.h |
yes |
no |
constants_obj_events
|
to evaluate regex_obj_event_gfx constants |
-include/constants/event_bg.h |
+
include/constants/event_bg.h |
yes |
no |
constants_event_bg
|
to find regex_sign_facing_directions names |
-include/constants/metatile_labels.h |
+
include/constants/metatile_labels.h |
yes |
yes |
constants_metatile_labels
|
to read/write metatile labels using define_metatile_label_prefix |
-include/constants/metatile_behaviors.h |
+
include/constants/metatile_behaviors.h |
yes |
no |
constants_metatile_behaviors
|
to evaluate regex_behaviors constants |
-include/constants/species.h |
+
include/constants/species.h |
yes |
no |
constants_species
|
to find names using define_species_prefix |
-include/global.fieldmap.h |
+
include/global.fieldmap.h |
yes |
no |
global_fieldmap
|
to evaluate map and tileset data masks, and to read regex_encounter_types / regex_terrain_types |
-include/fieldmap.h |
+
include/fieldmap.h |
yes |
no |
constants_fieldmap
|
to evaluate a variety of tileset and map constants |
-src/fieldmap.c |
+
src/fieldmap.c |
yes |
no |
fieldmap
|
to read symbol_attribute_table |
-src/event_object_movement.c |
+
src/event_object_movement.c |
yes |
no |
initial_facing_table
|
to read symbol_facing_directions |
-src/wild_encounter.c |
+
src/wild_encounter.c |
yes |
no |
wild_encounter
|
to evaluate define_max_encounter_rate |
-src/pokemon_icon.c |
+
src/pokemon_icon.c |
yes |
no |
pokemon_icon_table
|
to read symbol_pokemon_icon_table |
-graphics/pokemon/ |
+
graphics/pokemon/ |
yes |
no |
pokemon_gfx
|
diff --git a/docsrc/manual/project-files.rst b/docsrc/manual/project-files.rst
index e9e0e652..bbc71d70 100644
--- a/docsrc/manual/project-files.rst
+++ b/docsrc/manual/project-files.rst
@@ -47,6 +47,7 @@ The filepath that Porymap expects for each file can be overridden on the ``Files
src/data/object_events/object_event_graphics.h, yes, no, ``data_obj_event_gfx``, "to locate object event sprites using data from ``data_obj_event_pic_tables``"
src/data/graphics/pokemon.h, yes, no, ``data_pokemon_gfx``, "if ``symbol_pokemon_icon_table`` is read this file will be searched for filepaths to species icon"
src/data/region_map/region_map_sections.json, yes, yes, ``json_region_map_entries``, "for populating the locations list and for region map data"
+ src/data/region_map/regions.json, yes, yes, ``json_region_entries``, "For populating the regions list and for region map data"
src/data/region_map/porymap_config.json, yes, yes, ``json_region_porymap_cfg``, "Porymap's config file for the region map editor"
include/constants/global.h, yes, no, ``constants_global``, "to evaluate ``define_obj_event_count``"
include/constants/items.h, yes, no, ``constants_items``, "to find ``regex_items`` names"
diff --git a/forms/mapheaderform.ui b/forms/mapheaderform.ui
index d4fc36f3..3349288a 100644
--- a/forms/mapheaderform.ui
+++ b/forms/mapheaderform.ui
@@ -40,14 +40,14 @@
- -
+
-
Location
- -
+
-
<html><head/><body><p>The section of the region map which the map is grouped under. This also determines the name of the map that is displayed when the player enters it.</p></body></html>
@@ -60,14 +60,14 @@
- -
+
-
Requires Flash
- -
+
-
<html><head/><body><p>If checked, the player will need to use Flash to see fully on this map.</p></body></html>
@@ -77,14 +77,14 @@
- -
+
-
Weather
- -
+
-
<html><head/><body><p>The default weather on this map.</p></body></html>
@@ -97,14 +97,14 @@
- -
+
-
Type
- -
+
-
<html><head/><body><p>The map type is a general attribute, which is used for many different things. For example, underground type maps will have a special transition effect when the player enters/exits the map.</p></body></html>
@@ -117,14 +117,14 @@
- -
+
-
Battle Scene
- -
+
-
<html><head/><body><p>This field is used to help determine what graphics to use in the background of battles on this map.</p></body></html>
@@ -137,14 +137,14 @@
- -
+
-
Show Location Name
- -
+
-
<html><head/><body><p>If checked, a map name popup will appear when the player enters this map. The name that appears on this popup depends on the Location field.</p></body></html>
@@ -154,14 +154,14 @@
- -
+
-
Allow Running
- -
+
-
<html><head/><body><p>If checked, the player will be allowed to run on this map.</p></body></html>
@@ -171,14 +171,14 @@
- -
+
-
Allow Biking
- -
+
-
<html><head/><body><p>If checked, the player will be allowed to get on their bike on this map.</p></body></html>
@@ -188,14 +188,14 @@
- -
+
-
Allow Dig & Escape Rope
- -
+
-
<html><head/><body><p>If checked, the player will be allowed to use Dig or Escape Rope on this map.</p></body></html>
@@ -205,34 +205,44 @@
- -
+
-
Floor Number
- -
+
-
<html><head/><body><p>Floor number to be used for maps with elevators.</p></body></html>
- -
+
-
Location Name
- -
+
-
<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>
+ -
+
+
+ Region
+
+
+
+ -
+
+
diff --git a/include/config.h b/include/config.h
index ae1d1d2c..ed667b87 100644
--- a/include/config.h
+++ b/include/config.h
@@ -225,6 +225,9 @@ enum ProjectIdentifier {
define_map_empty,
define_map_section_prefix,
define_map_section_empty,
+ define_region_prefix,
+ define_region_empty,
+ define_region_count,
define_species_prefix,
define_species_empty,
regex_behaviors,
@@ -259,6 +262,7 @@ enum ProjectFilePath {
json_wild_encounters,
json_heal_locations,
json_region_map_entries,
+ json_region_entries,
json_region_porymap_cfg,
tilesets_headers,
tilesets_graphics,
diff --git a/include/core/mapheader.h b/include/core/mapheader.h
index 2058280a..7c18b734 100644
--- a/include/core/mapheader.h
+++ b/include/core/mapheader.h
@@ -14,6 +14,7 @@ public:
bool operator==(const MapHeader& other) const {
return m_song == other.m_song
&& m_location == other.m_location
+ && m_region == other.m_region
&& m_requiresFlash == other.m_requiresFlash
&& m_weather == other.m_weather
&& m_type == other.m_type
@@ -30,6 +31,8 @@ public:
void setSong(const QString &song);
void setLocation(const QString &location);
+ void setRegion(const QString ®ion);
+ void setUsesMultiRegion(bool usesMultiRegion);
void setRequiresFlash(bool requiresFlash);
void setWeather(const QString &weather);
void setType(const QString &type);
@@ -42,6 +45,8 @@ public:
QString song() const { return m_song; }
QString location() const { return m_location; }
+ QString region() const { return m_region; }
+ bool usesMultiRegion() const { return m_usesMultiRegion; }
bool requiresFlash() const { return m_requiresFlash; }
QString weather() const { return m_weather; }
QString type() const { return m_type; }
@@ -55,6 +60,8 @@ public:
signals:
void songChanged(QString);
void locationChanged(QString);
+ void regionChanged(QString);
+ void usesMultiRegionChanged(bool);
void requiresFlashChanged(bool);
void weatherChanged(QString);
void typeChanged(QString);
@@ -69,6 +76,8 @@ signals:
private:
QString m_song;
QString m_location;
+ QString m_region;
+ bool m_usesMultiRegion = false;
bool m_requiresFlash = false;
QString m_weather;
QString m_type;
diff --git a/include/project.h b/include/project.h
index c377362b..89d72dd3 100644
--- a/include/project.h
+++ b/include/project.h
@@ -52,6 +52,11 @@ public:
QStringList bgEventFacingDirections;
QStringList trainerTypes;
QStringList globalScriptLabels;
+ QStringList mapSectionIdNamesSaveOrder;
+ QStringList mapSectionIdNames;
+ QStringList regionIdNamesSaveOrder;
+ QStringList regionIdNames;
+ bool usingMultiRegion;
QMap encounterTypeToName;
QMap terrainTypeToName;
QMap> metatileLabelsMap;
@@ -187,6 +192,7 @@ public:
bool readTilesetLabels();
bool readTilesetMetatileLabels();
bool readRegionMapSections();
+ bool readRegionEntries();
bool readItemNames();
bool readFlagNames();
bool readVarNames();
@@ -273,6 +279,7 @@ public:
static int getNumPalettesTotal() { return num_pals_total; }
static int getNumPalettesSecondary() { return getNumPalettesTotal() - getNumPalettesPrimary(); }
static QString getEmptyMapsecName();
+ static QString getEmptyRegionName();
static QString getMapGroupPrefix();
private:
@@ -289,8 +296,6 @@ private:
QStringList orderedLayoutIdsMaster;
QHash mapLayouts;
QHash mapLayoutsMaster;
- QStringList mapSectionIdNamesSaveOrder;
- QStringList mapSectionIdNames;
// Fields for preserving top-level JSON data that Porymap isn't expecting.
QJsonObject customLayoutsData;
@@ -339,6 +344,14 @@ private:
};
QHash locationData;
+ // The extra data that can be associated with each REGION name.
+ struct RegionData
+ {
+ QString displayName;
+ QString displayText;
+ };
+ QHash regionData;
+
QJsonDocument readMapJson(const QString &mapName, QString *error = nullptr);
void setNewLayoutBlockdata(Layout *layout);
@@ -384,6 +397,7 @@ signals:
void mapSectionAdded(const QString &idName);
void mapSectionDisplayNameChanged(const QString &idName, const QString &displayName);
void mapSectionIdNamesChanged(const QStringList &idNames);
+ void regionIdNamesChanged(const QStringList &idNames);
void eventScriptLabelsRead();
};
diff --git a/include/ui/mapheaderform.h b/include/ui/mapheaderform.h
index fb4f7aa9..da2a9a87 100644
--- a/include/ui/mapheaderform.h
+++ b/include/ui/mapheaderform.h
@@ -35,6 +35,7 @@ public:
void setSong(const QString &song);
void setLocation(const QString &location);
+ void setRegion(const QString ®ion);
void setLocationName(const QString &locationName);
void setRequiresFlash(bool requiresFlash);
void setWeather(const QString &weather);
@@ -48,6 +49,7 @@ public:
QString song() const;
QString location() const;
+ QString region() const;
QString locationName() const;
bool requiresFlash() const;
QString weather() const;
@@ -68,10 +70,12 @@ private:
void setText(NoScrollComboBox *combo, const QString &text) const;
void setText(QLineEdit *lineEdit, const QString &text) const;
void setLocations(const QStringList &locations);
+ void setRegions(const QStringList ®ions);
void updateLocationName();
void onSongUpdated(const QString &song);
void onLocationChanged(const QString &location);
+ void onRegionChanged(const QString ®ion);
void onLocationNameChanged(const QString &locationName);
void onWeatherChanged(const QString &weather);
void onTypeChanged(const QString &type);
diff --git a/src/config.cpp b/src/config.cpp
index b2c2d9dc..aca22dbb 100644
--- a/src/config.cpp
+++ b/src/config.cpp
@@ -114,6 +114,9 @@ const QMap> ProjectConfig::defaultIde
{ProjectIdentifier::define_map_empty, {"define_map_empty", "MAP_UNDEFINED"}},
{ProjectIdentifier::define_map_section_prefix, {"define_map_section_prefix", "MAPSEC_"}},
{ProjectIdentifier::define_map_section_empty, {"define_map_section_empty", "NONE"}},
+ {ProjectIdentifier::define_region_prefix, {"define_region_prefix", "REGION_"}},
+ {ProjectIdentifier::define_region_empty, {"define_region_empty", "NONE"}},
+ {ProjectIdentifier::define_region_count, {"define_region_count", "REGIONS_COUNT"}},
{ProjectIdentifier::define_species_prefix, {"define_species_prefix", "SPECIES_"}},
{ProjectIdentifier::define_species_empty, {"define_species_empty", "NONE"}},
// Regex
@@ -150,6 +153,7 @@ const QMap> ProjectConfig::defaultPaths
{ProjectFilePath::json_wild_encounters, { "json_wild_encounters", "src/data/wild_encounters.json"}},
{ProjectFilePath::json_heal_locations, { "json_heal_locations", "src/data/heal_locations.json"}},
{ProjectFilePath::json_region_map_entries, { "json_region_map_entries", "src/data/region_map/region_map_sections.json"}},
+ {ProjectFilePath::json_region_entries, { "json_region_entries", "src/data/region_map/regions.json"}},
{ProjectFilePath::json_region_porymap_cfg, { "json_region_porymap_cfg", "src/data/region_map/porymap_config.json"}},
{ProjectFilePath::tilesets_headers, { "tilesets_headers", "src/data/tilesets/headers.h"}},
{ProjectFilePath::tilesets_graphics, { "tilesets_graphics", "src/data/tilesets/graphics.h"}},
diff --git a/src/core/mapheader.cpp b/src/core/mapheader.cpp
index 689a52dc..1fc18aba 100644
--- a/src/core/mapheader.cpp
+++ b/src/core/mapheader.cpp
@@ -3,6 +3,7 @@
MapHeader::MapHeader(const MapHeader& other) : MapHeader() {
m_song = other.m_song;
m_location = other.m_location;
+ m_region = other.m_region;
m_requiresFlash = other.m_requiresFlash;
m_weather = other.m_weather;
m_type = other.m_type;
@@ -20,6 +21,7 @@ MapHeader &MapHeader::operator=(const MapHeader &other) {
// repeatedly (but for now at least that's not a big issue).
setSong(other.m_song);
setLocation(other.m_location);
+ setRegion((other.m_region));
setRequiresFlash(other.m_requiresFlash);
setWeather(other.m_weather);
setType(other.m_type);
@@ -48,6 +50,22 @@ void MapHeader::setLocation(const QString &location) {
emit modified();
}
+void MapHeader::setRegion(const QString ®ion) {
+ if (m_region == region)
+ return;
+ m_region = region;
+ emit regionChanged(m_region);
+ emit modified();
+}
+
+void MapHeader::setUsesMultiRegion(bool usesMultiRegion) {
+ if (m_usesMultiRegion == usesMultiRegion)
+ return;
+ m_usesMultiRegion = usesMultiRegion;
+ emit usesMultiRegionChanged(m_usesMultiRegion);
+ emit modified();
+}
+
void MapHeader::setRequiresFlash(bool requiresFlash) {
if (m_requiresFlash == requiresFlash)
return;
diff --git a/src/project.cpp b/src/project.cpp
index 6fd27b17..c4df1b09 100644
--- a/src/project.cpp
+++ b/src/project.cpp
@@ -218,7 +218,7 @@ bool Project::load() {
&& readSongNames()
&& readMapGroups()
&& readHealLocations();
-
+ this->usingMultiRegion = readRegionEntries();
if (success) {
// No need to do this if something failed to load.
// (and in fact we shouldn't, because they contain
@@ -445,6 +445,14 @@ bool Project::loadMapData(Map* map) {
map->header()->setType(ParseUtil::jsonToQString(mapObj.take("map_type")));
map->header()->setShowsLocationName(ParseUtil::jsonToBool(mapObj.take("show_map_name")));
map->header()->setBattleScene(ParseUtil::jsonToQString(mapObj.take("battle_scene")));
+
+ if (this->usingMultiRegion) {
+ if (mapObj.contains("region")) {
+ map->header()->setRegion(ParseUtil::jsonToQString(mapObj.take("region")));
+ } else {
+ map->header()->setRegion(getEmptyRegionName());
+ }
+ }
if (projectConfig.mapAllowFlagsEnabled) {
map->header()->setAllowsBiking(ParseUtil::jsonToBool(mapObj.take("allow_cycling")));
@@ -1369,6 +1377,11 @@ bool Project::saveMap(Map *map, bool skipLayout) {
mapObj["layout"] = map->layoutId();
mapObj["music"] = map->header()->song();
mapObj["region_map_section"] = map->header()->location();
+ if (this->usingMultiRegion) {
+ if (map->header()->region() != getEmptyRegionName()) {
+ mapObj["region"] = map->header()->region();
+ }
+ }
mapObj["requires_flash"] = map->header()->requiresFlash();
mapObj["weather"] = map->header()->weather();
mapObj["map_type"] = map->header()->type();
@@ -2169,6 +2182,8 @@ bool Project::isIdentifierUnique(const QString &identifier) const {
return false;
if (this->mapSectionIdNames.contains(identifier))
return false;
+ if (this->regionIdNames.contains(identifier))
+ return false;
if (this->tilesetLabelsOrdered.contains(identifier))
return false;
if (this->mapLayouts.contains(identifier))
@@ -2227,6 +2242,8 @@ void Project::initNewMapSettings() {
this->newMapSettings.header.setSong(this->defaultSong);
this->newMapSettings.header.setLocation(this->mapSectionIdNames.value(0, "0"));
+ this->newMapSettings.header.setRegion(this->regionIdNames.value(0, "0"));
+ this->newMapSettings.header.setUsesMultiRegion(this->usingMultiRegion);
this->newMapSettings.header.setRequiresFlash(false);
this->newMapSettings.header.setWeather(this->weatherNames.value(0, "0"));
this->newMapSettings.header.setType(this->mapTypes.value(0, "0"));
@@ -2651,6 +2668,71 @@ bool Project::readRegionMapSections() {
return true;
}
+bool Project::readRegionEntries()
+{
+ this->regionData.clear();
+ this->regionIdNames.clear();
+ this->regionIdNamesSaveOrder.clear();
+
+ const QString defaultName = getEmptyRegionName();
+ const QString requiredPrefix = projectConfig.getIdentifier(ProjectIdentifier::define_region_prefix);
+
+ QJsonDocument doc;
+ const QString filepath = projectConfig.getFilePath(ProjectFilePath::json_region_entries);
+ QString error;
+ if (!parser.tryParseJsonFile(&doc, filepath, &error)) {
+ logWarn(QString("Failed to read region entries from '%1': %2").arg(filepath).arg(error));
+ return false;
+ }
+ watchFile(filepath);
+
+ // Make sure the default name is present in the list.
+ if (!this->regionIdNames.contains(defaultName)) {
+ this->regionIdNames.append(defaultName);
+ }
+
+ QJsonObject regionsGlobalObj = doc.object();
+ QJsonArray regions = regionsGlobalObj.take("regions").toArray();
+ logInfo(QString("[REGION] Loading %1 regions from %2").arg(regions.size()).arg(filepath));
+ for (int i = 0; i < regions.size(); i++) {
+ QJsonObject regionObj = regions.at(i).toObject();
+
+ // For each region, "id" is the only required field. This is the field we use to display the region names in various drop-downs.
+ QString idField = "id";
+
+ const QString idName = ParseUtil::jsonToQString(regionObj.take(idField));
+ if (!idName.startsWith(requiredPrefix)) {
+ logWarn(QString("Ignoring data for region '%1' in '%2'. IDs must start with the prefix '%3'").arg(idName).arg(filepath).arg(requiredPrefix));
+ continue;
+ }
+ logInfo(QString("[REGION] Region ID: %1").arg(idName));
+ this->regionIdNames.append(idName);
+ this->regionIdNamesSaveOrder.append(idName);
+
+ // Regions in the json file have additional data for generating region name strings.
+ RegionData region;
+ if (regionObj.contains("name")) {
+ region.displayName = ParseUtil::jsonToQString(regionObj.take("name"));
+ } else {
+ QString suffix = idName.mid(requiredPrefix.length());
+ QString normalizedName = suffix.toLower();
+ if (!normalizedName.isEmpty()) {
+ normalizedName[0] = normalizedName[0].toUpper();
+ }
+ region.displayName = normalizedName;
+ }
+ if (regionObj.contains("text")) {
+ region.displayText = ParseUtil::jsonToQString(regionObj.take("text"));
+ } else {
+ region.displayText = idName.mid(requiredPrefix.length());
+ }
+ this->regionData.insert(idName, region);
+ }
+ Util::numericalModeSort(this->regionIdNames);
+
+ return true;
+}
+
void Project::setRegionMapEntries(const QHash &entries) {
for (auto it = this->locationData.keyBegin(); it != this->locationData.keyEnd(); it++) {
this->locationData[*it].map = entries.value(*it);
@@ -2672,6 +2754,10 @@ QString Project::getEmptyMapsecName() {
return projectConfig.getIdentifier(ProjectIdentifier::define_map_section_prefix) + projectConfig.getIdentifier(ProjectIdentifier::define_map_section_empty);
}
+QString Project::getEmptyRegionName() {
+ return projectConfig.getIdentifier(ProjectIdentifier::define_region_prefix) + projectConfig.getIdentifier(ProjectIdentifier::define_region_empty);
+}
+
QString Project::getMapGroupPrefix() {
// We could expose this to users, but it's never enforced so it probably won't affect anyone.
return QStringLiteral("gMapGroup_");
diff --git a/src/ui/mapheaderform.cpp b/src/ui/mapheaderform.cpp
index 921aec82..c6f2fb44 100644
--- a/src/ui/mapheaderform.cpp
+++ b/src/ui/mapheaderform.cpp
@@ -16,6 +16,7 @@ MapHeaderForm::MapHeaderForm(QWidget *parent)
connect(ui->comboBox_Song, &QComboBox::currentTextChanged, this, &MapHeaderForm::onSongUpdated);
connect(ui->comboBox_Location, &QComboBox::currentTextChanged, this, &MapHeaderForm::onLocationChanged);
+ connect(ui->comboBox_Region, &QComboBox::currentTextChanged, this, &MapHeaderForm::onRegionChanged);
connect(ui->comboBox_Weather, &QComboBox::currentTextChanged, this, &MapHeaderForm::onWeatherChanged);
connect(ui->comboBox_Type, &QComboBox::currentTextChanged, this, &MapHeaderForm::onTypeChanged);
connect(ui->comboBox_BattleScene, &QComboBox::currentTextChanged, this, &MapHeaderForm::onBattleSceneChanged);
@@ -69,6 +70,10 @@ void MapHeaderForm::setProject(Project * project, bool allowChanges) {
ui->comboBox_Location->clear();
ui->comboBox_Location->addItems(m_project->locationNames());
+ const QSignalBlocker b_Regions(ui->comboBox_Region);
+ ui->comboBox_Region->clear();
+ ui->comboBox_Region->addItems(m_project->regionIdNames);
+
// Hide config-specific settings
bool hasFlags = projectConfig.mapAllowFlagsEnabled;
@@ -83,8 +88,13 @@ void MapHeaderForm::setProject(Project * project, bool allowChanges) {
ui->spinBox_FloorNumber->setVisible(floorNumEnabled);
ui->label_FloorNumber->setVisible(floorNumEnabled);
+ // Enable/disable region combo box
+ ui->label_Region->setVisible(m_project->usingMultiRegion);
+ ui->comboBox_Region->setVisible(m_project->usingMultiRegion);
+
// If the project changes any of the displayed data, update it accordingly.
connect(m_project, &Project::mapSectionIdNamesChanged, this, &MapHeaderForm::setLocations);
+ connect(m_project, &Project::regionIdNamesChanged, this, &MapHeaderForm::setRegions);
connect(m_project, &Project::mapSectionDisplayNameChanged, this, &MapHeaderForm::updateLocationName);
}
@@ -96,6 +106,14 @@ void MapHeaderForm::setLocations(const QStringList &locations) {
ui->comboBox_Location->setTextItem(before);
}
+void MapHeaderForm::setRegions(const QStringList ®ions) {
+ const QSignalBlocker b(ui->comboBox_Region);
+ const QString before = ui->comboBox_Region->currentText();
+ ui->comboBox_Region->clear();
+ ui->comboBox_Region->addItems(regions);
+ ui->comboBox_Region->setTextItem(before);
+}
+
// Assign a MapHeader that the form will keep in sync with the UI.
void MapHeaderForm::setHeader(MapHeader *header) {
if (m_header == header)
@@ -114,6 +132,7 @@ void MapHeaderForm::setHeader(MapHeader *header) {
// If the MapHeader is changed externally (for example, with the scripting API) update the UI accordingly
connect(m_header, &MapHeader::songChanged, this, &MapHeaderForm::setSong);
connect(m_header, &MapHeader::locationChanged, this, &MapHeaderForm::setLocation);
+ connect(m_header, &MapHeader::regionChanged, this, &MapHeaderForm::setRegion);
connect(m_header, &MapHeader::requiresFlashChanged, this, &MapHeaderForm::setRequiresFlash);
connect(m_header, &MapHeader::weatherChanged, this, &MapHeaderForm::setWeather);
connect(m_header, &MapHeader::typeChanged, this, &MapHeaderForm::setType);
@@ -136,6 +155,7 @@ void MapHeaderForm::clear() {
void MapHeaderForm::setHeaderData(const MapHeader &header) {
setSong(header.song());
setLocation(header.location());
+ setRegion(header.region());
setRequiresFlash(header.requiresFlash());
setWeather(header.weather());
setType(header.type());
@@ -156,6 +176,7 @@ MapHeader MapHeaderForm::headerData() const {
MapHeader header;
header.setSong(song());
header.setLocation(location());
+ header.setRegion(region());
header.setRequiresFlash(requiresFlash());
header.setWeather(weather());
header.setType(type());
@@ -175,6 +196,7 @@ void MapHeaderForm::updateLocationName() {
// Set data in UI
void MapHeaderForm::setSong(const QString &song) { setText(ui->comboBox_Song, song); }
void MapHeaderForm::setLocation(const QString &location) { setText(ui->comboBox_Location, location); }
+void MapHeaderForm::setRegion(const QString ®ion) { setText(ui->comboBox_Region, region); }
void MapHeaderForm::setLocationName(const QString &locationName) { setText(ui->lineEdit_LocationName, locationName); }
void MapHeaderForm::setRequiresFlash(bool requiresFlash) { ui->checkBox_RequiresFlash->setChecked(requiresFlash); }
void MapHeaderForm::setWeather(const QString &weather) { setText(ui->comboBox_Weather, weather); }
@@ -199,6 +221,7 @@ void MapHeaderForm::setText(QLineEdit *lineEdit, const QString &text) const {
// Read data from UI
QString MapHeaderForm::song() const { return ui->comboBox_Song->currentText(); }
QString MapHeaderForm::location() const { return ui->comboBox_Location->currentText(); }
+QString MapHeaderForm::region() const { return ui->comboBox_Region->currentText(); }
QString MapHeaderForm::locationName() const { return ui->lineEdit_LocationName->text(); }
bool MapHeaderForm::requiresFlash() const { return ui->checkBox_RequiresFlash->isChecked(); }
QString MapHeaderForm::weather() const { return ui->comboBox_Weather->currentText(); }
@@ -225,6 +248,7 @@ void MapHeaderForm::onLocationChanged(const QString &location) {
if (m_header) m_header->setLocation(location);
updateLocationName();
}
+void MapHeaderForm::onRegionChanged(const QString ®ion) { if (m_header) m_header->setRegion(region); }
void MapHeaderForm::onLocationNameChanged(const QString &locationName) {
if (m_project && m_allowProjectChanges) {
// The location name is actually part of the project, not the map header.