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 cacheBlockdata();
|
||||||
void cacheCollision();
|
void cacheCollision();
|
||||||
Block *getBlock(int x, int y);
|
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 _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);
|
void magicFillCollisionElevation(int x, int y, uint16_t collision, uint16_t elevation);
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <QGraphicsSceneMouseEvent>
|
#include <QGraphicsSceneMouseEvent>
|
||||||
#include <QCloseEvent>
|
#include <QCloseEvent>
|
||||||
#include <QAbstractItemModel>
|
#include <QAbstractItemModel>
|
||||||
|
#include <QJSValue>
|
||||||
#include "project.h"
|
#include "project.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
|
@ -37,7 +38,9 @@ public:
|
||||||
MainWindow(const MainWindow &) = delete;
|
MainWindow(const MainWindow &) = delete;
|
||||||
MainWindow & operator = (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:
|
public slots:
|
||||||
void scaleMapView(int);
|
void scaleMapView(int);
|
||||||
|
|
|
@ -15,7 +15,7 @@ class Scripting
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Scripting(MainWindow *mainWindow);
|
Scripting(MainWindow *mainWindow);
|
||||||
QJSValue newBlockObject(Block block);
|
static QJSValue fromBlock(Block block);
|
||||||
static void init(MainWindow *mainWindow);
|
static void init(MainWindow *mainWindow);
|
||||||
static void cb_MetatileChanged(int x, int y, Block prevBlock, Block newBlock);
|
static void cb_MetatileChanged(int x, int y, Block prevBlock, Block newBlock);
|
||||||
|
|
||||||
|
|
|
@ -45,9 +45,9 @@ public:
|
||||||
virtual void shift(QGraphicsSceneMouseEvent*);
|
virtual void shift(QGraphicsSceneMouseEvent*);
|
||||||
virtual void draw(bool ignoreCache = false);
|
virtual void draw(bool ignoreCache = false);
|
||||||
void updateMetatileSelection(QGraphicsSceneMouseEvent *event);
|
void updateMetatileSelection(QGraphicsSceneMouseEvent *event);
|
||||||
|
void paintNormal(int x, int y, bool fromScriptCallback = false);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void paintNormal(int x, int y);
|
|
||||||
void paintSmartPath(int x, int y);
|
void paintSmartPath(int x, int y);
|
||||||
static QList<int> smartPathTable;
|
static QList<int> smartPathTable;
|
||||||
|
|
||||||
|
|
|
@ -364,12 +364,12 @@ Block* Map::getBlock(int x, int y) {
|
||||||
return nullptr;
|
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;
|
int i = y * getWidth() + x;
|
||||||
if (layout->blockdata && layout->blockdata->blocks && i < layout->blockdata->blocks->size()) {
|
if (layout->blockdata && layout->blockdata->blocks && i < layout->blockdata->blocks->size()) {
|
||||||
Block prevBlock = layout->blockdata->blocks->value(i);
|
Block prevBlock = layout->blockdata->blocks->value(i);
|
||||||
layout->blockdata->blocks->replace(i, block);
|
layout->blockdata->blocks->replace(i, block);
|
||||||
if (invokeCallback) {
|
if (enableScriptCallback) {
|
||||||
Scripting::cb_MetatileChanged(x, y, prevBlock, block);
|
Scripting::cb_MetatileChanged(x, y, prevBlock, block);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2544,6 +2544,25 @@ void MainWindow::closeEvent(QCloseEvent *event) {
|
||||||
QMainWindow::closeEvent(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));
|
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) {
|
Scripting::Scripting(MainWindow *mainWindow) {
|
||||||
this->engine = new QJSEngine(mainWindow);
|
this->engine = new QJSEngine(mainWindow);
|
||||||
this->engine->installExtensions(QJSEngine::ConsoleExtension);
|
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->filepaths.append("D:\\devkitProOld\\msys\\home\\huder\\pretmap\\test_script.js");
|
||||||
this->loadModules(this->filepaths);
|
this->loadModules(this->filepaths);
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,13 @@ void Scripting::loadModules(QStringList moduleFiles) {
|
||||||
for (QString filepath : moduleFiles) {
|
for (QString filepath : moduleFiles) {
|
||||||
QJSValue module = this->engine->importModule(filepath);
|
QJSValue module = this->engine->importModule(filepath);
|
||||||
if (module.isError()) {
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,14 +59,14 @@ void Scripting::cb_MetatileChanged(int x, int y, Block prevBlock, Block newBlock
|
||||||
QJSValueList args {
|
QJSValueList args {
|
||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
instance->newBlockObject(prevBlock),
|
instance->fromBlock(prevBlock),
|
||||||
instance->newBlockObject(newBlock),
|
instance->fromBlock(newBlock),
|
||||||
};
|
};
|
||||||
instance->invokeCallback(OnBlockChanged, args);
|
instance->invokeCallback(OnBlockChanged, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
QJSValue Scripting::newBlockObject(Block block) {
|
QJSValue Scripting::fromBlock(Block block) {
|
||||||
QJSValue obj = this->engine->newObject();
|
QJSValue obj = instance->engine->newObject();
|
||||||
obj.setProperty("tile", block.tile);
|
obj.setProperty("tile", block.tile);
|
||||||
obj.setProperty("collision", block.collision);
|
obj.setProperty("collision", block.collision);
|
||||||
obj.setProperty("elevation", block.elevation);
|
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();
|
QPoint selectionDimensions = this->metatileSelector->getSelectionDimensions();
|
||||||
QList<uint16_t> *selectedMetatiles = this->metatileSelector->getSelectedMetatiles();
|
QList<uint16_t> *selectedMetatiles = this->metatileSelector->getSelectedMetatiles();
|
||||||
QList<QPair<uint16_t, uint16_t>> *selectedCollisions = this->metatileSelector->getSelectedCollisions();
|
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.
|
// Snap the selected position to the top-left of the block boundary.
|
||||||
// This allows painting via dragging the mouse to tile the painted region.
|
// This allows painting via dragging the mouse to tile the painted region.
|
||||||
int xDiff = x - this->paint_tile_initial_x;
|
int xDiff = x - initialX;
|
||||||
int yDiff = y - this->paint_tile_initial_y;
|
int yDiff = y - initialY;
|
||||||
if (xDiff < 0 && xDiff % selectionDimensions.x() != 0) xDiff -= selectionDimensions.x();
|
if (xDiff < 0 && xDiff % selectionDimensions.x() != 0) xDiff -= selectionDimensions.x();
|
||||||
if (yDiff < 0 && yDiff % selectionDimensions.y() != 0) yDiff -= selectionDimensions.y();
|
if (yDiff < 0 && yDiff % selectionDimensions.y() != 0) yDiff -= selectionDimensions.y();
|
||||||
|
|
||||||
x = this->paint_tile_initial_x + (xDiff / selectionDimensions.x()) * selectionDimensions.x();
|
x = initialX + (xDiff / selectionDimensions.x()) * selectionDimensions.x();
|
||||||
y = this->paint_tile_initial_y + (yDiff / selectionDimensions.y()) * selectionDimensions.y();
|
y = initialY + (yDiff / selectionDimensions.y()) * selectionDimensions.y();
|
||||||
|
|
||||||
for (int i = 0; i < selectionDimensions.x() && i + x < map->getWidth(); i++)
|
for (int i = 0; i < selectionDimensions.x() && i + x < map->getWidth(); i++)
|
||||||
for (int j = 0; j < selectionDimensions.y() && j + y < map->getHeight(); j++) {
|
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->collision = selectedCollisions->at(index).first;
|
||||||
block->elevation = selectedCollisions->at(index).second;
|
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.
|
// Porymap callback when a block is painted.
|
||||||
export function on_block_changed(x, y, prevBlock, newBlock) {
|
export function on_block_changed(x, y, prevBlock, newBlock) {
|
||||||
if (grassTiles.indexOf(newBlock.tile) != -1) {
|
try {
|
||||||
const i = randInt(0, grassTiles.length);
|
if (grassTiles.indexOf(newBlock.tile) != -1) {
|
||||||
api.scriptapi_setBlock(x, y, grassTiles[i], newBlock.collision, newBlock.elevation);
|
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