diff --git a/CHANGELOG.md b/CHANGELOG.md index c699db4b..efb5c7a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project somewhat adheres to [Semantic Versioning](https://semver.org/sp - Fix degraded image quality in exported timelapse gifs. - Fix custom top-level data in the `encounters` object of `wild_encounters.json` being discarded if no `fields` data is present. - Fix event sprites sometimes rendering with incorrect transparency temporarily after a sprite change. +- Fix event sprite names that appear in `symbol_obj_event_gfx_pointers` by value and not by name not rendering with the correct sprite. ## [6.3.0] - 2025-12-26 ### Added diff --git a/include/project.h b/include/project.h index c377362b..50d3307c 100644 --- a/include/project.h +++ b/include/project.h @@ -328,7 +328,7 @@ private: int spriteHeight = -1; bool inanimate = false; }; - QMap eventGraphicsMap; + QHash eventGraphicsMap; // The extra data that can be associated with each MAPSEC name. struct LocationData diff --git a/src/project.cpp b/src/project.cpp index b564b34b..6fdb0b13 100644 --- a/src/project.cpp +++ b/src/project.cpp @@ -3114,16 +3114,25 @@ bool Project::readEventGraphics() { const QMap picTables = parser.readCArrayMulti(picTablesFilepath); const QMap graphicIncbins = parser.readCIncbinMulti(gfxFilepath); - for (auto i = this->gfxDefines.constBegin(); i != this->gfxDefines.constEnd(); i++) { - const QString gfxName = i.key(); + for (auto it = pointerMap.begin(); it != pointerMap.end(); it++) { + // The index name is not necessarily a gfx define name. + // If it's a number string, normalize it to a decimal string. + QString indexName = it.key(); + bool ok; + int indexValue = indexName.toInt(&ok, 0); + const QString gfxName = ok ? QString::number(indexValue) : indexName; + if (this->eventGraphicsMap.contains(gfxName)) { + logWarn(QString("Duplicate entry in '%1' for index '%2' will be ignored.").arg(pointersName).arg(indexName)); + continue; + } // Strip the address-of operator to get the pointer's name. We'll use this name to get data about the event's sprite. // If we don't recognize the name, ignore it. The event will use a default sprite. - QString info_label = pointerMap.value(gfxName); - info_label.replace("&", ""); - if (!gfxInfos.contains(info_label)) + QString infoLabel = it.value(); + infoLabel.replace("&", ""); + if (!gfxInfos.contains(infoLabel)) continue; - const QHash gfxInfoAttributes = gfxInfos[info_label]; + const QHash gfxInfoAttributes = gfxInfos[infoLabel]; auto gfx = new EventGraphics; @@ -3200,10 +3209,35 @@ QPixmap Project::getEventPixmap(const QString &gfxName, int frame, bool hFlip) { EventGraphics* gfx = this->eventGraphicsMap.value(gfxName, nullptr); if (!gfx) { - // Invalid gfx constant. If this is a number, try to use that instead. + // String was not mapped directly to graphics data. + // Try to find matching graphics by converting to a number (either directly + // from the given string, or indirectly by resolving a gfx define). bool ok; - int gfxNum = ParseUtil::gameStringToInt(gfxName, &ok); - if (ok) gfx = this->eventGraphicsMap.value(this->gfxDefines.key(gfxNum, "NULL"), nullptr); + int gfxNum = gfxName.toInt(&ok, 0); + if (!ok) { + auto it = this->gfxDefines.constFind(gfxName); + if (it != this->gfxDefines.constEnd()) { + gfxNum = it.value(); + ok = true; + } + } + if (ok) { + // Successful number conversion, try any gfx define with this value. + for (const auto& gfxNameWithValue : this->gfxDefines.keys(gfxNum)) { + if (gfxNameWithValue == gfxName) continue; + gfx = this->eventGraphicsMap.value(gfxNameWithValue, nullptr); + if (gfx) break; + } + if (!gfx) { + // Try the number string directly. Note that even if we got this + // number by direct conversion earlier, the resulting string may + // still be different (e.g. '0xA' vs '10'). + const QString gfxNumString = QString::number(gfxNum); + if (gfxNumString != gfxName) { + gfx = this->eventGraphicsMap.value(gfxNumString, nullptr); + } + } + } } if (gfx && !gfx->loaded) { // This is the first request for this event's sprite. We'll attempt to load it now.