Implement three map scripting functions
This commit is contained in:
parent
267cd5e2cb
commit
d685718f8d
9 changed files with 57 additions and 22 deletions
|
@ -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);
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QCloseEvent>
|
||||
#include <QAbstractItemModel>
|
||||
#include <QJSValue>
|
||||
#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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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<int> smartPathTable;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<uint16_t> *selectedMetatiles = this->metatileSelector->getSelectedMetatiles();
|
||||
QList<QPair<uint16_t, uint16_t>> *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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue