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

View file

@ -95,7 +95,7 @@ bool Metatile::isMaskTooSmall(MetatileAttr * attr, int max) {
uint32_t n = log2(max); uint32_t n = log2(max);
// Get a mask for all values 0 to 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; uint32_t rangeMask = (1 << (n + 1)) - 1;
return attr->getClamped(rangeMask) != rangeMask; return attr->getClamped(rangeMask) != rangeMask;
@ -110,7 +110,7 @@ bool Metatile::doMasksOverlap(QList<uint32_t> masks) {
return false; return false;
} }
void Metatile::setCustomLayout() { void Metatile::setCustomLayout(Project * project) {
// Get the maximum size of any attribute mask // Get the maximum size of any attribute mask
const QHash<int, uint32_t> maxMasks = { const QHash<int, uint32_t> maxMasks = {
{1, 0xFF}, {1, 0xFF},
@ -135,9 +135,13 @@ void Metatile::setCustomLayout() {
logWarn("Metatile attribute masks are overlapping. This may result in unexpected attribute values."); 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 its available options.
// Warn the user if they have set a nonzero mask that is too small to contain these options. // They'll be allowed to select the options, but they'll be truncated to a different value when revisited.
// They'll be allowed to select them, 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)) 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)); 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)) if (isMaskTooSmall(&Metatile::encounterTypeAttr, NUM_METATILE_ENCOUNTER_TYPES - 1))

View file

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

View file

@ -503,11 +503,26 @@ void TilesetEditor::on_checkBox_yFlip_stateChanged(int checked)
this->metatileLayersItem->clearLastModifiedCoords(); this->metatileLayersItem->clearLastModifiedCoords();
} }
void TilesetEditor::on_comboBox_metatileBehaviors_textActivated(const QString &metatileBehavior) void TilesetEditor::on_comboBox_metatileBehaviors_currentTextChanged(const QString &metatileBehavior)
{ {
if (this->metatile) { 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); Metatile *prevMetatile = new Metatile(*this->metatile);
this->metatile->setBehavior(project->metatileBehaviorMap[metatileBehavior]); this->metatile->setBehavior(behavior);
MetatileHistoryItem *commit = new MetatileHistoryItem(this->getSelectedMetatileId(), MetatileHistoryItem *commit = new MetatileHistoryItem(this->getSelectedMetatileId(),
prevMetatile, new Metatile(*this->metatile)); prevMetatile, new Metatile(*this->metatile));
metatileHistory.push(commit); metatileHistory.push(commit);