Allow number values for behavior in editor, add mask warning

This commit is contained in:
GriffinR 2022-10-27 07:52:07 -04:00
parent 577dc2fce2
commit d2fa68ba18
5 changed files with 31 additions and 10 deletions

View file

@ -8,6 +8,8 @@
#include <QPoint>
#include <QString>
class Project;
enum {
METATILE_LAYER_MIDDLE_TOP,
METATILE_LAYER_BOTTOM_MIDDLE,
@ -91,7 +93,7 @@ public:
static int getIndexInTileset(int);
static QPoint coordFromPixmapCoord(const QPointF &pixelCoord);
static int getDefaultAttributesSize(BaseGameVersion version);
static void setCustomLayout();
static void setCustomLayout(Project*);
private:
// Stores how each attribute should be laid out for all metatiles, according to the user's config

View file

@ -85,7 +85,7 @@ private slots:
void on_actionRedo_triggered();
void on_comboBox_metatileBehaviors_textActivated(const QString &arg1);
void on_comboBox_metatileBehaviors_currentTextChanged(const QString &arg1);
void on_lineEdit_metatileLabel_editingFinished();

View file

@ -95,7 +95,7 @@ bool Metatile::isMaskTooSmall(MetatileAttr * attr, int max) {
uint32_t n = log2(max);
// Get a mask for all values 0 to max.
// This may fail for n=31, but that's not a concern here.
// This may fail for n > 30, but that's not possible here.
uint32_t rangeMask = (1 << (n + 1)) - 1;
return attr->getClamped(rangeMask) != rangeMask;
@ -110,7 +110,7 @@ bool Metatile::doMasksOverlap(QList<uint32_t> masks) {
return false;
}
void Metatile::setCustomLayout() {
void Metatile::setCustomLayout(Project * project) {
// Get the maximum size of any attribute mask
const QHash<int, uint32_t> maxMasks = {
{1, 0xFF},
@ -135,9 +135,13 @@ void Metatile::setCustomLayout() {
logWarn("Metatile attribute masks are overlapping. This may result in unexpected attribute values.");
}
// The available options in the Tileset Editor for Terrain Type, Encounter Type, and Layer Type are hard-coded.
// Warn the user if they have set a nonzero mask that is too small to contain these options.
// They'll be allowed to select them, but they'll be truncated to a different value when revisited.
// Warn the user if they have set a nonzero mask that is too small to contain its available options.
// They'll be allowed to select the options, but they'll be truncated to a different value when revisited.
if (!project->metatileBehaviorMapInverse.isEmpty()) {
int maxBehavior = project->metatileBehaviorMapInverse.lastKey();
if (isMaskTooSmall(&Metatile::behaviorAttr, maxBehavior))
logWarn(QString("Metatile Behavior mask is too small to contain all %1 available options.").arg(maxBehavior));
}
if (isMaskTooSmall(&Metatile::terrainTypeAttr, NUM_METATILE_TERRAIN_TYPES - 1))
logWarn(QString("Metatile Terrain Type mask is too small to contain all %1 available options.").arg(NUM_METATILE_TERRAIN_TYPES));
if (isMaskTooSmall(&Metatile::encounterTypeAttr, NUM_METATILE_ENCOUNTER_TYPES - 1))

View file

@ -505,7 +505,6 @@ bool MainWindow::openProject(QString dir) {
userConfig.load();
projectConfig.setProjectDir(dir);
projectConfig.load();
Metatile::setCustomLayout();
this->closeSupplementaryWindows();
this->setProjectSpecificUIVisibility();
@ -914,6 +913,7 @@ bool MainWindow::loadDataStructures() {
&& project->readEventGraphics()
&& project->readSongNames();
Metatile::setCustomLayout(project);
Scripting::populateGlobalObject(this);
return success && loadProjectCombos();

View file

@ -503,11 +503,26 @@ void TilesetEditor::on_checkBox_yFlip_stateChanged(int checked)
this->metatileLayersItem->clearLastModifiedCoords();
}
void TilesetEditor::on_comboBox_metatileBehaviors_textActivated(const QString &metatileBehavior)
void TilesetEditor::on_comboBox_metatileBehaviors_currentTextChanged(const QString &metatileBehavior)
{
if (this->metatile) {
int behavior;
if (project->metatileBehaviorMap.contains(metatileBehavior)) {
behavior = project->metatileBehaviorMap[metatileBehavior];
} else {
// Check if user has entered a number value instead
bool ok;
behavior = metatileBehavior.toInt(&ok);
if (!ok) return;
}
// This function can also be called when the user selects
// a different metatile. Stop this from being considered a change.
if (this->metatile->behavior == static_cast<uint32_t>(behavior))
return;
Metatile *prevMetatile = new Metatile(*this->metatile);
this->metatile->setBehavior(project->metatileBehaviorMap[metatileBehavior]);
this->metatile->setBehavior(behavior);
MetatileHistoryItem *commit = new MetatileHistoryItem(this->getSelectedMetatileId(),
prevMetatile, new Metatile(*this->metatile));
metatileHistory.push(commit);