Store warp behaviors as values, add version defaults

This commit is contained in:
GriffinR 2023-12-21 23:33:36 -05:00
parent a2d230666b
commit c543cc0899
6 changed files with 92 additions and 55 deletions

View file

@ -315,7 +315,6 @@ public:
this->blockMetatileIdMask = 0x03FF; this->blockMetatileIdMask = 0x03FF;
this->blockCollisionMask = 0x0C00; this->blockCollisionMask = 0x0C00;
this->blockElevationMask = 0xF000; this->blockElevationMask = 0xF000;
this->warpBehaviors = defaultWarpBehaviors;
this->identifiers.clear(); this->identifiers.clear();
this->readKeys.clear(); this->readKeys.clear();
} }
@ -413,8 +412,8 @@ public:
int getCollisionSheetWidth(); int getCollisionSheetWidth();
void setCollisionSheetHeight(int height); void setCollisionSheetHeight(int height);
int getCollisionSheetHeight(); int getCollisionSheetHeight();
void setWarpBehaviors(const QStringList &behaviors); void setWarpBehaviors(const QSet<uint32_t> &behaviors);
QStringList getWarpBehaviors(); QSet<uint32_t> getWarpBehaviors();
protected: protected:
virtual QString getConfigFilepath() override; virtual QString getConfigFilepath() override;
@ -423,8 +422,6 @@ protected:
virtual void onNewConfigFileCreated() override; virtual void onNewConfigFileCreated() override;
virtual void setUnreadKeys() override; virtual void setUnreadKeys() override;
private: private:
static const QStringList defaultWarpBehaviors;
BaseGameVersion baseGameVersion; BaseGameVersion baseGameVersion;
QString projectDir; QString projectDir;
QMap<ProjectIdentifier, QString> identifiers; QMap<ProjectIdentifier, QString> identifiers;
@ -465,7 +462,7 @@ private:
QString collisionSheetPath; QString collisionSheetPath;
int collisionSheetWidth; int collisionSheetWidth;
int collisionSheetHeight; int collisionSheetHeight;
QStringList warpBehaviors; QSet<uint32_t> warpBehaviors;
}; };
extern ProjectConfig projectConfig; extern ProjectConfig projectConfig;

View file

@ -79,7 +79,6 @@ public:
QMap<QString, uint16_t> unusedMetatileLabels; QMap<QString, uint16_t> unusedMetatileLabels;
QMap<QString, uint32_t> metatileBehaviorMap; QMap<QString, uint32_t> metatileBehaviorMap;
QMap<uint32_t, QString> metatileBehaviorMapInverse; QMap<uint32_t, QString> metatileBehaviorMapInverse;
QSet<uint32_t> warpBehaviorValues;
QMap<QString, QString> facingDirections; QMap<QString, QString> facingDirections;
ParseUtil parser; ParseUtil parser;
QFileSystemWatcher fileWatcher; QFileSystemWatcher fileWatcher;

View file

@ -16,35 +16,55 @@
#include <QAction> #include <QAction>
#include <QAbstractButton> #include <QAbstractButton>
const QStringList ProjectConfig::defaultWarpBehaviors = { const QSet<uint32_t> defaultWarpBehaviors_RSE = {
"MB_NORTH_ARROW_WARP", 0x0E, // MB_MOSSDEEP_GYM_WARP
"MB_SOUTH_ARROW_WARP", 0x0F, // MB_MT_PYRE_HOLE
"MB_WEST_ARROW_WARP", 0x1B, // MB_STAIRS_OUTSIDE_ABANDONED_SHIP
"MB_EAST_ARROW_WARP", 0x1C, // MB_SHOAL_CAVE_ENTRANCE
"MB_STAIRS_OUTSIDE_ABANDONED_SHIP", 0x29, // MB_LAVARIDGE_GYM_B1F_WARP
"MB_WATER_SOUTH_ARROW_WARP", 0x60, // MB_NON_ANIMATED_DOOR
"MB_SHOAL_CAVE_ENTRANCE", 0x61, // MB_LADDER
"MB_SECRET_BASE_SPOT_RED_CAVE_OPEN", 0x62, // MB_EAST_ARROW_WARP
"MB_SECRET_BASE_SPOT_BROWN_CAVE_OPEN", 0x63, // MB_WEST_ARROW_WARP
"MB_SECRET_BASE_SPOT_YELLOW_CAVE_OPEN", 0x64, // MB_NORTH_ARROW_WARP
"MB_SECRET_BASE_SPOT_BLUE_CAVE_OPEN", 0x65, // MB_SOUTH_ARROW_WARP
"MB_SECRET_BASE_SPOT_TREE_LEFT_OPEN", 0x67, // MB_AQUA_HIDEOUT_WARP
"MB_SECRET_BASE_SPOT_TREE_RIGHT_OPEN", 0x68, // MB_LAVARIDGE_GYM_1F_WARP
"MB_SECRET_BASE_SPOT_SHRUB_OPEN", 0x69, // MB_ANIMATED_DOOR
"MB_ANIMATED_DOOR", 0x6A, // MB_UP_ESCALATOR
"MB_NON_ANIMATED_DOOR", 0x6B, // MB_DOWN_ESCALATOR
"MB_PETALBURG_GYM_DOOR", 0x6C, // MB_WATER_DOOR
"MB_WATER_DOOR", 0x6D, // MB_WATER_SOUTH_ARROW_WARP
"MB_LADDER", 0x6E, // MB_DEEP_SOUTH_WARP
"MB_UP_ESCALATOR", 0x70, // MB_UNION_ROOM_WARP
"MB_DOWN_ESCALATOR", 0x8D, // MB_PETALBURG_GYM_DOOR
"MB_DEEP_SOUTH_WARP", 0x91, // MB_SECRET_BASE_SPOT_RED_CAVE_OPEN
"MB_LAVARIDGE_GYM_B1F_WARP", 0x93, // MB_SECRET_BASE_SPOT_BROWN_CAVE_OPEN
"MB_LAVARIDGE_GYM_1F_WARP", 0x95, // MB_SECRET_BASE_SPOT_YELLOW_CAVE_OPEN
"MB_AQUA_HIDEOUT_WARP", 0x97, // MB_SECRET_BASE_SPOT_TREE_LEFT_OPEN
"MB_MT_PYRE_HOLE", 0x99, // MB_SECRET_BASE_SPOT_SHRUB_OPEN
"MB_MOSSDEEP_GYM_WARP", 0x9B, // MB_SECRET_BASE_SPOT_BLUE_CAVE_OPEN
"MB_BRIDGE_OVER_OCEAN", 0x9D, // MB_SECRET_BASE_SPOT_TREE_RIGHT_OPEN
};
const QSet<uint32_t> defaultWarpBehaviors_FRLG = {
0x60, // MB_CAVE_DOOR
0x61, // MB_LADDER
0x62, // MB_EAST_ARROW_WARP
0x63, // MB_WEST_ARROW_WARP
0x64, // MB_NORTH_ARROW_WARP
0x65, // MB_SOUTH_ARROW_WARP
0x66, // MB_FALL_WARP
0x67, // MB_REGULAR_WARP
0x68, // MB_LAVARIDGE_1F_WARP
0x69, // MB_WARP_DOOR
0x6A, // MB_UP_ESCALATOR
0x6B, // MB_DOWN_ESCALATOR
0x6C, // MB_UP_RIGHT_STAIR_WARP
0x6D, // MB_UP_LEFT_STAIR_WARP
0x6E, // MB_DOWN_RIGHT_STAIR_WARP
0x6F, // MB_DOWN_LEFT_STAIR_WARP
0x71, // MB_UNION_ROOM_WARP
}; };
// TODO: symbol_wild_encounters should ultimately be removed from the table below. We can determine this name when we read the project. // TODO: symbol_wild_encounters should ultimately be removed from the table below. We can determine this name when we read the project.
@ -876,9 +896,11 @@ void ProjectConfig::parseConfigKeyValue(QString key, QString value) {
} else if (key == "collision_sheet_height") { } else if (key == "collision_sheet_height") {
this->collisionSheetHeight = getConfigUint32(key, value, 1, Block::maxValue); this->collisionSheetHeight = getConfigUint32(key, value, 1, Block::maxValue);
} else if (key == "warp_behaviors") { } else if (key == "warp_behaviors") {
this->warpBehaviors.clear();
value.remove(" "); value.remove(" ");
this->warpBehaviors = value.split(",", Qt::SkipEmptyParts); QStringList behaviorList = value.split(",", Qt::SkipEmptyParts);
this->warpBehaviors.removeDuplicates(); for (auto s : behaviorList)
this->warpBehaviors.insert(getConfigUint32(key, s));
} else { } else {
logWarn(QString("Invalid config key found in config file %1: '%2'").arg(this->getConfigFilepath()).arg(key)); logWarn(QString("Invalid config key found in config file %1: '%2'").arg(this->getConfigFilepath()).arg(key));
} }
@ -912,6 +934,7 @@ void ProjectConfig::setUnreadKeys() {
if (!readKeys.contains("metatile_encounter_type_mask")) this->metatileEncounterTypeMask = Metatile::getDefaultAttributesMask(this->baseGameVersion, Metatile::Attr::EncounterType); if (!readKeys.contains("metatile_encounter_type_mask")) this->metatileEncounterTypeMask = Metatile::getDefaultAttributesMask(this->baseGameVersion, Metatile::Attr::EncounterType);
if (!readKeys.contains("metatile_layer_type_mask")) this->metatileLayerTypeMask = Metatile::getDefaultAttributesMask(this->baseGameVersion, Metatile::Attr::LayerType); if (!readKeys.contains("metatile_layer_type_mask")) this->metatileLayerTypeMask = Metatile::getDefaultAttributesMask(this->baseGameVersion, Metatile::Attr::LayerType);
if (!readKeys.contains("enable_map_allow_flags")) this->enableMapAllowFlags = (this->baseGameVersion != BaseGameVersion::pokeruby); if (!readKeys.contains("enable_map_allow_flags")) this->enableMapAllowFlags = (this->baseGameVersion != BaseGameVersion::pokeruby);
if (!readKeys.contains("warp_behaviors")) this->warpBehaviors = isPokefirered ? defaultWarpBehaviors_FRLG : defaultWarpBehaviors_RSE;
} }
QMap<QString, QString> ProjectConfig::getKeyValueMap() { QMap<QString, QString> ProjectConfig::getKeyValueMap() {
@ -965,7 +988,10 @@ QMap<QString, QString> ProjectConfig::getKeyValueMap() {
map.insert("collision_sheet_path", this->collisionSheetPath); map.insert("collision_sheet_path", this->collisionSheetPath);
map.insert("collision_sheet_width", QString::number(this->collisionSheetWidth)); map.insert("collision_sheet_width", QString::number(this->collisionSheetWidth));
map.insert("collision_sheet_height", QString::number(this->collisionSheetHeight)); map.insert("collision_sheet_height", QString::number(this->collisionSheetHeight));
map.insert("warp_behaviors", this->warpBehaviors.join(",")); QStringList warpBehaviorStrs;
for (auto value : this->warpBehaviors)
warpBehaviorStrs.append("0x" + QString("%1").arg(value, 2, 16, QChar('0')).toUpper());
map.insert("warp_behaviors", warpBehaviorStrs.join(","));
return map; return map;
} }
@ -1419,12 +1445,12 @@ int ProjectConfig::getCollisionSheetHeight() {
return this->collisionSheetHeight; return this->collisionSheetHeight;
} }
void ProjectConfig::setWarpBehaviors(const QStringList &behaviors) { void ProjectConfig::setWarpBehaviors(const QSet<uint32_t> &behaviors) {
this->warpBehaviors = behaviors; this->warpBehaviors = behaviors;
this->save(); this->save();
} }
QStringList ProjectConfig::getWarpBehaviors() { QSet<uint32_t> ProjectConfig::getWarpBehaviors() {
return this->warpBehaviors; return this->warpBehaviors;
} }

View file

@ -2003,7 +2003,7 @@ void Editor::updateWarpEventWarning(Event *event) {
metatile = Tileset::getMetatile(block.metatileId(), map->layout->tileset_primary, map->layout->tileset_secondary); metatile = Tileset::getMetatile(block.metatileId(), map->layout->tileset_primary, map->layout->tileset_secondary);
} }
// metatile may be null if the warp is in the map border. Display the warning in this case // metatile may be null if the warp is in the map border. Display the warning in this case
bool validWarpBehavior = metatile && project->warpBehaviorValues.contains(metatile->behavior()); bool validWarpBehavior = metatile && projectConfig.getWarpBehaviors().contains(metatile->behavior());
warpEvent->setWarningEnabled(!validWarpBehavior); warpEvent->setWarningEnabled(!validWarpBehavior);
} }

View file

@ -2287,7 +2287,6 @@ bool Project::readTrainerTypes() {
bool Project::readMetatileBehaviors() { bool Project::readMetatileBehaviors() {
this->metatileBehaviorMap.clear(); this->metatileBehaviorMap.clear();
this->metatileBehaviorMapInverse.clear(); this->metatileBehaviorMapInverse.clear();
this->warpBehaviorValues.clear();
const QStringList prefixes = {projectConfig.getIdentifier(ProjectIdentifier::regex_behaviors)}; const QStringList prefixes = {projectConfig.getIdentifier(ProjectIdentifier::regex_behaviors)};
QString filename = projectConfig.getFilePath(ProjectFilePath::constants_metatile_behaviors); QString filename = projectConfig.getFilePath(ProjectFilePath::constants_metatile_behaviors);
@ -2307,15 +2306,6 @@ bool Project::readMetatileBehaviors() {
this->metatileBehaviorMapInverse.insert(value, i.key()); this->metatileBehaviorMapInverse.insert(value, i.key());
} }
// Construct warp behavior value list for the warp metatile behavior warning
const QStringList warpBehaviorNames = projectConfig.getWarpBehaviors();
for (auto name : warpBehaviorNames) {
if (this->metatileBehaviorMap.contains(name)) {
int value = this->metatileBehaviorMap.value(name);
this->warpBehaviorValues.insert(static_cast<uint32_t>(value));
}
}
return true; return true;
} }

View file

@ -302,14 +302,25 @@ QStringList ProjectSettingsEditor::getWarpBehaviorsList() {
} }
void ProjectSettingsEditor::setWarpBehaviorsList(QStringList list) { void ProjectSettingsEditor::setWarpBehaviorsList(QStringList list) {
list.removeDuplicates();
list.sort();
ui->textEdit_WarpBehaviors->setText(list.join("\n")); ui->textEdit_WarpBehaviors->setText(list.join("\n"));
} }
void ProjectSettingsEditor::updateWarpBehaviorsList(bool adding) { void ProjectSettingsEditor::updateWarpBehaviorsList(bool adding) {
const QString input = ui->comboBox_WarpBehaviors->currentText(); QString input = ui->comboBox_WarpBehaviors->currentText();
if (input.isEmpty()) if (input.isEmpty())
return; return;
// Check if input was a value string for a named behavior
bool ok;
uint32_t value = input.toUInt(&ok, 0);
if (ok && project->metatileBehaviorMapInverse.contains(value))
input = project->metatileBehaviorMapInverse.value(value);
if (!project->metatileBehaviorMap.contains(input))
return;
QStringList list = this->getWarpBehaviorsList(); QStringList list = this->getWarpBehaviorsList();
int pos = list.indexOf(input); int pos = list.indexOf(input);
@ -472,7 +483,15 @@ void ProjectSettingsEditor::refresh() {
lineEdit->setText(projectConfig.getCustomFilePath(lineEdit->objectName())); lineEdit->setText(projectConfig.getCustomFilePath(lineEdit->objectName()));
for (auto lineEdit : ui->scrollAreaContents_Identifiers->findChildren<QLineEdit*>()) for (auto lineEdit : ui->scrollAreaContents_Identifiers->findChildren<QLineEdit*>())
lineEdit->setText(projectConfig.getCustomIdentifier(lineEdit->objectName())); lineEdit->setText(projectConfig.getCustomIdentifier(lineEdit->objectName()));
this->setWarpBehaviorsList(projectConfig.getWarpBehaviors());
// Set warp behaviors
auto behaviorValues = projectConfig.getWarpBehaviors();
QStringList behaviorNames;
for (auto value : behaviorValues) {
if (project->metatileBehaviorMapInverse.contains(value))
behaviorNames.append(project->metatileBehaviorMapInverse.value(value));
}
this->setWarpBehaviorsList(behaviorNames);
this->refreshing = false; // Allow signals this->refreshing = false; // Allow signals
} }
@ -534,7 +553,13 @@ void ProjectSettingsEditor::save() {
projectConfig.setFilePath(lineEdit->objectName(), lineEdit->text()); projectConfig.setFilePath(lineEdit->objectName(), lineEdit->text());
for (auto lineEdit : ui->scrollAreaContents_Identifiers->findChildren<QLineEdit*>()) for (auto lineEdit : ui->scrollAreaContents_Identifiers->findChildren<QLineEdit*>())
projectConfig.setIdentifier(lineEdit->objectName(), lineEdit->text()); projectConfig.setIdentifier(lineEdit->objectName(), lineEdit->text());
projectConfig.setWarpBehaviors(this->getWarpBehaviorsList());
// Save warp behaviors
QStringList behaviorNames = this->getWarpBehaviorsList();
QSet<uint32_t> behaviorValues;
for (auto name : behaviorNames)
behaviorValues.insert(project->metatileBehaviorMap.value(name));
projectConfig.setWarpBehaviors(behaviorValues);
// Save border metatile IDs // Save border metatile IDs
projectConfig.setNewMapBorderMetatileIds(this->getBorderMetatileIds(ui->checkBox_EnableCustomBorderSize->isChecked())); projectConfig.setNewMapBorderMetatileIds(this->getBorderMetatileIds(ui->checkBox_EnableCustomBorderSize->isChecked()));