From 8697adf18623a658356b9262b04875fbe1330a27 Mon Sep 17 00:00:00 2001 From: Marcus Huderle Date: Sun, 3 May 2020 10:00:56 -0500 Subject: [PATCH] Add true tileset scripting functions --- include/core/map.h | 2 +- include/editor.h | 3 +++ include/mainwindow.h | 6 +++++ include/project.h | 2 +- include/scripting.h | 1 + src/core/map.cpp | 4 +-- src/editor.cpp | 23 ++++++++++++++++ src/mainwindow.cpp | 63 +++++++++++++++++++++++++++++++++++++++++++- src/project.cpp | 6 ++--- src/scripting.cpp | 4 +++ test_script.js | 33 ++++++++++++++--------- 11 files changed, 127 insertions(+), 20 deletions(-) diff --git a/include/core/map.h b/include/core/map.h index 1afd69c3..a679a55b 100644 --- a/include/core/map.h +++ b/include/core/map.h @@ -85,7 +85,7 @@ public: void removeEvent(Event*); void addEvent(Event*); QPixmap renderConnection(MapConnection, MapLayout *); - QPixmap renderBorder(); + QPixmap renderBorder(bool ignoreCache = false); void setDimensions(int newWidth, int newHeight, bool setNewBlockdata = true); void setBorderDimensions(int newWidth, int newHeight, bool setNewBlockdata = true); void cacheBorder(); diff --git a/include/editor.h b/include/editor.h index 1f9d9232..baf32b5e 100644 --- a/include/editor.h +++ b/include/editor.h @@ -66,6 +66,9 @@ public: void displayMapGrid(); void displayWildMonTables(); + void updateMapBorder(); + void updateMapConnections(); + void setEditingMap(); void setEditingCollision(); void setEditingObjects(); diff --git a/include/mainwindow.h b/include/mainwindow.h index c69351f4..fd320576 100644 --- a/include/mainwindow.h +++ b/include/mainwindow.h @@ -63,6 +63,12 @@ public: Q_INVOKABLE void addRect(int x, int y, int width, int height, QString color = "#000000"); Q_INVOKABLE void addFilledRect(int x, int y, int width, int height, QString color = "#000000"); Q_INVOKABLE void addImage(int x, int y, QString filepath); + void setTilesetPalette(Tileset *tileset, int paletteIndex, QList> colors); + Q_INVOKABLE void setPrimaryTilesetPalette(int paletteIndex, QList> colors); + Q_INVOKABLE void setSecondaryTilesetPalette(int paletteIndex, QList> colors); + QJSValue getTilesetPalette(Tileset *tileset, int paletteIndex); + Q_INVOKABLE QJSValue getPrimaryTilesetPalette(int paletteIndex); + Q_INVOKABLE QJSValue getSecondaryTilesetPalette(int paletteIndex); public slots: diff --git a/include/project.h b/include/project.h index e9147b2c..a1f13f98 100644 --- a/include/project.h +++ b/include/project.h @@ -142,7 +142,7 @@ public: void saveTilesetMetatileAttributes(Tileset*); void saveTilesetMetatiles(Tileset*); void saveTilesetTilesImage(Tileset*); - void saveTilesetPalettes(Tileset*, bool); + void saveTilesetPalettes(Tileset*); QString defaultSong; QStringList getSongNames(); diff --git a/include/scripting.h b/include/scripting.h index 7b8b0f91..614965ea 100644 --- a/include/scripting.h +++ b/include/scripting.h @@ -18,6 +18,7 @@ public: Scripting(MainWindow *mainWindow); static QJSValue fromBlock(Block block); static QJSValue dimensions(int width, int height); + static QJSEngine *getEngine(); static void init(MainWindow *mainWindow); static void cb_MetatileChanged(int x, int y, Block prevBlock, Block newBlock); static void cb_MapOpened(QString mapName); diff --git a/src/core/map.cpp b/src/core/map.cpp index 7101da04..c2229293 100644 --- a/src/core/map.cpp +++ b/src/core/map.cpp @@ -221,7 +221,7 @@ QPixmap Map::render(bool ignoreCache = false, MapLayout * fromLayout) { return pixmap; } -QPixmap Map::renderBorder() { +QPixmap Map::renderBorder(bool ignoreCache) { bool changed_any = false, border_resized = false; int width_ = getBorderWidth(); int height_ = getBorderHeight(); @@ -239,7 +239,7 @@ QPixmap Map::renderBorder() { } QPainter painter(&layout->border_image); for (int i = 0; i < layout->border->blocks->length(); i++) { - if (!border_resized && !borderBlockChanged(i, layout->cached_border)) { + if (!ignoreCache && (!border_resized && !borderBlockChanged(i, layout->cached_border))) { continue; } diff --git a/src/editor.cpp b/src/editor.cpp index 0e8a0c30..92c254ad 100644 --- a/src/editor.cpp +++ b/src/editor.cpp @@ -1440,6 +1440,29 @@ void Editor::displayMapBorder() { } } +void Editor::updateMapBorder() { + QPixmap pixmap = this->map->renderBorder(true); + for (auto item : this->borderItems) { + item->setPixmap(pixmap); + } +} + +void Editor::updateMapConnections() { + if (connection_items.size() != connection_edit_items.size()) + return; + + for (int i = 0; i < connection_items.size(); i++) { + Map *connected_map = project->getMap(connection_edit_items[i]->connection->map_name); + if (!connected_map) + continue; + + QPixmap pixmap = connected_map->renderConnection(*(connection_edit_items[i]->connection), map->layout); + connection_items[i]->setPixmap(pixmap); + connection_edit_items[i]->basePixmap = pixmap; + connection_edit_items[i]->setPixmap(pixmap); + } +} + int Editor::getBorderDrawDistance(int dimension) { // Draw sufficient border blocks to fill the player's view (BORDER_DISTANCE) if (dimension >= BORDER_DISTANCE) { diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 39b44058..29b73ed7 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1073,7 +1073,7 @@ void MainWindow::on_actionNew_Tileset_triggered() { editor->project->saveTilesetTilesImage(newSet); editor->project->saveTilesetMetatiles(newSet); editor->project->saveTilesetMetatileAttributes(newSet); - editor->project->saveTilesetPalettes(newSet, !createTilesetDialog->isSecondary); + editor->project->saveTilesetPalettes(newSet); //append to tileset specific files @@ -2746,3 +2746,64 @@ void MainWindow::addImage(int x, int y, QString filepath) { return; this->ui->graphicsView_Map->overlay.addImage(x, y, filepath); } + +void MainWindow::setTilesetPalette(Tileset *tileset, int paletteIndex, QList> colors) { + if (!this->editor || !this->editor->map || !this->editor->map->layout) + return; + if (paletteIndex >= tileset->palettes->size()) + return; + if (colors.size() != 16) + return; + + for (int i = 0; i < 16; i++) { + if (colors[i].size() != 3) + continue; + auto palettes = tileset->palettes; + (*palettes)[paletteIndex][i] = qRgb(colors[i][0], colors[i][1], colors[i][2]); + } + + if (this->tilesetEditor) { + this->tilesetEditor->setTilesets(this->editor->map->layout->tileset_primary_label, this->editor->map->layout->tileset_secondary_label); + } + this->editor->metatile_selector_item->draw(); + this->editor->selected_border_metatiles_item->draw(); + this->editor->map_item->draw(true); + this->editor->updateMapBorder(); + this->editor->updateMapConnections(); + this->editor->project->saveTilesetPalettes(tileset); +} + +void MainWindow::setPrimaryTilesetPalette(int paletteIndex, QList> colors) { + if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_primary) + return; + this->setTilesetPalette(this->editor->map->layout->tileset_primary, paletteIndex, colors); +} + +void MainWindow::setSecondaryTilesetPalette(int paletteIndex, QList> colors) { + if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_secondary) + return; + this->setTilesetPalette(this->editor->map->layout->tileset_secondary, paletteIndex, colors); +} + +QJSValue MainWindow::getTilesetPalette(Tileset *tileset, int paletteIndex) { + if (paletteIndex >= tileset->palettes->size()) + return QJSValue(); + + QList> palette; + for (auto color : tileset->palettes->value(paletteIndex)) { + palette.append(QList({qRed(color), qGreen(color), qBlue(color)})); + } + return Scripting::getEngine()->toScriptValue(palette); +} + +QJSValue MainWindow::getPrimaryTilesetPalette(int paletteIndex) { + if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_primary) + return QJSValue(); + return this->getTilesetPalette(this->editor->map->layout->tileset_primary, paletteIndex); +} + +QJSValue MainWindow::getSecondaryTilesetPalette(int paletteIndex) { + if (!this->editor || !this->editor->map || !this->editor->map->layout || !this->editor->map->layout->tileset_secondary) + return QJSValue(); + return this->getTilesetPalette(this->editor->map->layout->tileset_secondary, paletteIndex); +} diff --git a/src/project.cpp b/src/project.cpp index f791e50b..7e2a8731 100644 --- a/src/project.cpp +++ b/src/project.cpp @@ -1012,8 +1012,8 @@ void Project::saveTilesets(Tileset *primaryTileset, Tileset *secondaryTileset) { saveTilesetMetatiles(secondaryTileset); saveTilesetTilesImage(primaryTileset); saveTilesetTilesImage(secondaryTileset); - saveTilesetPalettes(primaryTileset, true); - saveTilesetPalettes(secondaryTileset, false); + saveTilesetPalettes(primaryTileset); + saveTilesetPalettes(secondaryTileset); } void Project::saveTilesetMetatileLabels(Tileset *primaryTileset, Tileset *secondaryTileset) { @@ -1150,7 +1150,7 @@ void Project::saveTilesetTilesImage(Tileset *tileset) { exportIndexed4BPPPng(tileset->tilesImage, tileset->tilesImagePath); } -void Project::saveTilesetPalettes(Tileset *tileset, bool /*primary*/) { +void Project::saveTilesetPalettes(Tileset *tileset) { PaletteUtil paletteParser; for (int i = 0; i < Project::getNumPalettesTotal(); i++) { QString filepath = tileset->palettePaths.at(i); diff --git a/src/scripting.cpp b/src/scripting.cpp index 8b64f296..4fdab50d 100644 --- a/src/scripting.cpp +++ b/src/scripting.cpp @@ -90,3 +90,7 @@ QJSValue Scripting::dimensions(int width, int height) { obj.setProperty("height", height); return obj; } + +QJSEngine *Scripting::getEngine() { + return instance->engine; +} diff --git a/test_script.js b/test_script.js index ed74953e..3eae34b3 100644 --- a/test_script.js +++ b/test_script.js @@ -1,17 +1,26 @@ -// Porymap callback when a block is painted. -export function on_block_changed(x, y, prevBlock, newBlock) { - map.clearOverlay() - map.addFilledRect(0, 0, map.getWidth() * 16 - 1, map.getHeight() * 16 - 1, "#80FF0040") - map.addRect(10, 10, 100, 30, "#FF00FF") - map.addImage(80, 80, "D:\\cygwin64\\home\\huder\\scratch\\github-avatar.png") - map.addText(`coords ${x}, ${y}`, 20, 20, "#00FF00", 24) - map.addText(`block ${prevBlock.metatileId}`, 20, 60, "#00FFFF", 18) - console.log("ran", x, y) +const nightTint = [0.6, 0.55, 1.0]; + +function applyTint(palette, tint) { + for (let i = 0; i < palette.length; i++) { + const color = palette[i]; + for (let j = 0; j < tint.length; j++) { + color[j] = Math.floor(color[j] * tint[j]); + } + } } // Porymap callback when a map is opened. export function on_map_opened(mapName) { - map.clearOverlay() - map.addFilledRect(0, 0, map.getWidth() * 16 - 1, map.getHeight() * 16 - 1, "#4000FF00") - console.log(`opened ${mapName}`) + try { + for (let i = 0; i < 13; i++) { + const primaryPalette = map.getPrimaryTilesetPalette(i) + applyTint(primaryPalette, nightTint) + map.setPrimaryTilesetPalette(i, primaryPalette) + const secondaryPalette = map.getSecondaryTilesetPalette(i) + applyTint(secondaryPalette, nightTint) + map.setSecondaryTilesetPalette(i, secondaryPalette) + } + } catch (err) { + console.log(err) + } }