Disable gravity when on flying platform.
[supertux.git] / src / player.cpp
index e8b4c2c..88b6761 100644 (file)
@@ -83,8 +83,6 @@ Player::~Player()
 void
 Player::init()
 {
-  Level* plevel = World::current()->get_level();
-
   holding_something = false;
 
   base.width = 32;
@@ -93,14 +91,17 @@ Player::init()
   size = SMALL;
   got_power = NONE_POWER;
 
-  base.x = plevel->start_pos_x;
-  base.y = plevel->start_pos_y;
+  base.x = 0;
+  base.y = 0;
   previous_base = old_base = base;
   dir = RIGHT;
   old_dir = dir;
   duck = false;
+  dead = false;
 
   dying   = DYING_NOT;
+  last_ground_y = 0;
+  fall_mode = ON_GROUND;
   jumping = false;
   can_jump = true;
   butt_jump = false;
@@ -179,6 +180,11 @@ Player::action(float elapsed_time)
 {
   bool jumped_in_solid = false;
 
+  if(dying && !dying_timer.check()) {
+    dead = true;
+    return;
+  }
+
   if (input.fire == UP)
     holding_something = false;
 
@@ -197,7 +203,7 @@ Player::action(float elapsed_time)
 
       collision_swept_object_map(&old_base, &base);
 
-      if (!invincible_timer.started()
+      if ((!invincible_timer.started() && !safe_timer.started())
           && (isspike(base.x, base.y) || isspike(base.x + base.width, base.y)
           ||  isspike(base.x, base.y + base.height)
           ||  isspike(base.x + base.width, base.y + base.height)))
@@ -415,6 +421,17 @@ Player::handle_horizontal_input()
 void
 Player::handle_vertical_input()
 {
+  // set fall mode...
+  if(on_ground()) {
+    fall_mode = ON_GROUND;
+    last_ground_y = base.y;
+  } else {
+    if(base.y > last_ground_y)
+      fall_mode = FALLING;
+    else if(fall_mode == ON_GROUND)
+      fall_mode = JUMPING;
+  }
+
   // Press jump key
   if(input.up == DOWN && can_jump && on_ground())
     {
@@ -596,7 +613,7 @@ Player::grabdistros()
 }
 
 void
-Player::draw(ViewPort& viewport, int layer)
+Player::draw(Camera& viewport, int layer)
 {
   PlayerSprite* sprite;
           
@@ -613,7 +630,7 @@ Player::draw(ViewPort& viewport, int layer)
 
   if(layer == LAYER_OBJECTS + 1) {
     // Draw arm overlay graphics when Tux is holding something
-    if ((holding_something && physic.get_velocity_y() == 0) || shooting_timer.check())
+    if ((holding_something && physic.get_velocity_y() == 0) || shooting_timer.check() && !duck)
     {
       if (dir == RIGHT)
         sprite->grab_right->draw(pos);
@@ -805,6 +822,7 @@ Player::collision(void* p_c_object, int c_object)
       pplatform_c = (FlyingPlatform*) p_c_object;
       
       base.y = pplatform_c->base.y - base.height;
+      physic.enable_gravity(false);
       break;
 
     default:
@@ -818,6 +836,9 @@ Player::collision(void* p_c_object, int c_object)
 void
 Player::kill(HurtMode mode)
 {
+  if(dying)
+    return;
+  
   play_sound(sounds[SND_HURT], SOUND_CENTER_SPEAKER);
 
   physic.set_velocity_x(0);
@@ -841,32 +862,12 @@ Player::kill(HurtMode mode)
       physic.enable_gravity(true);
       physic.set_acceleration(0, 0);
       physic.set_velocity(0, 7);
-      if(dying != DYING_SQUISHED)
       --player_status.lives;
       dying = DYING_SQUISHED;
+      dying_timer.start(3000);
     }
 }
 
-void
-Player::is_dying()
-{
-  remove_powerups();
-  dying = DYING_NOT;
-}
-
-bool Player::is_dead()
-{
-  float scroll_x =
-    World::current()->displaymanager.get_viewport().get_translation().x;
-  float scroll_y =
-    World::current()->displaymanager.get_viewport().get_translation().y;
-  if(base.y > screen->h + scroll_y || base.y > World::current()->get_level()->height*32 ||
-      base.x < scroll_x - AUTOSCROLL_DEAD_INTERVAL)  // can happen in auto-scrolling
-    return true;
-  else
-    return false;
-}
-
 /* Remove Tux's power ups */
 void
 Player::remove_powerups()
@@ -877,7 +878,15 @@ Player::remove_powerups()
 }
 
 void
-Player::check_bounds(ViewPort& viewport,
+Player::move(const Vector& vector)
+{
+  base.x = vector.x;
+  base.y = vector.y;
+  old_base = previous_base = base;
+}
+
+void
+Player::check_bounds(Camera& viewport,
     bool back_scrolling, bool hor_autoscroll)
 {
   /* Keep tux in bounds: */
@@ -891,10 +900,27 @@ Player::check_bounds(ViewPort& viewport,
   if (base.y > World::current()->get_level()->height * /*TILE_HEIGHT*/ 32)
     {
       kill(KILL);
+      return;
     }
 
-  if(base.x < viewport.get_translation().x && (!back_scrolling || hor_autoscroll))  // can happen if back scrolling is disabled
+  bool adjust = false;
+  // can happen if back scrolling is disabled
+  if(base.x < viewport.get_translation().x) {
     base.x = viewport.get_translation().x;
+    adjust = true;
+  }
+  if(base.x >= viewport.get_translation().x + screen->w - base.width) {
+    base.x = viewport.get_translation().x + screen->w - base.width;
+    adjust = true;
+  }
+
+  if(adjust) {
+    // squished now?
+    if(collision_object_map(base)) {
+      kill(KILL);
+      return;
+    }
+  }
 
   if(hor_autoscroll)
     {