remove jam buildfiles, we're using cmake now and I don't want to maintain 2 buildsystems
[supertux.git] / src / object / player.cpp
index c3d76f2..978e073 100644 (file)
@@ -51,6 +51,8 @@
 #include "object/sprite_particle.hpp"
 #include "trigger/climbable.hpp"
 
+//#define SWIMMING
+
 static const int TILES_FOR_BUTTJUMP = 3;
 static const float SHOOTING_TIME = .150f;
 /// time before idle animation starts
@@ -112,23 +114,27 @@ TuxBodyParts::set_action(std::string action, int loops)
 }
 
 void
-TuxBodyParts::draw(DrawingContext& context, const Vector& pos, int layer)
+TuxBodyParts::draw(DrawingContext& context, const Vector& pos, int layer, Portable* grabbed_object)
 {
   if(head != NULL)
-    head->draw(context, pos, layer-1);
+    head->draw(context, pos, layer-2);
   if(body != NULL)
-    body->draw(context, pos, layer-3);
+    body->draw(context, pos, layer-4);
   if(arms != NULL)
-    arms->draw(context, pos, layer+10);
+    arms->draw(context, pos, layer-1 + (grabbed_object?10:0));
   if(feet != NULL)
-    feet->draw(context, pos, layer-2);
+    feet->draw(context, pos, layer-3);
 }
 
 Player::Player(PlayerStatus* _player_status, const std::string& name)
-  : player_status(_player_status), grabbed_object(NULL), ghost_mode(false), climbing(0)
+  : scripting_controller(0), 
+    player_status(_player_status), 
+    scripting_controller_old(0),
+    grabbed_object(NULL), ghost_mode(false), edit_mode(false), climbing(0)
 {
   this->name = name;
   controller = main_controller;
+  scripting_controller = new CodeController();
   smalltux_gameover = sprite_manager->create("images/creatures/tux_small/smalltux-gameover.sprite");
   smalltux_star = sprite_manager->create("images/creatures/tux_small/smalltux-star.sprite");
   bigtux_star = sprite_manager->create("images/creatures/tux_big/bigtux-star.sprite");
@@ -141,6 +147,7 @@ Player::Player(PlayerStatus* _player_status, const std::string& name)
   sound_manager->preload("sounds/flip.wav");
   sound_manager->preload("sounds/invincible.wav");
   sound_manager->preload("sounds/splash.ogg");
+  sound_manager->preload("sounds/shoot.wav");
 
   init();
 }
@@ -151,6 +158,7 @@ Player::~Player()
   delete smalltux_gameover;
   delete smalltux_star;
   delete bigtux_star;
+  delete scripting_controller;
 }
 
 void
@@ -224,6 +232,29 @@ Player::set_controller(Controller* controller)
   this->controller = controller;
 }
 
+void 
+Player::use_scripting_controller(bool use_or_release)
+{
+  if ((use_or_release == true) && (controller != scripting_controller)) {
+    scripting_controller_old = get_controller();
+    set_controller(scripting_controller);
+  }
+  if ((use_or_release == false) && (controller == scripting_controller)) {
+    set_controller(scripting_controller_old);
+    scripting_controller_old = 0;
+  }
+}
+
+void 
+Player::do_scripting_controller(std::string control, bool pressed)
+{
+  for(int i = 0; Controller::controlNames[i] != 0; ++i) {
+    if(control == std::string(Controller::controlNames[i])) {
+      scripting_controller->press(Controller::Control(i), pressed);
+    }
+  }
+}
+
 bool
 Player::adjust_height(float new_height)
 {
@@ -539,9 +570,6 @@ Player::do_backflip() {
   if (!on_ground())
     return;
 
-  // TODO: we don't have an animation for firetux backflipping, so let's revert to bigtux
-  set_bonus(GROWUP_BONUS, true);
-
   backflip_direction = (dir == LEFT)?(+1):(-1);
   backflipping = true;
   do_jump(-580);
@@ -572,7 +600,7 @@ void
 Player::handle_vertical_input()
 {
   // Press jump key
-  if(controller->hold(Controller::JUMP) && (on_ground()) && (can_jump)) {
+  if(controller->pressed(Controller::JUMP) && (can_jump)) {
     if (duck) {
       // when running, only jump a little bit; else do a backflip
       if ((physic.get_velocity_x() != 0) || (controller->hold(Controller::LEFT)) || (controller->hold(Controller::RIGHT))) do_jump(-300); else do_backflip();
@@ -601,11 +629,13 @@ Player::handle_vertical_input()
 
   // swimming
   physic.set_acceleration_y(0);
+#ifdef SWIMMING
   if (swimming) {
     if (controller->hold(Controller::UP) || controller->hold(Controller::JUMP))
       physic.set_acceleration_y(-2000);
     physic.set_velocity_y(physic.get_velocity_y() * 0.94);
   }
+#endif
 }
 
 void
@@ -627,18 +657,31 @@ Player::handle_input()
   if( controller->released( Controller::PEEK_RIGHT ) ) {
     peeking = AUTO;
   }
+  if( controller->released( Controller::UP ) ) {
+    peeking = AUTO;
+  }
+  if( controller->released( Controller::DOWN ) ) {
+    peeking = AUTO;
+  }
   if( controller->pressed( Controller::PEEK_LEFT ) ) {
     peeking = LEFT;
   }
   if( controller->pressed( Controller::PEEK_RIGHT ) ) {
     peeking = RIGHT;
   }
+  if( controller->pressed( Controller::UP ) ) {
+    peeking = UP;
+  }
+  if( controller->pressed( Controller::DOWN ) ) {
+    peeking = DOWN;
+  }
 
   /* Handle horizontal movement: */
   if (!backflipping) handle_horizontal_input();
 
   /* Jump/jumping? */
-  if (!controller->hold(Controller::JUMP)) can_jump = true;
+  if (on_ground() && !controller->hold(Controller::JUMP))
+    can_jump = true;
 
   /* Handle vertical movement: */
   handle_vertical_input();
@@ -673,9 +716,13 @@ Player::handle_input()
       if(moving_object) {
         moving_object->set_pos(pos);
       } else {
-        log_debug << "Non MovingObjetc grabbed?!?" << std::endl;
+        log_debug << "Non MovingObject grabbed?!?" << std::endl;
+      }
+      if(controller->hold(Controller::UP)) {
+        grabbed_object->ungrab(*this, UP);
+      } else {
+        grabbed_object->ungrab(*this, dir);
       }
-      grabbed_object->ungrab(*this, dir);
       grabbed_object = NULL;
     }
   }
@@ -700,11 +747,16 @@ Player::try_grab()
       if(!portable->is_portable())
         continue;
 
+      // make sure the Portable is a MovingObject
       MovingObject* moving_object = dynamic_cast<MovingObject*> (portable);
-      assert(portable);
+      assert(moving_object);
       if(moving_object == NULL)
         continue;
 
+      // make sure the Portable isn't currently non-solid
+      if(moving_object->get_group() == COLGROUP_DISABLED) continue;
+
+      // check if we are within reach
       if(moving_object->get_bbox().contains(pos)) {
         if (climbing) stop_climbing(*climbing);
         grabbed_object = portable;
@@ -1000,7 +1052,7 @@ Player::draw(DrawingContext& context)
   else if (safe_timer.started() && size_t(game_time*40)%2)
     ;  // don't draw Tux
   else
-    tux_body->draw(context, get_pos(), layer);
+    tux_body->draw(context, get_pos(), layer, grabbed_object);
 
 }
 
@@ -1010,6 +1062,7 @@ Player::collision_tile(uint32_t tile_attributes)
   if(tile_attributes & Tile::HURTS)
     kill(false);
 
+#ifdef SWIMMING
   if( swimming ){
     if( tile_attributes & Tile::WATER ){
       no_water = false;
@@ -1023,6 +1076,7 @@ Player::collision_tile(uint32_t tile_attributes)
       sound_manager->play( "sounds/splash.ogg" );
     }
   }
+#endif
 }
 
 void
@@ -1080,7 +1134,6 @@ Player::collision(GameObject& other, const CollisionHit& hit)
 
   BadGuy* badguy = dynamic_cast<BadGuy*> (&other);
   if(badguy != NULL) {
-    if (hit.bottom) on_ground_flag = true;
     if(safe_timer.started() || invincible_timer.started())
       return FORCE_MOVE;
 
@@ -1109,6 +1162,7 @@ Player::kill(bool completely)
     return;
 
   sound_manager->play("sounds/hurt.wav");
+
   if (climbing) stop_climbing(*climbing);
 
   physic.set_velocity_x(0);
@@ -1131,6 +1185,13 @@ Player::kill(bool completely)
       duck = false;
     }
   } else {
+
+    // do not die when in edit mode
+    if (edit_mode) {
+      set_ghost_mode(true);
+      return;
+    }
+
     if (player_status->coins >= 25 && !GameSession::current()->get_reset_point_sectorname().empty())
     {
       for (int i = 0; i < 5; i++)
@@ -1189,7 +1250,7 @@ Player::check_bounds(Camera* camera)
   }
 
   /* fallen out of the level? */
-  if (get_pos().y > Sector::current()->get_height()) {
+  if ((get_pos().y > Sector::current()->get_height()) && (!ghost_mode)) {
     kill(true);
     return;
   }
@@ -1228,9 +1289,9 @@ Player::add_velocity(const Vector& velocity, const Vector& end_speed)
 void
 Player::bounce(BadGuy& )
 {
-  //if(controller->hold(Controller::JUMP))
-  //  physic.set_velocity_y(-520);
-  //else
+  if(controller->hold(Controller::JUMP))
+    physic.set_velocity_y(-520);
+  else
     physic.set_velocity_y(-300);
 }
 
@@ -1284,6 +1345,12 @@ Player::set_ghost_mode(bool enable)
 }
 
 
+void
+Player::set_edit_mode(bool enable)
+{
+  edit_mode = enable;
+}
+
 void 
 Player::start_climbing(Climbable& climbable)
 {