diff --git a/forms/projectsettingseditor.ui b/forms/projectsettingseditor.ui
index 653ef34f..72832b4b 100644
--- a/forms/projectsettingseditor.ui
+++ b/forms/projectsettingseditor.ui
@@ -370,7 +370,7 @@
0
0
531
- 490
+ 566
@@ -579,6 +579,57 @@
+ -
+
+
+ Map Data Layout
+
+
+
-
+
+
+ Metatile ID
+
+
+
+ -
+
+
+ Collision
+
+
+
+ -
+
+
+ Elevation
+
+
+
+ -
+
+
+ The mask used to read/write metatile IDs in map data.
+
+
+
+ -
+
+
+ The mask used to read/write collision values in map data.
+
+
+
+ -
+
+
+ The mask used to read/write elevation values in map data.
+
+
+
+
+
+
-
diff --git a/include/config.h b/include/config.h
index 8a0cbbed..4191bc98 100644
--- a/include/config.h
+++ b/include/config.h
@@ -243,6 +243,9 @@ public:
this->collisionSheetPath = QString();
this->collisionSheetWidth = 2;
this->collisionSheetHeight = 16;
+ this->blockMetatileIdMask = 0x03FF;
+ this->blockCollisionMask = 0x0C00;
+ this->blockElevationMask = 0xF000;
this->readKeys.clear();
}
static const QMap> defaultPaths;
@@ -313,6 +316,12 @@ public:
void setMetatileTerrainTypeMask(uint32_t mask);
void setMetatileEncounterTypeMask(uint32_t mask);
void setMetatileLayerTypeMask(uint32_t mask);
+ uint16_t getBlockMetatileIdMask();
+ uint16_t getBlockCollisionMask();
+ uint16_t getBlockElevationMask();
+ void setBlockMetatileIdMask(uint16_t mask);
+ void setBlockCollisionMask(uint16_t mask);
+ void setBlockElevationMask(uint16_t mask);
bool getMapAllowFlagsEnabled();
void setMapAllowFlagsEnabled(bool enabled);
void setEventIconPath(Event::Group group, const QString &path);
@@ -364,6 +373,9 @@ private:
uint32_t metatileTerrainTypeMask;
uint32_t metatileEncounterTypeMask;
uint32_t metatileLayerTypeMask;
+ uint16_t blockMetatileIdMask;
+ uint16_t blockCollisionMask;
+ uint16_t blockElevationMask;
bool enableMapAllowFlags;
QMap eventIconPaths;
QHash pokemonIconPaths;
diff --git a/src/config.cpp b/src/config.cpp
index 6307db02..e82a5dd3 100644
--- a/src/config.cpp
+++ b/src/config.cpp
@@ -688,6 +688,12 @@ void ProjectConfig::parseConfigKeyValue(QString key, QString value) {
this->metatileEncounterTypeMask = getConfigUint32(key, value);
} else if (key == "metatile_layer_type_mask") {
this->metatileLayerTypeMask = getConfigUint32(key, value);
+ } else if (key == "block_metatile_id_mask") {
+ this->blockMetatileIdMask = getConfigUint32(key, value, 1, 0xFFFF);
+ } else if (key == "block_collision_mask") {
+ this->blockCollisionMask = getConfigUint32(key, value, 0, 0xFFFE);
+ } else if (key == "block_elevation_mask") {
+ this->blockElevationMask = getConfigUint32(key, value, 0, 0xFFFE);
} else if (key == "enable_map_allow_flags") {
this->enableMapAllowFlags = getConfigBool(key, value);
#ifdef CONFIG_BACKWARDS_COMPATABILITY
@@ -799,6 +805,9 @@ QMap ProjectConfig::getKeyValueMap() {
map.insert("metatile_terrain_type_mask", "0x" + QString::number(this->metatileTerrainTypeMask, 16).toUpper());
map.insert("metatile_encounter_type_mask", "0x" + QString::number(this->metatileEncounterTypeMask, 16).toUpper());
map.insert("metatile_layer_type_mask", "0x" + QString::number(this->metatileLayerTypeMask, 16).toUpper());
+ map.insert("block_metatile_id_mask", "0x" + QString::number(this->blockMetatileIdMask, 16).toUpper());
+ map.insert("block_collision_mask", "0x" + QString::number(this->blockCollisionMask, 16).toUpper());
+ map.insert("block_elevation_mask", "0x" + QString::number(this->blockElevationMask, 16).toUpper());
map.insert("enable_map_allow_flags", QString::number(this->enableMapAllowFlags));
map.insert("event_icon_path_object", this->eventIconPaths[Event::Group::Object]);
map.insert("event_icon_path_warp", this->eventIconPaths[Event::Group::Warp]);
@@ -1152,6 +1161,33 @@ void ProjectConfig::setMetatileLayerTypeMask(uint32_t mask) {
this->save();
}
+uint16_t ProjectConfig::getBlockMetatileIdMask() {
+ return this->blockMetatileIdMask;
+}
+
+uint16_t ProjectConfig::getBlockCollisionMask() {
+ return this->blockCollisionMask;
+}
+
+uint16_t ProjectConfig::getBlockElevationMask() {
+ return this->blockElevationMask;
+}
+
+void ProjectConfig::setBlockMetatileIdMask(uint16_t mask) {
+ this->blockMetatileIdMask = mask;
+ this->save();
+}
+
+void ProjectConfig::setBlockCollisionMask(uint16_t mask) {
+ this->blockCollisionMask = mask;
+ this->save();
+}
+
+void ProjectConfig::setBlockElevationMask(uint16_t mask) {
+ this->blockElevationMask = mask;
+ this->save();
+}
+
bool ProjectConfig::getMapAllowFlagsEnabled() {
return this->enableMapAllowFlags;
}
diff --git a/src/ui/projectsettingseditor.cpp b/src/ui/projectsettingseditor.cpp
index e0c31f80..ce9a139c 100644
--- a/src/ui/projectsettingseditor.cpp
+++ b/src/ui/projectsettingseditor.cpp
@@ -102,6 +102,7 @@ void ProjectSettingsEditor::initUi() {
ui->lineEdit_BorderMetatiles->setValidator(validator);
this->setBorderMetatilesUi(projectConfig.getUseCustomBorderSize());
+ // Set spin box limits
int maxMetatileId = Project::getNumMetatilesTotal() - 1;
ui->spinBox_FillMetatile->setMaximum(maxMetatileId);
ui->spinBox_BorderMetatile1->setMaximum(maxMetatileId);
@@ -112,6 +113,11 @@ void ProjectSettingsEditor::initUi() {
ui->spinBox_Collision->setMaximum(Project::getMaxCollision());
ui->spinBox_MaxElevation->setMaximum(Project::getMaxElevation());
ui->spinBox_MaxCollision->setMaximum(Project::getMaxCollision());
+ // TODO: Move to a global
+ ui->spinBox_MetatileIdMask->setMinimum(0x1);
+ ui->spinBox_MetatileIdMask->setMaximum(0xFFFF); // Metatile IDs can use all 16 bits of a block
+ ui->spinBox_CollisionMask->setMaximum(0xFFFE); // Collision/elevation can only use 15; metatile IDs must have at least 1 bit
+ ui->spinBox_ElevationMask->setMaximum(0xFFFE);
}
void ProjectSettingsEditor::setBorderMetatilesUi(bool customSize) {
@@ -285,6 +291,9 @@ void ProjectSettingsEditor::refresh() {
ui->spinBox_EncounterTypeMask->setValue(projectConfig.getMetatileEncounterTypeMask());
ui->spinBox_LayerTypeMask->setValue(projectConfig.getMetatileLayerTypeMask());
ui->spinBox_TerrainTypeMask->setValue(projectConfig.getMetatileTerrainTypeMask());
+ ui->spinBox_MetatileIdMask->setValue(projectConfig.getBlockMetatileIdMask());
+ ui->spinBox_CollisionMask->setValue(projectConfig.getBlockCollisionMask());
+ ui->spinBox_ElevationMask->setValue(projectConfig.getBlockElevationMask());
// Set (and sync) border metatile IDs
auto metatileIds = projectConfig.getNewMapBorderMetatileIds();
@@ -345,6 +354,9 @@ void ProjectSettingsEditor::save() {
projectConfig.setMetatileTerrainTypeMask(ui->spinBox_TerrainTypeMask->value());
projectConfig.setMetatileEncounterTypeMask(ui->spinBox_EncounterTypeMask->value());
projectConfig.setMetatileLayerTypeMask(ui->spinBox_LayerTypeMask->value());
+ projectConfig.setBlockMetatileIdMask(ui->spinBox_MetatileIdMask->value());
+ projectConfig.setBlockCollisionMask(ui->spinBox_CollisionMask->value());
+ projectConfig.setBlockElevationMask(ui->spinBox_ElevationMask->value());
// Save line edit settings
projectConfig.setPrefabFilepath(ui->lineEdit_PrefabsPath->text());