1 /**
2  * @file handler_players.cc
3  * @brief players handler
4  * @date 2012-09-05
5  * @copyright 1991-2014 TLK Games
6  * @author Bruno Ethvignot
7  * @version $Revision: 24 $
8  */
9 /*
10  * copyright (c) 1991-2014 TLK Games all rights reserved
11  * $Id: handler_players.cc 24 2014-09-28 15:30:04Z bruno.ethvignot@gmail.com $
12  *
13  * TecnoballZ is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 3 of the License, or
16  * (at your option) any later version.
17  *
18  * TecnoballZ is distributed in the hope that it will be useful, but
19  * WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
26  * MA  02110-1301, USA.
27  */
28 #include "../include/handler_players.h"
29 #include "../include/controller_gems.h"
30 #include "../include/controller_sides_bricks.h"
31 #include "../include/controller_gems.h"
32 
33 Uint32 handler_players::max_of_players = 0;
34 handler_players *handler_players::first_player = NULL;
35 handler_players **handler_players::players_list = NULL;
36 
37 /*
38  * Create a player object
39  */
handler_players()40 handler_players::handler_players ()
41 {
42   object_init ();
43 
44   /*
45    * add a new player
46    */
47 
48   /* first player */
49   if (0 == max_of_players)
50     {
51       first_player = this;
52       next_player = this;
53       previous_player = this;
54     }
55   else
56     {
57       next_player = first_player;
58       handler_players *prev = first_player->get_previous_player ();
59       previous_player = prev;
60       first_player->set_previous_player (this);
61       prev->set_next_player (this);
62     }
63   max_of_players++;
64 
65   /*
66    * clear members members
67    */
68   player_num = max_of_players;
69   reset_members ();
70   /* clear name of the player */
71   Uint32 i;
72   for (i = 0; i < 6; i++)
73     {
74       player_name[i] = ' ';
75     }
76   player_name[i] = 0;
77 }
78 
79 /*
80  * Release a player object
81  */
~handler_players()82 handler_players::~handler_players ()
83 {
84   max_of_players--;
85   if (max_of_players > 0)
86     {
87       next_player->set_previous_player (previous_player);
88       previous_player->set_next_player (next_player);
89       if (first_player == this)
90         {
91           first_player = next_player;
92         }
93     }
94   else
95     {
96       first_player = NULL;
97     }
98   object_free ();
99 }
100 
101 /**
102  * Initialize a player object before a new game
103  * @param lifes number of lifes
104  * @param area area number (1 to 5)
105  * @param level level number in current area (1 to 12)
106  * @param money amount of money
107  * @param grdPt level_list of the guards
108  */
109 void
initialize(Uint32 lifes,Uint32 area,Uint32 level,Uint32 money,Uint32 grdPt)110 handler_players::initialize (Uint32 lifes, Uint32 area, Uint32 level,
111                              Uint32 money, Uint32 grdPt)
112 {
113   reset_members ();
114   number_of_lifes = lifes;
115   area_number = area;
116   level_number = level;
117   amount_of_money = money;
118   guardianPt = grdPt;
119 }
120 
121 /**
122  * Reset some members values
123  */
124 void
reset_members()125 handler_players::reset_members ()
126 {
127   /* clear the score value of the player */
128   score_value = 0;
129   bonus_life_counter = 0;
130   area_number = 1;
131   //area_number = 5; /*TEST*/
132   /* level number into the current area */
133   level_number = 1;
134   number_of_lifes = initial_num_of_lifes;
135   clear_shopping_cart ();
136   amount_of_money = 500;
137   for (Uint32 i = 0; i < controller_sides_bricks::MAX_OF_SIDES_BRICKS; i++)
138     {
139       map_left_wall[i] = true;
140       map_right_wall[i] = true;
141       map_top_wall[i] = true;
142     }
143   /* disable right, top and left paddles */
144   right_paddle_alive_counter = 0;
145   top_paddle_alive_counter = 0;
146   left_paddle_alive_counter = 0;
147   must_rebuild_walls = false;
148   less_bricks_count = 0;
149   /* width of the horizontal paddles
150    * and height of the vertical paddles */
151   paddle_length = 32 * resolution;
152   budget_prices = false;
153   guardianPt = 0;
154   clear_collected_gems ();
155 }
156 
157 /**
158  * Set the player name
159  * @param name the name of the player
160  */
161 void
set_name(const char * name)162 handler_players::set_name (const char *name)
163 {
164   for (Uint32 i = 0; i < PLAYER_NAME_LENGTH; i++)
165     {
166       player_name[i] = ' ';
167     }
168   for (Uint32 i = 0; i < PLAYER_NAME_LENGTH; i++)
169     {
170       char c = name[i];
171       if (0 == c)
172         {
173           return;
174         }
175       if (c >= 'a' && c <= 'z')
176         {
177           c = c - ('a' - 'A');
178         }
179       if ((c >= ' ' && c <= '!') ||
180           (c >= '-' && c <= '.') ||
181           (c >= '0' && c <= ':') || (c >= 'A' && c <= 'Z') || c == '\'')
182         {
183           player_name[i] = c;
184         }
185       else
186         {
187           player_name[i] = ' ';
188         }
189     }
190 }
191 
192 /**
193  * Return the current player name
194  * @return the current name the player
195  */
196 char *
get_name()197 handler_players::get_name ()
198 {
199   return &player_name[0];
200 }
201 
202 /**
203  * Return the area number
204  * @raturn area number, from 1 to 5
205  */
206 Uint32
get_area_number()207 handler_players::get_area_number ()
208 {
209   return area_number;
210 }
211 
212 /**
213  * Return the level number
214  * @return level number, from 1 to 13
215  */
216 Uint32
get_level_number()217 handler_players::get_level_number ()
218 {
219   return level_number;
220 }
221 
222 /**
223  * Return the number of life(s)
224  * @return the number of life(s)
225  */
226 Sint32
get_num_of_lifes()227 handler_players::get_num_of_lifes ()
228 {
229   return number_of_lifes;
230 }
231 
232 /**
233  * return the paddle's length
234  * @return the length of the paddle in pixels
235  */
236 Uint32
get_paddle_length()237 handler_players::get_paddle_length ()
238 {
239   return paddle_length;
240 }
241 
242 /**
243  * Initialize paddle's length
244  * @param length the length of the paddle in pixels
245  */
246 void
set_paddle_length(Uint32 length)247 handler_players::set_paddle_length (Uint32 length)
248 {
249   paddle_length = length;
250 }
251 
252 /**
253  * Return the current amount of money
254  * @return the amount of money
255  */
256 Uint32
get_money_amount()257 handler_players::get_money_amount ()
258 {
259   return amount_of_money;
260 }
261 
262 /**
263  * Decrease the amount of money
264  * @param value money amount
265  * @return true if the money amount could be descreased
266  */
267 bool
decrease_money_amount(Uint32 value)268 handler_players::decrease_money_amount (Uint32 value)
269 {
270   if (value > amount_of_money)
271     {
272       return false;
273     }
274   amount_of_money -= value;
275   return true;
276 }
277 
278 /**
279  * Increase the amount of money
280  * @param value money amount
281  */
282 void
increase_money_amount(Uint32 value)283 handler_players::increase_money_amount (Uint32 value)
284 {
285   amount_of_money += value;
286 }
287 
288 /**
289  * Increase the score
290  * @param value is the number of points to increase the score by
291  */
292 void
add_score(Uint32 value)293 handler_players::add_score (Uint32 value)
294 {
295   score_value += value;
296   bonus_life_counter += value;
297   if (bonus_life_counter > 25000)
298     {
299       add_life (1);
300       bonus_life_counter -= 25000;
301     }
302 }
303 
304 /**
305  * Clear the shopping cart
306  */
307 void
clear_shopping_cart()308 handler_players::clear_shopping_cart ()
309 {
310   Sint32 *cart = shopping_cart;
311   for (Uint32 i = 0; i < supervisor_shop::MAX_OF_CAPSULES_BOUGHT; i++)
312     {
313       *(cart++) = 0;
314     }
315   /* clear the number of items bought */
316   shopping_cart_items = 0;
317   /* end of the shopping cart */
318   *cart = -1;
319 }
320 
321 /**
322  * Return the list of items bought in th shop
323  * @return a pointer to the list of itemps bought in th shop
324  */
325 Sint32 *
get_shopping_cart()326 handler_players::get_shopping_cart ()
327 {
328   return shopping_cart;
329 }
330 
331 /**
332  * Return the number of itemp bought in th shop
333  * @return the number of items bought in th shop
334  */
335 Uint32
get_numof_items_in_shopping_cart()336 handler_players::get_numof_items_in_shopping_cart ()
337 {
338   return shopping_cart_items;
339 }
340 
341 /**
342  * Set the number of items bought
343  * @param count Number of items
344  */
345 void
set_numof_items_in_shopping_cart(Uint32 count)346 handler_players::set_numof_items_in_shopping_cart (Uint32 count)
347 {
348   shopping_cart_items = count;
349 }
350 
351 /**
352  * Clear the list of gems collected
353  */
354 void
clear_collected_gems()355 handler_players::clear_collected_gems ()
356 {
357   for (Uint32 i = 0; i < controller_gems::MAX_OF_GEMS; i++)
358     {
359       /* states of the 6 gems */
360       gems_state_list[i] = false;
361     }
362 }
363 
364 /**
365  * Verify if the 6 gemstones are collected
366  * @param gem_id last gem identifier collected
367  * @return true if all gems are collected, otherwise false
368  */
369 bool
are_collected_all_gems(Uint32 gemNu)370 handler_players::are_collected_all_gems (Uint32 gemNu)
371 {
372   gems_state_list[gemNu] = true;
373   for (Uint32 i = 0; i < controller_gems::MAX_OF_GEMS; i++)
374     {
375       if (!gems_state_list[i])
376         {
377           return false;
378         }
379     }
380   clear_collected_gems ();
381   return true;
382 }
383 
384 /**
385  * Return state of one of six gemstones
386  * @param gem_id gem identifier 0 to 5
387  * @return true if the gem is enabled, otherwise false
388  */
389 bool
is_collected_gem(Uint32 gem_id)390 handler_players::is_collected_gem (Uint32 gem_id)
391 {
392   return gems_state_list[gem_id];
393 }
394 
395 /**
396  * Get the alive counter of a paddle
397  * @param paddle_num paddle number RIGHT_PADDLE, TOP_PADDLE, or LEFT_PADDLE
398  * @return alive counter value, if 0 then the paddle is disabled
399  */
400 Uint32
get_paddle_alive_counter(Uint32 paddle_num)401 handler_players::get_paddle_alive_counter (Uint32 paddle_num)
402 {
403   switch (paddle_num)
404     {
405     case controller_paddles::RIGHT_PADDLE:
406       return right_paddle_alive_counter;
407       break;
408     case controller_paddles::TOP_PADDLE:
409       return top_paddle_alive_counter;
410       break;
411     default:
412       return left_paddle_alive_counter;
413       break;
414     }
415 }
416 
417 /**
418  * Set the alive counter of a paddle
419  * @param paddle_num paddle number RIGHT_PADDLE, TOP_PADDLE, or LEFT_PADDLE
420  * @param count value of the counter, if 0 then the paddle is disabled
421  */
422 void
set_paddle_alive_counter(Uint32 paddle_num,Uint32 counter)423 handler_players::set_paddle_alive_counter (Uint32 paddle_num, Uint32 counter)
424 {
425   switch (paddle_num)
426     {
427     case controller_paddles::RIGHT_PADDLE:
428       right_paddle_alive_counter = counter;
429       break;
430     case controller_paddles::TOP_PADDLE:
431       top_paddle_alive_counter = counter;
432       break;
433     case controller_paddles::LEFT_PADDLE:
434       left_paddle_alive_counter = counter;
435       break;
436     }
437 }
438 
439 /**
440  * Initialize less bricks option
441  * @param count number of bricks in less
442  */
443 void
set_less_bricks(Uint32 count)444 handler_players::set_less_bricks (Uint32 count)
445 {
446   less_bricks_count = count;
447 }
448 
449 /**
450  * Return number of bricks in less
451  * @return number of bricks in less
452  */
453 Uint32
get_less_bricks()454 handler_players::get_less_bricks ()
455 {
456   return less_bricks_count;
457 }
458 
459 /**
460  * Set the budget prices option
461  * @param enable true if enable the budget prices option, false otherwise
462  */
463 void
set_budget_prices(bool enable)464 handler_players::set_budget_prices (bool enable)
465 {
466   budget_prices = enable;
467 }
468 
469 /**
470  * Check if the budget prices option is enable
471  */
472 bool
is_budget_prices()473 handler_players::is_budget_prices ()
474 {
475   return budget_prices;
476 }
477 
478 /**
479  * Enable or disable the option which will rebuild the walls bricks
480  * on the next levels
481  * @param enable true if rebuilt the walls, false otherwise
482  */
483 void
set_rebuild_walls(bool enable)484 handler_players::set_rebuild_walls (bool enable)
485 {
486   must_rebuild_walls = enable;
487 }
488 
489 /**
490  * Check if the walls must be rebuilt.
491  * @return true if rebuilt the walls, false otherwise
492  */
493 bool
is_rebuild_walls()494 handler_players::is_rebuild_walls ()
495 {
496   return must_rebuild_walls;
497 }
498 
499 /**
500  * Return state of the left wall bricks
501  * @return a pointer to the map of the left wall
502  */
503 bool *
get_map_left()504 handler_players::get_map_left ()
505 {
506   return map_left_wall;
507 }
508 
509 /**
510  * Return state of the right wall bricks
511  * @return a pointer to the map of the right wall
512  */
513 bool *
get_map_right()514 handler_players::get_map_right ()
515 {
516   return map_right_wall;
517 }
518 
519 /**
520  * Return state of the top wall bricks
521  * @return a pointer to the map of the top wall
522  */
523 bool *
get_map_top()524 handler_players::get_map_top ()
525 {
526   return map_top_wall;
527 }
528 
529 //-----------------------------------------------------------------------------
530 // is the lastest level of tecnoballz?
531 //      output <= 1: end of game :-)
532 //-----------------------------------------------------------------------------
533 Sint32
zlastlevel()534 handler_players::zlastlevel ()
535 {
536   if (area_number >= 5 && level_number >= 13)
537     return 1;
538   else
539     return 0;
540 }
541 
542 //-----------------------------------------------------------------------------
543 // next level
544 //      output <= 1: end of game :-)
545 //-----------------------------------------------------------------------------
546 Sint32
next_level(Sint32 grdNx)547 handler_players::next_level (Sint32 grdNx)
548 {
549   Sint32 r = 0;
550   if (is_verbose)
551     printf
552       ("handler_players::next_level() area_number=%i, level_number=%i grdNx=%i guardianPt =%i\n",
553        area_number, level_number, grdNx, guardianPt);
554   if (area_number == 5 && level_number == 13)
555     {
556       area_number = 1;
557       level_number = 1;
558       r = 1;                    //end of game
559       guardianPt = 0;
560     }
561   else
562     {
563       if (area_number == 5 && level_number == 12)
564         {
565           level_number++;
566           guardianPt += grdNx;
567         }
568       else
569         {
570           level_number++;
571           if (level_number == 13)
572             {
573               area_number++;
574               level_number = 1;
575               guardianPt += grdNx;
576             }
577           if (level_number == 7)
578             guardianPt += grdNx;
579         }
580     }
581   if (is_verbose)
582     printf
583       ("handler_players::next_level() area_number=%i, level_number=%i,  guardianPt=%i\n",
584        area_number, level_number, guardianPt);
585   return r;
586 }
587 
588 /**
589  * Return the phase code
590  * @return the next phase code GUARDS_LEVEL or SHOP
591  */
592 Uint32
get_next_phase()593 handler_players::get_next_phase ()
594 {
595   /* MAIN_MENU is a very improbable case */
596   Uint32 phase = MAIN_MENU;
597   /* levels 6, 12 and the level 13 of the area 5 are guardians levels */
598   if (level_number == 6 || level_number == 12 || level_number == 13)
599     {
600       phase = GUARDS_LEVEL;
601     }
602   else
603     {
604       /* before a level, there is always the shop,
605        * except for the first level of the first area */
606       if (level_number > 0 && level_number < 12)
607         {
608           phase = SHOP;
609         }
610     }
611   return phase;
612 }
613 
614 /**
615  * Return previous player
616  * @return a pointer to the previous player object
617  */
618 handler_players *
get_previous_player()619 handler_players::get_previous_player ()
620 {
621   return previous_player;
622 }
623 
624 /**
625  * Set the next player
626  * @param player pointer to a object player
627  */
628 void
set_next_player(handler_players * player)629 handler_players::set_next_player (handler_players * player)
630 {
631   next_player = player;
632 }
633 
634 /**
635  * Get the previous player
636  * @param player pointer to a object player
637  */
638 void
set_previous_player(handler_players * player)639 handler_players::set_previous_player (handler_players * player)
640 {
641   previous_player = player;
642 }
643 
644 //-----------------------------------------------------------------------------
645 // get pointer to "level_list" of the guards
646 //-----------------------------------------------------------------------------
647 Sint32
getGuardPt()648 handler_players::getGuardPt ()
649 {
650   return guardianPt;
651 }
652 
653 //-----------------------------------------------------------------------------
654 // set pointer to "level_list" of the guards
655 //-----------------------------------------------------------------------------
656 void
setGuardPt(Sint32 grdPt)657 handler_players::setGuardPt (Sint32 grdPt)
658 {
659   guardianPt = grdPt;
660 }
661 
662 /**
663  * Add one or more lifes
664  * @param add number of lifes to add
665  */
666 void
add_life(Uint32 add)667 handler_players::add_life (Uint32 add)
668 {
669   number_of_lifes += add;
670 }
671 
672 /**
673  * Remove one or more lifes
674  * @param add number of lifes to remove
675  */
676 void
remove_life(Uint32 remove)677 handler_players::remove_life (Uint32 remove)
678 {
679   number_of_lifes -= remove;
680   if (number_of_lifes < 0)
681     {
682       number_of_lifes = 0;
683     }
684 }
685 
686 /**
687  * Remove all lifes, when the game over is forced
688  */
689 void
remove_all_lifes()690 handler_players::remove_all_lifes ()
691 {
692   number_of_lifes = 0;
693 }
694 
695 /*
696  * Statics methods
697  */
698 
699 /**
700  * Static method which return next player and determine the next phase
701  * @param player the current "handler_players" object
702  * @param next_phase pointer to "end_return"
703  * @param grdNx pointer to "level_list" of the guards (NULL by default)
704  * @return the new player object
705  */
706 handler_players *
get_next_player(handler_players * player,Uint32 * next_phase,Sint32 grdNx)707 handler_players::get_next_player (handler_players * player, Uint32 * next_phase,
708                              Sint32 grdNx)
709 {
710   Uint32 start = player->player_num;
711   Uint32 index = start;
712   if (current_phase != SHOP)
713     {
714       /* jump to the next level */
715       player->next_level (grdNx);
716     }
717 
718   /* process each player object */
719   for (Uint32 i = 0; i < max_of_players; i++)
720     {
721       if (++index > max_of_players)
722         {
723           index = 1;
724         }
725       handler_players *player = players_list[index - 1];
726       if (player->number_of_lifes <= 0)
727         {
728           continue;
729         }
730       /* get next phase: GUARDS_LEVEL or SHOP */
731       *next_phase = player->get_next_phase ();
732 
733       /* this player already went to the shop,
734        * he jump to the bricks level */
735       if (player->player_num <= start && *next_phase == SHOP
736           && current_phase == SHOP)
737         {
738           *next_phase = BRICKS_LEVEL;
739         }
740       /* multiplayers case: all players play the same level */
741       if (player->player_num > start && current_phase != SHOP
742           && *next_phase == SHOP)
743         {
744           *next_phase = BRICKS_LEVEL;
745         }
746       return player;
747     }
748   /* unlikely case  */
749   *next_phase = MAIN_MENU;
750   return players_list[0];
751 }
752 
753 /**
754  * Static method which initializes the maximum number of players
755  * @param numof maximum number of players, always 6
756  */
757 handler_players *
create_all_players(Uint32 numof)758 handler_players::create_all_players (Uint32 numof)
759 {
760 
761   try
762   {
763     players_list = new handler_players *[numof];
764   }
765   catch (std::bad_alloc &)
766   {
767     std::
768       cerr << "(!)handler_players::joueursADD() "
769       "not enough memory to allocate " <<
770       numof << " list elements!" << std::endl;
771     throw;
772   }
773 
774   /* create the players objects */
775   for (Uint32 i = 0; i < numof; i++)
776     {
777       players_list[i] = new handler_players ();
778     }
779   return first_player;
780 }
781 
782 /**
783  * Static method which releases all objects players
784  */
785 void
release_all_players()786 handler_players::release_all_players ()
787 {
788   for (Uint32 i = 0; i < max_of_players; i++)
789     {
790       delete first_player;
791     }
792   if (NULL != players_list)
793     {
794       delete[]players_list;
795       players_list = NULL;
796     }
797 }
798