shorten unstable time
[supertux.git] / src / object / block.cpp
index cc9c400..3bd3209 100644 (file)
 #include "flower.h"
 #include "oneup.h"
 #include "star.h"
+#include "player_status.h"
+#include "badguy/badguy.h"
+#include "coin.h"
+#include "object_factory.h"
 
 static const float BOUNCY_BRICK_MAX_OFFSET=8;
 static const float BOUNCY_BRICK_SPEED=90;
@@ -22,7 +26,7 @@ Block::Block(const Vector& pos, Sprite* newsprite)
   : sprite(newsprite), bouncing(false), bounce_dir(0), bounce_offset(0)
 {
   bbox.set_pos(pos);
-  bbox.set_size(32, 32);
+  bbox.set_size(32, 32.1);
   flags |= FLAG_SOLID;
   original_y = pos.y;
 }
@@ -35,17 +39,25 @@ Block::~Block()
 HitResponse
 Block::collision(GameObject& other, const CollisionHit& hitdata)
 {
-  // TODO kill badguys when bumping them...
-  
   Player* player = dynamic_cast<Player*> (&other);
   if(player) {
     // collided from below?
-    if(hitdata.normal.x == 0 && hitdata.normal.y < 0
-        && player->get_movement().y < 0) {
+    if(hitdata.normal.x == 0 && hitdata.normal.y < 0) {
       hit(*player);
     }
   }
 
+  if(bouncing) {
+    BadGuy* badguy = dynamic_cast<BadGuy*> (&other);
+    if(badguy) {
+      badguy->kill_fall();
+    }
+    Coin* coin = dynamic_cast<Coin*> (&other);
+    if(coin) {
+      coin->collect();
+    }
+  }
+
   return FORCE_MOVE;
 }
 
@@ -77,6 +89,7 @@ Block::draw(DrawingContext& context)
 void
 Block::start_bounce()
 {
+  original_y = bbox.p1.y;
   bouncing = true;
   bounce_dir = -BOUNCY_BRICK_SPEED;
   bounce_offset = 0;
@@ -91,7 +104,13 @@ BonusBlock::BonusBlock(const Vector& pos, int newdata)
 }
 
 void
-BonusBlock::hit(Player& player)
+BonusBlock::hit(Player& )
+{
+  try_open();
+}
+
+void
+BonusBlock::try_open()
 {
   if(sprite->get_action_name() == "empty") {
     SoundManager::get()->play_sound(IDToSound(SND_BRICK));
@@ -99,6 +118,7 @@ BonusBlock::hit(Player& player)
   }
   
   Sector* sector = Sector::current();
+  Player& player = *(sector->player);
   switch(data) {
     case 1: // coin
       Sector::current()->add_object(new BouncyCoin(get_pos()));
@@ -132,7 +152,7 @@ BonusBlock::hit(Player& player)
       break;
 
     case 3: // star
-      sector->add_object(new Star(get_pos()));
+      sector->add_object(new Star(get_pos() + Vector(0, -32)));
       break;
 
     case 4: // 1up
@@ -147,6 +167,8 @@ BonusBlock::hit(Player& player)
   sprite->set_action("empty");
 }
 
+//IMPLEMENT_FACTORY(BonusBlock, "bonusblock")
+
 //---------------------------------------------------------------------------
 
 Brick::Brick(const Vector& pos, int data)
@@ -160,13 +182,23 @@ Brick::Brick(const Vector& pos, int data)
 }
 
 void
-Brick::hit(Player& player)
+Brick::hit(Player& )
+{
+  if(sprite->get_action_name() == "empty")
+    return;
+  
+  try_break(true);
+}
+
+void
+Brick::try_break(bool playerhit)
 {
   if(sprite->get_action_name() == "empty")
     return;
   
   SoundManager::get()->play_sound(IDToSound(SND_BRICK));
   Sector* sector = Sector::current();
+  Player& player = *(sector->player);
   if(coin_counter > 0) {
     sector->add_object(new BouncyCoin(get_pos()));
     coin_counter--;
@@ -175,7 +207,7 @@ Brick::hit(Player& player)
       sprite->set_action("empty");
     start_bounce();
   } else if(breakable) {
-    if(player.size == SMALL) {
+    if(playerhit && player.size == SMALL) {
       start_bounce();
       return;
     }
@@ -195,3 +227,4 @@ Brick::hit(Player& player)
   }
 }
 
+//IMPLEMENT_FACTORY(Brick, "brick")