Merge branch 'dev' of https://github.com/huderlem/porymap into local-id

This commit is contained in:
GriffinR
2025-04-22 15:14:08 -04:00
63 changed files with 1266 additions and 942 deletions

View File

@@ -14,19 +14,20 @@
#include <QGraphicsPixmapItem>
#include "events.h"
#include "gridsettings.h"
static const QVersionNumber porymapVersion = QVersionNumber::fromString(PORYMAP_VERSION);
extern const QVersionNumber porymapVersion;
// In both versions the default new map border is a generic tree
#define DEFAULT_BORDER_RSE (QList<uint16_t>{0x1D4, 0x1D5, 0x1DC, 0x1DD})
#define DEFAULT_BORDER_FRLG (QList<uint16_t>{0x14, 0x15, 0x1C, 0x1D})
// Distance in pixels from the edge of a GBA screen (240x160) to the center 16x16 pixels.
#define GBA_H_DIST_TO_CENTER ((240-16)/2)
#define GBA_V_DIST_TO_CENTER ((160-16)/2)
#define CONFIG_BACKWARDS_COMPATABILITY
class KeyValueConfigBase
{
public:
void save();
bool save();
void load();
virtual ~KeyValueConfigBase();
virtual void reset() = 0;
@@ -36,9 +37,11 @@ protected:
virtual QMap<QString, QString> getKeyValueMap() = 0;
virtual void init() = 0;
virtual void setUnreadKeys() = 0;
bool getConfigBool(QString key, QString value);
int getConfigInteger(QString key, QString value, int min = INT_MIN, int max = INT_MAX, int defaultValue = 0);
uint32_t getConfigUint32(QString key, QString value, uint32_t min = 0, uint32_t max = UINT_MAX, uint32_t defaultValue = 0);
static bool getConfigBool(const QString &key, const QString &value);
static int getConfigInteger(const QString &key, const QString &value, int min = INT_MIN, int max = INT_MAX, int defaultValue = 0);
static uint32_t getConfigUint32(const QString &key, const QString &value, uint32_t min = 0, uint32_t max = UINT_MAX, uint32_t defaultValue = 0);
static QColor getConfigColor(const QString &key, const QString &value, const QColor &defaultValue = Qt::black);
};
class PorymapConfig: public KeyValueConfigBase
@@ -92,6 +95,7 @@ public:
this->rateLimitTimes.clear();
this->eventSelectionShapeMode = QGraphicsPixmapItem::MaskShape;
this->shownInGameReloadMessage = false;
this->gridSettings = GridSettings();
}
void addRecentProject(QString project);
void setRecentProjects(QStringList projects);
@@ -156,6 +160,7 @@ public:
QByteArray newMapDialogGeometry;
QByteArray newLayoutDialogGeometry;
bool shownInGameReloadMessage;
GridSettings gridSettings;
protected:
virtual QString getConfigFilepath() override;
@@ -214,6 +219,8 @@ enum ProjectIdentifier {
define_pals_total,
define_tiles_per_metatile,
define_map_size,
define_map_offset_width,
define_map_offset_height,
define_mask_metatile,
define_mask_collision,
define_mask_elevation,
@@ -317,6 +324,7 @@ public:
this->defaultMetatileId = 1;
this->defaultElevation = 3;
this->defaultCollision = 0;
this->defaultMapSize = QSize(20,20);
this->defaultPrimaryTileset = "gTileset_General";
this->prefabFilepath = QString();
this->prefabImportPrompted = false;
@@ -328,8 +336,8 @@ public:
this->eventIconPaths.clear();
this->pokemonIconPaths.clear();
this->collisionSheetPath = QString();
this->collisionSheetWidth = 2;
this->collisionSheetHeight = 16;
this->collisionSheetSize = QSize(2, 16);
this->playerViewDistance = QMargins(GBA_H_DIST_TO_CENTER, GBA_V_DIST_TO_CENTER, GBA_H_DIST_TO_CENTER, GBA_V_DIST_TO_CENTER);
this->blockMetatileIdMask = 0x03FF;
this->blockCollisionMask = 0x0C00;
this->blockElevationMask = 0xF000;
@@ -382,6 +390,7 @@ public:
uint16_t defaultMetatileId;
uint16_t defaultElevation;
uint16_t defaultCollision;
QSize defaultMapSize;
QList<uint16_t> newMapBorderMetatileIds;
QString defaultPrimaryTileset;
QString defaultSecondaryTileset;
@@ -404,8 +413,8 @@ public:
uint16_t unusedTileSplit;
bool mapAllowFlagsEnabled;
QString collisionSheetPath;
int collisionSheetWidth;
int collisionSheetHeight;
QSize collisionSheetSize;
QMargins playerViewDistance;
QList<uint32_t> warpBehaviors;
int maxEventsPerGroup;

View File

@@ -22,10 +22,6 @@
#define MAX_BORDER_WIDTH 255
#define MAX_BORDER_HEIGHT 255
// Number of metatiles to draw out from edge of map. Could allow modification of this in the future.
// porymap will reflect changes to it, but the value is hard-coded in the projects at the moment
#define BORDER_DISTANCE 7
class LayoutPixmapItem;
class CollisionPixmapItem;
class BorderMetatilesPixmapItem;
@@ -89,6 +85,7 @@ public:
void deleteConnections();
QList<MapConnection*> getConnections() const { return m_connections; }
MapConnection* getConnection(const QString &direction) const;
void removeConnection(MapConnection *);
void addConnection(MapConnection *);
void loadConnection(MapConnection *);

View File

@@ -96,8 +96,8 @@ public:
int getHeight() const { return height; }
int getBorderWidth() const { return border_width; }
int getBorderHeight() const { return border_height; }
int getBorderDrawWidth() const;
int getBorderDrawHeight() const;
QMargins getBorderMargins() const;
QRect getVisibleRect() const;
bool isWithinBounds(int x, int y) const;
bool isWithinBounds(const QRect &rect) const;
@@ -116,9 +116,12 @@ public:
void clearBorderCache();
void cacheBorder();
void setClean();
bool hasUnsavedChanges() const;
bool save(const QString &root);
bool saveBorder(const QString &root);
bool saveBlockdata(const QString &root);
bool layoutBlockChanged(int i, const Blockdata &cache);
uint16_t getBorderMetatileId(int x, int y);
@@ -143,6 +146,7 @@ public:
private:
void setNewDimensionsBlockdata(int newWidth, int newHeight);
void setNewBorderDimensionsBlockdata(int newWidth, int newHeight);
bool writeBlockdata(const QString &path, const Blockdata &blockdata) const;
static int getBorderDrawDistance(int dimension, qreal minimum);

View File

@@ -7,7 +7,7 @@
namespace PaletteUtil {
QList<QRgb> parse(QString filepath, bool *error);
void writeJASC(QString filepath, QVector<QRgb> colors, int offset, int nColors);
bool writeJASC(const QString &filepath, const QVector<QRgb> &colors, int offset, int nColors);
}
#endif // PALETTEUTIL_H

View File

@@ -55,17 +55,17 @@ public:
static QString getExpectedDir(QString tilesetName, bool isSecondary);
QString getExpectedDir();
void load();
void loadMetatiles();
void loadMetatileAttributes();
void loadTilesImage(QImage *importedImage = nullptr);
void loadPalettes();
bool load();
bool loadMetatiles();
bool loadMetatileAttributes();
bool loadTilesImage(QImage *importedImage = nullptr);
bool loadPalettes();
void save();
void saveMetatileAttributes();
void saveMetatiles();
void saveTilesImage();
void savePalettes();
bool save();
bool saveMetatileAttributes();
bool saveMetatiles();
bool saveTilesImage();
bool savePalettes();
bool appendToHeaders(QString root, QString friendlyName, bool usingAsm);
bool appendToGraphics(QString root, QString friendlyName, bool usingAsm);

View File

@@ -9,6 +9,7 @@ namespace Util {
int roundUp(int numToRound, int multiple);
QString toDefineCase(QString input);
QString toHexString(uint32_t value, int minLength = 0);
QString toHtmlParagraph(const QString &text);
Qt::Orientations getOrientation(bool xflip, bool yflip);
}

View File

@@ -57,8 +57,8 @@ public:
GridSettings gridSettings;
void setProject(Project * project);
void saveAll();
void saveCurrent();
bool saveAll();
bool saveCurrent();
void saveEncounterTabData();
void closeProject();
@@ -92,14 +92,16 @@ public:
void setConnectionsVisibility(bool visible);
void updateDivingMapsVisibility();
void renderDivingConnections();
void addConnection(MapConnection* connection);
void addNewConnection(const QString &mapName, const QString &direction);
void replaceConnection(const QString &mapName, const QString &direction);
void removeConnection(MapConnection* connection);
void removeSelectedConnection();
void addNewWildMonGroup(QWidget *window);
void deleteWildMonGroup();
void configureEncounterJSON(QWidget *);
EncounterTableModel* getCurrentWildMonTable();
void updateDiveMap(QString mapName);
void updateEmergeMap(QString mapName);
bool setDivingMapName(const QString &mapName, const QString &direction);
QString getDivingMapName(const QString &direction) const;
void setSelectedConnection(MapConnection *connection);
void updatePrimaryTileset(QString tilesetLabel, bool forceLoad = false);
@@ -120,6 +122,7 @@ public:
void updateEventPixmapItemZValue(EventPixmapItem *item);
qreal getEventOpacity(const Event *event) const;
void setPlayerViewRect(const QRectF &rect);
void updateCursorRectPos(int x, int y);
void setCursorRectVisible(bool visible);
@@ -215,7 +218,7 @@ private:
EditMode editMode = EditMode::None;
void save(bool currentOnly);
bool save(bool currentOnly);
void clearMap();
void clearMetatileSelector();
void clearMovementPermissionSelector();
@@ -234,8 +237,9 @@ private:
void removeConnectionPixmap(MapConnection *connection);
void displayConnection(MapConnection *connection);
void displayDivingConnection(MapConnection *connection);
void setDivingMapName(QString mapName, QString direction);
void removeDivingMapPixmap(MapConnection *connection);
void onDivingMapEditingFinished(NoScrollComboBox* combo, const QString &direction);
void updateDivingMapButton(QToolButton* button, const QString &mapName);
void updateEncounterFields(EncounterFields newFields);
QString getMovementPermissionText(uint16_t collision, uint16_t elevation);
QString getMetatileDisplayMessage(uint16_t metatileId);

View File

@@ -175,7 +175,7 @@ private slots:
void on_action_Reload_Project_triggered();
void on_action_Close_Project_triggered();
void on_action_Save_Project_triggered();
void save(bool currentOnly = false);
bool save(bool currentOnly = false);
void openEventMap(Event *event);
@@ -242,8 +242,6 @@ private slots:
void on_pushButton_AddConnection_clicked();
void on_button_OpenDiveMap_clicked();
void on_button_OpenEmergeMap_clicked();
void on_comboBox_DiveMap_currentTextChanged(const QString &mapName);
void on_comboBox_EmergeMap_currentTextChanged(const QString &mapName);
void on_comboBox_PrimaryTileset_currentTextChanged(const QString &arg1);
void on_comboBox_SecondaryTileset_currentTextChanged(const QString &arg1);
void on_pushButton_ChangeDimensions_clicked();

View File

@@ -108,10 +108,6 @@ public:
bool loadBlockdata(Layout *);
bool loadLayoutBorder(Layout *);
void saveTextFile(QString path, QString text);
void appendTextFile(QString path, QString text);
void deleteFile(QString path);
bool readMapGroups();
void addNewMapGroup(const QString &groupName);
QString mapNameToMapGroup(const QString &mapName) const;
@@ -168,25 +164,20 @@ public:
bool loadLayout(Layout *);
bool loadMapLayout(Map*);
bool loadLayoutTilesets(Layout *);
void loadTilesetAssets(Tileset*);
bool loadTilesetAssets(Tileset*);
void loadTilesetMetatileLabels(Tileset*);
void readTilesetPaths(Tileset* tileset);
void saveAll();
void saveGlobalData();
void saveLayout(Layout *);
void saveLayoutBlockdata(Layout *);
void saveLayoutBorder(Layout *);
void writeBlockdata(QString, const Blockdata &);
void saveMap(Map *map, bool skipLayout = false);
void saveConfig();
void saveMapLayouts();
void saveMapGroups();
void saveRegionMapSections();
void saveWildMonData();
void saveHealLocations();
void saveTilesets(Tileset*, Tileset*);
void saveTilesetMetatileLabels(Tileset*, Tileset*);
bool saveAll();
bool saveGlobalData();
bool saveConfig();
bool saveLayout(Layout *layout);
bool saveMap(Map *map, bool skipLayout = false);
bool saveTextFile(const QString &path, const QString &text);
bool saveRegionMapSections();
bool saveTilesets(Tileset*, Tileset*);
bool saveTilesetMetatileLabels(Tileset*, Tileset*);
void appendTilesetLabel(const QString &label, const QString &isSecondaryStr);
bool readTilesetLabels();
bool readTilesetMetatileLabels();
@@ -235,30 +226,34 @@ public:
static QString getExistingFilepath(QString filepath);
void applyParsedLimits();
void setRegionMapEntries(const QHash<QString, MapSectionEntry> &entries);
QHash<QString, MapSectionEntry> getRegionMapEntries() const;
QSet<QString> getTopLevelMapFields() const;
int getMapDataSize(int width, int height) const;
int getMaxMapDataSize() const { return this->maxMapDataSize; }
int getMaxMapWidth() const;
int getMaxMapHeight() const;
bool mapDimensionsValid(int width, int height) const;
bool calculateDefaultMapSize();
QSize getDefaultMapSize() const { return this->defaultMapSize; }
QSize getMapSizeAddition() const { return this->mapSizeAddition; }
int getMaxEvents(Event::Group group) const;
static QString getEmptyMapDefineName();
static QString getDynamicMapDefineName();
static QString getDynamicMapName();
static QString getEmptySpeciesName();
static int getNumTilesPrimary();
static int getNumTilesTotal();
static int getNumMetatilesPrimary();
static int getNumMetatilesTotal();
static int getNumPalettesPrimary();
static int getNumPalettesTotal();
static int getMaxMapDataSize();
static int getDefaultMapDimension();
static int getMaxMapWidth();
static int getMaxMapHeight();
static int getMapDataSize(int width, int height);
static bool mapDimensionsValid(int width, int height);
bool calculateDefaultMapSize();
int getMaxEvents(Event::Group group);
static QMargins getMetatileViewDistance();
static int getNumTilesPrimary() { return num_tiles_primary; }
static int getNumTilesTotal() { return num_tiles_total; }
static int getNumMetatilesPrimary() { return num_metatiles_primary; }
static int getNumMetatilesTotal() { return Block::getMaxMetatileId() + 1; }
static int getNumPalettesPrimary(){ return num_pals_primary; }
static int getNumPalettesTotal() { return num_pals_total; }
static QString getEmptyMapsecName();
static QString getMapGroupPrefix();
@@ -309,8 +304,6 @@ private:
};
QHash<QString, LocationData> locationData;
void updateLayout(Layout *);
void setNewLayoutBlockdata(Layout *layout);
void setNewLayoutBorder(Layout *layout);
@@ -318,17 +311,27 @@ private:
void recordFileChange(const QString &filepath);
void resetFileCache();
bool saveMapLayouts();
bool saveMapGroups();
bool saveWildMonData();
bool saveHealLocations();
bool appendTextFile(const QString &path, const QString &text);
QString findSpeciesIconPath(const QStringList &names) const;
int maxEventsPerGroup;
int maxObjectEvents;
int maxMapDataSize;
QSize defaultMapSize;
QSize mapSizeAddition;
// TODO: These really shouldn't be static, they're specific to a single project.
// We're making an assumption here that we only have one project open at a single time
// (which is true, but then if that's the case we should have some global Project instance instead)
static int num_tiles_primary;
static int num_tiles_total;
static int num_metatiles_primary;
static int num_pals_primary;
static int num_pals_total;
static int max_map_data_size;
static int default_map_dimension;
signals:
void fileChanged(const QString &filepath);

View File

@@ -43,8 +43,6 @@ protected:
virtual void mousePressEvent(QGraphicsSceneMouseEvent*) override;
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent*) override;
virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent*) override;
virtual void keyPressEvent(QKeyEvent*) override;
virtual void focusInEvent(QFocusEvent*) override;
signals:
void connectionItemDoubleClicked(MapConnection*);

View File

@@ -36,19 +36,17 @@ private:
protected:
virtual void mousePressEvent(QMouseEvent*) override;
virtual void focusInEvent(QFocusEvent*) override;
virtual void keyPressEvent(QKeyEvent*) override;
virtual bool eventFilter(QObject*, QEvent *event) override;
signals:
void selected();
void openMapClicked(MapConnection*);
private slots:
void on_comboBox_Direction_currentTextChanged(QString direction);
void on_comboBox_Map_currentTextChanged(QString mapName);
void on_spinBox_Offset_valueChanged(int offset);
void on_button_Delete_clicked();
void on_button_OpenMap_clicked();
private:
void commitDirection();
void commitMap(const QString &mapName);
void commitMove(int offset);
void commitRemove();
};
#endif // CONNECTIONSLISTITEM_H

View File

@@ -32,4 +32,17 @@ signals:
void clicked(QMouseEvent *event);
};
class ConnectionsView : public QGraphicsView
{
Q_OBJECT
public:
ConnectionsView(QWidget *parent = nullptr) : QGraphicsView(parent) {}
signals:
void pressedDelete();
protected:
virtual void keyPressEvent(QKeyEvent *event) override;
};
#endif // GRAPHICSVIEW_H

View File

@@ -64,6 +64,8 @@ private:
QPointer<Project> m_project = nullptr;
bool m_allowProjectChanges = true;
void setText(QComboBox *combo, const QString &text) const;
void setText(QLineEdit *lineEdit, const QString &text) const;
void setLocations(const QStringList &locations);
void updateLocationName();

View File

@@ -10,27 +10,28 @@
class MovableRect : public QGraphicsRectItem
{
public:
MovableRect(bool *enabled, int width, int height, QRgb color);
MovableRect(bool *enabled, const QRectF &rect, const QRgb &color);
QRectF boundingRect() const override {
qreal penWidth = 4;
return QRectF(-penWidth,
-penWidth,
30 * 8 + penWidth * 2,
20 * 8 + penWidth * 2);
this->rect().width() + penWidth * 2,
this->rect().height() + penWidth * 2);
}
void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) override {
if (!(*enabled)) return;
painter->setPen(this->color);
painter->drawRect(this->rect().x() - 2, this->rect().y() - 2, this->rect().width() + 3, this->rect().height() + 3);
painter->setPen(QColor(0, 0, 0));
painter->drawRect(this->rect().x() - 3, this->rect().y() - 3, this->rect().width() + 5, this->rect().height() + 5);
painter->drawRect(this->rect().x() - 1, this->rect().y() - 1, this->rect().width() + 1, this->rect().height() + 1);
painter->drawRect(this->rect() + QMargins(1,1,1,1)); // Fill
painter->setPen(Qt::black);
painter->drawRect(this->rect() + QMargins(2,2,2,2)); // Outer border
painter->drawRect(this->rect()); // Inner border
}
void updateLocation(int x, int y);
bool *enabled;
protected:
QRectF baseRect;
QRgb color;
};

View File

@@ -20,13 +20,16 @@ public:
virtual void accept() override;
signals:
void accepted(MapConnection *result);
void newConnectionedAdded(const QString &mapName, const QString &direction);
void connectionReplaced(const QString &mapName, const QString &direction);
private:
Ui::NewMapConnectionDialog *ui;
Map *m_map;
bool mapNameIsValid();
void setWarningVisible(bool visible);
bool askReplaceConnection(MapConnection *connection, const QString &newMapName);
};
#endif // NEWMAPCONNECTIONDIALOG_H

View File

@@ -18,6 +18,9 @@ public:
void setLineEdit(QLineEdit *edit);
void setFocusedScrollingEnabled(bool enabled);
signals:
void editingFinished();
private:
void setItem(int index, const QString &text);

View File

@@ -0,0 +1,25 @@
#ifndef NOSCROLLTEXTEDIT_H
#define NOSCROLLTEXTEDIT_H
#include <QTextEdit>
#include <QWheelEvent>
class NoScrollTextEdit : public QTextEdit
{
Q_OBJECT
public:
explicit NoScrollTextEdit(const QString &text, QWidget *parent = nullptr) : QTextEdit(text, parent) {
setFocusPolicy(Qt::StrongFocus);
};
explicit NoScrollTextEdit(QWidget *parent = nullptr) : NoScrollTextEdit(QString(), parent) {};
virtual void wheelEvent(QWheelEvent *event) override {
if (hasFocus()) {
QTextEdit::wheelEvent(event);
} else {
event->ignore();
}
};
};
#endif // NOSCROLLTEXTEDIT_H

View File

@@ -149,10 +149,10 @@ public:
void select(unsigned tileId);
unsigned selectedTile = 0;
void selectVFlip(bool hFlip) { this->tile_hFlip = hFlip; }
void selectHFlip(bool hFlip) { this->tile_hFlip = hFlip; }
bool tile_hFlip = false;
void selectHFlip(bool vFlip) { this->tile_vFlip = vFlip; }
void selectVFlip(bool vFlip) { this->tile_vFlip = vFlip; }
bool tile_vFlip = false;
void selectPalette(int palette) {

View File

@@ -71,8 +71,6 @@ private slots:
void on_spinBox_paletteSelector_valueChanged(int arg1);
void on_actionSave_Tileset_triggered();
void on_actionImport_Primary_Tiles_triggered();
void on_actionImport_Secondary_Tiles_triggered();
@@ -173,6 +171,8 @@ private:
bool lockSelection = false;
QSet<uint16_t> metatileReloadQueue;
bool save();
signals:
void tilesetsSaved(QString, QString);
};