Each module now includes its own header first. Removed sstream.h and the definition...
[crack-attack.git] / src / CelebrationManager.cxx
blob77395cf3318fe1223a91c129f2a821f5285c7059
1 /*
2 * CelebrationManager.cxx
3 * Daniel Nelson - 10/30/0
5 * Copyright (C) 2000 Daniel Nelson
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.
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.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 * Daniel Nelson - aluminumangel.org
22 * 174 W. 18th Ave.
23 * Columbus, OH 43210
25 * Handles the celebration after a game.
28 #include "CelebrationManager.h"
30 #include "Game.h"
31 #include "MetaState.h"
32 #include "Displayer.h"
33 #include "SparkleManager.h"
34 #include "MessageManager.h"
35 #include "WinRecord.h"
36 #include "Random.h"
37 #include "Score.h"
38 #ifdef AUDIO_ENABLED
39 #include "Music.h"
40 #endif
43 bool CelebrationManager::draw_game;
44 GLfloat CelebrationManager::light_level;
45 int CelebrationManager::spark_rate[DC_CSPARK_SOURCE_NUMBER];
46 int CelebrationManager::spark_color[DC_CSPARK_SOURCE_NUMBER];
48 float CelebrationManager::win_alpha;
49 float CelebrationManager::win_scale;
50 int CelebrationManager::win_flash1;
51 int CelebrationManager::win_flash2;
53 float CelebrationManager::loss_height;
54 float CelebrationManager::loss_velocity;
55 bool CelebrationManager::loss_rescale;
56 int CelebrationManager::loss_bounce_count;
58 void CelebrationManager::gameFinish ( )
60 draw_game = true;
61 light_level = 1.0f;
63 #ifdef AUDIO_ENABLED
64 Music::fadeout( 1000 );
65 #endif
67 MessageManager::mode = MM_CELEBRATION;
69 if (WinRecord::won) {
70 win_alpha = 0.0f;
71 win_scale = DC_STARTING_WIN_SCALE;
72 MessageManager::readyMessage(MS_WINNER);
74 } else {
75 loss_height = DC_STARTING_LOSS_HEIGHT;
76 loss_velocity = 0.0f;
77 loss_bounce_count = DC_STARTING_BOUNCE_COUNT;
79 if (WinRecord::isMatchFinished()) {
80 MessageManager::readyMessage(MS_GAME_OVER);
81 loss_rescale = true;
83 } else {
84 MessageManager::readyMessage(MS_LOSER);
85 loss_rescale = false;
90 void CelebrationManager::celebrationFinish ( )
92 draw_game = false;
94 MessageManager::mode = MM_NORMAL;
95 MessageManager::freeMessage();
98 void CelebrationManager::timeStep ( )
100 if (WinRecord::current_game == -1) return;
102 // fade out the game
103 if (Game::time_step < DC_CELEBRATION_FADE_TIME)
104 light_level = (DC_CELEBRATION_FADE_TIME
105 - Game::time_step) * (1.0f / (float) DC_CELEBRATION_FADE_TIME);
107 else if (Game::time_step == DC_CELEBRATION_FADE_TIME)
108 light_level = 0.0f;
110 // signal that the user is now allowed to end the celebration
111 else if (Game::time_step == DC_CELEBRATION_TIME)
112 MetaState::celebrationComplete();
114 // draw the game until the fade out is complete and no light motes exist
115 if (draw_game && !(Game::time_step < DC_CELEBRATION_FADE_TIME
116 || SparkleManager::mote_count > 0))
117 draw_game = false;
119 // handle the message behavior
121 // if we won
122 if (WinRecord::won) {
124 // fade in
125 if (Game::time_step < DC_WIN_FADE_TIME) {
126 win_alpha += 1.0f / (float) DC_WIN_FADE_TIME;
127 win_scale -= (DC_STARTING_WIN_SCALE - 1.0f) / (float) DC_WIN_FADE_TIME;
129 // reach static state
130 } else if (Game::time_step == DC_WIN_FADE_TIME) {
131 win_alpha = 1.0f;
132 win_scale = 1.0f;
133 win_flash1 = DC_WIN_FLASH_1_TIME;
134 win_flash2 = DC_WIN_FLASH_2_TIME;
136 spark_rate[DC_CSPARK_SOURCE_NUMBER - 1] = DC_CSPARK_FULL_RATE;
137 spark_color[DC_CSPARK_SOURCE_NUMBER - 1]
138 = Random::number(DC_CSPARK_COLOR_NUMBER);
139 for (int n = DC_CSPARK_SOURCE_NUMBER - 1; n--; ) {
140 spark_rate[n] = DC_CSPARK_STARTING_RATE;
141 spark_color[n] = Random::number(DC_CSPARK_COLOR_NUMBER);
143 #ifdef AUDIO_ENABLED
144 Music::play_youwin();
145 #endif
147 } else {
149 // flash...
151 if (win_flash1)
152 win_flash1--;
153 if (Random::chanceIn(DC_WIN_FLASH_1_CHANCE_IN))
154 if (win_flash1) {
155 if (win_flash1 < DC_WIN_FLASH_1_TIME / 2)
156 win_flash1 = (DC_WIN_FLASH_1_TIME / 2) - win_flash1;
157 } else
158 win_flash1 = DC_WIN_FLASH_1_TIME;
160 if (win_flash2)
161 win_flash2--;
162 if (Random::chanceIn(DC_WIN_FLASH_2_CHANCE_IN))
163 if (win_flash2) {
164 if (win_flash2 < DC_WIN_FLASH_2_TIME / 2)
165 win_flash2 = (DC_WIN_FLASH_2_TIME / 2) - win_flash2;
166 } else
167 win_flash2 = DC_WIN_FLASH_2_TIME;
169 // and, if you've been really good, spark
170 if (WinRecord::isMatchFinished()
171 && (!(MetaState::mode & CM_SOLO) ||
172 Score::topRank() || (MetaState::mode & CM_AI_HARD))) {
174 // this algorithm is supposed to cause the sparks to be created in
175 // spurts, sort of like a sputtering firework
177 for (int n = DC_CSPARK_SOURCE_NUMBER; n--; ) {
178 if (spark_rate[n] > DC_CSPARK_LOW_RATE)
179 spark_rate[n] -= DC_CSPARK_QUICK_RATE_DROP;
180 else if (spark_rate[n] > 0)
181 spark_rate[n]--;
183 if (Random::chanceIn(DC_CSPARK_BOOST_CHANCE_IN)) {
184 spark_rate[n] += DC_CSPARK_RATE_BOOST;
185 if (Random::chanceIn(DC_CSPARK_COLOR_CHANGE_CHANCE_IN))
186 spark_color[n] = Random::number(DC_CSPARK_COLOR_NUMBER);
189 if (Random::number(DC_CSPARK_FULL_RATE) < spark_rate[n])
190 SparkleManager::createCelebrationSpark(n, spark_color[n]);
195 // if we lost
196 } else {
198 // drop the sign
200 if (loss_bounce_count != DC_FINAL_BOUNCE_COUNT - 1) {
202 loss_height += loss_velocity;
203 loss_velocity += -DC_LOSS_GRAVITY - DC_LOSS_DRAG * loss_velocity;
205 // if we've hit bottom
206 if (loss_height < 0.0f) {
208 // if it's the last bounce
209 if (loss_bounce_count == DC_FINAL_BOUNCE_COUNT) {
210 loss_bounce_count--;
211 loss_velocity = 0.0f;
212 loss_height = 0.0f;
213 #ifdef AUDIO_ENABLED
214 Music::play_gameover();
215 #endif
216 // Not sure if this line should be here. It seems to break up
217 // many other parts of the program. Doing this allows any button
218 // to cause the game to return to the UI after the game-over
219 // sign has finished bouncing. If you find any problems with this
220 // line, remove it immediately.
221 //MetaState::state = MS_GAME_OVER_ANY_KEY_WAIT;
223 // otherwise, bounce
224 } else {
226 // near the final bounce, reduce the elasticity
227 if (loss_velocity > -DC_LOSS_MIN_VELOCITY) {
228 loss_bounce_count--;
229 loss_velocity = -DC_LOSS_END_BOUNCE_ELASTICITY
230 * loss_bounce_count * loss_velocity;
231 loss_height = -loss_height;
233 } else {
234 loss_height = -loss_height;
235 loss_velocity = -DC_LOSS_BOUNCE_ELASTICITY * loss_velocity;