Butt-jump stops gliding
[supertux.git] / src / object / player.cpp
index e50588e..a6aeed7 100644 (file)
@@ -42,6 +42,7 @@
 namespace {
 static const float BUTTJUMP_MIN_VELOCITY_Y = 400.0f;
 static const float SHOOTING_TIME = .150f;
+static const float GLIDE_TIME_PER_FLOWER = 0.5f;
 
 /** number of idle stages, including standing */
 static const unsigned int IDLE_STAGE_COUNT = 5;
@@ -72,10 +73,14 @@ static const float SKID_TIME = .3f;
 static const float MAX_WALK_XM = 230;
 /** maximum run velocity (pixel/s) */
 static const float MAX_RUN_XM = 320;
+/** bonus run velocity addition (pixel/s) */
+static const float BONUS_RUN_XM = 80;
 /** maximum horizontal climb velocity */
 static const float MAX_CLIMB_XM = 96;
 /** maximum vertical climb velocity */
 static const float MAX_CLIMB_YM = 128;
+/** maximum vertical glide velocity */
+static const float MAX_GLIDE_YM = 128;
 /** instant velocity when tux starts to walk */
 static const float WALK_SPEED = 100;
 
@@ -119,12 +124,15 @@ Player::Player(PlayerStatus* _player_status, const std::string& name_) :
   backflip_direction(),
   peekingX(),
   peekingY(),
+  glide_time(),
+  stone(),
   swimming(),
   speedlimit(),
   scripting_controller_old(0),
   jump_early_apex(),
   on_ice(),
   ice_this_frame(),
+  lightsprite(SpriteManager::current()->create("images/objects/lightmap_light/lightmap_light-tiny.sprite")),
   dir(),
   old_dir(),
   last_ground_y(),
@@ -140,6 +148,8 @@ Player::Player(PlayerStatus* _player_status, const std::string& name_) :
   safe_timer(),
   kick_timer(),
   shooting_timer(),
+  ability_timer(),
+  cooldown_timer(),
   dying_timer(),
   growing(),
   backflip_timer(),
@@ -213,10 +223,13 @@ Player::init()
   backflip_direction = 0;
   sprite->set_angle(0.0f);
   visible = true;
+  glide_time = 0;
+  stone = false;
   swimming = false;
   on_ice = false;
   ice_this_frame = false;
   speedlimit = 0; //no special limit
+  lightsprite->set_blend(Blend(GL_SRC_ALPHA, GL_ONE));
 
   on_ground_flag = false;
   grabbed_object = NULL;
@@ -398,6 +411,8 @@ Player::update(float elapsed_time)
       if (deactivated)
         do_standup();
     }
+    if (player_status->bonus == AIR_BONUS)
+      glide_time = player_status->max_air_time * GLIDE_TIME_PER_FLOWER;
   }
 
   // calculate movement for this frame
@@ -524,11 +539,11 @@ Player::handle_horizontal_input()
       ax = dirsign * RUN_ACCELERATION_X;
     }
     // limit speed
-    if(vx >= MAX_RUN_XM && dirsign > 0) {
-      vx = MAX_RUN_XM;
+    if(vx >= MAX_RUN_XM + BONUS_RUN_XM *((player_status->bonus == AIR_BONUS) ? 1 : 0) && dirsign > 0) {
+      vx = MAX_RUN_XM + BONUS_RUN_XM *((player_status->bonus == AIR_BONUS) ? 1 : 0);
       ax = 0;
-    } else if(vx <= -MAX_RUN_XM && dirsign < 0) {
-      vx = -MAX_RUN_XM;
+    } else if(vx <= -MAX_RUN_XM - BONUS_RUN_XM *((player_status->bonus == AIR_BONUS) ? 1 : 0) && dirsign < 0) {
+      vx = -MAX_RUN_XM - BONUS_RUN_XM *((player_status->bonus == AIR_BONUS) ? 1 : 0);
       ax = 0;
     }
   }
@@ -642,7 +657,7 @@ Player::do_backflip() {
 
   backflip_direction = (dir == LEFT)?(+1):(-1);
   backflipping = true;
-  do_jump(-580);
+  do_jump((player_status->bonus == AIR_BONUS) ? -720 : -580);
   SoundManager::current()->play("sounds/flip.wav");
   backflip_timer.start(TUX_BACKFLIP_TIME);
 }
@@ -706,16 +721,41 @@ Player::handle_vertical_input()
         do_backflip();
       }
     } else {
+      // airflower allows for higher jumps-
       // jump a bit higher if we are running; else do a normal jump
-      if (fabs(physic.get_velocity_x()) > MAX_WALK_XM) do_jump(-580); else do_jump(-520);
+      if(player_status->bonus == AIR_BONUS)
+        do_jump((fabs(physic.get_velocity_x()) > MAX_WALK_XM) ? -620 : -580);
+      else
+        do_jump((fabs(physic.get_velocity_x()) > MAX_WALK_XM) ? -580 : -520);
     }
-  }
+    // airflower glide only when holding jump key
+  } else  if (controller->hold(Controller::JUMP) && player_status->bonus == AIR_BONUS && physic.get_velocity_y() > MAX_GLIDE_YM) {
+      if (glide_time > 0 && !ability_timer.started())
+        ability_timer.start(glide_time);
+      else if (ability_timer.started()) {
+        log_debug << ability_timer.get_timeleft() << std::endl;
+        // glide stops after some duration or if buttjump is initiated
+        if ((ability_timer.get_timeleft() <= 0.05f) || controller->hold(Controller::DOWN)) {
+          glide_time = 0;
+          ability_timer.stop();
+        } else {
+          physic.set_velocity_y(MAX_GLIDE_YM);
+          physic.set_acceleration_y(0);
+        }
+      }
+    }
+      /*ability_timer.started() ? gliding = true : ability_timer.start(player_status->max_air_time);*/
+  //}
   // Let go of jump key
   else if(!controller->hold(Controller::JUMP)) {
     if (!backflipping && jumping && physic.get_velocity_y() < 0) {
       jumping = false;
       early_jump_apex();
     }
+    if (player_status->bonus == AIR_BONUS && ability_timer.started()){
+      glide_time = ability_timer.get_timeleft();
+      ability_timer.stop();
+    }
   }
 
   if(jump_early_apex && physic.get_velocity_y() >= 0) {
@@ -1189,6 +1229,13 @@ Player::draw(DrawingContext& context)
     ;  // don't draw Tux
   else {
     sprite->draw(context, get_pos(), LAYER_OBJECTS + 1);
+    // draw light with earthflower bonus
+    if (player_status->bonus == EARTH_BONUS){
+      context.push_target();
+      context.set_target(DrawingContext::LIGHTMAP);
+      lightsprite->draw(context, get_pos() + Vector(dir==LEFT ? 0 : 32, 0), 0);
+      context.pop_target();
+    }
   }
 
 }
@@ -1465,10 +1512,12 @@ Player::get_velocity()
 void
 Player::bounce(BadGuy& )
 {
-  if(controller->hold(Controller::JUMP))
-    physic.set_velocity_y(-520);
-  else
-    physic.set_velocity_y(-300);
+  if(!(player_status->bonus == AIR_BONUS))
+    physic.set_velocity_y(controller->hold(Controller::JUMP) ? -520 : -300);
+  else {
+    physic.set_velocity_y(controller->hold(Controller::JUMP) ? -580 : -340);
+    glide_time = player_status->max_air_time * GLIDE_TIME_PER_FLOWER;
+  }
 }
 
 //scripting Functions Below