1 /* --------------------------------------------------------------------
2 EXTREME TUXRACER
3
4 Copyright (C) 1999-2001 Jasmin F. Patry (Tuxracer)
5 Copyright (C) 2010 Extreme Tux Racer Team
6
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either version 2
10 of the License, or (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16 ---------------------------------------------------------------------*/
17
18 #ifdef HAVE_CONFIG_H
19 #include <etr_config.h>
20 #endif
21
22 #include "game_over.h"
23 #include "audio.h"
24 #include "ogl.h"
25 #include "view.h"
26 #include "course_render.h"
27 #include "env.h"
28 #include "hud.h"
29 #include "track_marks.h"
30 #include "particles.h"
31 #include "gui.h"
32 #include "font.h"
33 #include "spx.h"
34 #include "game_ctrl.h"
35 #include "translation.h"
36 #include "score.h"
37 #include "race_select.h"
38 #include "event.h"
39 #include "winsys.h"
40 #include "physics.h"
41 #include "tux.h"
42
43 CGameOver GameOver;
44
45 static CKeyframe *final_frame;
46 static int highscore_pos = MAX_SCORES;
47
QuitGameOver()48 void QuitGameOver() {
49 if (g_game.game_type == PRACTICING) {
50 State::manager.RequestEnterState(RaceSelect);
51 } else {
52 State::manager.RequestEnterState(Event);
53 }
54 }
55
Keyb(sf::Keyboard::Key key,bool release,int x,int y)56 void CGameOver::Keyb(sf::Keyboard::Key key, bool release, int x, int y) {
57 if (release) return;
58 if (key == sf::Keyboard::Enter || key == sf::Keyboard::Escape) QuitGameOver();
59 }
60
Mouse(int button,int state,int x,int y)61 void CGameOver::Mouse(int button, int state, int x, int y) {
62 QuitGameOver();
63 }
64
65
GameOverMessage(const CControl * ctrl)66 void GameOverMessage(const CControl *ctrl) {
67 int fwidth = 500;
68
69 int leftframe = (Winsys.resolution.width - fwidth) / 2;
70 int topframe = 80;
71
72 const sf::Color& backcol = colWhite;
73 static const sf::Color framecol(178, 178, 255);
74
75 if (param.use_papercut_font > 0) FT.SetSize(28);
76 else FT.SetSize(22);
77 if (g_game.raceaborted) {
78 DrawFrameX(leftframe, topframe, fwidth, 100, 4, backcol, framecol, 0.5f);
79 FT.SetColor(colDBlue);
80 FT.DrawString(CENTER, topframe+30, Trans.Text(25));
81 } else {
82 int firstMarker = leftframe + 60;
83 int secondMarker = leftframe + 310;
84 DrawFrameX(leftframe, topframe, fwidth, 210, 4, backcol, framecol, 0.5f);
85
86 if (param.use_papercut_font > 0) FT.SetSize(20);
87 else FT.SetSize(14);
88 if (g_game.race_result >= 0 || g_game.game_type != CUPRACING) FT.SetColor(colDBlue);
89 else FT.SetColor(colDRed);
90
91 sf::String line = Trans.Text(84) + ": ";
92 FT.DrawString(firstMarker, topframe + 15, line);
93 line = Int_StrN(g_game.score);
94 line += " pts";
95 FT.DrawString(secondMarker, topframe + 15, line);
96
97 line = Trans.Text(85) + ": ";
98 FT.DrawString(firstMarker, topframe + 40, line);
99 line = Int_StrN(g_game.herring);
100 if (g_game.game_type == CUPRACING) {
101 line += " (";
102 line += Int_StrN(g_game.race->herrings.x);
103 line += ')';
104 }
105 FT.DrawString(secondMarker, topframe + 40, line);
106
107 line = Trans.Text(86) + ": ";
108 FT.DrawString(firstMarker, topframe + 65, line);
109 line = Float_StrN(g_game.time, 2);
110 line += " s";
111 if (g_game.game_type == CUPRACING) {
112 line += " (";
113 line += Float_StrN(g_game.race->time.x, 2);
114 line += ')';
115 }
116 FT.DrawString(secondMarker, topframe + 65, line);
117
118 line = Trans.Text(87) + ": ";
119 FT.DrawString(firstMarker, topframe + 90, line);
120 line = Float_StrN(ctrl->way, 2);
121 line += " m";
122 FT.DrawString(secondMarker, topframe + 90, line);
123
124 line = Trans.Text(88) + ": ";
125 FT.DrawString(firstMarker, topframe + 115, line);
126 line = Float_StrN(ctrl->way / g_game.time * 3.6, 2);
127 line += " km/h";
128 FT.DrawString(secondMarker, topframe + 115, line);
129
130 if (param.use_papercut_font > 0) FT.SetSize(28);
131 else FT.SetSize(22);
132 if (g_game.game_type == CUPRACING) {
133 FT.DrawString(CENTER, topframe + 150, Trans.Text(22 + g_game.race_result)); // Text IDs 21 - 24; race_results is in [-1; 2]
134 } else {
135 if (highscore_pos < MAX_SCORES) {
136 line = Trans.Text(89) + ' ';
137 line += Int_StrN(highscore_pos + 1);
138 line += ' ' + Trans.Text(90);
139 FT.DrawString(CENTER, topframe+150, line);
140 }
141 }
142 }
143 }
144
145 // =========================================================================
Enter()146 void CGameOver::Enter() {
147 if (!g_game.raceaborted) highscore_pos = Score.CalcRaceResult();
148
149 if (g_game.game_type == CUPRACING) {
150 if (g_game.race_result >= 0) {
151 Music.PlayTheme(g_game.theme_id, MUS_WONRACE);
152 } else {
153 Music.PlayTheme(g_game.theme_id, MUS_LOSTRACE);
154 }
155 } else {
156 if (g_game.raceaborted) {
157 Music.PlayTheme(g_game.theme_id, MUS_LOSTRACE);
158 } else {
159 Music.PlayTheme(g_game.theme_id, MUS_WONRACE);
160 }
161 }
162
163
164 if (g_game.raceaborted || !g_game.use_keyframe) {
165 final_frame = nullptr;
166 } else {
167 if (g_game.game_type == CUPRACING) {
168 if (g_game.race_result < 0)
169 final_frame = g_game.character->GetKeyframe(LOSTRACE);
170 else final_frame = g_game.character->GetKeyframe(WONRACE);
171 } else final_frame = g_game.character->GetKeyframe(FINISH);
172
173 if (!g_game.raceaborted) {
174 const CControl *ctrl = g_game.player->ctrl;
175 final_frame->Init(ctrl->cpos, -0.18);
176 }
177 }
178 SetStationaryCamera(true);
179 }
180
181
Loop(float time_step)182 void CGameOver::Loop(float time_step) {
183 CControl *ctrl = g_game.player->ctrl;
184 int width = Winsys.resolution.width;
185 int height = Winsys.resolution.height;
186
187 ClearRenderContext();
188 Env.SetupFog();
189
190 update_view(ctrl, 0);
191
192 if (final_frame != nullptr) final_frame->Update(time_step);
193
194 SetupViewFrustum(ctrl);
195 Env.DrawSkybox(ctrl->viewpos);
196 Env.DrawFog();
197 Env.SetupLight();
198
199 RenderCourse();
200 DrawTrackmarks();
201 DrawTrees();
202
203 UpdateWind(time_step);
204 UpdateSnow(time_step, ctrl);
205 DrawSnow(ctrl);
206
207 g_game.character->shape->Draw();
208
209 {
210 ScopedRenderMode rm(GUI);
211 if (final_frame != nullptr) {
212 if (!final_frame->active) GameOverMessage(ctrl);
213 } else GameOverMessage(ctrl);
214 }
215 DrawHud(ctrl);
216 Reshape(width, height);
217 Winsys.SwapBuffers();
218 }
219