Improved buttons. You can create new level-subsets via the leveleditor now. Better...
[supertux.git] / src / player.c
index 0b8fb61..8b567cb 100644 (file)
@@ -68,9 +68,10 @@ void player_init(player_type* pplayer)
   pplayer->keymap.right = SDLK_RIGHT;
   pplayer->keymap.fire = SDLK_LCTRL;
 
-  timer_init(&pplayer->invincible_timer);
-  timer_init(&pplayer->skidding_timer);
-  timer_init(&pplayer->safe_timer);
+  timer_init(&pplayer->invincible_timer,YES);
+  timer_init(&pplayer->skidding_timer,YES);
+  timer_init(&pplayer->safe_timer,YES);
+  timer_init(&pplayer->frame_timer,YES);
   physic_init(&pplayer->hphysic);
   physic_init(&pplayer->vphysic);
 }
@@ -120,9 +121,12 @@ void player_level_begin(player_type* pplayer)
   pplayer->input.right = UP;
   pplayer->input.up = UP;
 
-  timer_init(&pplayer->invincible_timer);
-  timer_init(&pplayer->skidding_timer);
-  timer_init(&pplayer->safe_timer);
+  timer_init(&pplayer->invincible_timer,YES);
+  timer_init(&pplayer->skidding_timer,YES);
+  timer_init(&pplayer->safe_timer,YES);
+  timer_init(&pplayer->frame_timer,YES);
+  physic_init(&pplayer->hphysic);
+  physic_init(&pplayer->vphysic);
 }
 
 void player_action(player_type* pplayer)
@@ -149,7 +153,7 @@ void player_action(player_type* pplayer)
         }
       else
         {*/
-      if(!issolid( pplayer->base.x + 16,  pplayer->base.y + pplayer->base.height))
+      if( /*!issolid( pplayer->base.x + 16,  pplayer->base.y + pplayer->base.height )*/ !player_on_ground(pplayer))
         {
           if(!physic_is_set(&pplayer->vphysic))
             {
@@ -164,89 +168,102 @@ void player_action(player_type* pplayer)
 
           if (pplayer->base.ym > 0)
             {
-              pplayer->base.y = (int)(pplayer->base.y / 32) * 32;
+              pplayer->base.y = (int)(((int)(pplayer->base.y +1) / 32) * 32);
               pplayer->base.ym = 0;
             }
           physic_init(&pplayer->vphysic);
         }
 
-      while(issolid( pplayer->base.x + 16,  pplayer->base.y + pplayer->base.height) && !issolid( pplayer->base.x + 16,  pplayer->base.y))
+      while(issolid( pplayer->base.x + 16,  pplayer->base.y + pplayer->base.height) && !issolid( pplayer->base.x + 16,  pplayer->base.y + 1))
         {
           --pplayer->base.y;
         }
-      while(issolid( pplayer->base.x + 16,  pplayer->base.y) && !issolid( pplayer->base.x + 16,  pplayer->base.y + pplayer->base.height))
+      while(issolid( pplayer->base.x + 16,  pplayer->base.y + 1) && !issolid( pplayer->base.x + 16,  pplayer->base.y + pplayer->base.height))
         {
           ++pplayer->base.y;
         }
-      while(issolid( pplayer->base.x - 1,  pplayer->base.y) || issolid( pplayer->base.x - 1,  pplayer->base.y+pplayer->base.height))
+      while(issolid( pplayer->base.x - 1,  pplayer->base.y + 1) || issolid( pplayer->base.x - 1,  pplayer->base.y+pplayer->base.height))
         {
           ++pplayer->base.x;
         }
-      while(issolid( pplayer->base.x + 32,  pplayer->base.y) || issolid( pplayer->base.x + 32,  pplayer->base.y+pplayer->base.height))
+      while(issolid( pplayer->base.x + 32,  pplayer->base.y + 1) || issolid( pplayer->base.x + 32,  pplayer->base.y+pplayer->base.height))
         {
           --pplayer->base.x;
         }
 
-      if (isbrick(pplayer->base.x, pplayer->base.y - 1) ||
-          isfullbox(pplayer->base.x, pplayer->base.y - 1))
+      if(pplayer->base.ym < 0)
         {
-          trygrabdistro(pplayer->base.x, pplayer->base.y - 32,BOUNCE);
-          trybumpbadguy(pplayer->base.x, pplayer->base.y - 64);
-          bumpbrick(pplayer->base.x, pplayer->base.y - 1);
-          tryemptybox(pplayer->base.x, pplayer->base.y - 1);
-        }
 
-      if (isbrick(pplayer->base.x+ 31, pplayer->base.y - 1) ||
-          isfullbox(pplayer->base.x+ 31, pplayer->base.y - 1))
-        {
-          trygrabdistro(pplayer->base.x+ 31, pplayer->base.y - 32,BOUNCE);
-          trybumpbadguy(pplayer->base.x+ 31, pplayer->base.y - 64);
-          bumpbrick(pplayer->base.x+ 31, pplayer->base.y - 1);
-          tryemptybox(pplayer->base.x+ 31, pplayer->base.y - 1);
-        }
+          if (isbrick(pplayer->base.x, pplayer->base.y) ||
+              isfullbox(pplayer->base.x, pplayer->base.y))
+            {
+              trygrabdistro(pplayer->base.x, pplayer->base.y - 32,BOUNCE);
+              trybumpbadguy(pplayer->base.x, pplayer->base.y - 64);
 
+              if(pplayer->size == BIG)
+                trybreakbrick(pplayer->base.x, pplayer->base.y);
 
-      /* Get a distro from a brick? */
+              bumpbrick(pplayer->base.x, pplayer->base.y);
+              tryemptybox(pplayer->base.x, pplayer->base.y);
+            }
 
-      if (shape(pplayer->base.x, pplayer->base.y - 1) == 'x' ||
-          shape(pplayer->base.x, pplayer->base.y - 1) == 'y')
-        {
-          add_bouncy_distro((((int)pplayer->base.x)
-                             / 32) * 32,
-                            ((int)pplayer->base.y - 1 / 32) * 32);
-DEBUG_MSG("should work");
-          if (counting_distros == NO)
+          if (isbrick(pplayer->base.x+ 31, pplayer->base.y) ||
+              isfullbox(pplayer->base.x+ 31, pplayer->base.y))
             {
-              counting_distros = YES;
-              distro_counter = 100;
+              trygrabdistro(pplayer->base.x+ 31, pplayer->base.y - 32,BOUNCE);
+              trybumpbadguy(pplayer->base.x+ 31, pplayer->base.y - 64);
+
+              if(pplayer->size == BIG)
+                trybreakbrick(pplayer->base.x+ 31, pplayer->base.y);
+
+              bumpbrick(pplayer->base.x+ 31, pplayer->base.y);
+              tryemptybox(pplayer->base.x+ 31, pplayer->base.y);
             }
 
-          if (distro_counter <= 0)
-            level_change(&current_level,pplayer->base.x,pplayer->base.y - 1, 'a');
 
-          play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
-          score = score + SCORE_DISTRO;
-          distros++;
-        }
-      else if (shape(pplayer->base.x+ 31, pplayer->base.y - 1) == 'x' ||
-               shape(pplayer->base.x+ 31, pplayer->base.y - 1) == 'y')
-        {
-          add_bouncy_distro((((int)pplayer->base.x + 31)
-                             / 32) * 32,
-                            ((int)pplayer->base.y - 1 / 32) * 32);
-DEBUG_MSG("+31?");
-          if (counting_distros == NO)
+          if(pplayer->size == SMALL)
             {
-              counting_distros = YES;
-              distro_counter = 100;
-            }
+              /* Get a distro from a brick? */
 
-          if (distro_counter <= 0)
-            level_change(&current_level,pplayer->base.x+ 31, pplayer->base.y - 1, 'a');
+              if (shape(pplayer->base.x, pplayer->base.y) == 'x' ||
+                  shape(pplayer->base.x, pplayer->base.y) == 'y')
+                {
+                  add_bouncy_distro((((int)pplayer->base.x)
+                                     / 32) * 32,
+                                    ((int)pplayer->base.y / 32) * 32);
+                  if (counting_distros == NO)
+                    {
+                      counting_distros = YES;
+                      distro_counter = 100;
+                    }
 
-          play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
-          score = score + SCORE_DISTRO;
-          distros++;
+                  if (distro_counter <= 0)
+                    level_change(&current_level,pplayer->base.x,pplayer->base.y - 1, 'a');
+
+                  play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
+                  score = score + SCORE_DISTRO;
+                  distros++;
+                }
+              else if (shape(pplayer->base.x+ 31, pplayer->base.y) == 'x' ||
+                       shape(pplayer->base.x+ 31, pplayer->base.y) == 'y')
+                {
+                  add_bouncy_distro((((int)pplayer->base.x + 31)
+                                     / 32) * 32,
+                                    ((int)pplayer->base.y / 32) * 32);
+                  if (counting_distros == NO)
+                    {
+                      counting_distros = YES;
+                      distro_counter = 100;
+                    }
+
+                  if (distro_counter <= 0)
+                    level_change(&current_level,pplayer->base.x+ 31, pplayer->base.y, 'a');
+
+                  play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
+                  score = score + SCORE_DISTRO;
+                  distros++;
+                }
+            }
         }
 
       player_grabdistros(pplayer);
@@ -305,7 +322,7 @@ DEBUG_MSG("+31?");
 
           /* Reset score multiplier (for multi-hits): */
 
-      if (pplayer->base.ym > 0)
+      if (pplayer->base.ym > 2)
         score_multiplier = 1;
 
 
@@ -457,8 +474,7 @@ DEBUG_MSG("+31?");
                   trybumpbadguy(pplayer->base.x+ 31,
                                 pplayer->base.y - 96);
 
-                  if (isfullbox(pplayer->base.x+
-          printf("%f",pplayer->base.ym); 31, pplayer->base.y - 32))
+                  if (isfullbox(pplayer->base.x+ 31, pplayer->base.y - 32))
                     {
                       bumpbrick(pplayer->base.x+ 31, pplayer->base.y - 32);
                     }
@@ -500,7 +516,7 @@ DEBUG_MSG("+31?");
           else
           {
           /* It's a brick and we're small, make the brick
-             bounce, and grab any distros above it: * /
+             bounce, and grab any distros above it: *  /
 
           if (isbrick(pplayer->base.x, pplayer->base.y) ||
               isfullbox(pplayer->base.x, pplayer->base.y))
@@ -626,7 +642,7 @@ DEBUG_MSG("+31?");
   }
 
 
-
+  */
   timer_check(&pplayer->safe_timer);
 
 
@@ -675,6 +691,20 @@ DEBUG_MSG("+31?");
 
 }
 
+int player_on_ground(player_type *pplayer)
+{
+  if( issolid(pplayer->base.x + pplayer->base.width / 2, pplayer->base.y + pplayer->base.height + 1) ||
+      issolid(pplayer->base.x + 1, pplayer->base.y + pplayer->base.height + 1) ||
+      issolid(pplayer->base.x + pplayer->base.width - 1, pplayer->base.y + pplayer->base.height + 1)  )
+    {
+      return YES;
+    }
+  else
+    {
+      return NO;
+    }
+}
+
 void player_handle_horizontal_input(player_type *pplayer, int dir)
 {
   if (pplayer->jumping == NO)
@@ -759,12 +789,13 @@ void player_handle_vertical_input(player_type *pplayer)
 {
   if(pplayer->input.up == DOWN)
     {
-      if (issolid(pplayer->base.x + 16, pplayer->base.y + pplayer->base.height + 1))
+      if (player_on_ground(pplayer))
         {
           if(!physic_is_set(&pplayer->vphysic))
             {
               physic_set_state(&pplayer->vphysic,PH_VT);
-              physic_set_start_vy(&pplayer->vphysic,5.2);
+              physic_set_start_vy(&pplayer->vphysic,5.5);
+              --pplayer->base.y;
               pplayer->jumping = YES;
               if (pplayer->size == SMALL)
                 play_sound(sounds[SND_JUMP], SOUND_CENTER_SPEAKER);
@@ -775,19 +806,6 @@ void player_handle_vertical_input(player_type *pplayer)
     }
   else if(pplayer->input.up == UP && pplayer->jumping == YES)
     {
-      /* Land: * /
-      DEBUG_MSG("Stop Jump");
-      pplayer->jumping = NO;
-
-      if (pplayer->base.ym > 0)
-        {
-          pplayer->base.y = (int)(pplayer->base.y / 32) * 32;
-          pplayer->base.ym = 0;
-        }
-      physic_init(&pplayer->vphysic);
-      }
-      else if(pplayer->input.up == UP)
-      {*/
       if (issolid(pplayer->base.x + 16, pplayer->base.y + pplayer->base.height + 1))
         {
           physic_init(&pplayer->vphysic);
@@ -796,11 +814,13 @@ void player_handle_vertical_input(player_type *pplayer)
       else
         {
           pplayer->jumping = NO;
-          physic_set_state(&pplayer->vphysic,PH_VT);
-          physic_set_start_vy(&pplayer->vphysic,0);
-          if(physic_is_set(&pplayer->vphysic) && pplayer->vphysic.start_vx != 0)
+          if(physic_is_set(&pplayer->vphysic))
             {
-              physic_set_start_vy(&pplayer->vphysic,0);
+              if(physic_get_velocity(&pplayer->vphysic) < 0.)
+                {
+                  physic_set_state(&pplayer->vphysic,PH_VT);
+                  physic_set_start_vy(&pplayer->vphysic,0);
+                }
             }
           else
             {
@@ -865,9 +885,17 @@ void player_input(player_type *pplayer)
   else
     {
       if(pplayer->base.xm > 0)
-        pplayer->base.xm = (int)(pplayer->base.xm - frame_ratio);
+        {
+          pplayer->base.xm = (int)(pplayer->base.xm - frame_ratio);
+          if(pplayer->base.xm < 0)
+            pplayer->base.xm = 0;
+        }
       else if(pplayer->base.xm < 0)
-        pplayer->base.xm = (int)(pplayer->base.xm + frame_ratio);
+        {
+          pplayer->base.xm = (int)(pplayer->base.xm + frame_ratio);
+          if(pplayer->base.xm > 0)
+            pplayer->base.xm = 0;
+        }
     }
 
   /* Jump/jumping? */
@@ -907,21 +935,25 @@ void player_input(player_type *pplayer)
 
   /* (Tux): */
 
-  if (pplayer->input.right == UP && pplayer->input.left == UP)
+  if(!timer_check(&pplayer->frame_timer))
     {
-      pplayer->frame_main = 1;
-      pplayer->frame = 1;
-    }
-  else
-    {
-      if ((pplayer->input.fire == DOWN && (frame % 2) == 0) ||
-          (frame % 4) == 0)
-        pplayer->frame_main = (pplayer->frame_main + 1) % 4;
+      timer_start(&pplayer->frame_timer,25);
+      if (pplayer->input.right == UP && pplayer->input.left == UP)
+        {
+          pplayer->frame_main = 1;
+          pplayer->frame = 1;
+        }
+      else
+        {
+          if ((pplayer->input.fire == DOWN && (frame % 2) == 0) ||
+              (frame % 4) == 0)
+            pplayer->frame_main = (pplayer->frame_main + 1) % 4;
 
-      pplayer->frame = pplayer->frame_main;
+          pplayer->frame = pplayer->frame_main;
 
-      if (pplayer->frame == 3)
-        pplayer->frame = 1;
+          if (pplayer->frame == 3)
+            pplayer->frame = 1;
+        }
     }
 
 }
@@ -1017,13 +1049,13 @@ void player_draw(player_type* pplayer)
               if (pplayer->dir == RIGHT)
                 {
                   texture_draw(&bigcape_right[frame % 2],
-                               pplayer->base.x- scroll_x, pplayer->base.y,
+                               pplayer->base.x- scroll_x - 8, pplayer->base.y,
                                NO_UPDATE);
                 }
               else
                 {
                   texture_draw(&bigcape_left[frame % 2],
-                               pplayer->base.x-scroll_x, pplayer->base.y,
+                               pplayer->base.x-scroll_x - 8, pplayer->base.y,
                                NO_UPDATE);
                 }
             }
@@ -1039,13 +1071,13 @@ void player_draw(player_type* pplayer)
                           if (pplayer->dir == RIGHT)
                             {
                               texture_draw(&bigtux_right[pplayer->frame],
-                                           pplayer->base.x- scroll_x, pplayer->base.y,
+                                           pplayer->base.x- scroll_x - 8, pplayer->base.y,
                                            NO_UPDATE);
                             }
                           else
                             {
                               texture_draw(&bigtux_left[pplayer->frame],
-                                           pplayer->base.x- scroll_x, pplayer->base.y,
+                                           pplayer->base.x- scroll_x - 8, pplayer->base.y,
                                            NO_UPDATE);
                             }
                         }
@@ -1054,13 +1086,13 @@ void player_draw(player_type* pplayer)
                           if (pplayer->dir == RIGHT)
                             {
                               texture_draw(&bigtux_right_jump,
-                                           pplayer->base.x- scroll_x, pplayer->base.y,
+                                           pplayer->base.x- scroll_x - 8, pplayer->base.y,
                                            NO_UPDATE);
                             }
                           else
                             {
                               texture_draw(&bigtux_left_jump,
-                                           pplayer->base.x- scroll_x, pplayer->base.y,
+                                           pplayer->base.x- scroll_x - 8, pplayer->base.y,
                                            NO_UPDATE);
                             }
                         }
@@ -1070,13 +1102,13 @@ void player_draw(player_type* pplayer)
                       if (pplayer->dir == RIGHT)
                         {
                           texture_draw(&skidtux_right,
-                                       pplayer->base.x- scroll_x, pplayer->base.y,
+                                       pplayer->base.x- scroll_x - 8, pplayer->base.y,
                                        NO_UPDATE);
                         }
                       else
                         {
                           texture_draw(&skidtux_left,
-                                       pplayer->base.x- scroll_x, pplayer->base.y,
+                                       pplayer->base.x- scroll_x - 8, pplayer->base.y,
                                        NO_UPDATE);
                         }
                     }
@@ -1085,12 +1117,12 @@ void player_draw(player_type* pplayer)
                 {
                   if (pplayer->dir == RIGHT)
                     {
-                      texture_draw(&ducktux_right, pplayer->base.x- scroll_x, pplayer->base.y,
+                      texture_draw(&ducktux_right, pplayer->base.x- scroll_x - 8, pplayer->base.y,
                                    NO_UPDATE);
                     }
                   else
                     {
-                      texture_draw(&ducktux_left, pplayer->base.x- scroll_x, pplayer->base.y,
+                      texture_draw(&ducktux_left, pplayer->base.x- scroll_x - 8, pplayer->base.y,
                                    NO_UPDATE);
                     }
                 }
@@ -1108,13 +1140,13 @@ void player_draw(player_type* pplayer)
                           if (pplayer->dir == RIGHT)
                             {
                               texture_draw(&bigfiretux_right[pplayer->frame],
-                                           pplayer->base.x- scroll_x, pplayer->base.y,
+                                           pplayer->base.x- scroll_x - 8, pplayer->base.y,
                                            NO_UPDATE);
                             }
                           else
                             {
                               texture_draw(&bigfiretux_left[pplayer->frame],
-                                           pplayer->base.x- scroll_x, pplayer->base.y,
+                                           pplayer->base.x- scroll_x - 8, pplayer->base.y,
                                            NO_UPDATE);
                             }
                         }
@@ -1123,13 +1155,13 @@ void player_draw(player_type* pplayer)
                           if (pplayer->dir == RIGHT)
                             {
                               texture_draw(&bigfiretux_right_jump,
-                                           pplayer->base.x- scroll_x, pplayer->base.y,
+                                           pplayer->base.x- scroll_x - 8, pplayer->base.y,
                                            NO_UPDATE);
                             }
                           else
                             {
                               texture_draw(&bigfiretux_left_jump,
-                                           pplayer->base.x- scroll_x, pplayer->base.y,
+                                           pplayer->base.x- scroll_x - 8, pplayer->base.y,
                                            NO_UPDATE);
                             }
                         }
@@ -1139,13 +1171,13 @@ void player_draw(player_type* pplayer)
                       if (pplayer->dir == RIGHT)
                         {
                           texture_draw(&skidfiretux_right,
-                                       pplayer->base.x- scroll_x, pplayer->base.y,
+                                       pplayer->base.x- scroll_x - 8, pplayer->base.y,
                                        NO_UPDATE);
                         }
                       else
                         {
                           texture_draw(&skidfiretux_left,
-                                       pplayer->base.x- scroll_x, pplayer->base.y,
+                                       pplayer->base.x- scroll_x - 8, pplayer->base.y,
                                        NO_UPDATE);
                         }
                     }
@@ -1154,12 +1186,12 @@ void player_draw(player_type* pplayer)
                 {
                   if (pplayer->dir == RIGHT)
                     {
-                      texture_draw(&duckfiretux_right, pplayer->base.x- scroll_x, pplayer->base.y,
+                      texture_draw(&duckfiretux_right, pplayer->base.x- scroll_x - 8, pplayer->base.y,
                                    NO_UPDATE);
                     }
                   else
                     {
-                      texture_draw(&duckfiretux_left, pplayer->base.x- scroll_x, pplayer->base.y,
+                      texture_draw(&duckfiretux_left, pplayer->base.x- scroll_x - 8, pplayer->base.y,
                                    NO_UPDATE);
                     }
                 }
@@ -1231,7 +1263,8 @@ void player_collision(player_type* pplayer, void* p_c_object, int c_object)
                       else
                         {
                           pbad_c->dying = FALLING;
-                          pbad_c->base.ym = -8;
+                          physic_set_state(&pplayer->vphysic,PH_VT);
+                          physic_set_start_vy(&pplayer->vphysic,-2.);
                           play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
                         }
                     }
@@ -1246,7 +1279,8 @@ void player_collision(player_type* pplayer, void* p_c_object, int c_object)
               else
                 {
                   pbad_c->dying = FALLING;
-                  pbad_c->base.ym = -8;
+                  physic_set_state(&pplayer->vphysic,PH_VT);
+                  physic_set_start_vy(&pplayer->vphysic,-2.);
                   play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
                 }
             }