#pragma once #ifndef CONFIG_H #define CONFIG_H #include #include #include #include #include #include #include #include #include #include "events.h" static const QVersionNumber porymapVersion = QVersionNumber::fromString(PORYMAP_VERSION); // In both versions the default new map border is a generic tree #define DEFAULT_BORDER_RSE (QList{0x1D4, 0x1D5, 0x1DC, 0x1DD}) #define DEFAULT_BORDER_FRLG (QList{0x14, 0x15, 0x1C, 0x1D}) #define CONFIG_BACKWARDS_COMPATABILITY enum MapSortOrder { Group = 0, Area = 1, Layout = 2, }; class KeyValueConfigBase { public: void save(); void load(); virtual ~KeyValueConfigBase(); virtual void reset() = 0; protected: virtual QString getConfigFilepath() = 0; virtual void parseConfigKeyValue(QString key, QString value) = 0; virtual QMap 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); }; class PorymapConfig: public KeyValueConfigBase { public: PorymapConfig() { reset(); } virtual void reset() override { this->recentProjects.clear(); this->projectManuallyClosed = false; this->reopenOnLaunch = true; this->mapSortOrder = MapSortOrder::Group; this->prettyCursors = true; this->mirrorConnectingMaps = true; this->showDiveEmergeMaps = false; this->diveEmergeMapOpacity = 30; this->diveMapOpacity = 15; this->emergeMapOpacity = 15; this->collisionOpacity = 50; this->collisionZoom = 30; this->metatilesZoom = 30; this->tilesetEditorMetatilesZoom = 30; this->tilesetEditorTilesZoom = 30; this->showPlayerView = false; this->showCursorTile = true; this->showBorder = true; this->showGrid = false; this->showTilesetEditorMetatileGrid = false; this->showTilesetEditorLayerGrid = true; this->monitorFiles = true; this->tilesetCheckerboardFill = true; this->theme = "default"; this->textEditorOpenFolder = ""; this->textEditorGotoLine = ""; this->paletteEditorBitDepth = 24; this->projectSettingsTab = 0; this->warpBehaviorWarningDisabled = false; this->checkForUpdates = true; this->lastUpdateCheckTime = QDateTime(); this->lastUpdateCheckVersion = porymapVersion; this->rateLimitTimes.clear(); } void addRecentProject(QString project); void setRecentProjects(QStringList projects); QString getRecentProject(); QStringList getRecentProjects(); void setMainGeometry(QByteArray, QByteArray, QByteArray, QByteArray, QByteArray); void setTilesetEditorGeometry(QByteArray, QByteArray, QByteArray); void setPaletteEditorGeometry(QByteArray, QByteArray); void setRegionMapEditorGeometry(QByteArray, QByteArray); void setProjectSettingsEditorGeometry(QByteArray, QByteArray); void setCustomScriptsEditorGeometry(QByteArray, QByteArray); QMap getMainGeometry(); QMap getTilesetEditorGeometry(); QMap getPaletteEditorGeometry(); QMap getRegionMapEditorGeometry(); QMap getProjectSettingsEditorGeometry(); QMap getCustomScriptsEditorGeometry(); bool reopenOnLaunch; bool projectManuallyClosed; MapSortOrder mapSortOrder; bool prettyCursors; bool mirrorConnectingMaps; bool showDiveEmergeMaps; int diveEmergeMapOpacity; int diveMapOpacity; int emergeMapOpacity; int collisionOpacity; int collisionZoom; int metatilesZoom; int tilesetEditorMetatilesZoom; int tilesetEditorTilesZoom; bool showPlayerView; bool showCursorTile; bool showBorder; bool showGrid; bool showTilesetEditorMetatileGrid; bool showTilesetEditorLayerGrid; bool monitorFiles; bool tilesetCheckerboardFill; QString theme; QString textEditorOpenFolder; QString textEditorGotoLine; int paletteEditorBitDepth; int projectSettingsTab; bool warpBehaviorWarningDisabled; bool checkForUpdates; QDateTime lastUpdateCheckTime; QVersionNumber lastUpdateCheckVersion; QMap rateLimitTimes; protected: virtual QString getConfigFilepath() override; virtual void parseConfigKeyValue(QString key, QString value) override; virtual QMap getKeyValueMap() override; virtual void init() override {}; virtual void setUnreadKeys() override {}; private: QString stringFromByteArray(QByteArray); QByteArray bytesFromString(QString); QStringList recentProjects; QByteArray mainWindowGeometry; QByteArray mainWindowState; QByteArray mapSplitterState; QByteArray mainSplitterState; QByteArray metatilesSplitterState; QByteArray tilesetEditorGeometry; QByteArray tilesetEditorState; QByteArray tilesetEditorSplitterState; QByteArray paletteEditorGeometry; QByteArray paletteEditorState; QByteArray regionMapEditorGeometry; QByteArray regionMapEditorState; QByteArray projectSettingsEditorGeometry; QByteArray projectSettingsEditorState; QByteArray customScriptsEditorGeometry; QByteArray customScriptsEditorState; }; extern PorymapConfig porymapConfig; enum BaseGameVersion { none, pokeruby, pokefirered, pokeemerald, }; enum ProjectIdentifier { symbol_facing_directions, symbol_obj_event_gfx_pointers, symbol_pokemon_icon_table, symbol_wild_encounters, symbol_heal_locations_type, symbol_heal_locations, symbol_spawn_points, symbol_spawn_maps, symbol_spawn_npcs, symbol_attribute_table, symbol_tilesets_prefix, define_obj_event_count, define_min_level, define_max_level, define_tiles_primary, define_tiles_total, define_metatiles_primary, define_pals_primary, define_pals_total, define_map_size, define_mask_metatile, define_mask_collision, define_mask_elevation, define_mask_behavior, define_mask_layer, define_attribute_behavior, define_attribute_layer, define_attribute_terrain, define_attribute_encounter, define_metatile_label_prefix, define_heal_locations_prefix, define_spawn_prefix, define_map_prefix, define_map_dynamic, define_map_empty, define_map_section_prefix, define_map_section_empty, define_map_section_count, regex_behaviors, regex_obj_event_gfx, regex_items, regex_flags, regex_vars, regex_movement_types, regex_map_types, regex_battle_scenes, regex_weather, regex_coord_event_weather, regex_secret_bases, regex_sign_facing_directions, regex_trainer_types, regex_music, regex_species, }; enum ProjectFilePath { data_map_folders, data_scripts_folders, data_layouts_folders, data_tilesets_folders, data_event_scripts, json_map_groups, json_layouts, json_wild_encounters, json_region_map_entries, json_region_porymap_cfg, tilesets_headers, tilesets_graphics, tilesets_metatiles, tilesets_headers_asm, tilesets_graphics_asm, tilesets_metatiles_asm, data_obj_event_gfx_pointers, data_obj_event_gfx_info, data_obj_event_pic_tables, data_obj_event_gfx, data_pokemon_gfx, data_heal_locations, constants_global, constants_map_groups, constants_items, constants_flags, constants_vars, constants_weather, constants_songs, constants_heal_locations, constants_pokemon, constants_map_types, constants_trainer_types, constants_secret_bases, constants_obj_event_movement, constants_obj_events, constants_event_bg, constants_region_map_sections, constants_metatile_labels, constants_metatile_behaviors, constants_species, constants_fieldmap, global_fieldmap, fieldmap, initial_facing_table, pokemon_icon_table, pokemon_gfx, }; class ProjectConfig: public KeyValueConfigBase { public: ProjectConfig() { reset(); } virtual void reset() override { this->baseGameVersion = BaseGameVersion::pokeemerald; // Reset non-version-specific settings this->usePoryScript = false; this->tripleLayerMetatilesEnabled = false; this->defaultMetatileId = 1; this->defaultElevation = 3; this->defaultCollision = 0; this->defaultPrimaryTileset = "gTileset_General"; this->prefabFilepath = QString(); this->prefabImportPrompted = false; this->tilesetsHaveCallback = true; this->tilesetsHaveIsCompressed = true; this->filePaths.clear(); this->eventIconPaths.clear(); this->pokemonIconPaths.clear(); this->collisionSheetPath = QString(); this->collisionSheetWidth = 2; this->collisionSheetHeight = 16; this->blockMetatileIdMask = 0x03FF; this->blockCollisionMask = 0x0C00; this->blockElevationMask = 0xF000; this->identifiers.clear(); this->readKeys.clear(); } static const QMap> defaultIdentifiers; static const QMap> defaultPaths; static const QStringList versionStrings; static BaseGameVersion stringToBaseGameVersion(const QString &string); void reset(BaseGameVersion baseGameVersion); void setFilePath(ProjectFilePath pathId, const QString &path); void setFilePath(const QString &pathId, const QString &path); QString getCustomFilePath(ProjectFilePath pathId); QString getCustomFilePath(const QString &pathId); QString getFilePath(ProjectFilePath pathId); void setIdentifier(ProjectIdentifier id, const QString &text); void setIdentifier(const QString &id, const QString &text); QString getCustomIdentifier(ProjectIdentifier id); QString getCustomIdentifier(const QString &id); QString getIdentifier(ProjectIdentifier id); QString getBaseGameVersionString(BaseGameVersion version); QString getBaseGameVersionString(); int getNumLayersInMetatile(); int getNumTilesInMetatile(); void setEventIconPath(Event::Group group, const QString &path); QString getEventIconPath(Event::Group group); void setPokemonIconPath(const QString &species, const QString &path); QString getPokemonIconPath(const QString &species); QHash getPokemonIconPaths(); BaseGameVersion baseGameVersion; QString projectDir; bool usePoryScript; bool useCustomBorderSize; bool eventWeatherTriggerEnabled; bool eventSecretBaseEnabled; bool hiddenItemQuantityEnabled; bool hiddenItemRequiresItemfinderEnabled; bool healLocationRespawnDataEnabled; bool eventCloneObjectEnabled; bool floorNumberEnabled; bool createMapTextFileEnabled; bool tripleLayerMetatilesEnabled; uint16_t defaultMetatileId; uint16_t defaultElevation; uint16_t defaultCollision; QList newMapBorderMetatileIds; QString defaultPrimaryTileset; QString defaultSecondaryTileset; QString prefabFilepath; bool prefabImportPrompted; bool tilesetsHaveCallback; bool tilesetsHaveIsCompressed; int metatileAttributesSize; uint32_t metatileBehaviorMask; uint32_t metatileTerrainTypeMask; uint32_t metatileEncounterTypeMask; uint32_t metatileLayerTypeMask; uint16_t blockMetatileIdMask; uint16_t blockCollisionMask; uint16_t blockElevationMask; bool mapAllowFlagsEnabled; QString collisionSheetPath; int collisionSheetWidth; int collisionSheetHeight; QSet warpBehaviors; protected: virtual QString getConfigFilepath() override; virtual void parseConfigKeyValue(QString key, QString value) override; virtual QMap getKeyValueMap() override; virtual void init() override; virtual void setUnreadKeys() override; private: QStringList readKeys; QMap identifiers; QMap filePaths; QMap eventIconPaths; QHash pokemonIconPaths; }; extern ProjectConfig projectConfig; class UserConfig: public KeyValueConfigBase { public: UserConfig() { reset(); } virtual void reset() override { this->recentMap = QString(); this->useEncounterJson = true; this->customScripts.clear(); this->readKeys.clear(); } void parseCustomScripts(QString input); QString outputCustomScripts(); void setCustomScripts(QStringList scripts, QList enabled); QStringList getCustomScriptPaths(); QList getCustomScriptsEnabled(); QString projectDir; QString recentMap; bool useEncounterJson; protected: virtual QString getConfigFilepath() override; virtual void parseConfigKeyValue(QString key, QString value) override; virtual QMap getKeyValueMap() override; virtual void init() override; virtual void setUnreadKeys() override; #ifdef CONFIG_BACKWARDS_COMPATABILITY friend class ProjectConfig; #endif private: QStringList readKeys; QMap customScripts; }; extern UserConfig userConfig; class QAction; class Shortcut; class ShortcutsConfig : public KeyValueConfigBase { public: ShortcutsConfig() : user_shortcuts({ }), default_shortcuts({ }) { } virtual void reset() override { user_shortcuts.clear(); } // Call this before applying user shortcuts so that the user can restore defaults. void setDefaultShortcuts(const QObjectList &objects); QList defaultShortcuts(const QObject *object) const; void setUserShortcuts(const QObjectList &objects); void setUserShortcuts(const QMultiMap &objects_keySequences); QList userShortcuts(const QObject *object) const; protected: virtual QString getConfigFilepath() override; virtual void parseConfigKeyValue(QString key, QString value) override; virtual QMap getKeyValueMap() override; virtual void init() override { }; virtual void setUnreadKeys() override { }; private: QMultiMap user_shortcuts; QMultiMap default_shortcuts; enum StoreType { User, Default }; QString cfgKey(const QObject *object) const; QList currentShortcuts(const QObject *object) const; void storeShortcutsFromList(StoreType storeType, const QObjectList &objects); void storeShortcuts( StoreType storeType, const QString &cfgKey, const QList &keySequences); }; extern ShortcutsConfig shortcutsConfig; #endif // CONFIG_H