diff --git a/include/core/event.h b/include/core/event.h index 3e3c92c9..cd7da8b4 100644 --- a/include/core/event.h +++ b/include/core/event.h @@ -74,18 +74,21 @@ public: QJsonObject buildSignEventJSON(); QJsonObject buildHiddenItemEventJSON(); QJsonObject buildSecretBaseEventJSON(); - void setPixmapFromSpritesheet(QImage, int, int); + void setPixmapFromSpritesheet(QImage, int, int, int, bool); int getPixelX(); int getPixelY(); QMap getExpectedFields(); void readCustomValues(QJsonObject values); void addCustomValuesTo(QJsonObject *obj); + void setFrameFromMovement(QString); QMap values; QMap customValues; QPixmap pixmap; int spriteWidth; int spriteHeight; + int frame = 0; + bool hFlip = false; bool usingSprite; }; diff --git a/include/project.h b/include/project.h index f3068a07..4762e9cd 100644 --- a/include/project.h +++ b/include/project.h @@ -43,6 +43,7 @@ public: QStringList *bgEventFacingDirections = nullptr; QMap metatileBehaviorMap; QMap metatileBehaviorMapInverse; + QMap facingDirections; QMap *map_cache; Map* loadMap(QString); @@ -106,6 +107,7 @@ public: void readFlagNames(); void readVarNames(); void readMovementTypes(); + void readInitialFacingDirections(); void readMapTypes(); void readMapBattleScenes(); void readWeatherNames(); @@ -126,6 +128,7 @@ public: QStringList readCArray(QString text, QString label); QString readCIncbin(QString text, QString label); QMap readCDefines(QString text, QStringList prefixes); + QMap readNamedIndexCArray(QString text, QString label); static int getNumTilesPrimary(); static int getNumTilesTotal(); diff --git a/src/core/event.cpp b/src/core/event.cpp index 767d85d5..a80f4011 100644 --- a/src/core/event.cpp +++ b/src/core/event.cpp @@ -342,13 +342,35 @@ QJsonObject Event::buildSecretBaseEventJSON() return secretBaseObj; } -void Event::setPixmapFromSpritesheet(QImage spritesheet, int spriteWidth, int spriteHeight) +void Event::setPixmapFromSpritesheet(QImage spritesheet, int spriteWidth, int spriteHeight, int frame, bool hFlip) { // Set first palette color fully transparent. - QImage img = spritesheet.copy(0, 0, spriteWidth, spriteHeight); + QImage img = spritesheet.copy(frame * spriteWidth % spritesheet.width(), 0, spriteWidth, spriteHeight); + if (hFlip) { + img = img.transformed(QTransform().scale(-1, 1)); + } img.setColor(0, qRgba(0, 0, 0, 0)); pixmap = QPixmap::fromImage(img); this->spriteWidth = spriteWidth; this->spriteHeight = spriteHeight; this->usingSprite = true; } + +void Event::setFrameFromMovement(QString facingDir) { + // defaults + this->frame = 0; + this->hFlip = false; + if (facingDir == "DIR_NORTH") { + this->frame = 1; + this->hFlip = false; + } else if (facingDir == "DIR_SOUTH") { + this->frame = 0; + this->hFlip = false; + } else if (facingDir == "DIR_WEST") { + this->frame = 2; + this->hFlip = false; + } else if (facingDir == "DIR_EAST") { + this->frame = 2; + this->hFlip = true; + } +} diff --git a/src/editor.cpp b/src/editor.cpp index 8a6eb27a..abcec186 100644 --- a/src/editor.cpp +++ b/src/editor.cpp @@ -761,6 +761,8 @@ void Editor::displayMapEvents() { DraggablePixmapItem *Editor::addMapEvent(Event *event) { DraggablePixmapItem *object = new DraggablePixmapItem(event, this); + event->setFrameFromMovement(project->facingDirections.value(event->get("movement_type"))); + object->updatePixmap(); if (!event->usingSprite) { object->setOpacity(0.7); } @@ -1202,7 +1204,7 @@ QList *Editor::getObjects() { void Editor::redrawObject(DraggablePixmapItem *item) { if (item) { - item->setPixmap(item->event->pixmap); + item->setPixmap(item->event->pixmap.copy(item->event->frame * item->event->spriteWidth % item->event->pixmap.width(), 0, item->event->spriteWidth, item->event->spriteHeight)); item->setShapeMode(QGraphicsPixmapItem::BoundingRectShape); if (selected_events && selected_events->contains(item)) { QImage image = item->pixmap().toImage(); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index c0fe2d97..e1b54e6f 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -600,6 +600,7 @@ void MainWindow::loadDataStructures() { project->readFlagNames(); project->readVarNames(); project->readMovementTypes(); + project->readInitialFacingDirections(); project->readMapTypes(); project->readMapBattleScenes(); project->readWeatherNames(); @@ -1452,6 +1453,11 @@ void MainWindow::updateSelectedObjects() { if (!editor->project->movementTypes->contains(value)) { combo->addItem(value); } + connect(combo, static_cast(&QComboBox::currentTextChanged), + this, [this, item, frame](QString value){ + item->event->setFrameFromMovement(editor->project->facingDirections.value(value)); + item->updatePixmap(); + }); combo->addItems(*editor->project->movementTypes); combo->setToolTip("The object's natural movement behavior when the player is not interacting with it."); } else if (key == "weather") { diff --git a/src/project.cpp b/src/project.cpp index 934de678..5629d22b 100644 --- a/src/project.cpp +++ b/src/project.cpp @@ -1535,6 +1535,11 @@ void Project::readMovementTypes() { readCDefinesSorted(filepath, prefixes, movementTypes); } +void Project::readInitialFacingDirections() { + QString text = readTextFile(root + "/src/event_object_movement.c"); + facingDirections = readNamedIndexCArray(text, "gInitialMovementTypeFacingDirections"); +} + void Project::readMapTypes() { QString filepath = root + "/include/constants/map_types.h"; QStringList prefixes = (QStringList() << "MAP_TYPE_"); @@ -1708,7 +1713,7 @@ void Project::loadEventPixmaps(QList objects) { spriteHeight = dimensionMatch.captured(2).toInt(); } } - object->setPixmapFromSpritesheet(spritesheet, spriteWidth, spriteHeight); + object->setPixmapFromSpritesheet(spritesheet, spriteWidth, spriteHeight, object->frame, object->hFlip); } } } @@ -1760,6 +1765,25 @@ QStringList Project::readCArray(QString text, QString label) { return list; } +QMap Project::readNamedIndexCArray(QString text, QString label) { + QMap map; + + QRegularExpression re_text(QString("\\b%1\\b\\s*\\[?\\s*\\]?\\s*=\\s*\\{([^\\}]*)\\}").arg(label)); + text = re_text.match(text).captured(1).replace(QRegularExpression("\\s*"), ""); + + QRegularExpression re("\\[(?[A-Za-z1-9_]*)\\]=(?[A-Za-z1-9_]*)"); + QRegularExpressionMatchIterator iter = re.globalMatch(text); + + while (iter.hasNext()) { + QRegularExpressionMatch match = iter.next(); + QString key = match.captured("index"); + QString value = match.captured("value"); + map.insert(key, value); + } + + return map; +} + QString Project::readCIncbin(QString text, QString label) { QString path;