Fix new event data being discarded on maps with shared_events_map

This commit is contained in:
GriffinR 2025-08-06 11:33:02 -04:00
parent 73b774be7d
commit a5823f04f1
8 changed files with 59 additions and 45 deletions

View File

@ -26,6 +26,7 @@ and this project somewhat adheres to [Semantic Versioning](https://semver.org/sp
- Invalid tile IDs are now rendered as magenta (like invalid metatiles), instead of rendering the same as a transparent tile.
- While holding down `Ctrl` (`Cmd` on macOS) painting on the metatile layer view will now only change the tile's palette.
- Full menu paths are now listed for shortcuts in the Shortcuts Editor.
- Adding new event data to a map that has a `shared_events_map` will now remove the `shared_events_map`, rather than discard the event data.
### Fixed
- Fix crash when rendering tiles with invalid palette numbers.

View File

@ -1638,9 +1638,6 @@
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_NoEvents">
<property name="text">
<string>There are no events on the current map.</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignCenter</set>
</property>

View File

@ -161,6 +161,7 @@ public:
QString getIdName() const { return this->idName; }
static QString groupToString(Event::Group group);
static QString groupToJsonKey(Event::Group group);
static QString typeToString(Event::Type type);
static QString typeToJsonKey(Event::Type type);
static Event::Type typeFromJsonKey(QString type);

View File

@ -64,6 +64,8 @@ public:
void setSharedEventsMap(const QString &sharedEventsMap) { m_sharedEventsMap = sharedEventsMap; }
void setSharedScriptsMap(const QString &sharedScriptsMap);
bool isInheritingEvents() const { return !m_sharedEventsMap.isEmpty() && !hasEvents(); }
bool isInheritingScripts() const { return !m_sharedScriptsMap.isEmpty(); }
QString sharedEventsMap() const { return m_sharedEventsMap; }
QString sharedScriptsMap() const { return m_sharedScriptsMap; }
@ -85,6 +87,7 @@ public:
void addEvent(Event *);
int getIndexOfEvent(Event *) const;
bool hasEvent(Event *) const;
bool hasEvents() const;
QStringList getScriptLabels(Event::Group group = Event::Group::None);
QString getScriptsFilepath() const;

View File

@ -63,6 +63,16 @@ void Event::modify() {
this->map->modify();
}
QString Event::groupToJsonKey(Event::Group group) {
static const QMap<Event::Group, QString> map = {
{Event::Group::Object, "object_events"},
{Event::Group::Warp, "warp_events"},
{Event::Group::Coord, "coord_events"},
{Event::Group::Bg, "bg_events"},
};
return map.value(group);
}
const QMap<Event::Group, QString> groupToStringMap = {
{Event::Group::Object, "Object"},
{Event::Group::Warp, "Warp"},

View File

@ -280,14 +280,23 @@ int Map::getNumEvents(Event::Group group) const {
if (group == Event::Group::None) {
// Total number of events
int numEvents = 0;
for (auto i = m_events.constBegin(); i != m_events.constEnd(); i++) {
numEvents += i.value().length();
for (auto it = m_events.constBegin(); it != m_events.constEnd(); it++) {
numEvents += it.value().length();
}
return numEvents;
}
return m_events[group].length();
}
bool Map::hasEvents() const {
for (auto it = m_events.constBegin(); it != m_events.constEnd(); it++) {
if (!it.value().isEmpty()) {
return true;
}
}
return false;
}
void Map::removeEvent(Event *event) {
for (auto i = m_events.begin(); i != m_events.end(); i++) {
i.value().removeAll(event);

View File

@ -1461,6 +1461,7 @@ void MainWindow::clearProjectUI() {
ui->comboBox_LayoutSelector->clear();
this->mapHeaderForm->clear();
ui->label_NoEvents->setText("");
prefab.clearPrefabUi();
@ -2479,6 +2480,14 @@ void MainWindow::updateSelectedEvents() {
}
else {
ui->tabWidget_EventType->hide();
if (this->editor->map && this->editor->map->isInheritingEvents()) {
QString message = QString("<span style=\"color:red;\">NOTE:</span> This map inherits events from %1."
"<br>Adding any events will separate it from that map.").arg(this->editor->map->sharedEventsMap());
ui->label_NoEvents->setText(message);
} else {
ui->label_NoEvents->setText(QStringLiteral("There are no events on the current map."));
}
ui->label_NoEvents->show();
}
}

View File

@ -360,10 +360,10 @@ QSet<QString> Project::getTopLevelMapFields() const {
"show_map_name",
"battle_scene",
"connections",
"object_events",
"warp_events",
"coord_events",
"bg_events",
Event::groupToJsonKey(Event::Group::Object),
Event::groupToJsonKey(Event::Group::Warp),
Event::groupToJsonKey(Event::Group::Coord),
Event::groupToJsonKey(Event::Group::Bg),
"shared_events_map",
"shared_scripts_map",
};
@ -462,10 +462,10 @@ bool Project::loadMapData(Map* map) {
static const QMap<QString, Event::Type> defaultEventTypes = {
// Map of the expected keys for each event group, and the default type of that group.
// If the default type is Type::None then each event must specify its type, or its an error.
{"object_events", Event::Type::Object},
{"warp_events", Event::Type::Warp},
{"coord_events", Event::Type::None},
{"bg_events", Event::Type::None},
{Event::groupToJsonKey(Event::Group::Object), Event::Type::Object},
{Event::groupToJsonKey(Event::Group::Warp), Event::Type::Warp},
{Event::groupToJsonKey(Event::Group::Coord), Event::Type::None},
{Event::groupToJsonKey(Event::Group::Bg), Event::Type::None},
};
for (auto i = defaultEventTypes.constBegin(); i != defaultEventTypes.constEnd(); i++) {
QString eventGroupKey = i.key();
@ -1396,43 +1396,27 @@ bool Project::saveMap(Map *map, bool skipLayout) {
mapObj["connections"] = OrderedJson();
}
if (map->sharedEventsMap().isEmpty()) {
// Object events
OrderedJson::array objectEventsArr;
for (const auto &event : map->getEvents(Event::Group::Object)){
objectEventsArr.push_back(event->buildEventJson(this));
}
mapObj["object_events"] = objectEventsArr;
// Warp events
OrderedJson::array warpEventsArr;
for (const auto &event : map->getEvents(Event::Group::Warp)) {
warpEventsArr.push_back(event->buildEventJson(this));
}
mapObj["warp_events"] = warpEventsArr;
// Coord events
OrderedJson::array coordEventsArr;
for (const auto &event : map->getEvents(Event::Group::Coord)) {
coordEventsArr.push_back(event->buildEventJson(this));
}
mapObj["coord_events"] = coordEventsArr;
// Bg Events
OrderedJson::array bgEventsArr;
for (const auto &event : map->getEvents(Event::Group::Bg)) {
bgEventsArr.push_back(event->buildEventJson(this));
}
mapObj["bg_events"] = bgEventsArr;
} else {
if (map->isInheritingEvents()) {
mapObj["shared_events_map"] = map->sharedEventsMap();
}
if (!map->sharedScriptsMap().isEmpty()) {
if (map->isInheritingScripts()) {
mapObj["shared_scripts_map"] = map->sharedScriptsMap();
}
if (!map->isInheritingEvents()) {
auto buildEventsJson = [this, map](Event::Group group, OrderedJson::object *json) {
OrderedJson::array arr;
for (const auto &event : map->getEvents(group)){
arr.push_back(event->buildEventJson(this));
}
(*json)[Event::groupToJsonKey(group)] = arr;
};
buildEventsJson(Event::Group::Object, &mapObj);
buildEventsJson(Event::Group::Warp, &mapObj);
buildEventsJson(Event::Group::Coord, &mapObj);
buildEventsJson(Event::Group::Bg, &mapObj);
}
// Update the global heal locations array using the Map's heal location events.
// This won't get saved to disc until Project::saveHealLocations is called.
QList<HealLocationEvent*> hlEvents;