diff --git a/include/core/map.h b/include/core/map.h index 33a9db68..1afd69c3 100644 --- a/include/core/map.h +++ b/include/core/map.h @@ -74,7 +74,7 @@ public: void cacheBlockdata(); void cacheCollision(); Block *getBlock(int x, int y); - void setBlock(int x, int y, Block block, bool invokeCallback = false); + void setBlock(int x, int y, Block block, bool enableScriptCallback = false); void floodFillCollisionElevation(int x, int y, uint16_t collision, uint16_t elevation); void _floodFillCollisionElevation(int x, int y, uint16_t collision, uint16_t elevation); void magicFillCollisionElevation(int x, int y, uint16_t collision, uint16_t elevation); diff --git a/include/mainwindow.h b/include/mainwindow.h index 117b264e..af0649c8 100644 --- a/include/mainwindow.h +++ b/include/mainwindow.h @@ -10,6 +10,7 @@ #include #include #include +#include #include "project.h" #include "config.h" #include "map.h" @@ -37,7 +38,9 @@ public: MainWindow(const MainWindow &) = delete; MainWindow & operator = (const MainWindow &) = delete; - Q_INVOKABLE void scriptapi_setBlock(int x, int y, int tile, int collision, int elevation); + Q_INVOKABLE QJSValue getBlock(int x, int y); + Q_INVOKABLE void setBlock(int x, int y, int tile, int collision, int elevation); + Q_INVOKABLE void setBlocksFromSelection(int x, int y); public slots: void scaleMapView(int); diff --git a/include/scripting.h b/include/scripting.h index c5dc4323..d063b10e 100644 --- a/include/scripting.h +++ b/include/scripting.h @@ -15,7 +15,7 @@ class Scripting { public: Scripting(MainWindow *mainWindow); - QJSValue newBlockObject(Block block); + static QJSValue fromBlock(Block block); static void init(MainWindow *mainWindow); static void cb_MetatileChanged(int x, int y, Block prevBlock, Block newBlock); diff --git a/include/ui/mappixmapitem.h b/include/ui/mappixmapitem.h index e0111eb0..6ea8a090 100644 --- a/include/ui/mappixmapitem.h +++ b/include/ui/mappixmapitem.h @@ -45,9 +45,9 @@ public: virtual void shift(QGraphicsSceneMouseEvent*); virtual void draw(bool ignoreCache = false); void updateMetatileSelection(QGraphicsSceneMouseEvent *event); + void paintNormal(int x, int y, bool fromScriptCallback = false); private: - void paintNormal(int x, int y); void paintSmartPath(int x, int y); static QList smartPathTable; diff --git a/src/core/map.cpp b/src/core/map.cpp index aada600b..7101da04 100644 --- a/src/core/map.cpp +++ b/src/core/map.cpp @@ -364,12 +364,12 @@ Block* Map::getBlock(int x, int y) { return nullptr; } -void Map::setBlock(int x, int y, Block block, bool invokeCallback) { +void Map::setBlock(int x, int y, Block block, bool enableScriptCallback) { int i = y * getWidth() + x; if (layout->blockdata && layout->blockdata->blocks && i < layout->blockdata->blocks->size()) { Block prevBlock = layout->blockdata->blocks->value(i); layout->blockdata->blocks->replace(i, block); - if (invokeCallback) { + if (enableScriptCallback) { Scripting::cb_MetatileChanged(x, y, prevBlock, block); } } diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 2e68858e..e32e3cc8 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -2544,6 +2544,25 @@ void MainWindow::closeEvent(QCloseEvent *event) { QMainWindow::closeEvent(event); } -void MainWindow::scriptapi_setBlock(int x, int y, int tile, int collision, int elevation) { +QJSValue MainWindow::getBlock(int x, int y) { + if (!this->editor || !this->editor->map) + return QJSValue(); + Block *block = this->editor->map->getBlock(x, y); + if (!block) { + return Scripting::fromBlock(Block()); + } + return Scripting::fromBlock(*block); +} + +void MainWindow::setBlock(int x, int y, int tile, int collision, int elevation) { + if (!this->editor || !this->editor->map) + return; this->editor->map->setBlock(x, y, Block(tile, collision, elevation)); } + +void MainWindow::setBlocksFromSelection(int x, int y) { + if (this->editor && this->editor->map_item) { + this->editor->map_item->paintNormal(x, y, true); + } +} + diff --git a/src/scripting.cpp b/src/scripting.cpp index 48ec12e3..fbc5a33c 100644 --- a/src/scripting.cpp +++ b/src/scripting.cpp @@ -14,7 +14,7 @@ void Scripting::init(MainWindow *mainWindow) { Scripting::Scripting(MainWindow *mainWindow) { this->engine = new QJSEngine(mainWindow); this->engine->installExtensions(QJSEngine::ConsoleExtension); - this->engine->globalObject().setProperty("api", this->engine->newQObject(mainWindow)); + this->engine->globalObject().setProperty("map", this->engine->newQObject(mainWindow)); this->filepaths.append("D:\\devkitProOld\\msys\\home\\huder\\pretmap\\test_script.js"); this->loadModules(this->filepaths); } @@ -23,7 +23,13 @@ void Scripting::loadModules(QStringList moduleFiles) { for (QString filepath : moduleFiles) { QJSValue module = this->engine->importModule(filepath); if (module.isError()) { - logError(QString("Failed to load custom script file '%1'").arg(filepath)); + logError(QString("Failed to load custom script file '%1'\nName: %2\nMessage: %3\nFile: %4\nLine Number: %5\nStack: %6") + .arg(filepath) + .arg(module.property("name").toString()) + .arg(module.property("message").toString()) + .arg(module.property("fileName").toString()) + .arg(module.property("lineNumber").toString()) + .arg(module.property("stack").toString())); continue; } @@ -53,14 +59,14 @@ void Scripting::cb_MetatileChanged(int x, int y, Block prevBlock, Block newBlock QJSValueList args { x, y, - instance->newBlockObject(prevBlock), - instance->newBlockObject(newBlock), + instance->fromBlock(prevBlock), + instance->fromBlock(newBlock), }; instance->invokeCallback(OnBlockChanged, args); } -QJSValue Scripting::newBlockObject(Block block) { - QJSValue obj = this->engine->newObject(); +QJSValue Scripting::fromBlock(Block block) { + QJSValue obj = instance->engine->newObject(); obj.setProperty("tile", block.tile); obj.setProperty("collision", block.collision); obj.setProperty("elevation", block.elevation); diff --git a/src/ui/mappixmapitem.cpp b/src/ui/mappixmapitem.cpp index 412892d2..b2afbbd0 100644 --- a/src/ui/mappixmapitem.cpp +++ b/src/ui/mappixmapitem.cpp @@ -69,20 +69,22 @@ void MapPixmapItem::shift(QGraphicsSceneMouseEvent *event) { } } -void MapPixmapItem::paintNormal(int x, int y) { +void MapPixmapItem::paintNormal(int x, int y, bool fromScriptCallback) { QPoint selectionDimensions = this->metatileSelector->getSelectionDimensions(); QList *selectedMetatiles = this->metatileSelector->getSelectedMetatiles(); QList> *selectedCollisions = this->metatileSelector->getSelectedCollisions(); + int initialX = fromScriptCallback ? x : this->paint_tile_initial_x; + int initialY = fromScriptCallback ? y : this->paint_tile_initial_y; // Snap the selected position to the top-left of the block boundary. // This allows painting via dragging the mouse to tile the painted region. - int xDiff = x - this->paint_tile_initial_x; - int yDiff = y - this->paint_tile_initial_y; + int xDiff = x - initialX; + int yDiff = y - initialY; if (xDiff < 0 && xDiff % selectionDimensions.x() != 0) xDiff -= selectionDimensions.x(); if (yDiff < 0 && yDiff % selectionDimensions.y() != 0) yDiff -= selectionDimensions.y(); - x = this->paint_tile_initial_x + (xDiff / selectionDimensions.x()) * selectionDimensions.x(); - y = this->paint_tile_initial_y + (yDiff / selectionDimensions.y()) * selectionDimensions.y(); + x = initialX + (xDiff / selectionDimensions.x()) * selectionDimensions.x(); + y = initialY + (yDiff / selectionDimensions.y()) * selectionDimensions.y(); for (int i = 0; i < selectionDimensions.x() && i + x < map->getWidth(); i++) for (int j = 0; j < selectionDimensions.y() && j + y < map->getHeight(); j++) { @@ -96,7 +98,7 @@ void MapPixmapItem::paintNormal(int x, int y) { block->collision = selectedCollisions->at(index).first; block->elevation = selectedCollisions->at(index).second; } - map->setBlock(actualX, actualY, *block, true); + map->setBlock(actualX, actualY, *block, !fromScriptCallback); } } } diff --git a/test_script.js b/test_script.js index 52f654fd..df98dc42 100644 --- a/test_script.js +++ b/test_script.js @@ -8,8 +8,13 @@ const grassTiles = [0x8, 0x9, 0x10, 0x11]; // Porymap callback when a block is painted. export function on_block_changed(x, y, prevBlock, newBlock) { - if (grassTiles.indexOf(newBlock.tile) != -1) { - const i = randInt(0, grassTiles.length); - api.scriptapi_setBlock(x, y, grassTiles[i], newBlock.collision, newBlock.elevation); + try { + if (grassTiles.indexOf(newBlock.tile) != -1) { + const i = randInt(0, grassTiles.length); + map.setBlock(x, y, grassTiles[i], newBlock.collision, newBlock.elevation); + } + map.setBlocksFromSelection(1, 1) + } catch(err) { + console.log(err); } }