Support event lookup by ID name

This commit is contained in:
GriffinR 2025-04-07 11:44:54 -04:00
parent ecad60843c
commit 2d827f62f7
12 changed files with 88 additions and 52 deletions

View File

@ -300,12 +300,12 @@ public:
void setTargetMap(QString newTargetMap) { this->targetMap = newTargetMap; }
QString getTargetMap() const { return this->targetMap; }
void setTargetID(int newTargetID) { this->targetID = newTargetID; }
int getTargetID() const { return this->targetID; }
void setTargetID(QString newTargetID) { this->targetID = newTargetID; }
QString getTargetID() const { return this->targetID; }
private:
QString targetMap;
int targetID = 0;
QString targetID;
};

View File

@ -76,6 +76,7 @@ public:
void resetEvents();
QList<Event *> getEvents(Event::Group group = Event::Group::None) const;
Event* getEvent(Event::Group group, int index) const;
Event* getEvent(Event::Group group, const QString &idName) const;
int getNumEvents(Event::Group group = Event::Group::None) const;
QStringList getScriptLabels(Event::Group group = Event::Group::None);
QString getScriptsFilePath() const;

View File

@ -251,11 +251,11 @@ private slots:
signals:
void eventsChanged();
void openEventMap(Event*);
void openConnectedMap(MapConnection*);
void wildMonTableOpened(EncounterTableModel*);
void wildMonTableClosed();
void wildMonTableEdited();
void warpEventDoubleClicked(QString, int, Event::Group);
void currentMetatilesSelectionChanged();
void mapRulerStatusChanged(const QString &);
void tilesetUpdated(QString);

View File

@ -177,7 +177,7 @@ private slots:
void on_action_Save_Project_triggered();
void save(bool currentOnly = false);
void openWarpMap(QString map_name, int event_id, Event::Group event_group);
void openEventMap(Event *event);
void duplicate();
void setClipboardData(poryjson::Json::object);

View File

@ -42,13 +42,14 @@ signals:
void positionChanged(Event *event);
void xChanged(int);
void yChanged(int);
void spriteChanged(QPixmap pixmap);
void spriteChanged(const QPixmap &pixmap);
void doubleClicked(Event *event);
protected:
virtual void mousePressEvent(QGraphicsSceneMouseEvent*) override;
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent*) override;
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent*) override;
virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent*) override;
virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent*) override { emit doubleClicked(this->event); }
};
#endif // DRAGGABLEPIXMAPITEM_H

View File

@ -275,7 +275,7 @@ bool CloneObjectEvent::loadFromJson(QJsonObject json, Project *project) {
this->setY(readInt(&json, "y"));
this->setIdName(readString(&json, "local_id"));
this->setGfx(readString(&json, "graphics_id"));
this->setTargetID(readInt(&json, "target_local_id"));
this->setTargetID(readString(&json, "target_local_id"));
// Log a warning if "target_map" isn't a known map ID, but don't overwrite user data.
const QString mapConstant = readString(&json, "target_map");
@ -289,7 +289,7 @@ bool CloneObjectEvent::loadFromJson(QJsonObject json, Project *project) {
void CloneObjectEvent::setDefaultValues(Project *project) {
this->setGfx(project->gfxDefines.key(0, "0"));
this->setTargetID(1);
this->setTargetID(QString::number(Event::getIndexOffset(Event::Group::Object)));
if (this->getMap()) this->setTargetMap(this->getMap()->name());
}
@ -308,9 +308,8 @@ QSet<QString> CloneObjectEvent::getExpectedFields() {
void CloneObjectEvent::loadPixmap(Project *project) {
// Try to get the targeted object to clone
int eventIndex = this->targetID - 1;
Map *clonedMap = project->loadMap(this->targetMap);
Event *clonedEvent = clonedMap ? clonedMap->getEvent(Event::Group::Object, eventIndex) : nullptr;
Event *clonedEvent = clonedMap ? clonedMap->getEvent(Event::Group::Object, this->targetID) : nullptr;
if (clonedEvent && clonedEvent->getEventType() == Event::Type::Object) {
// Get graphics data from cloned object

View File

@ -194,6 +194,21 @@ Event* Map::getEvent(Event::Group group, int index) const {
return m_events[group].value(index, nullptr);
}
Event* Map::getEvent(Event::Group group, const QString &idName) const {
bool idIsNumber;
int id = idName.toInt(&idIsNumber, 0);
if (idIsNumber)
return getEvent(group, id - Event::getIndexOffset(group));
auto events = getEvents(group);
for (const auto &event : events) {
if (event->getIdName() == idName) {
return event;
}
}
return nullptr;
}
int Map::getNumEvents(Event::Group group) const {
if (group == Event::Group::None) {
// Total number of events

View File

@ -1699,6 +1699,7 @@ void Editor::displayMapEvents() {
DraggablePixmapItem *Editor::addEventPixmapItem(Event *event) {
this->project->loadEventPixmap(event);
auto item = new DraggablePixmapItem(event, this);
connect(item, &DraggablePixmapItem::doubleClicked, this, &Editor::openEventMap);
redrawEventPixmapItem(item);
this->events_group->addToGroup(item);
return item;

View File

@ -338,7 +338,7 @@ void MainWindow::initEditor() {
this->editor = new Editor(ui);
connect(this->editor, &Editor::eventsChanged, this, &MainWindow::updateEvents);
connect(this->editor, &Editor::openConnectedMap, this, &MainWindow::onOpenConnectedMap);
connect(this->editor, &Editor::warpEventDoubleClicked, this, &MainWindow::openWarpMap);
connect(this->editor, &Editor::openEventMap, this, &MainWindow::openEventMap);
connect(this->editor, &Editor::currentMetatilesSelectionChanged, this, &MainWindow::currentMetatilesSelectionChanged);
connect(this->editor, &Editor::wildMonTableEdited, this, &MainWindow::markMapEdited);
connect(this->editor, &Editor::mapRulerStatusChanged, this, &MainWindow::onMapRulerStatusChanged);
@ -1055,19 +1055,56 @@ void MainWindow::refreshCollisionSelector() {
on_horizontalSlider_CollisionZoom_valueChanged(ui->horizontalSlider_CollisionZoom->value());
}
void MainWindow::openWarpMap(QString map_name, int event_id, Event::Group event_group) {
// Open the destination map.
if (!userSetMap(map_name))
// Some events (like warps) have data that refers to an event on a different map.
// This function opens that map, and selects the event it's referring to.
void MainWindow::openEventMap(Event *sourceEvent) {
if (!sourceEvent || !this->editor->map) return;
QString targetMapName;
QString targetEventIdName;
Event::Group targetEventGroup;
Event::Type eventType = sourceEvent->getEventType();
if (eventType == Event::Type::Warp) {
// Warp events open to their destination warp event.
WarpEvent *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);
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);
QString baseId = base->getBaseID();
targetMapName = this->editor->project->mapConstantsToMapNames.value(mapPrefix + baseId.left(baseId.lastIndexOf("_")));
targetEventIdName = "0";
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);
targetMapName = heal->getRespawnMapName();
targetEventIdName = heal->getRespawnNPC();
targetEventGroup = Event::Group::Object;
} else {
// Other event types have no target map to open.
return;
}
if (!userSetMap(targetMapName))
return;
// Select the target event.
int index = event_id - Event::getIndexOffset(event_group);
Event* event = this->editor->map->getEvent(event_group, index);
if (event) {
this->editor->selectMapEvent(event);
// Map opened successfully, now try to select the targeted event on that map.
Event* targetEvent = this->editor->map->getEvent(targetEventGroup, targetEventIdName);
if (targetEvent) {
this->editor->selectMapEvent(targetEvent);
} else {
// Can still warp to this map, but can't select the specified event
logWarn(QString("%1 %2 doesn't exist on map '%3'").arg(Event::groupToString(event_group)).arg(event_id).arg(map_name));
logWarn(QString("%1 '%2' doesn't exist on map '%3'").arg(Event::groupToString(targetEventGroup)).arg(targetEventIdName).arg(targetMapName));
}
}

View File

@ -162,8 +162,10 @@ void Project::clearTilesetCache() {
Map* Project::loadMap(const QString &mapName) {
Map* map = this->maps.value(mapName);
if (!map)
if (!map) {
logError(QString("Unknown map name '%1'.").arg(mapName));
return nullptr;
}
if (isMapLoaded(map))
return map;
@ -445,7 +447,12 @@ bool Project::loadLayout(Layout *layout) {
Layout *Project::loadLayout(QString layoutId) {
Layout *layout = this->mapLayouts.value(layoutId);
if (!layout || !loadLayout(layout)) {
if (!layout) {
logError(QString("Unknown layout ID '%1'.").arg(layoutId));
return nullptr;
}
if (!loadLayout(layout)) {
logError(QString("Failed to load layout '%1'").arg(layoutId));
return nullptr;
}

View File

@ -103,31 +103,3 @@ void DraggablePixmapItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouse) {
this->editor->selectMapEvent(this->event);
}
}
// Events with properties that specify a map will open that map when double-clicked.
void DraggablePixmapItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *) {
Event::Type eventType = this->event->getEventType();
if (eventType == Event::Type::Warp) {
WarpEvent *warp = dynamic_cast<WarpEvent *>(this->event);
QString destMap = warp->getDestinationMap();
int warpId = ParseUtil::gameStringToInt(warp->getDestinationWarpID());
emit editor->warpEventDoubleClicked(destMap, warpId, Event::Group::Warp);
}
else if (eventType == Event::Type::CloneObject) {
CloneObjectEvent *clone = dynamic_cast<CloneObjectEvent *>(this->event);
emit editor->warpEventDoubleClicked(clone->getTargetMap(), clone->getTargetID(), Event::Group::Object);
}
else if (eventType == Event::Type::SecretBase) {
const QString mapPrefix = projectConfig.getIdentifier(ProjectIdentifier::define_map_prefix);
SecretBaseEvent *base = dynamic_cast<SecretBaseEvent *>(this->event);
QString baseId = base->getBaseID();
QString destMap = editor->project->mapConstantsToMapNames.value(mapPrefix + baseId.left(baseId.lastIndexOf("_")));
emit editor->warpEventDoubleClicked(destMap, 0, Event::Group::Warp);
}
else if (eventType == Event::Type::HealLocation && projectConfig.healLocationRespawnDataEnabled) {
HealLocationEvent *heal = dynamic_cast<HealLocationEvent *>(this->event);
const QString localIdName = heal->getRespawnNPC();
int localId = 0; // TODO: Get value from localIdName
emit editor->warpEventDoubleClicked(heal->getRespawnMapName(), localId, Event::Group::Object);
}
}

View File

@ -453,13 +453,16 @@ void CloneObjectFrame::connectSignals(MainWindow *window) {
});
// target id
// TODO: Replace spinner with combo box populated with local IDs from target map.
this->spinner_target_id->disconnect();
/*
connect(this->spinner_target_id, QOverload<int>::of(&QSpinBox::valueChanged), [this](int value) {
this->clone->setTargetID(value);
this->clone->getPixmapItem()->updatePixmap();
this->combo_sprite->setCurrentText(this->clone->getGfx());
this->clone->modify();
});
*/
}
void CloneObjectFrame::initialize() {
@ -474,7 +477,7 @@ void CloneObjectFrame::initialize() {
// target id
this->spinner_target_id->setMinimum(1);
this->spinner_target_id->setMaximum(126);
this->spinner_target_id->setValue(this->clone->getTargetID());
//this->spinner_target_id->setValue(this->clone->getTargetID());
// target map
this->combo_target_map->setTextItem(this->clone->getTargetMap());