1 //
2 //  SuperTuxKart - a fun racing game with go-kart
3 //  Copyright (C) 2008-2015 Joerg Henrichs
4 //
5 //  This program is free software; you can redistribute it and/or
6 //  modify it under the terms of the GNU General Public License
7 //  as published by the Free Software Foundation; either version 3
8 //  of the License, or (at your option) any later version.
9 //
10 //  This program is distributed in the hope that it will be useful,
11 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 //  GNU General Public License for more details.
14 //
15 //  You should have received a copy of the GNU General Public License
16 //  along with this program; if not, write to the Free Software
17 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18 
19 #ifndef HEADER_CHALLENGE_DATA_HPP
20 #define HEADER_CHALLENGE_DATA_HPP
21 
22 #include <string>
23 #include <vector>
24 #include <stdio.h>
25 #include <stdexcept>
26 
27 
28 #include "race/race_manager.hpp"
29 
30 /**
31   * \brief the description of one challenge
32   * \ingroup challenges
33   */
34 class ChallengeData
35 {
36 public:
37     /** The type of reward you get when fulfilling this challenge.
38     */
39     enum RewardType
40     {
41         UNLOCK_TRACK,
42         UNLOCK_GP,
43         UNLOCK_MODE,
44         UNLOCK_KART,
45         UNLOCK_DIFFICULTY
46     };
47 
48     /** The level of completion of a GP challenge
49     */
50     enum GPLevel
51     {
52         GP_NONE,
53         GP_EASY,
54         GP_MEDIUM,
55         GP_HARD,
56         GP_BEST
57     };
58     // ------------------------------------------------------------------------
59     class UnlockableFeature
60     {
61     public:
62 
63         std::string        m_name; // internal name
64         irr::core::stringw m_user_name; // not all types of feature have one
65         RewardType         m_type;
66 
67         const irr::core::stringw getUnlockedMessage() const;
68     };   // UnlockableFeature
69     // ------------------------------------------------------------------------
70 
71     /** The various types of challenges that we support, which esp. determine
72      *  when a challenge is tested if it is fulfilled. For now we have GP
73      *  (a GP challenge, tested at the end of a GP), Race (tested at the
74      *  end of a challenge race), and 'any', which is checked at the end of
75      *  each race (maybe even non challenged once). An example for 'any' is
76      *  'are all challenges unclocked on highest level', which needs to be
77      *  tested after each race (but is itself not a race mode, so it's not
78      *  that you can start this challenge, which differentiates it from
79      *  a race challenge). */
80     enum ChallengeModeType
81     {
82         CM_GRAND_PRIX,
83         CM_SINGLE_RACE,
84         CM_ANY
85     };
86 
87     /** The type of value stored by m_unlock_special_value */
88     enum SpecialUnlockType
89     {
90         SPECIAL_NONE,
91         SPECIAL_MAX_REQ_IN_LOWER_DIFF
92     };
93 
94 
95 private:
96 
97     /** The challenge mode of this challenge. */
98     ChallengeModeType              m_mode;
99 
100     /** The minor type, used when m_mode is CM_GP or CM_RACE only. */
101     RaceManager::MinorRaceModeType m_minor;
102 
103     int                            m_num_laps;
104     bool                           m_reverse;
105     int                            m_position[RaceManager::DIFFICULTY_COUNT];
106     int                            m_default_num_karts[RaceManager::DIFFICULTY_COUNT];
107     std::string                    m_ai_kart_ident[RaceManager::DIFFICULTY_COUNT];
108     std::string                    m_replay_files[RaceManager::DIFFICULTY_COUNT];
109     float                          m_time[RaceManager::DIFFICULTY_COUNT];
110     int                            m_energy[RaceManager::DIFFICULTY_COUNT];
111     RaceManager::AISuperPower      m_ai_superpower[RaceManager::DIFFICULTY_COUNT];
112     std::string                    m_gp_id;
113     std::string                    m_track_id;
114     std::string                    m_filename;
115     /** Version number of the challenge. */
116     int                            m_version;
117     bool                           m_is_unlock_list;
118     bool                           m_is_ghost_replay;
119 
120     void setUnlocks(const std::string &id,
121                     ChallengeData::RewardType reward);
122     void error(const char *id) const;
123 
124     /** Short, internal name for this challenge. */
125     std::string              m_id;
126 
127     /** Features to unlock. */
128     std::vector<UnlockableFeature> m_feature;
129 
130     /** Number of trophies required to access this challenge */
131     int m_num_trophies;
132     /** Number of completed challenges required to access this challenge
133       * (esp. useful for the final challenge) */
134     int m_num_completed_challenges;
135 
136     /** Variables only used by unlock lists */
137     SpecialUnlockType m_unlock_special_type;
138     int               m_unlock_special_value;
139 
140 public:
141                  ChallengeData(const std::string& filename);
142 
~ChallengeData()143     virtual      ~ChallengeData() {}
144 
145     /** sets the right parameters in RaceManager to try this challenge */
146     void         setRace(RaceManager::Difficulty d) const;
147 
148     virtual void check() const;
149     virtual bool isChallengeFulfilled(bool check_best=false) const;
150     virtual GPLevel isGPFulfilled() const;
151     void  addUnlockTrackReward(const std::string &track_name);
152     void  addUnlockModeReward(const std::string &internal_mode_name,
153                               const irr::core::stringw &user_mode_name);
154     void  addUnlockGPReward(const std::string &gp_name);
155     void  addUnlockDifficultyReward(const std::string &internal_name,
156                                     const irr::core::stringw &user_name);
157     void  addUnlockKartReward(const std::string &internal_name,
158                               const irr::core::stringw &user_name);
159 
160     // ------------------------------------------------------------------------
161     /** Returns the version number of this challenge. */
getVersion() const162     int  getVersion() const { return m_version; }
163 
164     // ------------------------------------------------------------------------
165     /** Returns the list of unlockable features for this challenge.
166      */
167     const std::vector<UnlockableFeature>&
getFeatures() const168         getFeatures() const { return m_feature; }
169 
170     // ------------------------------------------------------------------------
171     /** Returns the id of the challenge. */
getChallengeId() const172     const std::string &getChallengeId() const { return m_id; }
173 
174     // ------------------------------------------------------------------------
175     /** Sets the id of this challenge. */
setChallengeId(const std::string & s)176     void  setChallengeId(const std::string& s) { m_id = s; }
177 
178     // ------------------------------------------------------------------------
179     /** Returns the track associated with this challenge. */
getTrackId() const180     const std::string& getTrackId() const
181     {
182         assert(m_mode==CM_SINGLE_RACE);
183         return m_track_id;
184     }   // getTrackId
185 
186     // ------------------------------------------------------------------------
187     /** Returns the id of the grand prix associated with this challenge. */
getGPId() const188     const std::string& getGPId() const
189     {
190         assert(m_mode==CM_GRAND_PRIX);
191         return m_gp_id;
192     }   // getGPId
193 
194     // ------------------------------------------------------------------------
195     /** Return number of laps. */
getNumLaps() const196     int getNumLaps() const
197     {
198         assert(m_mode==CM_SINGLE_RACE);
199         return m_num_laps;
200     }   // getNumLaps
201 
202     // ------------------------------------------------------------------------
203     /** Return reverse mode. */
getReverse() const204     bool getReverse() const { return m_reverse; }
205     // ------------------------------------------------------------------------
206     /** Get number of required trophies to start this challenge */
getNumTrophies() const207     int getNumTrophies() const { return m_num_trophies; }
208     // ------------------------------------------------------------------------
209     /** Get number of required completed challenges to start this challenge */
getNumChallenges() const210     int getNumChallenges() const { return m_num_completed_challenges; }
211     // ------------------------------------------------------------------------
212     /** Returns if this challenge is a grand prix. */
isGrandPrix() const213     bool isGrandPrix() const { return m_mode == CM_GRAND_PRIX; }
214     // ------------------------------------------------------------------------
215     /** Returns if this challenge is a grand prix. */
isSingleRace() const216     bool isSingleRace() const { return m_mode == CM_SINGLE_RACE; }
217     // ------------------------------------------------------------------------
218     /** Returns if this challenge is using ghost replay. */
isGhostReplay() const219     bool isGhostReplay() const { return m_is_ghost_replay; }
220     // ------------------------------------------------------------------------
221     /** Returns if this challenge is an unlock list. */
isUnlockList() const222     bool isUnlockList() const { return m_is_unlock_list; }
223     // ------------------------------------------------------------------------
224     /** Returns the special unlock list value */
getSpecialType() const225     SpecialUnlockType getSpecialType() const { return m_unlock_special_type; }
226     // ------------------------------------------------------------------------
227     /** Returns the special unlock list value */
getSpecialValue() const228     int getSpecialValue() const { return m_unlock_special_value; }
229     // ------------------------------------------------------------------------
230     /** Returns the challenge mode of this challenge. */
getMode() const231     ChallengeModeType getMode() const { return m_mode; }
232     // ------------------------------------------------------------------------
233     /** Returns the minor mode of this challenge. */
getMinorMode() const234     RaceManager::MinorRaceModeType getMinorMode()  const { return m_minor; }
235     // ------------------------------------------------------------------------
236     /** Returns the description of this challenge.
237      */
238     const irr::core::stringw getChallengeDescription() const;
239 
240     // ------------------------------------------------------------------------
241     /** Returns the maximum position the player must have in order to win.
242      */
getMaxPosition(RaceManager::Difficulty difficulty) const243     int getMaxPosition(RaceManager::Difficulty difficulty) const
244     {
245         return m_position[difficulty];
246     }   // getPosition
247 
248     // ------------------------------------------------------------------------
249     /** Returns the number of karts to use.
250      */
getNumKarts(RaceManager::Difficulty difficulty) const251     int getNumKarts(RaceManager::Difficulty difficulty) const
252     {
253         return m_default_num_karts[difficulty];
254     }   // getNumKarts
255     // ------------------------------------------------------------------------
256     /** Returns the maximum time in which the kart must finish.
257      */
getTimeRequirement(RaceManager::Difficulty difficulty) const258     float getTimeRequirement(RaceManager::Difficulty difficulty) const
259     {
260         return m_time[difficulty];
261     }   // getTimeRequirement
262     // ------------------------------------------------------------------------
263     /** Return the energy that a kart must at least have at the end of a race.
264      */
getEnergy(RaceManager::Difficulty difficulty) const265     int getEnergy(RaceManager::Difficulty difficulty) const
266     {
267         return m_energy[difficulty];
268     }   // getEnergy
269     // ------------------------------------------------------------------------
270     /** Returns the name of the AI to use (used for boss challenge).
271      */
getAIKartIdent(RaceManager::Difficulty difficulty) const272     const std::string& getAIKartIdent(RaceManager::Difficulty difficulty) const
273     {
274         return m_ai_kart_ident[difficulty];
275     }
276 
277 };   // ChallengeData
278 
279 #endif   // HEADER_CHALLENGE_DATA_HPP
280