1 /*
2  *  Copyright (C) 2011-2016  OpenDungeons Team
3  *
4  *  This program is free software: you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation, either version 3 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef CONFIGMANAGER_H
19 #define CONFIGMANAGER_H
20 
21 #include <OgreSingleton.h>
22 #include <OgreColourValue.h>
23 
24 #include <cstdint>
25 
26 class CreatureDefinition;
27 class Weapon;
28 class SpawnCondition;
29 class Skill;
30 class TileSet;
31 class TileSetValue;
32 
33 enum class TileVisual;
34 
35 namespace Config
36 {
37 //! \brief Config options names
38 // Categories
39 enum Ctg : std::size_t
40 {
41     NONE  = 0,
42     VIDEO = 1,
43     AUDIO = 2,
44     GAME  = 3,
45     INPUT = 4,
46     TOTAL = 5
47 };
48 
49 // Video
50 const std::string RENDERER = "Renderer";
51 const std::string VIDEO_MODE = "Video Mode";
52 const std::string VSYNC = "VSync";
53 const std::string FULL_SCREEN = "Full Screen";
54 // Audio
55 const std::string MUSIC_VOLUME = "Music Volume";
56 // Input
57 const std::string KEYBOARD_GRAB = "Keyboard Grab";
58 const std::string MOUSE_GRAB = "Mouse Grab";
59 // Game
60 const std::string NICKNAME = "Nickname";
61 const std::string KEEPERVOICE = "KeeperVoice";
62 const std::string MINIMAP_TYPE = "MinimapType";
63 const std::string LIGHT_FACTOR = "LightFactor";
64 }
65 
66 //! \brief This class is used to manage global configuration such as network configuration, global creature stats, ...
67 //! It should NOT be used to load level specific stuff. For that, there is GameMap.
68 class ConfigManager : public Ogre::Singleton<ConfigManager>
69 {
70 public:
71     //! \brief Loads the game configuration files.
72     //! \param configPath The system configuration path.
73     //! \param userConfigPath The user profile config path or empty if not used.
74     //! \note In server mode, the configuration doesn't load the user config and thus,
75     //! doesn't set the userConfigPath.
76     ConfigManager(const std::string& configPath, const std::string& userConfigPath,
77         const std::string& soundPath);
78     ~ConfigManager();
79 
80     static const std::string DefaultWorkerCreatureDefinition;
81     static const std::string DEFAULT_TILESET_NAME;
82     static const std::string DEFAULT_KEEPER_VOICE;
83 
84     const Ogre::ColourValue& getColorFromId(const std::string& id) const;
getCreatureDefinitions()85     inline const std::map<std::string, CreatureDefinition*>& getCreatureDefinitions() const
86     { return mCreatureDefs; }
87     const CreatureDefinition* getCreatureDefinition(const std::string& name) const;
88 
getWeapons()89     inline const std::vector<const Weapon*>& getWeapons() const
90     { return mWeapons; }
91     const Weapon* getWeapon(const std::string& name) const;
92 
getCreatureDeathCounter()93     inline uint32_t getCreatureDeathCounter() const
94     { return mCreatureDeathCounter; }
95 
getMaxCreaturesPerSeatAbsolute()96     inline uint32_t getMaxCreaturesPerSeatAbsolute() const
97     { return mMaxCreaturesPerSeatAbsolute; }
98 
getMaxCreaturesPerSeatDefault()99     inline uint32_t getMaxCreaturesPerSeatDefault() const
100     { return mMaxCreaturesPerSeatDefault; }
101 
getCreatureBaseMood()102     inline int32_t getCreatureBaseMood() const
103     { return mCreatureBaseMood; }
104 
getCreatureMoodHappy()105     inline int32_t getCreatureMoodHappy() const
106     { return mCreatureMoodHappy; }
107 
getCreatureMoodUpset()108     inline int32_t getCreatureMoodUpset() const
109     { return mCreatureMoodUpset; }
110 
getCreatureMoodAngry()111     inline int32_t getCreatureMoodAngry() const
112     { return mCreatureMoodAngry; }
113 
getCreatureMoodFurious()114     inline int32_t getCreatureMoodFurious() const
115     { return mCreatureMoodFurious; }
116 
getSlapDamagePercent()117     inline double getSlapDamagePercent() const
118     { return mSlapDamagePercent; }
119 
getSlapEffectDuration()120     inline uint32_t getSlapEffectDuration() const
121     { return mSlapEffectDuration; }
122 
getTimePayDay()123     inline int64_t getTimePayDay() const
124     { return mTimePayDay; }
125 
getNetworkPort()126     inline uint32_t getNetworkPort() const
127     { return mNetworkPort; }
128 
getClientConnectionTimeout()129     inline uint32_t getClientConnectionTimeout() const
130     { return mClientConnectionTimeout; }
131 
getBaseSpawnPoint()132     inline uint32_t getBaseSpawnPoint() const
133     { return mBaseSpawnPoint; }
134 
getNbTurnsFuriousMax()135     inline int32_t getNbTurnsFuriousMax() const
136     { return mNbTurnsFuriousMax; }
137 
getMaxManaPerSeat()138     inline double getMaxManaPerSeat() const
139     { return mMaxManaPerSeat; }
140 
getClaimingWallPenalty()141     inline double getClaimingWallPenalty() const
142     { return mClaimingWallPenalty; }
143 
getDigCoefGold()144     inline double getDigCoefGold() const
145     { return mDigCoefGold; }
146 
getDigCoefGem()147     inline double getDigCoefGem() const
148     { return mDigCoefGem; }
149 
getDigCoefClaimedWall()150     inline double getDigCoefClaimedWall() const
151     { return mDigCoefClaimedWall; }
152 
getNbTurnsKoCreatureAttacked()153     inline int32_t getNbTurnsKoCreatureAttacked() const
154     { return mNbTurnsKoCreatureAttacked; }
155 
getMainMenuMusic()156     inline const std::string& getMainMenuMusic() const
157     { return mMainMenuMusic; }
158 
getMasterServerUrl()159     inline const std::string& getMasterServerUrl() const
160     { return mMasterServerUrl; }
161 
162     const std::vector<const SpawnCondition*>& getCreatureSpawnConditions(const CreatureDefinition* def) const;
163 
164     //! \brief Get the fighter creature definition spawnable in portals according to the given faction.
165     const std::vector<std::string>& getFactionSpawnPool(const std::string& faction) const;
166 
167     //! \brief Get the default worker creature definition spawnable according to the given faction.
168     const std::string& getFactionWorkerClass(const std::string& faction) const;
169 
getRogueWorkerClass()170     const std::string& getRogueWorkerClass() const
171     { return mDefaultWorkerRogue; }
172 
getFactions()173     inline const std::vector<std::string>& getFactions() const
174     { return mFactions; }
175 
176     //! Rooms configuration
177     const std::string& getRoomConfigString(const std::string& param) const;
178     uint32_t getRoomConfigUInt32(const std::string& param) const;
179     int32_t getRoomConfigInt32(const std::string& param) const;
180     double getRoomConfigDouble(const std::string& param) const;
181 
182     //! Traps configuration
183     const std::string& getTrapConfigString(const std::string& param) const;
184     uint32_t getTrapConfigUInt32(const std::string& param) const;
185     int32_t getTrapConfigInt32(const std::string& param) const;
186     double getTrapConfigDouble(const std::string& param) const;
187 
188     //! Spells configuration
189     const std::string& getSpellConfigString(const std::string& param) const;
190     uint32_t getSpellConfigUInt32(const std::string& param) const;
191     int32_t getSpellConfigInt32(const std::string& param) const;
192     double getSpellConfigDouble(const std::string& param) const;
193 
194     int32_t getSkillPoints(const std::string& res) const;
195 
getCreatureDefinitionDefaultWorker()196     inline const CreatureDefinition* getCreatureDefinitionDefaultWorker() const
197     { return mCreatureDefinitionDefaultWorker; }
198 
getNbWorkersDigSameFaceTile()199     inline uint32_t getNbWorkersDigSameFaceTile() const
200     { return mNbWorkersDigSameFaceTile; }
201 
getNbWorkersClaimSameTile()202     inline uint32_t getNbWorkersClaimSameTile() const
203     { return mNbWorkersClaimSameTile; }
204 
205     //! Returns the tileset for the given name. If the tileset is not found, returns the default tileset
206     const TileSet* getTileSet(const std::string& tileSetName) const;
207 
208     //! \brief Set a config value. Only permits predetermined types.
setAudioValue(const std::string & param,const std::string & value)209     void setAudioValue(const std::string& param, const std::string& value)
210     { mUserConfig[Config::Ctg::AUDIO][param] = value; }
setVideoValue(const std::string & param,const std::string & value)211     void setVideoValue(const std::string& param, const std::string& value)
212     { mUserConfig[Config::Ctg::VIDEO][param] = value; }
setInputValue(const std::string & param,const std::string & value)213     void setInputValue(const std::string& param, const std::string& value)
214     { mUserConfig[Config::Ctg::INPUT][param] = value; }
setGameValue(const std::string & param,const std::string & value)215     void setGameValue(const std::string& param, const std::string& value)
216     { mUserConfig[Config::Ctg::GAME][param] = value; }
217 
218     //! \brief Get a config value.
219     inline const std::string getAudioValue(const std::string& param,
220                                             const std::string& defaultValue = std::string(),
221                                             bool triggerError = true) const
222     { return getUserValue(Config::Ctg::AUDIO, param, defaultValue, triggerError); }
223     inline const std::string getVideoValue(const std::string& param,
224                                             const std::string& defaultValue = std::string(),
225                                             bool triggerError = true) const
226     { return getUserValue(Config::Ctg::VIDEO, param, defaultValue, triggerError); }
227     inline const std::string getInputValue(const std::string& param,
228                                             const std::string& defaultValue = std::string(),
229                                             bool triggerError = true) const
230     { return getUserValue(Config::Ctg::INPUT, param, defaultValue, triggerError); }
231     inline const std::string getGameValue(const std::string& param,
232                                            const std::string& defaultValue = std::string(),
233                                            bool triggerError = true) const
234     { return getUserValue(Config::Ctg::GAME, param, defaultValue, triggerError); }
235 
236     //! \brief Save the user configuration file.
237     bool saveUserConfig();
238 
239     //! \brief Tries to restore the previous video config
240     //! To be called at startup once the user config has been loaded.
241     bool initVideoConfig(Ogre::Root& ogreRoot);
242 
getKeeperVoices()243     const std::vector<std::string>& getKeeperVoices() const
244     { return mKeeperVoices; }
245 
246 private:
247     //! \brief Function used to load the global configuration. They should return true if the configuration
248     //! is ok and false if a mandatory parameter is missing
249     bool loadGlobalConfig(const std::string& configPath);
250     bool loadGlobalConfigSeatColors(std::stringstream& configFile);
251     bool loadGlobalConfigDefinitionFiles(std::stringstream& configFile);
252     bool loadGlobalGameConfig(std::stringstream& configFile);
253     bool loadCreatureDefinitions(const std::string& fileName);
254     bool loadEquipements(const std::string& fileName);
255     bool loadSpawnConditions(const std::string& fileName);
256     bool loadFactions(const std::string& fileName);
257     bool loadRooms(const std::string& fileName);
258     bool loadTraps(const std::string& fileName);
259     bool loadSpellConfig(const std::string& fileName);
260     bool loadSkills(const std::string& fileName);
261     bool loadTilesets(const std::string& fileName);
262     bool loadTilesetValues(std::istream& defFile, TileVisual tileVisual, std::vector<TileSetValue>& tileValues);
263 
264     //! \brief Loads the user configuration values, and use default ones if it cannot do it.
265     void loadUserConfig(const std::string& fileName);
266 
267     void loadKeeperVoices(const std::string& soundPath);
268 
269     //! \brief Get a config value.
270     const std::string getUserValue(Config::Ctg category,
271                                     const std::string& param,
272                                     const std::string& defaultValue = std::string(),
273                                     bool triggerError = true) const;
274 
275     std::map<std::string, Ogre::ColourValue> mSeatColors;
276     std::map<std::string, CreatureDefinition*> mCreatureDefs;
277     std::vector<const Weapon*> mWeapons;
278     std::string mFilenameCreatureDefinition;
279     std::string mFilenameEquipmentDefinition;
280     std::string mFilenameSpawnConditions;
281     std::string mFilenameFactions;
282     std::string mFilenameRooms;
283     std::string mFilenameTraps;
284     std::string mFilenameSpells;
285     std::string mFilenameSkills;
286     std::string mFilenameTilesets;
287     std::string mFilenameUserCfg;
288     uint32_t mNetworkPort;
289     uint32_t mClientConnectionTimeout;
290     uint32_t mBaseSpawnPoint;
291     uint32_t mCreatureDeathCounter;
292     uint32_t mMaxCreaturesPerSeatAbsolute;
293     uint32_t mMaxCreaturesPerSeatDefault;
294     int32_t mCreatureBaseMood;
295     int32_t mCreatureMoodHappy;
296     int32_t mCreatureMoodUpset;
297     int32_t mCreatureMoodAngry;
298     int32_t mCreatureMoodFurious;
299     double mSlapDamagePercent;
300     uint32_t mSlapEffectDuration;
301     int64_t mTimePayDay;
302     int32_t mNbTurnsFuriousMax;
303     double mMaxManaPerSeat;
304     double mClaimingWallPenalty;
305     double mDigCoefGold;
306     double mDigCoefGem;
307     double mDigCoefClaimedWall;
308     int32_t mNbTurnsKoCreatureAttacked;
309     std::string mDefaultWorkerRogue;
310     std::string mMainMenuMusic;
311     std::string mMasterServerUrl;
312     std::map<const CreatureDefinition*, std::vector<const SpawnCondition*> > mCreatureSpawnConditions;
313     std::map<const std::string, std::vector<std::string> > mFactionSpawnPool;
314 
315     //! \brief Stores the faction default worker creature definition.
316     std::map<const std::string, std::string> mFactionDefaultWorkerClass;
317 
318     std::vector<std::string> mFactions;
319     std::map<const std::string, std::string> mRoomsConfig;
320     std::map<const std::string, std::string> mTrapsConfig;
321     std::map<const std::string, std::string> mSpellConfig;
322     std::map<const std::string, int32_t> mSkillPoints;
323 
324     //! \brief Default definition for the editor. At map loading, it will spawn a creature from
325     //! the default seat worker depending on seat faction
326     CreatureDefinition* mCreatureDefinitionDefaultWorker;
327 
328     uint32_t mNbWorkersDigSameFaceTile;
329     uint32_t mNbWorkersClaimSameTile;
330 
331     //! \brief Allowed tilesets
332     std::map<std::string, const TileSet*> mTileSets;
333 
334     //! \brief User config values
335     //! < category, < param, value > >
336     std::vector< std::map<std::string, std::string> > mUserConfig;
337 
338     //! \brief List of the found keeper voices (in the relative sound folder)
339     std::vector<std::string> mKeeperVoices;
340 };
341 
342 #endif //CONFIGMANAGER_H
343