1 /**
2  * @file supervisor_guards_level.cc
3  * @brief Guardians level supervisor
4  * @created 2003-01-09
5  * @date 2007-11-18
6  * @copyright 1991-2014 TLK Games
7  * @author Bruno Ethvignot
8  * @version $Revision: 24 $
9  */
10 /*
11  * copyright (c) 1991-2014 TLK Games all rights reserved
12  * $Id: supervisor_guards_level.cc 24 2014-09-28 15:30:04Z bruno.ethvignot@gmail.com $
13  *
14  * TecnoballZ is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 3 of the License, or
17  * (at your option) any later version.
18  *
19  * TecnoballZ is distributed in the hope that it will be useful, but
20  * WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
27  * MA  02110-1301, USA.
28  */
29 #include "../include/supervisor_guards_level.h"
30 #include "../include/handler_resources.h"
31 
32 /**
33  * Create the guards level supervisor
34  */
supervisor_guards_level()35 supervisor_guards_level::supervisor_guards_level ()
36 {
37   initialize ();
38   tiles_map = new tilesmap_scrolling ();
39   guards = controller_guardians::get_instance ();
40   paddles = controller_paddles::get_instance ();
41   font_game = controller_font_game::get_instance ();
42   explosions = controller_explosions::get_instance ();
43   bullets = controller_bullets::get_instance ();
44   money_capsules = controller_moneys::get_instance ();
45   power_up_capsules = controller_capsules::get_instance ();
46   balls = controller_balls::get_instance ();
47   viewfinders_paddles = controller_viewfinders::get_instance ();
48   player_indicators = controller_indicators::get_instance ();
49   gigablitz = controller_gigablitz::get_instance ();
50   game_over = controller_game_over::get_instance ();
51   metallic_spheres = new controller_spheres ();
52   popup_menu = new handler_popup_menu ();
53   sprite_playername = NULL;
54 }
55 
56 /**
57  * Release the guards level supervisor
58  */
~supervisor_guards_level()59 supervisor_guards_level::~supervisor_guards_level ()
60 {
61   if (NULL != sprite_playername)
62     {
63       delete sprite_playername;
64       sprite_playername = NULL;
65     }
66   delete popup_menu;
67   delete metallic_spheres;
68   delete game_over;
69   delete gigablitz;
70   delete player_indicators;
71   delete viewfinders_paddles;
72   delete balls;
73   delete power_up_capsules;
74   delete money_capsules;
75   delete bullets;
76   delete explosions;
77   delete font_game;
78   delete paddles;
79   delete guards;
80   delete tiles_map;
81   release ();
82 }
83 
84 /**
85  * Initializations of the guardian's level
86  */
87 void
first_init()88 supervisor_guards_level::first_init ()
89 {
90   game_screen->clear ();
91 #ifndef SOUNDISOFF
92   audio->play_music (handler_audio::MUSICGUARD);
93   audio->enable_sound ();
94 #endif
95   sprites->reset ();
96   next_phase = 0;
97   gameover_counter = 0;
98   count_next = 0;
99   is_victory_initialized = false;
100   is_victory = false;
101   area_number = current_player->get_area_number ();
102   level_number = current_player->get_level_number ();
103   Sint32 grdP = current_player->getGuardPt ();
104   if (is_verbose)
105   {
106     std::cout << ">supervisor_guards_level::first_init() " <<
107       "area_number: " << area_number << "; level_number: " <<
108       level_number << "; grdP: " << grdP << std::endl;
109   }
110 
111   /* gigablitz sprites are contained separately and in its own bitmap */
112   gigablitz->create_gigablitz_sprites ();
113 
114   /*
115    * sprites who are contained into the large bitmap
116    */
117   resources->load_sprites_bitmap ();
118   bullets->create_sprites_list ();
119   guards->create_guardians_list (grdP);
120   paddles->create_paddles_sprites ();
121   balls->create_sprites_list ();
122   money_capsules->create_sprites_list ();
123   power_up_capsules->create_sprites_list (6);
124   player_indicators->create_indicators_sprites ();
125   explosions->create_explosions_list ();
126   viewfinders_paddles->create_sprites_list ();
127   /* mobile characters at the end of the level */
128   font_game->create_sprites_list ();
129   game_over->create_sprites_list ();
130   metallic_spheres->create_sprites_list ();
131 
132   /* initialize escape menu */
133   popup_menu->first_init (sprites_bitmap);
134   resources->release_sprites_bitmap ();
135 
136  /* initialize controller of the big letters animated composing the word
137   * "game over"  */
138   game_over->first_init (32 * resolution);
139   init_level ();
140 
141   /* initialize background vertical scrolling */
142   tiles_map->initialize ();
143   display->lock_surfaces ();
144 
145   /*
146    * initialize the balls controller *
147    */
148   balls->init (
149     /* time delay before ball leaves paddle */
150     level_desc->ball_release_time,
151     0,
152     /* time delay before ball accelerates */
153     50 * 99,
154    /* time delay before titl available */
155    level_desc->tilt_delay,
156    /* ball speed 3 or 4 */
157    level_desc->starting_speed);
158   /* in the guardians levels, the balls are always forced to power 2 */
159   balls->set_power_2 ();
160 
161   money_capsules->initialize (3 + difficulty_level, player_indicators);
162 
163   /* initialize le capsules controller */
164   power_up_capsules->initialize (
165                           /* delay of appearance of a penalty capsule */
166                           level_desc->capsules_frequency * difficulty_level,
167                           /* list of penalties capsules */
168                           level_desc->capsules_list);
169 
170   /* initialize mobile characters at the end of the level */
171   font_game->initialize (level_number, 32 * resolution);
172   viewfinders_paddles->initialize ();
173   display->unlock_surfaces ();
174   keyboard->clear_command_keys ();
175   keyboard->set_grab_input (true);
176   sprite_display_scores *pOver = game_over->get_sprite_high_score ();
177   sprite_playername = pOver->string2bob (current_player->get_name ());
178   sprites->add (sprite_playername);
179   sprite_playername->enable ();
180   sprite_playername->
181     set_coordinates ((display->get_width () -
182                       sprite_playername->get_sprite_width ()) / 2, resolution);
183   sprite_playername->set_draw_method (sprite_object::COPY_FROM_BITMAP);
184   if (is_verbose)
185   {
186     std::cout << ">supervisor_guards_level::first_init() End!" << std::endl;
187   }
188 }
189 
190 /**
191  * The main loop of the guardians phase
192  */
193 Uint32
main_loop()194 supervisor_guards_level::main_loop ()
195 {
196   Sint32 popup_event = -1;
197 
198   /*
199    * gameover: the player has no more lives
200    */
201   if (current_player->get_num_of_lifes () <= 0)
202     {
203       if (gameover_counter > 0)
204         {
205 #ifndef SOUNDISOFF
206           audio->disable_sound ();
207 #endif
208           paddles->disable_all_paddles ();
209           power_up_capsules->disable_sprites ();
210           money_capsules->disable_sprites ();
211           guards->disable_sprites ();
212           explosions->disable_sprites ();
213           font_game->disable_sprites ();
214           gigablitz->disable_sprites ();
215           balls->disable_sprites ();
216           bullets->disable_sprites ();
217           if (is_victory && !is_victory_initialized)
218             {
219               metallic_spheres->initialize ();
220               tiles_map->switch_map (tilesmap_scrolling::TILES_COLOR_CONGRATULATIONS,
221                                      tilesmap_scrolling::MAP_CONGRATULATIONS);
222               scroll_speed = 1;
223               scroll_start_delay = 300;
224               is_victory_initialized = true;
225             }
226         }
227       gameover_counter++;
228       display->wait_frame ();
229 
230       if (scroll_start_delay > 0)
231         {
232           scroll_start_delay--;
233           tiles_map->scroll (0);
234         }
235       else
236         {
237           tiles_map->scroll (scroll_speed);
238         }
239 
240       display->lock_surfaces ();
241       viewfinders_paddles->run ();
242       player_indicators->display_money_and_lifes ();
243       font_game->move ();
244       sprites->draw ();
245       if (gameover_counter >= 1)
246         {
247           game_over->run (is_victory);
248           if (is_victory)
249             {
250               /* animate the metal spheres */
251               metallic_spheres->run ();
252             }
253         }
254       display->unlock_surfaces ();
255       display->window_update ();
256       if (keyboard->wait_key () && gameover_counter > 150)
257         {
258           current_player = handler_players::get_next_player (current_player,
259                                                     &next_phase,
260                                                     guards->
261                                                     get_max_of_sprites () +
262                                                     1);
263         }
264     }
265   else
266     {
267       /*
268        * game running !
269        */
270       display->wait_frame ();
271       if (!keyboard->command_is_pressed (handler_keyboard::COMMAND_KEY_PAUSE))
272         {
273           run_scroll ();
274           tiles_map->scroll (scroll_speed);
275           display->lock_surfaces ();
276           paddles->move_paddle ();
277           paddles->check_if_release_ball ();
278           balls->run_in_guardians_level ();
279           viewfinders_paddles->run ();
280           /* moving guards, and fire bullets and gigablitz */
281           guards->run ();
282           bullets->move ();
283           bullets->check_paddle_collisions ();
284           money_capsules->move_bottom ();
285           power_up_capsules->move_in_guardians_level ();
286           font_game->move ();
287           player_indicators->display_money_and_lifes ();
288           /* move Gigablitz and check collision with paddle */
289           gigablitz->run_in_guardians_level ();
290           explosions->play_animation ();
291           bullets->play_animation_loop ();
292 
293         }
294       else
295         {
296           bullets->play_animation_loop ();
297           tiles_map->scroll (0);
298           display->lock_surfaces ();
299         }
300 
301       /* display all sprites in the game offscreen */
302       sprites->draw ();
303       popup_event = popup_menu->run ();
304       display->unlock_surfaces ();
305       display->window_update ();
306     }
307 
308 
309   /* next level */
310   if (guards->is_guardians_destroyed () && !is_victory)
311     {
312       if (count_next > 0)
313         {
314           count_next++;
315           gigablitz->disable_sprites ();
316           balls->disable_sprites ();
317           bullets->disable_sprites ();
318           if (count_next > 500 || keyboard->wait_key())
319             {
320               is_victory = current_player->zlastlevel ();
321               if (is_victory)
322                 {
323                   current_player->remove_all_lifes ();
324                   count_next = 0;
325                 }
326               else
327                 {
328                   current_player = handler_players::get_next_player
329                     (current_player,
330                      &next_phase, guards->get_max_of_sprites () + 1);
331                 }
332             }
333         }
334       else
335         {
336           font_game->enable ();
337           gigablitz->disable_sprites ();
338           balls->disable_sprites ();
339           bullets->disable_sprites ();
340           count_next = 1;
341         }
342     }
343 
344   /* cheat mode: F2=destroyed the two guards / F3=guard 1 / F4=guard 2 */
345   cheat_keys ();
346 
347   /* escape key to quit the game! */
348   if (keyboard->command_is_pressed (handler_keyboard::QUIT_TECNOBALLZ) ||
349       popup_event == handler_popup_menu::QUIT_TECNOBALLZ)
350     {
351       next_phase = LEAVE_TECNOBALLZ;
352     }
353   if (keyboard->command_is_pressed (handler_keyboard::CAUSE_GAME_OVER) ||
354       popup_event == handler_popup_menu::CAUSE_GAME_OVER)
355     {
356       current_player->remove_all_lifes ();
357     }
358   if (keyboard->command_is_pressed (handler_keyboard::QUIT_TO_MAIN_MENU) ||
359       popup_event == handler_popup_menu::QUIT_TO_MAIN_MENU)
360     {
361       next_phase = MAIN_MENU;
362     }
363 
364 
365 
366   return next_phase;
367 }
368 
369 /**
370  * Determine the pointer on the guardians difficulty level
371  */
372 void
init_level()373 supervisor_guards_level::init_level ()
374 {
375   level_desc = ptLev_data->get_guardians_levels_params (area_number, level_number);
376   scroll_type = level_desc->scroll_id;
377   scroll_start_delay = level_desc->scroll_delay;
378   scroll_speed = 0;
379 }
380 
381 /**
382  * Handle speed et behavior of the background scrolling
383  */
384 void
run_scroll()385 supervisor_guards_level::run_scroll ()
386 {
387   if (scroll_start_delay > 0)
388     {
389       scroll_start_delay--;
390       scroll_speed = 0;
391       return;
392     }
393   sprite_bullet *bullet = bullets->get_last_bullet ();
394   sprite_ball *ball = balls->get_first_ball ();
395   scroll_speed = guards->get_scrolling_speed (scroll_type, scroll_speed, ball, bullet);
396 }
397 
398 /**
399  * Cheat mode: F2=destroyed the two guards / F3=guard 1 / F4=guard 2
400  */
401 void
cheat_keys()402 supervisor_guards_level::cheat_keys ()
403 {
404   if (!is_enabled_cheat_mode)
405     {
406       return;
407     }
408   if (!keyboard->key_is_pressed (SDLK_RSHIFT) ||
409       keyboard->key_is_pressed (SDLK_LSHIFT) ||
410       !keyboard->key_is_pressed (SDLK_RCTRL) ||
411       keyboard->key_is_pressed (SDLK_LCTRL) ||
412       keyboard->key_is_pressed (SDLK_RALT) ||
413       keyboard->key_is_pressed (SDLK_LALT))
414     {
415       return;
416     }
417 
418   if (keyboard->key_is_pressed (SDLK_F2))
419     {
420       guards->killguards ();
421     }
422   if (keyboard->key_is_pressed (SDLK_F3))
423     {
424       guards->killguards (1);
425     }
426   if (keyboard->key_is_pressed (SDLK_F4))
427     {
428       guards->killguards (2);
429     }
430 }
431 
432