- added translation table for the old format
[supertux.git] / src / player.cpp
1 //
2 // C Implementation: player/tux
3 //
4 // Description:
5 //
6 //
7 // Author: Tobias Glaesser <tobi.web@gmx.de> & Bill Kendrick, (C) 2004
8 //
9 // Copyright: See COPYING file that comes with this distribution
10 //
11 //
12
13 #include "gameloop.h"
14 #include "globals.h"
15 #include "player.h"
16 #include "defines.h"
17 #include "scene.h"
18 #include "screen.h"
19
20 texture_type tux_life;
21 texture_type tux_right[3];
22 texture_type tux_left[3];
23 texture_type bigtux_right[3];
24 texture_type bigtux_left[3];
25 texture_type bigtux_right_jump;
26 texture_type bigtux_left_jump;
27 texture_type ducktux_right;
28 texture_type ducktux_left;
29 texture_type skidtux_right;
30 texture_type skidtux_left;
31 texture_type firetux_right[3];
32 texture_type firetux_left[3];
33 texture_type bigfiretux_right[3];
34 texture_type bigfiretux_left[3];
35 texture_type bigfiretux_right_jump;
36 texture_type bigfiretux_left_jump;
37 texture_type duckfiretux_right;
38 texture_type duckfiretux_left;
39 texture_type skidfiretux_right;
40 texture_type skidfiretux_left;
41 texture_type cape_right[2];
42 texture_type cape_left[2];
43 texture_type bigcape_right[2];
44 texture_type bigcape_left[2];
45
46 void player_input_init(player_input_type* pplayer_input)
47 {
48   pplayer_input->down = UP;
49   pplayer_input->fire = UP;
50   pplayer_input->left = UP;
51   pplayer_input->old_fire = UP;
52   pplayer_input->right = UP;
53   pplayer_input->up = UP;
54 }
55
56 void
57 Player::init()
58 {
59   base.width = 32;
60   base.height = 32;
61
62   size = SMALL;
63   got_coffee = false;
64
65   // FIXME: Make the start position configurable via the levelfile
66   base.x = 100;
67   base.y = 240;
68   
69   base.xm = 0;
70   base.ym = 0;
71   old_base = base;
72   dir = RIGHT;
73   duck = false;
74
75   dying   = DYING_NOT;
76   jumping = false;
77
78   frame_main = 0;
79   frame_ = 0;
80   lives = 3;
81   score = 0;
82   distros = 0;
83
84   player_input_init(&input);
85
86   keymap.jump  = SDLK_UP;
87   keymap.duck  = SDLK_DOWN;
88   keymap.left  = SDLK_LEFT;
89   keymap.right = SDLK_RIGHT;
90   keymap.fire  = SDLK_LCTRL;
91
92   timer_init(&invincible_timer,true);
93   timer_init(&skidding_timer,true);
94   timer_init(&safe_timer,true);
95   timer_init(&frame_timer,true);
96   physic_init(&hphysic);
97   physic_init(&vphysic);
98 }
99
100 int
101 Player::key_event(SDLKey key, int state)
102 {
103   if(key == keymap.right)
104     {
105       input.right = state;
106       return true;
107     }
108   else if(key == keymap.left)
109     {
110       input.left = state;
111       return true;
112     }
113   else if(key == keymap.jump)
114     {
115       input.up = state;
116       return true;
117     }
118   else if(key == keymap.duck)
119     {
120       input.down = state;
121       return true;
122     }
123   else if(key == keymap.fire)
124     {
125       input.fire = state;
126       return true;
127     }
128   else
129     return false;
130 }
131
132 void
133 Player::level_begin()
134 {
135   base.x  = 100;
136   base.y  = 240;
137   base.xm = 0;
138   base.ym = 0;
139   old_base = base;
140
141   player_input_init(&input);
142
143   timer_init(&invincible_timer,true);
144   timer_init(&skidding_timer,true);
145   timer_init(&safe_timer,true);
146   timer_init(&frame_timer,true);
147   physic_init(&hphysic);
148   physic_init(&vphysic);
149 }
150
151 void
152 Player::action()
153 {
154   bool jumped_in_solid = false;
155
156   /* --- HANDLE TUX! --- */
157
158   handle_input();
159
160   /* Move tux: */
161
162   previous_base = base;
163
164   base.x += base.xm * frame_ratio;
165   base.y += base.ym * frame_ratio;
166
167   collision_swept_object_map(&old_base,&base);
168
169   keep_in_bounds();
170
171   /* Land: */
172
173   if (!dying)
174     {
175
176
177       if( !on_ground())
178         {
179           if(under_solid())
180             {
181               physic_set_state(&vphysic,PH_VT);
182               physic_set_start_vy(&vphysic,0);
183               jumped_in_solid = true;
184             }
185           else
186             {
187               if(!physic_is_set(&vphysic))
188                 {
189                   physic_set_state(&vphysic,PH_VT);
190                   physic_set_start_vy(&vphysic,0);
191                 }
192             }
193           base.ym = physic_get_velocity(&vphysic);
194
195         }
196       else
197         {
198
199           /* Land: */
200
201           if (base.ym > 0)
202             {
203               base.y = (int)(((int)base.y / 32) * 32);
204               base.ym = 0;
205             }
206
207           physic_init(&vphysic);
208
209           /* Reset score multiplier (for multi-hits): */
210
211           score_multiplier = 1;
212         }
213
214       if(jumped_in_solid)
215         {
216           if (isbrick(base.x, base.y) ||
217               isfullbox(base.x, base.y))
218             {
219               trygrabdistro(base.x, base.y - 32,BOUNCE);
220               trybumpbadguy(base.x, base.y - 64);
221
222               if(size == BIG)
223                 trybreakbrick(base.x, base.y);
224
225               bumpbrick(base.x, base.y);
226               tryemptybox(base.x, base.y, RIGHT);
227             }
228
229           if (isbrick(base.x+ 31, base.y) ||
230               isfullbox(base.x+ 31, base.y))
231             {
232               trygrabdistro(base.x+ 31, base.y - 32,BOUNCE);
233               trybumpbadguy(base.x+ 31, base.y - 64);
234
235               if(size == BIG)
236                 trybreakbrick(base.x+ 31, base.y);
237
238               bumpbrick(base.x+ 31, base.y);
239               tryemptybox(base.x+ 31, base.y, LEFT);
240             }
241
242
243           if(size == SMALL)
244             {
245               /* Get a distro from a brick? */
246               if (shape(base.x, base.y) == 'x' ||
247                   shape(base.x, base.y) == 'y')
248                 {
249                   add_bouncy_distro((((int)base.x)
250                                      / 32) * 32,
251                                     ((int)base.y / 32) * 32);
252                   if (counting_distros == false)
253                     {
254                       counting_distros = true;
255                       distro_counter = 100;
256                     }
257
258                   if (distro_counter <= 0)
259                     level_change(&current_level,base.x,base.y - 1, TM_IA, 'a');
260                     
261                   play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
262                   score = score + SCORE_DISTRO;
263                   distros++;
264                 }
265               else if (shape(base.x+ 31, base.y) == 'x' ||
266                        shape(base.x+ 31, base.y) == 'y')
267                 {
268                   add_bouncy_distro((((int)base.x + 31)
269                                      / 32) * 32,
270                                     ((int)base.y / 32) * 32);
271                   if (counting_distros == false)
272                     {
273                       counting_distros = true;
274                       distro_counter = 100;
275                     }
276
277                   if (distro_counter <= 0)
278                     level_change(&current_level,base.x+ 31, base.y, TM_IA, 'a');
279
280                   play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
281                   score = score + SCORE_DISTRO;
282                   distros++;
283                 }
284             }
285         }
286
287       grabdistros();
288
289       if (jumped_in_solid)
290         {
291           ++base.y;
292           ++old_base.y;
293           if(on_ground())
294             {
295               /* Make sure jumping is off. */
296               jumping = false;
297             }
298         }
299
300     }
301
302   timer_check(&safe_timer);
303
304
305   /* ---- DONE HANDLING TUX! --- */
306
307   /* Handle invincibility timer: */
308
309
310   if (get_current_music() == HERRING_MUSIC && !timer_check(&invincible_timer))
311     {
312       /*
313          no, we are no more invincible
314          or we were not in invincible mode
315          but are we in hurry ?
316        */
317
318
319       if (timer_get_left(&time_left) < TIME_WARNING)
320         {
321           /* yes, we are in hurry
322              stop the herring_song, prepare to play the correct
323              fast level_song !
324            */
325           set_current_music(HURRYUP_MUSIC);
326         }
327       else
328         {
329           set_current_music(LEVEL_MUSIC);
330         }
331
332       /* start playing it */
333       play_current_music();
334     }
335
336   /* Handle skidding: */
337
338   timer_check(&skidding_timer);
339
340   /* End of level? */
341
342   if (base.x >= endpos && endpos != 0)
343     {
344       next_level = 1;
345     }
346
347 }
348
349 bool
350 Player::on_ground()
351 {
352   return ( issolid(base.x + base.width / 2, base.y + base.height) ||
353            issolid(base.x + 1, base.y + base.height) ||
354            issolid(base.x + base.width - 1, base.y + base.height)  );
355 }
356
357 bool
358 Player::under_solid()
359 {
360   return ( issolid(base.x + base.width / 2, base.y) ||
361            issolid(base.x + 1, base.y) ||
362            issolid(base.x + base.width - 1, base.y)  );
363 }
364
365 void
366 Player::handle_horizontal_input(int newdir)
367 {
368   if ((newdir ? (base.xm < -SKID_XM) : (base.xm > SKID_XM)) && !timer_started(&skidding_timer) &&
369       dir == !newdir && on_ground())
370     {
371       timer_start(&skidding_timer, SKID_TIME);
372
373       play_sound(sounds[SND_SKID], SOUND_CENTER_SPEAKER);
374
375     }
376   dir = newdir;
377
378
379   if ((newdir ? (base.xm < 0) : (base.xm > 0)) && !isice(base.x, base.y + base.height) &&
380       !timer_started(&skidding_timer))
381     {
382       base.xm = 0;
383     }
384
385   if (!duck)
386     {
387       if (dir == newdir)
388         {
389           /* Facing the direction we're jumping?  Go full-speed: */
390
391           if (input.fire == UP)
392             {
393               base.xm = base.xm + ( newdir ? WALK_SPEED : -WALK_SPEED) * frame_ratio;
394
395               if(newdir)
396                 {
397                   if (base.xm > MAX_WALK_XM)
398                     base.xm = MAX_WALK_XM;
399                 }
400               else
401                 {
402                   if (base.xm < -MAX_WALK_XM)
403                     base.xm = -MAX_WALK_XM;
404                 }
405             }
406           else if ( input.fire == DOWN)
407             {
408               base.xm = base.xm + ( newdir ? RUN_SPEED : -RUN_SPEED) * frame_ratio;
409
410               if(newdir)
411                 {
412                   if (base.xm > MAX_RUN_XM)
413                     base.xm = MAX_RUN_XM;
414                 }
415               else
416                 {
417                   if (base.xm < -MAX_RUN_XM)
418                     base.xm = -MAX_RUN_XM;
419                 }
420             }
421           else
422             {
423               /* Not facing the direction we're jumping?
424                  Go half-speed: */
425
426               base.xm = base.xm + ( newdir ? (WALK_SPEED / 2) : -(WALK_SPEED / 2)) * frame_ratio;
427
428               if(newdir)
429                 {
430                   if (base.xm > MAX_WALK_XM / 2)
431                     base.xm = MAX_WALK_XM / 2;
432                 }
433               else
434                 {
435                   if (base.xm < -MAX_WALK_XM / 2)
436                     base.xm = -MAX_WALK_XM / 2;
437                 }
438             }
439         }
440
441     }
442 }
443
444 void
445 Player::handle_vertical_input()
446 {
447   if(input.up == DOWN)
448     {
449       if (on_ground())
450         {
451           if(!physic_is_set(&vphysic))
452             {
453               physic_set_state(&vphysic,PH_VT);
454               physic_set_start_vy(&vphysic,5.5);
455               --base.y;
456               jumping = true;
457               if (size == SMALL)
458                 play_sound(sounds[SND_JUMP], SOUND_CENTER_SPEAKER);
459               else
460                 play_sound(sounds[SND_BIGJUMP], SOUND_CENTER_SPEAKER);
461             }
462         }
463     }
464   else if(input.up == UP && jumping)
465     {
466       if (on_ground())
467         {
468           physic_init(&vphysic);
469           jumping = false;
470         }
471       else
472         {
473           jumping = false;
474           if(physic_is_set(&vphysic))
475             {
476               if(physic_get_velocity(&vphysic) < 0.)
477                 {
478                   physic_set_state(&vphysic,PH_VT);
479                   physic_set_start_vy(&vphysic,0);
480                 }
481             }
482           else
483             {
484               if(!physic_is_set(&vphysic))
485                 {
486                   physic_set_state(&vphysic,PH_VT);
487                 }
488             }
489         }
490     }
491 }
492
493 void
494 Player::handle_input()
495 {
496   /* Handle key and joystick state: */
497   if(duck == false)
498     {
499       if (input.right == DOWN && input.left == UP)
500         {
501           handle_horizontal_input(RIGHT);
502         }
503       else if (input.left == DOWN && input.right == UP)
504         {
505           handle_horizontal_input(LEFT);
506         }
507       else
508         {
509           if(base.xm > 0)
510             {
511               base.xm = (int)(base.xm - frame_ratio);
512               if(base.xm < 0)
513                 base.xm = 0;
514             }
515           else if(base.xm < 0)
516             {
517               base.xm = (int)(base.xm + frame_ratio);
518               if(base.xm > 0)
519                 base.xm = 0;
520             }
521         }
522     }
523
524   /* Jump/jumping? */
525
526   if ( input.up == DOWN || (input.up == UP && jumping))
527     {
528       handle_vertical_input();
529     }
530
531   /* Shoot! */
532
533   if (input.fire == DOWN && input.old_fire == UP && got_coffee)
534     {
535       add_bullet(base.x, base.y, base.xm, dir);
536     }
537
538
539   /* Duck! */
540
541   if (input.down == DOWN)
542     {
543       if (size == BIG && duck != true)
544         {
545           duck = true;
546           base.height = 32;
547           base.y += 32;
548         }
549     }
550   else
551     {
552       if (size == BIG && duck)
553         {
554           /* Make sure we're not standing back up into a solid! */
555           base.height = 64;
556           base.y -= 32;
557
558           if (!collision_object_map(&base) /*issolid(base.x + 16, base.y - 16)*/)
559             {
560               duck = false;
561               base.height = 64;
562               old_base.y -= 32;
563               old_base.height = 64;
564             }
565           else
566             {
567               base.height = 32;
568               base.y += 32;
569             }
570         }
571       else
572         {
573           duck = false;
574         }
575     }
576
577   /* (Tux): */
578
579   if(!timer_check(&frame_timer))
580     {
581       timer_start(&frame_timer,25);
582       if (input.right == UP && input.left == UP)
583         {
584           frame_main = 1;
585           frame_ = 1;
586         }
587       else
588         {
589           if ((input.fire == DOWN && (global_frame_counter % 2) == 0) ||
590               (global_frame_counter % 4) == 0)
591             frame_main = (frame_main + 1) % 4;
592
593           frame_ = frame_main;
594
595           if (frame_ == 3)
596             frame_ = 1;
597         }
598     }
599
600 }
601
602 void
603 Player::grabdistros()
604 {
605   /* Grab distros: */
606   if (!dying)
607     {
608       trygrabdistro(base.x, base.y, NO_BOUNCE);
609       trygrabdistro(base.x+ 31, base.y, NO_BOUNCE);
610
611       trygrabdistro(base.x, base.y + base.height, NO_BOUNCE);
612       trygrabdistro(base.x+ 31, base.y + base.height, NO_BOUNCE);
613
614       if(size == BIG)
615         {
616           trygrabdistro(base.x, base.y + base.height / 2, NO_BOUNCE);
617           trygrabdistro(base.x+ 31, base.y + base.height / 2, NO_BOUNCE);
618         }
619
620     }
621
622   /* Enough distros for a One-up? */
623   if (distros >= DISTROS_LIFEUP)
624     {
625       distros = distros - DISTROS_LIFEUP;
626       if(lives < MAX_LIVES)
627         lives++;
628       /*We want to hear the sound even, if MAX_LIVES is reached*/
629       play_sound(sounds[SND_LIFEUP], SOUND_CENTER_SPEAKER);
630     }
631 }
632
633 void
634 Player::draw()
635 {
636   if (!timer_started(&safe_timer) || (global_frame_counter % 2) == 0)
637     {
638       if (size == SMALL)
639         {
640           if (timer_started(&invincible_timer))
641             {
642               /* Draw cape: */
643
644               if (dir == RIGHT)
645                 {
646                   texture_draw(&cape_right[global_frame_counter % 2],
647                                base.x- scroll_x, base.y);
648                 }
649               else
650                 {
651                   texture_draw(&cape_left[global_frame_counter % 2],
652                                base.x- scroll_x, base.y);
653                 }
654             }
655
656
657           if (!got_coffee)
658             {
659               if (dir == RIGHT)
660                 {
661                   texture_draw(&tux_right[frame_], base.x- scroll_x, base.y);
662                 }
663               else
664                 {
665                   texture_draw(&tux_left[frame_], base.x- scroll_x, base.y);
666                 }
667             }
668           else
669             {
670               /* Tux got coffee! */
671
672               if (dir == RIGHT)
673                 {
674                   texture_draw(&firetux_right[frame_], base.x- scroll_x, base.y);
675                 }
676               else
677                 {
678                   texture_draw(&firetux_left[frame_], base.x- scroll_x, base.y);
679                 }
680             }
681         }
682       else
683         {
684           if (timer_started(&invincible_timer))
685             {
686               /* Draw cape: */
687               if (dir == RIGHT)
688                 {
689                   texture_draw(&bigcape_right[global_frame_counter % 2],
690                                base.x- scroll_x - 8, base.y);
691                 }
692               else
693                 {
694                   texture_draw(&bigcape_left[global_frame_counter % 2],
695                                base.x-scroll_x - 8, base.y);
696                 }
697             }
698
699           if (!got_coffee)
700             {
701               if (!duck)
702                 {
703                   if (!timer_started(&skidding_timer))
704                     {
705                       if (!jumping || base.ym > 0)
706                         {
707                           if (dir == RIGHT)
708                             {
709                               texture_draw(&bigtux_right[frame_],
710                                            base.x- scroll_x - 8, base.y);
711                             }
712                           else
713                             {
714                               texture_draw(&bigtux_left[frame_],
715                                            base.x- scroll_x - 8, base.y);
716                             }
717                         }
718                       else
719                         {
720                           if (dir == RIGHT)
721                             {
722                               texture_draw(&bigtux_right_jump,
723                                            base.x- scroll_x - 8, base.y);
724                             }
725                           else
726                             {
727                               texture_draw(&bigtux_left_jump,
728                                            base.x- scroll_x - 8, base.y);
729                             }
730                         }
731                     }
732                   else
733                     {
734                       if (dir == RIGHT)
735                         {
736                           texture_draw(&skidtux_right,
737                                        base.x- scroll_x - 8, base.y);
738                         }
739                       else
740                         {
741                           texture_draw(&skidtux_left,
742                                        base.x- scroll_x - 8, base.y);
743                         }
744                     }
745                 }
746               else
747                 {
748                   if (dir == RIGHT)
749                     {
750                       texture_draw(&ducktux_right, base.x- scroll_x - 8, base.y - 16);
751                     }
752                   else
753                     {
754                       texture_draw(&ducktux_left, base.x- scroll_x - 8, base.y - 16);
755                     }
756                 }
757             }
758           else
759             {
760               /* Tux has coffee! */
761
762               if (!duck)
763                 {
764                   if (!timer_started(&skidding_timer))
765                     {
766                       if (!jumping || base.ym > 0)
767                         {
768                           if (dir == RIGHT)
769                             {
770                               texture_draw(&bigfiretux_right[frame_],
771                                            base.x- scroll_x - 8, base.y);
772                             }
773                           else
774                             {
775                               texture_draw(&bigfiretux_left[frame_],
776                                            base.x- scroll_x - 8, base.y);
777                             }
778                         }
779                       else
780                         {
781                           if (dir == RIGHT)
782                             {
783                               texture_draw(&bigfiretux_right_jump,
784                                            base.x- scroll_x - 8, base.y);
785                             }
786                           else
787                             {
788                               texture_draw(&bigfiretux_left_jump,
789                                            base.x- scroll_x - 8, base.y);
790                             }
791                         }
792                     }
793                   else
794                     {
795                       if (dir == RIGHT)
796                         {
797                           texture_draw(&skidfiretux_right,
798                                        base.x- scroll_x - 8, base.y);
799                         }
800                       else
801                         {
802                           texture_draw(&skidfiretux_left,
803                                        base.x- scroll_x - 8, base.y);
804                         }
805                     }
806                 }
807               else
808                 {
809                   if (dir == RIGHT)
810                     {
811                       texture_draw(&duckfiretux_right, base.x- scroll_x - 8, base.y - 16);
812                     }
813                   else
814                     {
815                       texture_draw(&duckfiretux_left, base.x- scroll_x - 8, base.y - 16);
816                     }
817                 }
818             }
819         }
820     }
821 }
822
823 void
824 Player::collision(void* p_c_object, int c_object)
825 {
826   BadGuy* pbad_c = NULL;
827
828   switch (c_object)
829     {
830     case CO_BADGUY:
831       pbad_c = (BadGuy*) p_c_object;
832       /* Hurt the player if he just touched it: */
833
834       if (!pbad_c->dying && !dying &&
835           !timer_started(&safe_timer) &&
836           pbad_c->mode != HELD)
837         {
838           if (pbad_c->mode == FLAT  && input.fire != DOWN)
839             {
840               /* Kick: */
841
842               pbad_c->mode = KICK;
843               play_sound(sounds[SND_KICK], SOUND_CENTER_SPEAKER);
844
845               if (base.x < pbad_c->base.x + (pbad_c->base.width/2))
846                 {
847                   pbad_c->dir = RIGHT;
848                   pbad_c->base.x = pbad_c->base.x + 16;
849                 }
850               else
851                 {
852                   pbad_c->dir = LEFT;
853                   pbad_c->base.x = pbad_c->base.x - 32;
854                 }
855
856               timer_start(&pbad_c->timer,5000);
857             }
858           else if (pbad_c->mode == FLAT && input.fire == DOWN)
859             {
860               pbad_c->mode = HELD;
861               pbad_c->base.y-=8;
862             }
863           else if (pbad_c->mode == KICK)
864             {
865               if (base.y < pbad_c->base.y - 16 &&
866                   timer_started(&pbad_c->timer))
867                 {
868                   /* Step on (stop being kicked) */
869
870                   pbad_c->mode = FLAT;
871                   play_sound(sounds[SND_STOMP], SOUND_CENTER_SPEAKER);
872                   timer_start(&pbad_c->timer, 10000);
873                 }
874               else
875                 {
876                   /* Hurt if you get hit by kicked laptop: */
877
878                   if (timer_started(&pbad_c->timer))
879                     {
880                       if (!timer_started(&invincible_timer))
881                         {
882                           kill(SHRINK);
883                         }
884                       else
885                         {
886                           pbad_c->dying = DYING_FALLING;
887                           play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
888                           add_score(pbad_c->base.x - scroll_x,
889                                     pbad_c->base.y,
890                                     25 * score_multiplier);
891                         }
892                     }
893                 }
894             }
895           else
896             {
897               if (!timer_started(&invincible_timer ))
898                 {
899                   kill(SHRINK);
900                 }
901               else
902                 {
903                   pbad_c->dying = DYING_FALLING;
904                   play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
905                   add_score(pbad_c->base.x - scroll_x,
906                             pbad_c->base.y,
907                             25 * score_multiplier);
908                 }
909             }
910           score_multiplier++;
911         }
912       break;
913     default:
914       break;
915     }
916
917 }
918
919 /* Kill Player! */
920
921 void
922 Player::kill(int mode)
923 {
924   base.ym = -5;
925
926   play_sound(sounds[SND_HURT], SOUND_CENTER_SPEAKER);
927
928   if (dir == RIGHT)
929     base.xm = -8;
930   else if (dir == LEFT)
931     base.xm = 8;
932
933   if (mode == SHRINK && size == BIG)
934     {
935       if (got_coffee)
936         got_coffee = false;
937
938       size = SMALL;
939       base.height = 32;
940
941       timer_start(&safe_timer,TUX_SAFE_TIME);
942     }
943   else
944     {
945       dying = DYING_SQUISHED;
946     }
947 }
948
949 void
950 Player::is_dying()
951 {
952   base.ym = base.ym + gravity;
953
954   /* He died :^( */
955
956   --lives;
957   remove_powerups();
958   dying = DYING_NOT;
959   
960   level_begin();
961
962 }
963
964 /* Remove Tux's power ups */
965 void
966 Player::remove_powerups()
967 {
968   got_coffee = false;
969   size = SMALL;
970   base.height = 32;
971 }
972
973 void
974 Player::keep_in_bounds()
975 {
976   /* Keep tux in bounds: */
977   if (base.x< 0)
978     base.x= 0;
979   else if(base.x< scroll_x)
980     base.x= scroll_x;
981   else if (base.x< 160 + scroll_x && scroll_x > 0 && debug_mode)
982     {
983       scroll_x = base.x- 160;
984       /*base.x+= 160;*/
985
986       if(scroll_x < 0)
987         scroll_x = 0;
988
989     }
990   else if (base.x> screen->w / 2 + scroll_x && scroll_x < ((current_level.width * 32) - screen->w))
991     {
992       /* Scroll the screen in past center: */
993
994       scroll_x = base.x- screen->w / 2;
995       /*base.x= 320 + scroll_x;*/
996
997       if (scroll_x > ((current_level.width * 32) - screen->w))
998         scroll_x = ((current_level.width * 32) - screen->w);
999     }
1000   else if (base.x> 608 + scroll_x)
1001     {
1002       /* ... unless there's no more to scroll! */
1003
1004       /*base.x= 608 + scroll_x;*/
1005     }
1006
1007   /* Keep in-bounds, vertically: */
1008
1009   if (base.y > screen->h)
1010     {
1011       kill(KILL);
1012     }
1013 }