1 //
2 //  SuperTuxKart - a fun racing game with go-kart
3 //  Copyright (C) 2010-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_RACE_RESULT_GUI_HPP
20 #define HEADER_RACE_RESULT_GUI_HPP
21 
22 
23 #include "guiengine/screen.hpp"
24 #include "states_screens/dialogs/message_dialog.hpp"
25 #include "states_screens/race_gui_base.hpp"
26 #include "states_screens/state_manager.hpp"
27 
28 #include <assert.h>
29 #include <vector>
30 
31 
32 namespace irr
33 {
34     namespace gui
35     {
36         class ScalableFont;
37     }
38 }
39 
40 class MusicInformation;
41 class SFXBase;
42 
43 /**
44   * \brief Displays the results (while the end animation is shown).
45   * \ingroup states_screens
46   */
47 class RaceResultGUI : public RaceGUIBase,
48                       public GUIEngine::Screen,
49                       public GUIEngine::ScreenSingleton<RaceResultGUI>,
50                       public MessageDialog::IConfirmDialogListener
51 {
52 private:
53     /** Timer variable for animations. */
54     float                      m_timer;
55 
56     /** Finite state machine for the animations:
57         INIT:            Set up data structures.
58         RACE_RESULT:     The rows scroll into place.
59         OLD_GP_TABLE:    Scroll new table into place, sorted by previous
60                          GP ranks
61         INCREASE_POINTS: The overall points are added up
62         RESORT_TABLE:    Resort the table so that it is now sorted by
63                          GP points.
64         WAIT_TILL_END    Some delay to wait for end, after a period it
65                          wii automatically end. */
66     enum                       {RR_INIT,
67                                 RR_RACE_RESULT,
68                                 RR_OLD_GP_RESULTS,
69                                 RR_INCREASE_POINTS,
70                                 RR_RESORT_TABLE,
71                                 RR_WAIT_TILL_END}
72                                m_animation_state;
73 
74     class RowInfo
75     {
76     public:
77         /** Start time for each line of the animation. */
78         float            m_start_at;
79         /** Currenct X position. */
80         float            m_x_pos;
81         /** Currenct Y position. */
82         float            m_y_pos;
83         /** True if kart is a player kart. */
84         bool             m_is_player_kart;
85         /** The radius to use when sorting the entries. Positive values
86             will rotate downwards, negatives are upwards. */
87         float            m_radius;
88         /** The center point when sorting the entries. */
89         float            m_centre_point;
90         /** The names of all karts in the right order. */
91         core::stringw    m_kart_name;
92         /** Points earned in this race. */
93         float            m_new_points;
94         /** New overall points after this race. */
95         int              m_new_overall_points;
96         /** When updating the number of points in the display, this is the
97             currently displayed number of points. This is a floating point number
98             since it stores the increments during increasing the points. */
99         float            m_current_displayed_points;
100         /** The kart icons. */
101         video::ITexture *m_kart_icon;
102         /** The times of all karts in the right order. */
103         core::stringw    m_finish_time_string;
104     };   // Rowinfo
105 
106     /** The team icons. */
107 
108     std::vector<RowInfo>       m_all_row_infos;
109 
110     /** Time to wait till the next row starts to be animated. */
111     float                      m_time_between_rows;
112 
113     /** The time a single line scrolls into place. */
114     float                      m_time_single_scroll;
115 
116     /** Time to rotate the GP entries. */
117     float                      m_time_rotation;
118 
119     /** The time for inreasing the points by one during the
120         point update phase. */
121     float                      m_time_for_points;
122 
123     /** The overall time the first phase (scrolling) is displayed.
124         This includes a small waiting time at the end. */
125     float                      m_time_overall_scroll;
126 
127     /** Distance between each row of the race results */
128     unsigned int               m_distance_between_rows;
129 
130     /** Distance between each row of the highscore, race data, etc.*/
131     unsigned int               m_distance_between_meta_rows;
132 
133     /** The size of the kart icons. */
134     unsigned int               m_width_icon;
135 
136     /** Width of the kart name column. */
137     unsigned int               m_width_kart_name;
138 
139     /** Width of the finish time column. */
140     unsigned int               m_width_finish_time;
141 
142     /** Width of the new points columns. */
143     unsigned int               m_width_new_points;
144 
145     /** Position of left end of table (so that the whole
146         table is aligned. */
147     unsigned int               m_leftmost_column;
148 
149     /** Top-most pixel for first row. */
150     unsigned int               m_top;
151 
152     /** Size of space between columns. */
153     unsigned int               m_width_column_space;
154 
155     /** The overall width of the table. */
156     unsigned int               m_table_width;
157 
158     /** The font to use. */
159     gui::ScalableFont         *m_font;
160 
161     /** True if a GP position was changed. If not, the point increase
162      *  animation can be skipped. */
163     bool                       m_gp_position_was_changed;
164 
165     /** The previous monospace state of the font. */
166     //bool                       m_was_monospace;
167 
168     /** Sound effect at end of race. */
169     SFXBase                   *m_finish_sound;
170 
171     /** Music to be played after race ended. */
172     MusicInformation          *m_race_over_music;
173 
174     /** For highscores */
175     int m_highscore_rank;
176 
177     unsigned int m_width_all_points;
178 
179     int m_max_tracks;
180     int m_start_track;
181     int m_end_track;
182     int m_sshot_height;
183 
184     PtrVector<GUIEngine::Widget, HOLD>  m_gp_progress_widgets;
185 
186     static const int SSHOT_SEPARATION = 10;
187 
188     void displayOneEntry(unsigned int x, unsigned int y,
189                          unsigned int n, bool display_points);
190     void determineTableLayout();
191     void determineGPLayout();
192     void enableAllButtons();
193     void enableGPProgress();
194     void addGPProgressWidget(GUIEngine::Widget* widget);
195     void displayGPProgress();
196     void displayPostRaceInfo();
197     void displayCTFResults();
198     void displaySoccerResults();
199     void displayScreenShots();
200 
201     int  getFontHeight () const;
202 
203 public:
204 
205                  RaceResultGUI();
206     virtual void renderGlobal(float dt) OVERRIDE;
207 
208     /** \brief Implement callback from parent class GUIEngine::Screen */
loadedFromFile()209     virtual void loadedFromFile() OVERRIDE {};
210 
211     virtual void init() OVERRIDE;
212     virtual void tearDown() OVERRIDE;
213     virtual bool onEscapePressed() OVERRIDE;
214     virtual GUIEngine::EventPropagation
215                  filterActions(PlayerAction action, int deviceID, const unsigned int value,
216                                Input::InputType type, int playerId) OVERRIDE;
217     void eventCallback(GUIEngine::Widget* widget, const std::string& name,
218                        const int playerID) OVERRIDE;
219     friend class GUIEngine::ScreenSingleton<RaceResultGUI>;
220 
221     /** Should not be called anymore.  */
getMiniMapSize() const222     const core::dimension2du getMiniMapSize() const OVERRIDE
223                   { return core::dimension2du(0, 0); }
224 
225     /** No kart specific view needs to be rendered in the result gui. */
renderPlayerView(const Camera * camera,float dt)226     virtual void renderPlayerView(const Camera *camera, float dt) OVERRIDE {}
227 
228     virtual void onUpdate(float dt) OVERRIDE;
229     virtual void onDraw(float dt) OVERRIDE;
230 
231     /** No more messages need to be displayed, but the function might still be
232      *  called (e.g. 'new lap' message if the end controller is used for more
233      *  than one lap). So do nothing in this case.
234     */
addMessage(const irr::core::stringw & m,const AbstractKart * kart,float time,const video::SColor & color=video::SColor (255,255,0,255),bool important=true,bool big_font=false,bool outline=false)235     virtual void addMessage(const irr::core::stringw &m,
236                             const AbstractKart *kart,
237                             float time,
238                             const video::SColor &color=
239                                 video::SColor(255, 255, 0, 255),
240                             bool important=true,
241                             bool big_font=false,
242                             bool outline=false) OVERRIDE { }
243 
244     void nextPhase();
245 
246     /** Show no highscore */
247     void clearHighscores();
248 
249     /**
250       * To call if the user got a new highscore
251       * \param kart identity of the kart that made the highscore
252       * \param player identity of the player that made the highscore
253       * \param rank Highscore rank (first highscore, second highscore, etc.). This is not the race rank
254       * \param time Finish time in seconds
255       */
256     void setHighscore(int rank);
257 
258     virtual void onConfirm() OVERRIDE;
259     void cleanupGPProgress();
260 };   // RaceResultGUI
261 
262 #endif
263