#pragma once #ifndef MAP_H #define MAP_H #include "blockdata.h" #include "mapconnection.h" #include "maplayout.h" #include "tileset.h" #include "events.h" #include #include #include #include #include #define DEFAULT_BORDER_WIDTH 2 #define DEFAULT_BORDER_HEIGHT 2 // Maximum based only on data type (u8) of map border width/height #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; class Map : public QObject { Q_OBJECT public: explicit Map(QObject *parent = nullptr); ~Map(); public: void setName(const QString &mapName) { m_name = mapName; } QString name() const { return m_name; } void setConstantName(const QString &constantName) { m_constantName = constantName; } QString constantName() const { return m_constantName; } static QString mapConstantFromName(QString mapName, bool includePrefix = true); void setLayout(Layout *layout); Layout* layout() const { return m_layout; } void setLayoutId(const QString &layoutId) { m_layoutId = layoutId; } QString layoutId() const { return m_layoutId; } int getWidth() const; int getHeight() const; int getBorderWidth() const; int getBorderHeight() const; // TODO: Combine these into a separate MapHeader class? void setSong(const QString &song); void setLocation(const QString &location); void setRequiresFlash(bool requiresFlash); void setWeather(const QString &weather); void setType(const QString &type); void setShowsLocation(bool showsLocation); void setAllowsRunning(bool allowsRunning); void setAllowsBiking(bool allowsBiking); void setAllowsEscaping(bool allowsEscaping); void setFloorNumber(int floorNumber); void setBattleScene(const QString &battleScene); QString song() const { return m_song; } QString location() const { return m_location; } bool requiresFlash() const { return m_requiresFlash; } QString weather() const { return m_weather; } QString type() const { return m_type; } bool showsLocation() const { return m_showsLocation; } bool allowsRunning() const { return m_allowsRunning; } bool allowsBiking() const { return m_allowsBiking; } bool allowsEscaping() const { return m_allowsEscaping; } int floorNumber() const { return m_floorNumber; } QString battleScene() const { return m_battleScene; } void setSharedEventsMap(const QString &sharedEventsMap) { m_sharedEventsMap = sharedEventsMap; } void setSharedScriptsMap(const QString &sharedScriptsMap) { m_sharedScriptsMap = sharedScriptsMap; } QString sharedEventsMap() const { return m_sharedEventsMap; } QString sharedScriptsMap() const { return m_sharedScriptsMap; } void setNeedsLayoutDir(bool needsLayoutDir) { m_needsLayoutDir = needsLayoutDir; } void setNeedsHealLocation(bool needsHealLocation) { m_needsHealLocation = needsHealLocation; } void setIsPersistedToFile(bool persistedToFile) { m_isPersistedToFile = persistedToFile; } void setHasUnsavedDataChanges(bool unsavedDataChanges) { m_hasUnsavedDataChanges = unsavedDataChanges; } bool needsLayoutDir() const { return m_needsLayoutDir; } bool needsHealLocation() const { return m_needsHealLocation; } bool isPersistedToFile() const { return m_isPersistedToFile; } bool hasUnsavedDataChanges() const { return m_hasUnsavedDataChanges; } void resetEvents(); QList getEvents(Event::Group group = Event::Group::None) const; Event* getEvent(Event::Group group, int index) const; int getNumEvents(Event::Group group = Event::Group::None) const; QStringList getScriptLabels(Event::Group group = Event::Group::None); QString getScriptsFilePath() const; void openScript(QString label); void removeEvent(Event *); void addEvent(Event *); int getIndexOfEvent(Event *) const; void deleteConnections(); QList getConnections() const; void removeConnection(MapConnection *); void addConnection(MapConnection *); void loadConnection(MapConnection *); QRect getConnectionRect(const QString &direction, Layout *fromLayout = nullptr); QPixmap renderConnection(const QString &direction, Layout *fromLayout = nullptr); QUndoStack* editHistory() const { return m_editHistory; } void commit(QUndoCommand*); void modify(); void setClean(); bool hasUnsavedChanges() const; void pruneEditHistory(); void setCustomAttributes(const QMap &attributes) { m_customAttributes = attributes; } QMap customAttributes() const { return m_customAttributes; } private: QString m_name; QString m_constantName; QString m_layoutId; // TODO: Why do we do half this->layout()->id and half this->layoutId. Should these ever be different? QString m_song; QString m_location; bool m_requiresFlash; QString m_weather; QString m_type; bool m_showsLocation; bool m_allowsRunning; bool m_allowsBiking; bool m_allowsEscaping; int m_floorNumber = 0; QString m_battleScene; QString m_sharedEventsMap = ""; QString m_sharedScriptsMap = ""; QStringList m_scriptsFileLabels; QMap m_customAttributes; Layout *m_layout = nullptr; bool m_isPersistedToFile = true; bool m_hasUnsavedDataChanges = false; bool m_needsLayoutDir = true; bool m_needsHealLocation = false; bool m_scriptsLoaded = false; QMap> m_events; QList m_ownedEvents; // for memory management QList m_metatileLayerOrder; QList m_metatileLayerOpacity; void trackConnection(MapConnection*); // MapConnections in 'ownedConnections' but not 'connections' persist in the edit history. QList m_connections; QSet m_ownedConnections; QUndoStack *m_editHistory = nullptr; signals: void modified(); void mapDimensionsChanged(const QSize &size); void openScriptRequested(QString label); void connectionAdded(MapConnection*); void connectionRemoved(MapConnection*); }; #endif // MAP_H