Ice bullets ricochet again. Also made Igel ignore ice bullets.
authorChristoph Sommer <mail@christoph-sommer.de>
Wed, 16 Aug 2006 23:06:58 +0000 (23:06 +0000)
committerChristoph Sommer <mail@christoph-sommer.de>
Wed, 16 Aug 2006 23:06:58 +0000 (23:06 +0000)
SVN-Revision: 4191

src/badguy/badguy.cpp
src/badguy/igel.cpp
src/object/bullet.cpp
src/object/bullet.hpp

index c29e70b..ae6c39f 100644 (file)
@@ -241,7 +241,7 @@ BadGuy::collision_squished(Player& )
 }
 
 HitResponse
-BadGuy::collision_bullet(Bullet& bullet, const CollisionHit& )
+BadGuy::collision_bullet(Bullet& bullet, const CollisionHit& hit)
 {
   if (is_frozen()) {
     if(bullet.get_type() == FIRE_BONUS) {
@@ -250,8 +250,8 @@ BadGuy::collision_bullet(Bullet& bullet, const CollisionHit& )
       bullet.remove_me();
       return ABORT_MOVE;
     } else {
-      // other bullets are absorbed by frozen badguys
-      bullet.remove_me();
+      // other bullets ricochet
+      bullet.ricochet(*this, hit);
       return FORCE_MOVE;
     }
   } 
@@ -280,8 +280,8 @@ BadGuy::collision_bullet(Bullet& bullet, const CollisionHit& )
     return ABORT_MOVE;
   }
   else {
-    // in all other cases, bullets are absorbed
-    bullet.remove_me();
+    // in all other cases, bullets ricochet
+    bullet.ricochet(*this, hit);
     return FORCE_MOVE;
   }
 }
index 2451065..6a4e477 100644 (file)
@@ -71,12 +71,12 @@ Igel::can_see(const MovingObject& o)
   Rect mb = get_bbox();
   Rect ob = o.get_bbox();
 
-  bool inReach_left = (ob.p2.x >= mb.p1.x-((dir == LEFT) ? RANGE_OF_VISION : 0));
-  bool inReach_right = (ob.p1.x <= mb.p2.x+((dir == RIGHT) ? RANGE_OF_VISION : 0));
+  bool inReach_left = ((ob.p2.x < mb.p1.x) && (ob.p2.x >= mb.p1.x-((dir == LEFT) ? RANGE_OF_VISION : 0)));
+  bool inReach_right = ((ob.p1.x > mb.p2.x) && (ob.p1.x <= mb.p2.x+((dir == RIGHT) ? RANGE_OF_VISION : 0)));
   bool inReach_top = (ob.p2.y >= mb.p1.y);
   bool inReach_bottom = (ob.p1.y <= mb.p2.y);
 
-  return (inReach_left && inReach_right && inReach_top && inReach_bottom);
+  return ((inReach_left || inReach_right) && inReach_top && inReach_bottom);
 }
 
 void
@@ -84,11 +84,12 @@ Igel::active_update(float elapsed_time)
 {
   bool wants_to_flee = false;
 
-  // check if we see a bullet
+  // check if we see a fire bullet
   Sector* sector = Sector::current();
   for (Sector::GameObjects::iterator i = sector->gameobjects.begin(); i != sector->gameobjects.end(); ++i) {
     Bullet* bullet = dynamic_cast<Bullet*>(*i);
     if (!bullet) continue;
+    if (bullet->get_type() != FIRE_BONUS) continue;
     if (can_see(*bullet)) wants_to_flee = true;
   }
 
@@ -106,16 +107,13 @@ Igel::active_update(float elapsed_time)
 HitResponse
 Igel::collision_bullet(Bullet& bullet, const CollisionHit& hit)
 {
-  //remove bullet
-  bullet.remove_me();
-
-  // die if hit on front side
+  // default reaction if hit on front side
   if (((dir == LEFT) && hit.left) || ((dir == RIGHT) && hit.right)) {
-    kill_fall();
-    return ABORT_MOVE;
+    return BadGuy::collision_bullet(bullet, hit);
   }
 
-  // else ignore bullet
+  // else make bullet ricochet and ignore the hit
+  bullet.ricochet(*this, hit);
   return FORCE_MOVE;
 }
 
index 3a35faf..564b7ba 100644 (file)
@@ -95,6 +95,12 @@ Bullet::collision_solid(const CollisionHit& hit)
   }
 }
 
+void 
+Bullet::ricochet(GameObject& , const CollisionHit& hit)
+{
+  collision_solid(hit);
+}
+
 HitResponse
 Bullet::collision(GameObject& , const CollisionHit& )
 {
index 90547a3..b18e375 100644 (file)
@@ -35,6 +35,13 @@ public:
   void draw(DrawingContext& context);
   void collision_solid(const CollisionHit& hit);
   HitResponse collision(GameObject& other, const CollisionHit& hit);
+
+  /**
+   * Makes bullet bounce off an object (that got hit).
+   * To be called by the collision handler of that object.
+   * Note that the @c hit parameter is filled in as perceived by the object, not by the bullet.
+   */
+  void ricochet(GameObject& other, const CollisionHit& hit);
   
   BonusType get_type()
   {