Properly paint prefabs and create them from dialog box

This commit is contained in:
Marcus Huderle
2022-09-07 20:38:30 -05:00
parent bc4cbbabfa
commit 96ad32c6db
11 changed files with 358 additions and 21 deletions

View File

@@ -6,6 +6,7 @@
#include "editor.h"
#include "eventpropertiesframe.h"
#include "ui_eventpropertiesframe.h"
#include "prefabcreationdialog.h"
#include "bordermetatilespixmapitem.h"
#include "currentselectedmetatilespixmapitem.h"
#include "customattributestable.h"
@@ -557,8 +558,6 @@ bool MainWindow::openProject(QString dir) {
editor->metatile_selector_item,
ui->scrollAreaWidgetContents_Prefabs,
ui->label_prefabHelp,
editor->ui->comboBox_PrimaryTileset->currentText(),
editor->ui->comboBox_SecondaryTileset->currentText(),
editor->map);
for (auto action : this->registeredActions) {
this->ui->menuTools->removeAction(action);
@@ -3176,6 +3175,15 @@ void MainWindow::on_actionRegion_Map_Editor_triggered() {
}
}
void MainWindow::on_pushButton_CreatePrefab_clicked() {
PrefabCreationDialog dialog(this, this->editor->metatile_selector_item, this->editor->map);
dialog.setWindowTitle("Create Prefab");
dialog.setWindowModality(Qt::NonModal);
if (dialog.exec() == QDialog::Accepted) {
dialog.savePrefab();
}
}
bool MainWindow::initRegionMapEditor() {
this->regionMapEditor = new RegionMapEditor(this, this->editor->project);
this->regionMapEditor->setAttribute(Qt::WA_DeleteOnClose);

View File

@@ -177,11 +177,22 @@ bool isSmartPathTile(QList<MetatileSelectionItem> metatileItems, uint16_t metati
return false;
}
bool isValidSmartPathSelection(MetatileSelection selection) {
if (selection.dimensions.x() != 3 || selection.dimensions.y() != 3)
return false;
for (int i = 0; i < selection.metatileItems.length(); i++) {
if (!selection.metatileItems.at(i).enabled)
return false;
}
return true;
}
void MapPixmapItem::paintSmartPath(int x, int y, bool fromScriptCall) {
MetatileSelection selection = this->metatileSelector->getMetatileSelection();
// Smart path should never be enabled without a 3x3 block selection.
if (selection.dimensions.x() != 3 || selection.dimensions.y() != 3) return;
if (!isValidSmartPathSelection(selection))
return;
// Shift to the middle tile of the smart path selection.
uint16_t openTile = selection.metatileItems.at(4).metatileId;
@@ -420,13 +431,15 @@ 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).metatileId;
if (setCollisions) {
CollisionSelectionItem item = selectedCollisions.at(index);
block.collision = item.collision;
block.elevation = item.elevation;
if (selectedMetatiles.at(index).enabled) {
block.metatileId = selectedMetatiles.at(index).metatileId;
if (setCollisions) {
CollisionSelectionItem item = selectedCollisions.at(index);
block.collision = item.collision;
block.elevation = item.elevation;
}
map->setBlock(x, y, block, !fromScriptCall);
}
map->setBlock(x, y, block, !fromScriptCall);
}
}
}
@@ -480,7 +493,7 @@ void MapPixmapItem::floodFill(
int index = j * selectionDimensions.x() + i;
uint16_t metatileId = selectedMetatiles.at(index).metatileId;
uint16_t old_metatileId = block.metatileId;
if (selectedMetatiles.count() != 1 || old_metatileId != metatileId) {
if (selectedMetatiles.at(index).enabled && (selectedMetatiles.count() != 1 || old_metatileId != metatileId)) {
block.metatileId = metatileId;
if (setCollisions) {
CollisionSelectionItem item = selectedCollisions.at(index);
@@ -514,9 +527,8 @@ void MapPixmapItem::floodFill(
void MapPixmapItem::floodFillSmartPath(int initialX, int initialY, bool fromScriptCall) {
MetatileSelection selection = this->metatileSelector->getMetatileSelection();
// Smart path should never be enabled without a 3x3 block selection.
if (selection.dimensions.x() != 3 || selection.dimensions.y() != 3) return;
if (!isValidSmartPathSelection(selection))
return;
// Shift to the middle tile of the smart path selection.
uint16_t openTile = selection.metatileItems.at(4).metatileId;

View File

@@ -4,6 +4,7 @@
#include "ui_prefabframe.h"
#include "parseutil.h"
#include "currentselectedmetatilespixmapitem.h"
#include "log.h"
#include <QJsonDocument>
#include <QJsonObject>
@@ -86,9 +87,29 @@ QList<PrefabItem> Prefab::getPrefabsForTilesets(QString primaryTileset, QString
return filteredPrefabs;
}
void Prefab::initPrefabUI(MetatileSelector *selector, QWidget *prefabWidget, QLabel *emptyPrefabLabel, QString primaryTileset, QString secondaryTileset, Map *map) {
void Prefab::initPrefabUI(MetatileSelector *selector, QWidget *prefabWidget, QLabel *emptyPrefabLabel, Map *map) {
logInfo("initPrefabUI");
this->selector = selector;
this->prefabWidget = prefabWidget;
this->emptyPrefabLabel = emptyPrefabLabel;
this->loadPrefabs();
QList<PrefabItem> prefabs = this->getPrefabsForTilesets(primaryTileset, secondaryTileset);
logInfo("initPrefabUI loaded prefabs");
this->updatePrefabUi(map);
logInfo("initPrefabUI after updatePrefabUi");
}
void Prefab::updatePrefabUi(Map *map) {
// Cleanup the PrefabFrame to have a clean slate.
auto layout = this->prefabWidget->layout();
while (layout && layout->count() > 1) {
auto child = layout->takeAt(1);
if (child->widget()) {
delete child->widget();
}
delete child;
}
QList<PrefabItem> prefabs = this->getPrefabsForTilesets(map->layout->tileset_primary_label, map->layout->tileset_secondary_label);
if (prefabs.isEmpty()) {
emptyPrefabLabel->setVisible(true);
return;
@@ -115,5 +136,10 @@ void Prefab::initPrefabUI(MetatileSelector *selector, QWidget *prefabWidget, QLa
prefabWidget->layout()->addItem(spacer);
}
void Prefab::addPrefab(MetatileSelection selection, Map *map, QString name) {
this->items.append(PrefabItem{name, map->layout->tileset_primary_label, map->layout->tileset_secondary_label, selection});
this->updatePrefabUi(map);
}
Prefab prefab;

View File

@@ -0,0 +1,49 @@
#include "prefabcreationdialog.h"
#include "ui_prefabcreationdialog.h"
#include "currentselectedmetatilespixmapitem.h"
#include "graphicsview.h"
#include "prefab.h"
#include <QObject>
PrefabCreationDialog::PrefabCreationDialog(QWidget *parent, MetatileSelector *metatileSelector, Map *map) :
QDialog(parent),
ui(new Ui::PrefabCreationDialog)
{
ui->setupUi(this);
this->map = map;
this->selection = metatileSelector->getMetatileSelection();
QGraphicsScene *scene = new QGraphicsScene;
QGraphicsPixmapItem *pixmapItem = scene->addPixmap(drawMetatileSelection(this->selection, map));
scene->setSceneRect(scene->itemsBoundingRect());
this->ui->graphicsView_Prefab->setScene(scene);
this->ui->graphicsView_Prefab->setFixedSize(scene->itemsBoundingRect().width() + 2,
scene->itemsBoundingRect().height() + 2);
QObject::connect(this->ui->graphicsView_Prefab, &ClickableGraphicsView::clicked, [=](QMouseEvent *event){
auto pos = event->pos();
int selectionWidth = this->selection.dimensions.x() * 16;
int selectionHeight = this->selection.dimensions.y() * 16;
if (pos.x() < 0 || pos.x() >= selectionWidth || pos.y() < 0 || pos.y() >= selectionHeight)
return;
int metatileX = pos.x() / 16;
int metatileY = pos.y() / 16;
int index = metatileY * this->selection.dimensions.x() + metatileX;
bool toggledState = !this->selection.metatileItems[index].enabled;
this->selection.metatileItems[index].enabled = toggledState;
if (this->selection.hasCollision) {
this->selection.collisionItems[index].enabled = toggledState;
}
pixmapItem->setPixmap(drawMetatileSelection(this->selection, map));
});
}
PrefabCreationDialog::~PrefabCreationDialog()
{
delete ui;
}
void PrefabCreationDialog::savePrefab() {
prefab.addPrefab(this->selection, this->map, this->ui->lineEdit_PrefabName->text());
}