1 //
2 // SuperTuxKart - a fun racing game with go-kart
3 // Copyright (C) 2006-2019 SuperTuxKart-Team
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 #include "challenges/story_mode_timer.hpp"
20
21 #include "config/player_manager.hpp"
22 #include "config/user_config.hpp"
23 #include "states_screens/dialogs/message_dialog.hpp"
24 #include "utils/string_utils.hpp"
25 #include "utils/time.hpp"
26 #include "utils/translation.hpp"
27
28 StoryModeTimer *story_mode_timer = 0;
29
StoryModeTimer()30 StoryModeTimer::StoryModeTimer()
31 {
32 m_player_tested = false;
33 m_valid_speedrun_ended = false;
34 m_story_mode_ended = false;
35 m_stored_speedrun_milliseconds = 0;
36 m_stored_story_mode_milliseconds = 0;
37 m_valid_speedrun_started = false;
38 m_story_mode_started = false;
39 m_speedrun_pause_active = false;
40 m_story_mode_pause_active = false;
41 m_loading_pause = false;
42 m_player_can_speedrun = false;
43 m_speedrun_milliseconds = 0;
44 m_story_mode_milliseconds = 0;
45 m_speedrun_total_pause_time = 0;
46 m_story_mode_total_pause_time = 0;
47 m_speedrun_start = 0;
48 m_speedrun_end = 0;
49 m_speedrun_pause_start = 0;
50
51 m_story_mode_start = 0;
52 m_story_mode_end = 0;
53 m_story_mode_pause_start = 0;
54
55 m_speedrun_total_pause_time = 0;
56 m_story_mode_total_pause_time = 0;
57
58 } // SpeedrunTimer
59
reset()60 void StoryModeTimer::reset()
61 {
62 PlayerProfile *player = PlayerManager::getCurrentPlayer();
63
64 // May happen when there is no player profile at all
65 if (player == NULL)
66 {
67 m_valid_speedrun_ended = false;
68 m_story_mode_ended = false;
69 m_stored_speedrun_milliseconds = 0;
70 m_stored_story_mode_milliseconds = 0;
71 }
72 else
73 {
74 m_valid_speedrun_ended = player->isSpeedrunFinished();
75 m_story_mode_ended = player->isFinished();
76 m_stored_speedrun_milliseconds = player->getSpeedrunTimer();
77 m_stored_story_mode_milliseconds = player->getStoryModeTimer();
78 }
79
80 m_valid_speedrun_started = false;
81 m_story_mode_started = false;
82 m_speedrun_pause_active = false;
83 m_story_mode_pause_active = false;
84 m_loading_pause = false;
85 m_player_can_speedrun = false;
86 m_speedrun_milliseconds = 0;
87 m_story_mode_milliseconds = 0;
88 m_speedrun_total_pause_time = 0;
89 m_story_mode_total_pause_time = 0;
90 m_speedrun_start = 0;
91 m_speedrun_end = 0;
92 m_speedrun_pause_start = 0;
93
94 m_story_mode_start = 0;
95 m_story_mode_end = 0;
96 m_story_mode_pause_start = 0;
97
98 m_speedrun_total_pause_time = 0;
99 m_story_mode_total_pause_time = 0;
100 }
101
startTimer()102 void StoryModeTimer::startTimer()
103 {
104 // The speedrun timer runs even if not enabled, as long
105 // as the conditions match, as the ovrehead is minimal
106 // and it thus persist if the user disable/reenable it.
107 if (!m_valid_speedrun_started && m_player_can_speedrun)
108 {
109 m_speedrun_start = StkTime::getMonoTimeMs();
110 m_valid_speedrun_started = true;
111 }
112
113 // The normal story mode timer runs along the speedrun timer
114 // so that if speedrun mode is disabled, its value exists
115 // and is correct
116 if (!m_story_mode_started)
117 {
118 m_story_mode_start = StkTime::getMonoTimeMs();
119 m_story_mode_end = m_story_mode_start;
120 m_story_mode_started = true;
121 }
122 }
123
stopTimer()124 void StoryModeTimer::stopTimer()
125 {
126 if (m_valid_speedrun_started)
127 {
128 m_speedrun_end = StkTime::getMonoTimeMs();
129 m_valid_speedrun_ended = true;
130 }
131
132 if (m_story_mode_started)
133 {
134 m_story_mode_end = StkTime::getMonoTimeMs();
135 m_story_mode_ended = true;
136 }
137 updateTimer();
138 }
139
140 /* Pauses the story mode and speedrun timer, if applicable.
141 * The speedrun timer is only paused on loading screens,
142 * while the story mode timer can also be paused when
143 * quitting the story mode. */
pauseTimer(bool loading)144 void StoryModeTimer::pauseTimer(bool loading)
145 {
146 // Don't change the pause time if there is no run,
147 // if it is finished, or if it is already set.
148
149 if ( m_valid_speedrun_started && !m_speedrun_pause_active &&
150 !m_valid_speedrun_ended && loading)
151 {
152 pauseSpeedrunTimer();
153 }
154 if ( m_story_mode_started && !m_story_mode_pause_active &&
155 !m_story_mode_ended)
156 {
157 pauseStoryModeTimer();
158 m_loading_pause = loading;
159 }
160 } // pauseTimer
161
pauseSpeedrunTimer()162 void StoryModeTimer::pauseSpeedrunTimer()
163 {
164 m_speedrun_pause_start = StkTime::getMonoTimeMs();
165 m_speedrun_pause_active = true;
166 }
167
pauseStoryModeTimer()168 void StoryModeTimer::pauseStoryModeTimer()
169 {
170 m_story_mode_pause_start = StkTime::getMonoTimeMs();
171 m_story_mode_pause_active = true;
172 }
173
174
unpauseTimer(bool loading)175 void StoryModeTimer::unpauseTimer(bool loading)
176 {
177 //Don't unpause if there is no run or no previous pause
178 if (m_valid_speedrun_started && m_speedrun_pause_active && !m_valid_speedrun_ended && loading)
179 {
180 unpauseSpeedrunTimer();
181 }
182 if (m_story_mode_started && m_story_mode_pause_active &&
183 !m_story_mode_ended && (m_loading_pause || ( !m_loading_pause && !loading)))
184 {
185 unpauseStoryModeTimer();
186 }
187 } //unpauseTimer
188
unpauseSpeedrunTimer()189 void StoryModeTimer::unpauseSpeedrunTimer()
190 {
191 uint64_t now = StkTime::getMonoTimeMs();
192 m_speedrun_total_pause_time += now - m_speedrun_pause_start;
193 m_speedrun_pause_active = false;
194
195 Log::verbose("StoryModeTimer", "Total speedrun pause time : %ims.", (int)m_speedrun_total_pause_time);
196 } // unpauseSpeedrunTimer
197
unpauseStoryModeTimer()198 void StoryModeTimer::unpauseStoryModeTimer()
199 {
200 uint64_t now = StkTime::getMonoTimeMs();
201 m_story_mode_total_pause_time += now - m_story_mode_pause_start;
202 m_story_mode_pause_active = false;
203 } // unpauseStoryModeTimer
204
updateTimer()205 void StoryModeTimer::updateTimer()
206 {
207 if (!m_player_tested)
208 {
209 reset();
210 testPlayerRun();
211 }
212
213 updateSpeedrunTimer();
214 updateStoryModeTimer();
215 } // updateTimer
216
updateSpeedrunTimer()217 void StoryModeTimer::updateSpeedrunTimer()
218 {
219 if (m_stored_speedrun_milliseconds < 0)
220 {
221 m_speedrun_milliseconds = -1;
222 return;
223 }
224
225 uint64_t elapsed_time;
226
227 if (m_valid_speedrun_ended)
228 {
229 elapsed_time = m_speedrun_end - m_speedrun_start - m_speedrun_total_pause_time;
230 }
231 else
232 {
233 uint64_t now = StkTime::getMonoTimeMs();
234 elapsed_time = now - m_speedrun_start - m_speedrun_total_pause_time;
235 }
236
237 m_speedrun_milliseconds = m_stored_speedrun_milliseconds + elapsed_time;
238 }
239
updateStoryModeTimer()240 void StoryModeTimer::updateStoryModeTimer()
241 {
242 if (m_stored_story_mode_milliseconds < 0)
243 {
244 m_story_mode_milliseconds = -1;
245 return;
246 }
247
248 uint64_t elapsed_time;
249
250 if (m_story_mode_ended)
251 {
252 elapsed_time = m_story_mode_end - m_story_mode_start - m_story_mode_total_pause_time;
253 }
254 else
255 {
256 uint64_t now = StkTime::getMonoTimeMs();
257 elapsed_time = now - m_story_mode_start - m_story_mode_total_pause_time;
258 }
259 m_story_mode_milliseconds = m_stored_story_mode_milliseconds + elapsed_time;
260 }
261
262 //Check if the current player has already entered story mode or not
testPlayerRun()263 void StoryModeTimer::testPlayerRun()
264 {
265 PlayerProfile *player = PlayerManager::getCurrentPlayer();
266
267 // May happen when there is no player profile at all
268 // Will be called again until a player profile is created
269 if (player == NULL)
270 return;
271
272 if (player->isFirstTime())
273 {
274 m_player_can_speedrun = true;
275 }
276
277
278 if(!m_player_can_speedrun && UserConfigParams::m_speedrun_mode)
279 {
280 UserConfigParams::m_speedrun_mode = false;
281 new MessageDialog(_("Speedrun mode disabled. It can only be enabled if the game"
282 " has not been closed since the launch of the story mode.\n\n"
283 "Closing the game before the story mode's"
284 " completion invalidates the timer.\n\n"
285 "To use the speedrun mode, please use a new profile."),
286 MessageDialog::MESSAGE_DIALOG_OK,
287 NULL, false, false, 0.6f, 0.7f);
288 }
289
290 m_player_tested = true;
291 }
292
293 /* When the active player changes, resets and reload timer data */
playerHasChanged()294 void StoryModeTimer::playerHasChanged()
295 {
296 m_player_tested = false;
297 } // playerHasChanged
298
getTimerString()299 std::string StoryModeTimer::getTimerString()
300 {
301 if (UserConfigParams::m_speedrun_mode && !m_valid_speedrun_started && !m_valid_speedrun_ended)
302 {
303 return StringUtils::timeToString(/*time in seconds*/ 0,
304 /*precision*/ 3, true, /* display hours*/ true);
305 }
306
307 if (UserConfigParams::m_speedrun_mode)
308 return StringUtils::timeToString(/*time in seconds*/ m_speedrun_milliseconds/1000.0f,
309 /*precision*/ 3, true, /* display hours*/ true);
310 else
311 return StringUtils::timeToString(/*time in seconds*/ m_story_mode_milliseconds/1000.0f,
312 /*precision*/ 0, true, /* display hours*/ true);
313 } // getStoryModeTimerString
314
315 /* EOF */
316