Add prefab tab and refactor metatile selection data
This commit is contained in:
parent
6f68e7e9de
commit
a943b6b260
8 changed files with 257 additions and 171 deletions
|
@ -344,7 +344,7 @@
|
|||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="MapView" name="graphicsView_Map">
|
||||
<widget class="MapView" name="graphicsView_Map" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
|
@ -357,24 +357,6 @@
|
|||
<property name="autoFillBackground">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="verticalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAsNeeded</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAsNeeded</enum>
|
||||
</property>
|
||||
<property name="sizeAdjustPolicy">
|
||||
<enum>QAbstractScrollArea::AdjustIgnored</enum>
|
||||
</property>
|
||||
<property name="dragMode">
|
||||
<enum>QGraphicsView::NoDrag</enum>
|
||||
</property>
|
||||
<property name="transformationAnchor">
|
||||
<enum>QGraphicsView::AnchorUnderMouse</enum>
|
||||
</property>
|
||||
<property name="resizeAnchor">
|
||||
<enum>QGraphicsView::AnchorUnderMouse</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
@ -1276,6 +1258,79 @@
|
|||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_prefabs">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<attribute name="title">
|
||||
<string>Prefabs</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton">
|
||||
<property name="text">
|
||||
<string>Create New Prefab from Current Selection</string>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="default">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_3">
|
||||
<property name="title">
|
||||
<string>Prefabs for Map's Tilesets</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_15">
|
||||
<item>
|
||||
<widget class="QScrollArea" name="scrollArea">
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="scrollAreaWidgetContents_Prefabs">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>396</width>
|
||||
<height>630</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_14">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_prefabHelp">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p>No prefabs have been created for the currently-used tilesets. Create some by using the button above!</p><p>Prefabs are &quot;prefabricated&quot; metatile selections that are used for easy selecting of complicated map structures. For example, a useful prefab could be a building or tree formation, which would otherwise be annoying to paint with the regular metatile picker.</p></body></html></string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
@ -1415,6 +1470,12 @@
|
|||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
|
@ -2986,11 +3047,6 @@
|
|||
<header>adjustingstackedwidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>GraphicsView</class>
|
||||
<extends>QGraphicsView</extends>
|
||||
<header>graphicsview.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>NewEventToolButton</class>
|
||||
<extends>QToolButton</extends>
|
||||
|
@ -3001,6 +3057,11 @@
|
|||
<extends>QWidget</extends>
|
||||
<header>qtabbar.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>MapView</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>mapview.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../resources/images.qrc"/>
|
||||
|
|
|
@ -58,16 +58,16 @@ public:
|
|||
int initialX,
|
||||
int initialY,
|
||||
QPoint selectionDimensions,
|
||||
QList<uint16_t> *selectedMetatiles,
|
||||
QList<QPair<uint16_t, uint16_t>> *selectedCollisions,
|
||||
QList<MetatileSelectionItem> selectedMetatiles,
|
||||
QList<CollisionSelectionItem> selectedCollisions,
|
||||
bool fromScriptCall = false);
|
||||
void floodFill(int x, int y, bool fromScriptCall = false);
|
||||
void floodFill(int x, int y, uint16_t metatileId, bool fromScriptCall = false);
|
||||
void floodFill(int initialX,
|
||||
int initialY,
|
||||
QPoint selectionDimensions,
|
||||
QList<uint16_t> *selectedMetatiles,
|
||||
QList<QPair<uint16_t, uint16_t>> *selectedCollisions,
|
||||
QList<MetatileSelectionItem> selectedMetatiles,
|
||||
QList<CollisionSelectionItem> selectedCollisions,
|
||||
bool fromScriptCall = false);
|
||||
void floodFillSmartPath(int initialX, int initialY, bool fromScriptCall = false);
|
||||
virtual void pick(QGraphicsSceneMouseEvent*);
|
||||
|
|
|
@ -7,6 +7,27 @@
|
|||
#include "tileset.h"
|
||||
#include "maplayout.h"
|
||||
|
||||
struct MetatileSelectionItem
|
||||
{
|
||||
bool enabled;
|
||||
uint16_t metatileId;
|
||||
};
|
||||
|
||||
struct CollisionSelectionItem
|
||||
{
|
||||
bool enabled;
|
||||
uint16_t collision;
|
||||
uint16_t elevation;
|
||||
};
|
||||
|
||||
struct MetatileSelection
|
||||
{
|
||||
QPoint dimensions;
|
||||
bool hasCollision;
|
||||
QList<MetatileSelectionItem> metatileItems;
|
||||
QList<CollisionSelectionItem> collisionItems;
|
||||
};
|
||||
|
||||
class MetatileSelector: public SelectablePixmapItem {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
@ -16,9 +37,7 @@ public:
|
|||
this->map = map;
|
||||
this->primaryTileset = map->layout->tileset_primary;
|
||||
this->secondaryTileset = map->layout->tileset_secondary;
|
||||
this->selectedMetatiles = new QList<uint16_t>();
|
||||
this->selectedCollisions = new QList<QPair<uint16_t, uint16_t>>();
|
||||
this->externalSelectedMetatiles = new QList<uint16_t>();
|
||||
this->selection = MetatileSelection{};
|
||||
setAcceptHoverEvents(true);
|
||||
}
|
||||
QPoint getSelectionDimensions();
|
||||
|
@ -26,8 +45,7 @@ public:
|
|||
bool select(uint16_t metatile);
|
||||
bool selectFromMap(uint16_t metatileId, uint16_t collision, uint16_t elevation);
|
||||
void setTilesets(Tileset*, Tileset*);
|
||||
QList<uint16_t>* getSelectedMetatiles();
|
||||
QList<QPair<uint16_t, uint16_t>>* getSelectedCollisions();
|
||||
MetatileSelection getMetatileSelection();
|
||||
void setExternalSelection(int, int, QList<uint16_t>, QList<QPair<uint16_t, uint16_t>>);
|
||||
QPoint getMetatileIdCoordsOnWidget(uint16_t);
|
||||
void setMap(Map*);
|
||||
|
@ -43,11 +61,10 @@ private:
|
|||
bool externalSelection;
|
||||
int numMetatilesWide;
|
||||
Map *map;
|
||||
QList<uint16_t> *selectedMetatiles;
|
||||
QList<QPair<uint16_t, uint16_t>> *selectedCollisions;
|
||||
int externalSelectionWidth;
|
||||
int externalSelectionHeight;
|
||||
QList<uint16_t> *externalSelectedMetatiles;
|
||||
QList<uint16_t> externalSelectedMetatiles;
|
||||
MetatileSelection selection;
|
||||
|
||||
void updateSelectedMetatiles();
|
||||
void updateExternalSelectedMetatiles();
|
||||
|
|
|
@ -1379,7 +1379,8 @@ void MainWindow::redrawMetatileSelection()
|
|||
|
||||
QPoint size = editor->metatile_selector_item->getSelectionDimensions();
|
||||
if (size.x() == 1 && size.y() == 1) {
|
||||
QPoint pos = editor->metatile_selector_item->getMetatileIdCoordsOnWidget(editor->metatile_selector_item->getSelectedMetatiles()->at(0));
|
||||
MetatileSelection selection = editor->metatile_selector_item->getMetatileSelection();
|
||||
QPoint pos = editor->metatile_selector_item->getMetatileIdCoordsOnWidget(selection.metatileItems.first().metatileId);
|
||||
pos *= scale;
|
||||
ui->scrollArea_2->ensureVisible(pos.x(), pos.y(), 8 * scale, 8 * scale);
|
||||
}
|
||||
|
@ -1388,8 +1389,10 @@ void MainWindow::redrawMetatileSelection()
|
|||
void MainWindow::currentMetatilesSelectionChanged()
|
||||
{
|
||||
redrawMetatileSelection();
|
||||
if (this->tilesetEditor)
|
||||
this->tilesetEditor->selectMetatile(editor->metatile_selector_item->getSelectedMetatiles()->at(0));
|
||||
if (this->tilesetEditor) {
|
||||
MetatileSelection selection = editor->metatile_selector_item->getMetatileSelection();
|
||||
this->tilesetEditor->selectMetatile(selection.metatileItems.first().metatileId);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_mapList_activated(const QModelIndex &index)
|
||||
|
@ -1461,15 +1464,18 @@ void MainWindow::copy() {
|
|||
OrderedJson::object copyObject;
|
||||
copyObject["object"] = "metatile_selection";
|
||||
OrderedJson::array metatiles;
|
||||
for (auto item : *editor->metatile_selector_item->getSelectedMetatiles()) {
|
||||
metatiles.append(static_cast<int>(item));
|
||||
MetatileSelection selection = editor->metatile_selector_item->getMetatileSelection();
|
||||
for (auto item : selection.metatileItems) {
|
||||
metatiles.append(static_cast<int>(item.metatileId));
|
||||
}
|
||||
OrderedJson::array collisions;
|
||||
for (auto collisionPair : *editor->metatile_selector_item->getSelectedCollisions()) {
|
||||
OrderedJson::object collision;
|
||||
collision["collision"] = collisionPair.first;
|
||||
collision["elevation"] = collisionPair.second;
|
||||
collisions.append(collision);
|
||||
if (selection.hasCollision) {
|
||||
for (auto item : selection.collisionItems) {
|
||||
OrderedJson::object collision;
|
||||
collision["collision"] = item.collision;
|
||||
collision["elevation"] = item.elevation;
|
||||
collisions.append(collision);
|
||||
}
|
||||
}
|
||||
if (collisions.length() != metatiles.length()) {
|
||||
// fill in collisions
|
||||
|
@ -3013,7 +3019,9 @@ void MainWindow::on_actionTileset_Editor_triggered()
|
|||
} else {
|
||||
this->tilesetEditor->activateWindow();
|
||||
}
|
||||
this->tilesetEditor->selectMetatile(this->editor->metatile_selector_item->getSelectedMetatiles()->at(0));
|
||||
|
||||
MetatileSelection selection = this->editor->metatile_selector_item->getMetatileSelection();
|
||||
this->tilesetEditor->selectMetatile(selection.metatileItems.first().metatileId);
|
||||
}
|
||||
|
||||
void MainWindow::initTilesetEditor() {
|
||||
|
|
|
@ -5,18 +5,17 @@
|
|||
#include <QPainter>
|
||||
|
||||
void BorderMetatilesPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
|
||||
QList<uint16_t> *selectedMetatiles = this->metatileSelector->getSelectedMetatiles();
|
||||
QPoint selectionDimensions = this->metatileSelector->getSelectionDimensions();
|
||||
MetatileSelection selection = this->metatileSelector->getMetatileSelection();
|
||||
QPoint pos = Metatile::coordFromPixmapCoord(event->pos());
|
||||
int width = map->getBorderWidth();
|
||||
int height = map->getBorderHeight();
|
||||
|
||||
Blockdata oldBorder = map->layout->border;
|
||||
|
||||
for (int i = 0; i < selectionDimensions.x() && (i + pos.x()) < width; i++) {
|
||||
for (int j = 0; j < selectionDimensions.y() && (j + pos.y()) < height; j++) {
|
||||
uint16_t metatileId = selectedMetatiles->at(j * selectionDimensions.x() + i);
|
||||
map->setBorderMetatileId(pos.x() + i, pos.y() + j, metatileId, true);
|
||||
for (int i = 0; i < selection.dimensions.x() && (i + pos.x()) < width; i++) {
|
||||
for (int j = 0; j < selection.dimensions.y() && (j + pos.y()) < height; j++) {
|
||||
MetatileSelectionItem item = selection.metatileItems.at(j * selection.dimensions.x() + i);
|
||||
map->setBorderMetatileId(pos.x() + i, pos.y() + j, item.metatileId, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,20 +3,20 @@
|
|||
#include <QPainter>
|
||||
|
||||
void CurrentSelectedMetatilesPixmapItem::draw() {
|
||||
QList<uint16_t> *selectedMetatiles = metatileSelector->getSelectedMetatiles();
|
||||
QPoint selectionDimensions = metatileSelector->getSelectionDimensions();
|
||||
int width = selectionDimensions.x() * 16;
|
||||
int height = selectionDimensions.y() * 16;
|
||||
MetatileSelection selection = metatileSelector->getMetatileSelection();
|
||||
int width = selection.dimensions.x() * 16;
|
||||
int height = selection.dimensions.y() * 16;
|
||||
QImage image(width, height, QImage::Format_RGBA8888);
|
||||
QPainter painter(&image);
|
||||
|
||||
for (int i = 0; i < selectionDimensions.x(); i++) {
|
||||
for (int j = 0; j < selectionDimensions.y(); j++) {
|
||||
for (int i = 0; i < selection.dimensions.x(); i++) {
|
||||
for (int j = 0; j < selection.dimensions.y(); j++) {
|
||||
int x = i * 16;
|
||||
int y = j * 16;
|
||||
int index = j * selectionDimensions.x() + i;
|
||||
int index = j * selection.dimensions.x() + i;
|
||||
MetatileSelectionItem item = selection.metatileItems.at(index);
|
||||
QImage metatile_image = getMetatileImage(
|
||||
selectedMetatiles->at(index),
|
||||
item.metatileId,
|
||||
map->layout->tileset_primary,
|
||||
map->layout->tileset_secondary,
|
||||
map->metatileLayerOrder,
|
||||
|
|
|
@ -102,9 +102,7 @@ void MapPixmapItem::shift(int xDelta, int yDelta, bool fromScriptCall) {
|
|||
}
|
||||
|
||||
void MapPixmapItem::paintNormal(int x, int y, bool fromScriptCall) {
|
||||
QPoint selectionDimensions = this->metatileSelector->getSelectionDimensions();
|
||||
QList<uint16_t> *selectedMetatiles = this->metatileSelector->getSelectedMetatiles();
|
||||
QList<QPair<uint16_t, uint16_t>> *selectedCollisions = this->metatileSelector->getSelectedCollisions();
|
||||
MetatileSelection selection = this->metatileSelector->getMetatileSelection();
|
||||
int initialX = fromScriptCall ? x : this->paint_tile_initial_x;
|
||||
int initialY = fromScriptCall ? y : this->paint_tile_initial_y;
|
||||
|
||||
|
@ -112,26 +110,28 @@ void MapPixmapItem::paintNormal(int x, int y, bool fromScriptCall) {
|
|||
// This allows painting via dragging the mouse to tile the painted region.
|
||||
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();
|
||||
if (xDiff < 0 && xDiff % selection.dimensions.x() != 0) xDiff -= selection.dimensions.x();
|
||||
if (yDiff < 0 && yDiff % selection.dimensions.y() != 0) yDiff -= selection.dimensions.y();
|
||||
|
||||
x = initialX + (xDiff / selectionDimensions.x()) * selectionDimensions.x();
|
||||
y = initialY + (yDiff / selectionDimensions.y()) * selectionDimensions.y();
|
||||
x = initialX + (xDiff / selection.dimensions.x()) * selection.dimensions.x();
|
||||
y = initialY + (yDiff / selection.dimensions.y()) * selection.dimensions.y();
|
||||
|
||||
// for edit history
|
||||
Blockdata oldMetatiles = !fromScriptCall ? map->layout->blockdata : Blockdata();
|
||||
|
||||
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 i = 0; i < selection.dimensions.x() && i + x < map->getWidth(); i++)
|
||||
for (int j = 0; j < selection.dimensions.y() && j + y < map->getHeight(); j++) {
|
||||
int actualX = i + x;
|
||||
int actualY = j + y;
|
||||
Block block;
|
||||
if (map->getBlock(actualX, actualY, &block)) {
|
||||
int index = j * selectionDimensions.x() + i;
|
||||
block.metatileId = selectedMetatiles->at(index);
|
||||
if (selectedCollisions && selectedCollisions->length() == selectedMetatiles->length()) {
|
||||
block.collision = selectedCollisions->at(index).first;
|
||||
block.elevation = selectedCollisions->at(index).second;
|
||||
int index = j * selection.dimensions.x() + i;
|
||||
MetatileSelectionItem item = selection.metatileItems.at(index);
|
||||
block.metatileId = item.metatileId;
|
||||
if (selection.hasCollision && selection.collisionItems.length() == selection.metatileItems.length()) {
|
||||
CollisionSelectionItem collisionItem = selection.collisionItems.at(index);
|
||||
block.collision = collisionItem.collision;
|
||||
block.elevation = collisionItem.elevation;
|
||||
}
|
||||
map->setBlock(actualX, actualY, block, !fromScriptCall);
|
||||
}
|
||||
|
@ -166,22 +166,29 @@ QList<int> MapPixmapItem::smartPathTable = QList<int>({
|
|||
|
||||
#define IS_SMART_PATH_TILE(block) (selectedMetatiles->contains(block.metatileId))
|
||||
|
||||
bool isSmartPathTile(QList<MetatileSelectionItem> metatileItems, uint16_t metatileId) {
|
||||
for (int i = 0; i < metatileItems.length(); i++) {
|
||||
if (metatileItems.at(i).metatileId == metatileId) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void MapPixmapItem::paintSmartPath(int x, int y, bool fromScriptCall) {
|
||||
QPoint selectionDimensions = this->metatileSelector->getSelectionDimensions();
|
||||
QList<uint16_t> *selectedMetatiles = this->metatileSelector->getSelectedMetatiles();
|
||||
QList<QPair<uint16_t, uint16_t>> *selectedCollisions = this->metatileSelector->getSelectedCollisions();
|
||||
MetatileSelection selection = this->metatileSelector->getMetatileSelection();
|
||||
|
||||
// Smart path should never be enabled without a 3x3 block selection.
|
||||
if (selectionDimensions.x() != 3 || selectionDimensions.y() != 3) return;
|
||||
if (selection.dimensions.x() != 3 || selection.dimensions.y() != 3) return;
|
||||
|
||||
// Shift to the middle tile of the smart path selection.
|
||||
uint16_t openTile = selectedMetatiles->at(4);
|
||||
uint16_t openTile = selection.metatileItems.at(4).metatileId;
|
||||
uint16_t openTileCollision = 0;
|
||||
uint16_t openTileElevation = 0;
|
||||
bool setCollisions = false;
|
||||
if (selectedCollisions && selectedCollisions->length() == selectedMetatiles->length()) {
|
||||
openTileCollision = selectedCollisions->at(4).first;
|
||||
openTileElevation = selectedCollisions->at(4).second;
|
||||
if (selection.hasCollision && selection.collisionItems.length() == selection.metatileItems.length()) {
|
||||
openTileCollision = selection.collisionItems.at(4).collision;
|
||||
openTileElevation = selection.collisionItems.at(4).elevation;
|
||||
setCollisions = true;
|
||||
}
|
||||
|
||||
|
@ -220,7 +227,7 @@ void MapPixmapItem::paintSmartPath(int x, int y, bool fromScriptCall) {
|
|||
int actualX = i + x;
|
||||
int actualY = j + y;
|
||||
Block block;
|
||||
if (!map->getBlock(actualX, actualY, &block) || !IS_SMART_PATH_TILE(block)) {
|
||||
if (!map->getBlock(actualX, actualY, &block) || !isSmartPathTile(selection.metatileItems, block.metatileId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -231,19 +238,20 @@ void MapPixmapItem::paintSmartPath(int x, int y, bool fromScriptCall) {
|
|||
Block left;
|
||||
|
||||
// Get marching squares value, to determine which tile to use.
|
||||
if (map->getBlock(actualX, actualY - 1, &top) && IS_SMART_PATH_TILE(top))
|
||||
if (map->getBlock(actualX, actualY - 1, &top) && isSmartPathTile(selection.metatileItems, top.metatileId))
|
||||
id += 1;
|
||||
if (map->getBlock(actualX + 1, actualY, &right) && IS_SMART_PATH_TILE(right))
|
||||
if (map->getBlock(actualX + 1, actualY, &right) && isSmartPathTile(selection.metatileItems, right.metatileId))
|
||||
id += 2;
|
||||
if (map->getBlock(actualX, actualY + 1, &bottom) && IS_SMART_PATH_TILE(bottom))
|
||||
if (map->getBlock(actualX, actualY + 1, &bottom) && isSmartPathTile(selection.metatileItems, bottom.metatileId))
|
||||
id += 4;
|
||||
if (map->getBlock(actualX - 1, actualY, &left) && IS_SMART_PATH_TILE(left))
|
||||
if (map->getBlock(actualX - 1, actualY, &left) && isSmartPathTile(selection.metatileItems, left.metatileId))
|
||||
id += 8;
|
||||
|
||||
block.metatileId = selectedMetatiles->at(smartPathTable[id]);
|
||||
block.metatileId = selection.metatileItems.at(smartPathTable[id]).metatileId;
|
||||
if (setCollisions) {
|
||||
block.collision = selectedCollisions->at(smartPathTable[id]).first;
|
||||
block.elevation = selectedCollisions->at(smartPathTable[id]).second;
|
||||
CollisionSelectionItem collisionItem = selection.collisionItems.at(smartPathTable[id]);
|
||||
block.collision = collisionItem.collision;
|
||||
block.elevation = collisionItem.elevation;
|
||||
}
|
||||
map->setBlock(actualX, actualY, block, !fromScriptCall);
|
||||
}
|
||||
|
@ -348,12 +356,11 @@ void MapPixmapItem::floodFill(QGraphicsSceneMouseEvent *event) {
|
|||
} else {
|
||||
QPoint pos = Metatile::coordFromPixmapCoord(event->pos());
|
||||
Block block;
|
||||
QList<uint16_t> *selectedMetatiles = this->metatileSelector->getSelectedMetatiles();
|
||||
QPoint selectionDimensions = this->metatileSelector->getSelectionDimensions();
|
||||
int metatileId = selectedMetatiles->first();
|
||||
if (selectedMetatiles->count() > 1 || (map->getBlock(pos.x(), pos.y(), &block) && block.metatileId != metatileId)) {
|
||||
MetatileSelection selection = this->metatileSelector->getMetatileSelection();
|
||||
int metatileId = selection.metatileItems.first().metatileId;
|
||||
if (selection.metatileItems.count() > 1 || (map->getBlock(pos.x(), pos.y(), &block) && block.metatileId != metatileId)) {
|
||||
bool smartPathsEnabled = event->modifiers() & Qt::ShiftModifier;
|
||||
if ((this->settings->smartPathsEnabled || smartPathsEnabled) && selectionDimensions.x() == 3 && selectionDimensions.y() == 3)
|
||||
if ((this->settings->smartPathsEnabled || smartPathsEnabled) && selection.dimensions.x() == 3 && selection.dimensions.y() == 3)
|
||||
this->floodFillSmartPath(pos.x(), pos.y());
|
||||
else
|
||||
this->floodFill(pos.x(), pos.y());
|
||||
|
@ -375,34 +382,31 @@ void MapPixmapItem::magicFill(QGraphicsSceneMouseEvent *event) {
|
|||
|
||||
void MapPixmapItem::magicFill(int x, int y, uint16_t metatileId, bool fromScriptCall) {
|
||||
QPoint selectionDimensions(1, 1);
|
||||
QList<uint16_t> *selectedMetatiles = new QList<uint16_t>({ metatileId });
|
||||
this->magicFill(x, y, selectionDimensions, selectedMetatiles, nullptr, fromScriptCall);
|
||||
delete selectedMetatiles;
|
||||
QList<MetatileSelectionItem> selectedMetatiles = QList<MetatileSelectionItem>({MetatileSelectionItem{ true, metatileId }});
|
||||
this->magicFill(x, y, selectionDimensions, selectedMetatiles, QList<CollisionSelectionItem>(), fromScriptCall);
|
||||
}
|
||||
|
||||
void MapPixmapItem::magicFill(int x, int y, bool fromScriptCall) {
|
||||
QPoint selectionDimensions = this->metatileSelector->getSelectionDimensions();
|
||||
QList<uint16_t> *selectedMetatiles = this->metatileSelector->getSelectedMetatiles();
|
||||
QList<QPair<uint16_t, uint16_t>> *selectedCollisions = this->metatileSelector->getSelectedCollisions();
|
||||
this->magicFill(x, y, selectionDimensions, selectedMetatiles, selectedCollisions, fromScriptCall);
|
||||
MetatileSelection selection = this->metatileSelector->getMetatileSelection();
|
||||
this->magicFill(x, y, selection.dimensions, selection.metatileItems, selection.collisionItems, fromScriptCall);
|
||||
}
|
||||
|
||||
void MapPixmapItem::magicFill(
|
||||
int initialX,
|
||||
int initialY,
|
||||
QPoint selectionDimensions,
|
||||
QList<uint16_t> *selectedMetatiles,
|
||||
QList<QPair<uint16_t, uint16_t>> *selectedCollisions,
|
||||
QList<MetatileSelectionItem> selectedMetatiles,
|
||||
QList<CollisionSelectionItem> selectedCollisions,
|
||||
bool fromScriptCall) {
|
||||
Block block;
|
||||
if (map->getBlock(initialX, initialY, &block)) {
|
||||
if (selectedMetatiles->length() == 1 && selectedMetatiles->value(0) == block.metatileId) {
|
||||
if (selectedMetatiles.length() == 1 && selectedMetatiles.at(0).metatileId == block.metatileId) {
|
||||
return;
|
||||
}
|
||||
|
||||
Blockdata oldMetatiles = !fromScriptCall ? map->layout->blockdata : Blockdata();
|
||||
|
||||
bool setCollisions = selectedCollisions && selectedCollisions->length() == selectedMetatiles->length();
|
||||
bool setCollisions = selectedCollisions.length() == selectedMetatiles.length();
|
||||
uint16_t metatileId = block.metatileId;
|
||||
for (int y = 0; y < map->getHeight(); y++) {
|
||||
for (int x = 0; x < map->getWidth(); x++) {
|
||||
|
@ -414,10 +418,11 @@ void MapPixmapItem::magicFill(
|
|||
if (i < 0) i = selectionDimensions.x() + i;
|
||||
if (j < 0) j = selectionDimensions.y() + j;
|
||||
int index = j * selectionDimensions.x() + i;
|
||||
block.metatileId = selectedMetatiles->at(index);
|
||||
block.metatileId = selectedMetatiles.at(index).metatileId;
|
||||
if (setCollisions) {
|
||||
block.collision = selectedCollisions->at(index).first;
|
||||
block.elevation = selectedCollisions->at(index).second;
|
||||
CollisionSelectionItem item = selectedCollisions.at(index);
|
||||
block.collision = item.collision;
|
||||
block.elevation = item.elevation;
|
||||
}
|
||||
map->setBlock(x, y, block, !fromScriptCall);
|
||||
}
|
||||
|
@ -431,27 +436,24 @@ void MapPixmapItem::magicFill(
|
|||
}
|
||||
|
||||
void MapPixmapItem::floodFill(int initialX, int initialY, bool fromScriptCall) {
|
||||
QPoint selectionDimensions = this->metatileSelector->getSelectionDimensions();
|
||||
QList<uint16_t> *selectedMetatiles = this->metatileSelector->getSelectedMetatiles();
|
||||
QList<QPair<uint16_t, uint16_t>> *selectedCollisions = this->metatileSelector->getSelectedCollisions();
|
||||
this->floodFill(initialX, initialY, selectionDimensions, selectedMetatiles, selectedCollisions, fromScriptCall);
|
||||
MetatileSelection selection = this->metatileSelector->getMetatileSelection();
|
||||
this->floodFill(initialX, initialY, selection.dimensions, selection.metatileItems, selection.collisionItems, fromScriptCall);
|
||||
}
|
||||
|
||||
void MapPixmapItem::floodFill(int initialX, int initialY, uint16_t metatileId, bool fromScriptCall) {
|
||||
QPoint selectionDimensions(1, 1);
|
||||
QList<uint16_t> *selectedMetatiles = new QList<uint16_t>({ metatileId });
|
||||
this->floodFill(initialX, initialY, selectionDimensions, selectedMetatiles, nullptr, fromScriptCall);
|
||||
delete selectedMetatiles;
|
||||
QList<MetatileSelectionItem> selectedMetatiles = QList<MetatileSelectionItem>({MetatileSelectionItem{true, metatileId}});
|
||||
this->floodFill(initialX, initialY, selectionDimensions, selectedMetatiles, QList<CollisionSelectionItem>(), fromScriptCall);
|
||||
}
|
||||
|
||||
void MapPixmapItem::floodFill(
|
||||
int initialX,
|
||||
int initialY,
|
||||
QPoint selectionDimensions,
|
||||
QList<uint16_t> *selectedMetatiles,
|
||||
QList<QPair<uint16_t, uint16_t>> *selectedCollisions,
|
||||
QList<MetatileSelectionItem> selectedMetatiles,
|
||||
QList<CollisionSelectionItem> selectedCollisions,
|
||||
bool fromScriptCall) {
|
||||
bool setCollisions = selectedCollisions && selectedCollisions->length() == selectedMetatiles->length();
|
||||
bool setCollisions = selectedCollisions.length() == selectedMetatiles.length();
|
||||
Blockdata oldMetatiles = !fromScriptCall ? map->layout->blockdata : Blockdata();
|
||||
|
||||
QSet<int> visited;
|
||||
|
@ -474,13 +476,14 @@ void MapPixmapItem::floodFill(
|
|||
if (i < 0) i = selectionDimensions.x() + i;
|
||||
if (j < 0) j = selectionDimensions.y() + j;
|
||||
int index = j * selectionDimensions.x() + i;
|
||||
uint16_t metatileId = selectedMetatiles->at(index);
|
||||
uint16_t metatileId = selectedMetatiles.at(index).metatileId;
|
||||
uint16_t old_metatileId = block.metatileId;
|
||||
if (selectedMetatiles->count() != 1 || old_metatileId != metatileId) {
|
||||
if (selectedMetatiles.count() != 1 || old_metatileId != metatileId) {
|
||||
block.metatileId = metatileId;
|
||||
if (setCollisions) {
|
||||
block.collision = selectedCollisions->at(index).first;
|
||||
block.elevation = selectedCollisions->at(index).second;
|
||||
CollisionSelectionItem item = selectedCollisions.at(index);
|
||||
block.collision = item.collision;
|
||||
block.elevation = item.elevation;
|
||||
}
|
||||
map->setBlock(x, y, block, !fromScriptCall);
|
||||
}
|
||||
|
@ -508,21 +511,20 @@ void MapPixmapItem::floodFill(
|
|||
}
|
||||
|
||||
void MapPixmapItem::floodFillSmartPath(int initialX, int initialY, bool fromScriptCall) {
|
||||
QPoint selectionDimensions = this->metatileSelector->getSelectionDimensions();
|
||||
QList<uint16_t> *selectedMetatiles = this->metatileSelector->getSelectedMetatiles();
|
||||
QList<QPair<uint16_t, uint16_t>> *selectedCollisions = this->metatileSelector->getSelectedCollisions();
|
||||
MetatileSelection selection = this->metatileSelector->getMetatileSelection();
|
||||
|
||||
// Smart path should never be enabled without a 3x3 block selection.
|
||||
if (selectionDimensions.x() != 3 || selectionDimensions.y() != 3) return;
|
||||
if (selection.dimensions.x() != 3 || selection.dimensions.y() != 3) return;
|
||||
|
||||
// Shift to the middle tile of the smart path selection.
|
||||
uint16_t openTile = selectedMetatiles->at(4);
|
||||
uint16_t openTile = selection.metatileItems.at(4).metatileId;
|
||||
uint16_t openTileCollision = 0;
|
||||
uint16_t openTileElevation = 0;
|
||||
bool setCollisions = false;
|
||||
if (selectedCollisions && selectedCollisions->length() == selectedMetatiles->length()) {
|
||||
openTileCollision = selectedCollisions->at(4).first;
|
||||
openTileElevation = selectedCollisions->at(4).second;
|
||||
if (selection.hasCollision && selection.collisionItems.length() == selection.metatileItems.length()) {
|
||||
CollisionSelectionItem item = selection.collisionItems.at(4);
|
||||
openTileCollision = item.collision;
|
||||
openTileElevation = item.elevation;
|
||||
setCollisions = true;
|
||||
}
|
||||
|
||||
|
@ -586,36 +588,37 @@ void MapPixmapItem::floodFillSmartPath(int initialX, int initialY, bool fromScri
|
|||
Block left;
|
||||
|
||||
// Get marching squares value, to determine which tile to use.
|
||||
if (map->getBlock(x, y - 1, &top) && IS_SMART_PATH_TILE(top))
|
||||
if (map->getBlock(x, y - 1, &top) && isSmartPathTile(selection.metatileItems, top.metatileId))
|
||||
id += 1;
|
||||
if (map->getBlock(x + 1, y, &right) && IS_SMART_PATH_TILE(right))
|
||||
if (map->getBlock(x + 1, y, &right) && isSmartPathTile(selection.metatileItems, right.metatileId))
|
||||
id += 2;
|
||||
if (map->getBlock(x, y + 1, &bottom) && IS_SMART_PATH_TILE(bottom))
|
||||
if (map->getBlock(x, y + 1, &bottom) && isSmartPathTile(selection.metatileItems, bottom.metatileId))
|
||||
id += 4;
|
||||
if (map->getBlock(x - 1, y, &left) && IS_SMART_PATH_TILE(left))
|
||||
if (map->getBlock(x - 1, y, &left) && isSmartPathTile(selection.metatileItems, left.metatileId))
|
||||
id += 8;
|
||||
|
||||
block.metatileId = selectedMetatiles->at(smartPathTable[id]);
|
||||
block.metatileId = selection.metatileItems.at(smartPathTable[id]).metatileId;
|
||||
if (setCollisions) {
|
||||
block.collision = selectedCollisions->at(smartPathTable[id]).first;
|
||||
block.elevation = selectedCollisions->at(smartPathTable[id]).second;
|
||||
CollisionSelectionItem item = selection.collisionItems.at(smartPathTable[id]);
|
||||
block.collision = item.collision;
|
||||
block.elevation = item.elevation;
|
||||
}
|
||||
map->setBlock(x, y, block, !fromScriptCall);
|
||||
|
||||
// Visit neighbors if they are smart-path tiles, and don't revisit any.
|
||||
if (!visited.contains(x + 1 + y * map->getWidth()) && map->getBlock(x + 1, y, &block) && IS_SMART_PATH_TILE(block)) {
|
||||
if (!visited.contains(x + 1 + y * map->getWidth()) && map->getBlock(x + 1, y, &block) && isSmartPathTile(selection.metatileItems, block.metatileId)) {
|
||||
todo.append(QPoint(x + 1, y));
|
||||
visited.insert(x + 1 + y * map->getWidth());
|
||||
}
|
||||
if (!visited.contains(x - 1 + y * map->getWidth()) && map->getBlock(x - 1, y, &block) && IS_SMART_PATH_TILE(block)) {
|
||||
if (!visited.contains(x - 1 + y * map->getWidth()) && map->getBlock(x - 1, y, &block) && isSmartPathTile(selection.metatileItems, block.metatileId)) {
|
||||
todo.append(QPoint(x - 1, y));
|
||||
visited.insert(x - 1 + y * map->getWidth());
|
||||
}
|
||||
if (!visited.contains(x + (y + 1) * map->getWidth()) && map->getBlock(x, y + 1, &block) && IS_SMART_PATH_TILE(block)) {
|
||||
if (!visited.contains(x + (y + 1) * map->getWidth()) && map->getBlock(x, y + 1, &block) && isSmartPathTile(selection.metatileItems, block.metatileId)) {
|
||||
todo.append(QPoint(x, y + 1));
|
||||
visited.insert(x + (y + 1) * map->getWidth());
|
||||
}
|
||||
if (!visited.contains(x + (y - 1) * map->getWidth()) && map->getBlock(x, y - 1, &block) && IS_SMART_PATH_TILE(block)) {
|
||||
if (!visited.contains(x + (y - 1) * map->getWidth()) && map->getBlock(x, y - 1, &block) && isSmartPathTile(selection.metatileItems, block.metatileId)) {
|
||||
todo.append(QPoint(x, y - 1));
|
||||
visited.insert(x + (y - 1) * map->getWidth());
|
||||
}
|
||||
|
|
|
@ -4,11 +4,7 @@
|
|||
#include <QPainter>
|
||||
|
||||
QPoint MetatileSelector::getSelectionDimensions() {
|
||||
if (this->externalSelection) {
|
||||
return QPoint(this->externalSelectionWidth, this->externalSelectionHeight);
|
||||
} else {
|
||||
return SelectablePixmapItem::getSelectionDimensions();
|
||||
}
|
||||
return selection.dimensions;
|
||||
}
|
||||
|
||||
void MetatileSelector::draw() {
|
||||
|
@ -57,7 +53,8 @@ bool MetatileSelector::select(uint16_t metatileId) {
|
|||
bool MetatileSelector::selectFromMap(uint16_t metatileId, uint16_t collision, uint16_t elevation) {
|
||||
if (!Tileset::metatileIsValid(metatileId, this->primaryTileset, this->secondaryTileset)) return false;
|
||||
this->select(metatileId);
|
||||
this->selectedCollisions->append(QPair<uint16_t, uint16_t>(collision, elevation));
|
||||
this->selection.collisionItems.append(CollisionSelectionItem{true, collision, elevation});
|
||||
this->selection.hasCollision = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -71,28 +68,27 @@ void MetatileSelector::setTilesets(Tileset *primaryTileset, Tileset *secondaryTi
|
|||
this->draw();
|
||||
}
|
||||
|
||||
QList<uint16_t>* MetatileSelector::getSelectedMetatiles() {
|
||||
return this->selectedMetatiles;
|
||||
}
|
||||
|
||||
QList<QPair<uint16_t, uint16_t>>* MetatileSelector::getSelectedCollisions() {
|
||||
return this->selectedCollisions;
|
||||
MetatileSelection MetatileSelector::getMetatileSelection() {
|
||||
return selection;
|
||||
}
|
||||
|
||||
void MetatileSelector::setExternalSelection(int width, int height, QList<uint16_t> metatiles, QList<QPair<uint16_t, uint16_t>> collisions) {
|
||||
this->externalSelection = true;
|
||||
this->externalSelectionWidth = width;
|
||||
this->externalSelectionHeight = height;
|
||||
this->externalSelectedMetatiles->clear();
|
||||
this->selectedMetatiles->clear();
|
||||
this->selectedCollisions->clear();
|
||||
this->externalSelectedMetatiles.clear();
|
||||
this->selection.metatileItems.clear();
|
||||
this->selection.collisionItems.clear();
|
||||
this->selection.hasCollision = true;
|
||||
this->selection.dimensions = QPoint(width, height);
|
||||
for (int i = 0; i < metatiles.length(); i++) {
|
||||
this->selectedCollisions->append(collisions.at(i));
|
||||
auto collision = collisions.at(i);
|
||||
this->selection.collisionItems.append(CollisionSelectionItem{true, collision.first, collision.second});
|
||||
uint16_t metatileId = metatiles.at(i);
|
||||
this->externalSelectedMetatiles->append(metatileId);
|
||||
this->externalSelectedMetatiles.append(metatileId);
|
||||
if (!Tileset::metatileIsValid(metatileId, this->primaryTileset, this->secondaryTileset))
|
||||
metatileId = 0;
|
||||
this->selectedMetatiles->append(metatileId);
|
||||
this->selection.metatileItems.append(MetatileSelectionItem{true, metatileId});
|
||||
}
|
||||
|
||||
this->draw();
|
||||
|
@ -138,28 +134,30 @@ void MetatileSelector::hoverLeaveEvent(QGraphicsSceneHoverEvent*) {
|
|||
|
||||
void MetatileSelector::updateSelectedMetatiles() {
|
||||
this->externalSelection = false;
|
||||
this->selectedMetatiles->clear();
|
||||
this->selectedCollisions->clear();
|
||||
this->selection.metatileItems.clear();
|
||||
this->selection.collisionItems.clear();
|
||||
this->selection.hasCollision = false;
|
||||
this->selection.dimensions = SelectablePixmapItem::getSelectionDimensions();
|
||||
QPoint origin = this->getSelectionStart();
|
||||
QPoint dimensions = this->getSelectionDimensions();
|
||||
for (int j = 0; j < dimensions.y(); j++) {
|
||||
for (int i = 0; i < dimensions.x(); i++) {
|
||||
for (int j = 0; j < this->selection.dimensions.y(); j++) {
|
||||
for (int i = 0; i < this->selection.dimensions.x(); i++) {
|
||||
uint16_t metatileId = this->getMetatileId(origin.x() + i, origin.y() + j);
|
||||
if (!Tileset::metatileIsValid(metatileId, this->primaryTileset, this->secondaryTileset))
|
||||
metatileId = 0;
|
||||
this->selectedMetatiles->append(metatileId);
|
||||
this->selection.metatileItems.append(MetatileSelectionItem{true, metatileId});
|
||||
}
|
||||
}
|
||||
emit selectedMetatilesChanged();
|
||||
}
|
||||
|
||||
void MetatileSelector::updateExternalSelectedMetatiles() {
|
||||
this->selectedMetatiles->clear();
|
||||
for (int i = 0; i < this->externalSelectedMetatiles->count(); ++i) {
|
||||
uint16_t metatileId = this->externalSelectedMetatiles->at(i);
|
||||
this->selection.metatileItems.clear();
|
||||
this->selection.dimensions = QPoint(this->externalSelectionWidth, this->externalSelectionHeight);
|
||||
for (int i = 0; i < this->externalSelectedMetatiles.count(); ++i) {
|
||||
uint16_t metatileId = this->externalSelectedMetatiles.at(i);
|
||||
if (!Tileset::metatileIsValid(metatileId, this->primaryTileset, this->secondaryTileset))
|
||||
metatileId = 0;
|
||||
this->selectedMetatiles->append(metatileId);
|
||||
this->selection.metatileItems.append(MetatileSelectionItem{true, metatileId});
|
||||
}
|
||||
emit selectedMetatilesChanged();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue