Draw bouncy coin above other objects
[supertux.git] / src / object / player.cpp
index 0bc2e85..35f874e 100644 (file)
@@ -1,7 +1,7 @@
 //  $Id$
 //
-//  SuperTux -  A Jump'n Run
-//  Copyright (C) 2003 Tobias Glaesser <tobi.web@gmx.de>
+//  SuperTux
+//  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
 //
 //  This program is free software; you can redistribute it and/or
 //  modify it under the terms of the GNU General Public License
@@ -31,7 +31,6 @@
 #include "sprite/sprite.hpp"
 #include "sector.hpp"
 #include "resources.hpp"
-#include "video/screen.hpp"
 #include "statistics.hpp"
 #include "game_session.hpp"
 #include "object/tilemap.hpp"
 #include "object/bullet.hpp"
 #include "trigger/trigger_base.hpp"
 #include "control/joystickkeyboardcontroller.hpp"
+#include "scripting/squirrel_util.hpp"
 #include "main.hpp"
 #include "platform.hpp"
 #include "badguy/badguy.hpp"
 #include "player_status.hpp"
-#include "msg.hpp"
+#include "log.hpp"
+#include "falling_coin.hpp"
 
 static const int TILES_FOR_BUTTJUMP = 3;
 static const float SHOOTING_TIME = .150;
@@ -94,7 +95,7 @@ TuxBodyParts::draw(DrawingContext& context, const Vector& pos, int layer)
   if(body != NULL)
     body->draw(context, pos, layer-3);
   if(arms != NULL)
-    arms->draw(context, pos, layer);
+    arms->draw(context, pos, layer+10);
   if(feet != NULL)
     feet->draw(context, pos, layer-2);
 }
@@ -106,6 +107,7 @@ Player::Player(PlayerStatus* _player_status)
   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");
+
   init();
 }
 
@@ -120,9 +122,9 @@ void
 Player::init()
 {
   if(is_big())
-    bbox.set_size(31.8, 63.8);
+    bbox.set_size(31.8, 62.8);
   else
-    bbox.set_size(31.8, 31.8);
+    bbox.set_size(31.8, 30.8);
   adjust_height = 0;
 
   dir = RIGHT;
@@ -150,6 +152,19 @@ Player::init()
 }
 
 void
+Player::expose(HSQUIRRELVM vm, int table_idx)
+{
+  Scripting::Player* interface = static_cast<Scripting::Player*> (this);
+  expose_object(vm, table_idx, interface, "Tux", false);
+}
+
+void
+Player::unexpose(HSQUIRRELVM vm, int table_idx)
+{
+  Scripting::unexpose_object(vm, table_idx, "Tux");
+}
+
+void
 Player::set_controller(Controller* controller)
 {
   this->controller = controller;
@@ -180,7 +195,7 @@ Player::update(float elapsed_time)
       if(moving_object) {
         moving_object->set_pos(pos);
       } else {
-        msg_debug("Non MovingObjetc grabbed?!?");
+        log_debug << "Non MovingObjetc grabbed?!?" << std::endl;
       }
       grabbed_object->ungrab(*this, dir);
       grabbed_object = 0;
@@ -519,17 +534,63 @@ Player::handle_input()
 }
 
 void
-Player::set_bonus(BonusType type, bool animate)
+Player::add_coins(int count)
 {
-  if(player_status->bonus >= type)
-    return;
+  player_status->add_coins(count);
+}
+
+void
+Player::add_bonus(const std::string& bonustype)
+{
+  if(bonustype == "grow")
+    add_bonus(GROWUP_BONUS);
+  else if(bonustype == "fireflower")
+    add_bonus(FIRE_BONUS);
+  else if(bonustype == "iceflower")
+    add_bonus(ICE_BONUS);
+  else if(bonustype == "none")
+    add_bonus(NO_BONUS);
+  
   
+  std::ostringstream msg;
+  msg << "Unknown bonus type "  << bonustype;
+  throw std::runtime_error(msg.str());
+}
+
+void
+Player::add_bonus(BonusType type, bool animate)
+{
+  // always ignore NO_BONUS
+  if (type == NO_BONUS) {
+    return;
+  }
+
+  // ignore GROWUP_BONUS if we're already big
+  if (type == GROWUP_BONUS) {
+    if (player_status->bonus == GROWUP_BONUS) return; 
+    if (player_status->bonus == FIRE_BONUS) return;
+    if (player_status->bonus == ICE_BONUS) return;
+  }
+
+  set_bonus(type, animate);
+}
+
+void
+Player::set_bonus(BonusType type, bool animate)
+{
   if(player_status->bonus == NO_BONUS) {
-    adjust_height = 63.8;
+    adjust_height = 62.8;
     if(animate)
       growing_timer.start(GROWING_TIME);
   }
-  
+
+  if ((type == NO_BONUS) || (type == GROWUP_BONUS)) {
+    player_status->max_fire_bullets = 0;
+    player_status->max_ice_bullets = 0;
+  }
+  if (type == FIRE_BONUS) player_status->max_fire_bullets++;
+  if (type == ICE_BONUS) player_status->max_ice_bullets++;
+
   player_status->bonus = type;
 }
 
@@ -568,7 +629,7 @@ Player::draw(DrawingContext& context)
   else
     tux_body = small_tux;
 
-  int layer = LAYER_OBJECTS + 10;
+  int layer = LAYER_OBJECTS + 1;
 
   /* Set Tux sprite action */
   if (duck && is_big())
@@ -828,24 +889,31 @@ Player::kill(HurtMode mode)
           || player_status->bonus == ICE_BONUS)
         {
           safe_timer.start(TUX_SAFE_TIME);
-          player_status->bonus = GROWUP_BONUS;
+         set_bonus(GROWUP_BONUS);
         }
       else 
         {
           //growing_timer.start(GROWING_TIME);
           safe_timer.start(TUX_SAFE_TIME /* + GROWING_TIME */);
-          adjust_height = 31.8;
+          adjust_height = 30.8;
           duck = false;
-          player_status->bonus = NO_BONUS;
+          set_bonus(NO_BONUS);
         }
     }
   else
     {
+      srand(time(0));
+      int i;
+      for (i = 0; (i < 5) && (i < player_status->coins); i++)
+      {
+        // the numbers: starting x, starting y, velocity y
+        Sector::current()->add_object(new FallingCoin(get_pos() + Vector(rand()%5, rand()%50 - 32), rand()%200 - 100));
+      }
       physic.enable_gravity(true);
       physic.set_acceleration(0, 0);
       physic.set_velocity(0, 700);
-      player_status->lives -= 1;
-      player_status->bonus = NO_BONUS;
+      player_status->coins -= 25;
+      set_bonus(NO_BONUS);
       dying = true;
       dying_timer.start(3.0);
       set_group(COLGROUP_DISABLED);
@@ -949,3 +1017,4 @@ void Player::walk(float speed)
 {
   physic.set_velocity_x(speed);
 }
+