Remove last MAP_ prefix requirement

This commit is contained in:
GriffinR 2025-05-07 12:17:09 -04:00
parent aa32276381
commit a906783f68
3 changed files with 44 additions and 13 deletions

View File

@ -115,6 +115,7 @@ public:
QString getMapConstant(const QString &mapName, const QString &defaultValue = QString()) const;
QString getMapLayoutId(const QString &mapName, const QString &defaultValue = QString()) const;
QString getMapLocation(const QString &mapName, const QString &defaultValue = QString()) const;
QString secretBaseIdToMapName(const QString &secretBaseId) const;
struct NewMapSettings {
QString name;

View File

@ -1135,24 +1135,29 @@ void MainWindow::openEventMap(Event *sourceEvent) {
Event::Type eventType = sourceEvent->getEventType();
if (eventType == Event::Type::Warp) {
// Warp events open to their destination warp event.
WarpEvent *warp = dynamic_cast<WarpEvent *>(sourceEvent);
auto warp = dynamic_cast<WarpEvent *>(sourceEvent);
targetMapName = warp->getDestinationMap();
targetEventIdName = warp->getDestinationWarpID();
targetEventGroup = Event::Group::Warp;
} else if (eventType == Event::Type::CloneObject) {
// Clone object events open to their target object event.
CloneObjectEvent *clone = dynamic_cast<CloneObjectEvent *>(sourceEvent);
auto clone = dynamic_cast<CloneObjectEvent *>(sourceEvent);
targetMapName = clone->getTargetMap();
targetEventIdName = clone->getTargetID();
targetEventGroup = Event::Group::Object;
} else if (eventType == Event::Type::SecretBase) {
// Secret Bases open to their secret base entrance
const QString mapPrefix = projectConfig.getIdentifier(ProjectIdentifier::define_map_prefix);
SecretBaseEvent *base = dynamic_cast<SecretBaseEvent *>(sourceEvent);
auto base = dynamic_cast<SecretBaseEvent *>(sourceEvent);
// Extract the map name from the secret base ID.
QString baseId = base->getBaseID();
targetMapName = this->editor->project->mapConstantsToMapNames.value(mapPrefix + baseId.left(baseId.lastIndexOf("_")));
if (baseId.isEmpty())
return;
targetMapName = this->editor->project->secretBaseIdToMapName(baseId);
if (targetMapName.isEmpty()) {
WarningMessage::show(QString("Failed to determine which map '%1' refers to.").arg(baseId), this);
return;
}
// Just select the first warp. Normally the only warp event on every secret base map is the entrance/exit, so this is usually correct.
// The warp IDs for secret bases are specified in the project's C code, not in the map data, so we don't have an easy way to read the actual IDs.
@ -1160,7 +1165,7 @@ void MainWindow::openEventMap(Event *sourceEvent) {
targetEventGroup = Event::Group::Warp;
} else if (eventType == Event::Type::HealLocation && projectConfig.healLocationRespawnDataEnabled) {
// Heal location events open to their respawn NPC
HealLocationEvent *heal = dynamic_cast<HealLocationEvent *>(sourceEvent);
auto heal = dynamic_cast<HealLocationEvent *>(sourceEvent);
targetMapName = heal->getRespawnMapName();
targetEventIdName = heal->getRespawnNPC();
targetEventGroup = Event::Group::Object;
@ -1168,7 +1173,7 @@ void MainWindow::openEventMap(Event *sourceEvent) {
// Other event types have no target map to open.
return;
}
if (!userSetMap(targetMapName))
if (targetMapName.isEmpty() || !userSetMap(targetMapName))
return;
// Map opened successfully, now try to select the targeted event on that map.

View File

@ -1975,12 +1975,6 @@ bool Project::readMapGroups() {
failedMapNames.append(mapName);
continue;
}
const QString expectedPrefix = projectConfig.getIdentifier(ProjectIdentifier::define_map_prefix);
if (!mapConstant.startsWith(expectedPrefix)) {
logWarn(QString("Map '%1' has invalid \"id\" value '%2' and will be ignored. Value must begin with '%3'.").arg(mapName).arg(mapConstant).arg(expectedPrefix));
failedMapNames.append(mapName);
continue;
}
auto it = this->mapConstantsToMapNames.constFind(mapConstant);
if (it != this->mapConstantsToMapNames.constEnd()) {
logWarn(QString("Map '%1' has the same \"id\" value '%2' as map '%3' and will be ignored.").arg(mapName).arg(it.key()).arg(it.value()));
@ -2081,6 +2075,37 @@ QString Project::getMapLocation(const QString &mapName, const QString &defaultVa
return map ? map->header()->location() : defaultValue;
}
// Determining which map a secret base ID refers to relies on assumptions about its name.
// The default format is for a secret base ID of 'SECRET_BASE_FOO_#' to refer to a map with the constant
// 'MAP_SECRET_BASE_FOO', so we strip the `_#` suffix and add the default map prefix 'MAP_'. If this fails,
// we'll try every combination of that prefix, suffix, and 'SECRET_BASE_FOO'.
QString Project::secretBaseIdToMapName(const QString &secretBaseId) const {
const QString mapPrefix = projectConfig.getIdentifier(ProjectIdentifier::define_map_prefix);
QString baseIdNoSuffix = secretBaseId.left(secretBaseId.lastIndexOf("_"));
auto it = this->mapConstantsToMapNames.constFind(mapPrefix + baseIdNoSuffix);
if (it != this->mapConstantsToMapNames.constEnd()) {
// Found a result of the format 'SECRET_BASE_FOO_#' -> 'MAP_SECRET_BASE_FOO'.
return it.value();
}
it = this->mapConstantsToMapNames.constFind(baseIdNoSuffix);
if (it != this->mapConstantsToMapNames.constEnd()) {
// Found a result of the format 'SECRET_BASE_FOO_#' -> 'SECRET_BASE_FOO'.
return it.value();
}
it = this->mapConstantsToMapNames.constFind(mapPrefix + secretBaseId);
if (it != this->mapConstantsToMapNames.constEnd()) {
// Found a result of the format 'SECRET_BASE_FOO_#' -> 'MAP_SECRET_BASE_FOO_#'.
return it.value();
}
it = this->mapConstantsToMapNames.constFind(secretBaseId);
if (it != this->mapConstantsToMapNames.constEnd()) {
// 'SECRET_BASE_FOO_#' is already a map constant.
return it.value();
}
return QString();
}
// When we ask the user to provide a new identifier for something (like a map name or MAPSEC id)
// we use this to make sure that it doesn't collide with any known identifiers first.
// Porymap knows of many more identifiers than this, but for simplicity we only check the lists that users can add to via Porymap.