diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f6fb02f..585f2b16 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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. diff --git a/forms/mainwindow.ui b/forms/mainwindow.ui index 30520979..96567305 100644 --- a/forms/mainwindow.ui +++ b/forms/mainwindow.ui @@ -1638,9 +1638,6 @@ - - There are no events on the current map. - Qt::AlignmentFlag::AlignCenter diff --git a/include/core/events.h b/include/core/events.h index 0e8af1f7..816cf953 100644 --- a/include/core/events.h +++ b/include/core/events.h @@ -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); diff --git a/include/core/map.h b/include/core/map.h index 734d5945..f3a377c1 100644 --- a/include/core/map.h +++ b/include/core/map.h @@ -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; diff --git a/src/core/events.cpp b/src/core/events.cpp index 58a2b997..194a7ab1 100644 --- a/src/core/events.cpp +++ b/src/core/events.cpp @@ -63,6 +63,16 @@ void Event::modify() { this->map->modify(); } +QString Event::groupToJsonKey(Event::Group group) { + static const QMap 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 groupToStringMap = { {Event::Group::Object, "Object"}, {Event::Group::Warp, "Warp"}, diff --git a/src/core/map.cpp b/src/core/map.cpp index 01ed855f..f7b75838 100644 --- a/src/core/map.cpp +++ b/src/core/map.cpp @@ -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); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index f3bc15f8..baf4c056 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -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("NOTE: This map inherits events from %1." + "
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(); } } diff --git a/src/project.cpp b/src/project.cpp index f26a49ad..08ed9611 100644 --- a/src/project.cpp +++ b/src/project.cpp @@ -360,10 +360,10 @@ QSet 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 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 hlEvents;