patch contributed by markos_64:
[supertux.git] / src / object / block.cpp
index 0a8b037..0dcc549 100644 (file)
@@ -13,6 +13,8 @@
 #include "flower.h"
 #include "oneup.h"
 #include "star.h"
+#include "badguy/badguy.h"
+#include "coin.h"
 
 static const float BOUNCY_BRICK_MAX_OFFSET=8;
 static const float BOUNCY_BRICK_SPEED=90;
@@ -35,22 +37,26 @@ Block::~Block()
 HitResponse
 Block::collision(GameObject& other, const CollisionHit& hitdata)
 {
-  if(bouncing)
-    return FORCE_MOVE;
-  
-  // TODO kill badguys when bumping them...
-  
   Player* player = dynamic_cast<Player*> (&other);
-  if(!player)
-    return ABORT_MOVE;
+  if(player) {
+    // collided from below?
+    if(hitdata.normal.x == 0 && hitdata.normal.y < 0) {
+      hit(*player);
+    }
+  }
 
-  // collided from below?
-  if(hitdata.normal.x == 0 && hitdata.normal.y < 0
-      && player->get_movement().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 ABORT_MOVE;
+  return FORCE_MOVE;
 }
 
 void
@@ -61,9 +67,9 @@ Block::action(float elapsed_time)
   
   float offset = original_y - get_pos().y;
   if(offset > BOUNCY_BRICK_MAX_OFFSET) {
-    bounce_dir *= -1;
+    bounce_dir = BOUNCY_BRICK_SPEED;
     movement = Vector(0, bounce_dir * elapsed_time);
-  } else if(offset < -EPSILON) {
+  } else if(offset < BOUNCY_BRICK_SPEED * elapsed_time && bounce_dir > 0) {
     movement = Vector(0, offset);
     bounce_dir = 0;
     bouncing = false;
@@ -95,7 +101,7 @@ BonusBlock::BonusBlock(const Vector& pos, int newdata)
 }
 
 void
-BonusBlock::hit(Player* player)
+BonusBlock::hit(Player& player)
 {
   if(sprite->get_action_name() == "empty") {
     SoundManager::get()->play_sound(IDToSound(SND_BRICK));
@@ -106,11 +112,11 @@ BonusBlock::hit(Player* player)
   switch(data) {
     case 1: // coin
       Sector::current()->add_object(new BouncyCoin(get_pos()));
-      player->get_status().incCoins();
+      player.get_status().incCoins();
       break;
 
     case 2: // grow/fireflower
-      if(player->size == SMALL) {
+      if(player.size == SMALL) {
         SpecialRiser* riser = new SpecialRiser(
             new GrowUp(get_pos() + Vector(0, -32)));
         sector->add_object(riser);
@@ -123,7 +129,7 @@ BonusBlock::hit(Player* player)
       break;
 
     case 5: // grow/iceflower
-      if(player->size == SMALL) {
+      if(player.size == SMALL) {
         SpecialRiser* riser = new SpecialRiser(
             new GrowUp(get_pos() + Vector(0, -32)));
         sector->add_object(riser);                                            
@@ -136,7 +142,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
@@ -154,8 +160,8 @@ BonusBlock::hit(Player* player)
 //---------------------------------------------------------------------------
 
 Brick::Brick(const Vector& pos, int data)
-  : Block(pos, sprite_manager->create("brick")),
-  breakable(false), coin_counter(0)
+  : Block(pos, sprite_manager->create("brick")), breakable(false),
+    coin_counter(0)
 {
   if(data == 1)
     coin_counter = 5;
@@ -164,7 +170,7 @@ Brick::Brick(const Vector& pos, int data)
 }
 
 void
-Brick::hit(Player* player)
+Brick::hit(Player& player)
 {
   if(sprite->get_action_name() == "empty")
     return;
@@ -174,12 +180,12 @@ Brick::hit(Player* player)
   if(coin_counter > 0) {
     sector->add_object(new BouncyCoin(get_pos()));
     coin_counter--;
-    player->get_status().incCoins();
+    player.get_status().incCoins();
     if(coin_counter == 0)
       sprite->set_action("empty");
     start_bounce();
   } else if(breakable) {
-    if(player->size == SMALL) {
+    if(player.size == SMALL) {
       start_bounce();
       return;
     }