}
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) {
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;
}
}
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;
}
}
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
{
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;
}
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;
}
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()
{