Committed gnomino's iceflower patch. Also added placeholder graphics (selfmade, PD...
authorChristoph Sommer <mail@christoph-sommer.de>
Wed, 16 Aug 2006 01:08:19 +0000 (01:08 +0000)
committerChristoph Sommer <mail@christoph-sommer.de>
Wed, 16 Aug 2006 01:08:19 +0000 (01:08 +0000)
SVN-Revision: 4188

29 files changed:
data/images/creatures/tux_big/big-ice-tux-head.sprite [new file with mode: 0644]
data/images/creatures/tux_big/head-ice-duck-0.png [new file with mode: 0644]
data/images/creatures/tux_big/head-ice-skid-0.png [new file with mode: 0644]
data/images/creatures/tux_big/head-ice-stand-0.png [new file with mode: 0644]
data/images/objects/bullets/icebullet.sprite
data/images/objects/particles/icetux-cap.png [new file with mode: 0644]
data/images/objects/particles/icetux-cap.sprite [new file with mode: 0644]
data/scripts/console.nut
src/badguy/badguy.cpp
src/badguy/badguy.hpp
src/badguy/dispenser.cpp
src/badguy/dispenser.hpp
src/badguy/fish.cpp
src/badguy/fish.hpp
src/badguy/jumpy.cpp
src/badguy/jumpy.hpp
src/badguy/mrbomb.cpp
src/badguy/mrbomb.hpp
src/badguy/spiky.cpp
src/badguy/spiky.hpp
src/badguy/sspiky.cpp
src/badguy/sspiky.hpp
src/badguy/walking_badguy.cpp
src/badguy/walking_badguy.hpp
src/object/bullet.cpp
src/object/bullet.hpp
src/object/player.cpp
src/resources.cpp
src/sector.cpp

diff --git a/data/images/creatures/tux_big/big-ice-tux-head.sprite b/data/images/creatures/tux_big/big-ice-tux-head.sprite
new file mode 100644 (file)
index 0000000..10ffb88
--- /dev/null
@@ -0,0 +1,91 @@
+(supertux-sprite
+       (action
+         (name "walk-right")
+         (fps 15.0)
+         (hitbox 5 32 0 0)
+         (images "head-ice-stand-0.png"))
+
+       (action
+         (name "walk-left")
+         (fps 15.0)
+         (hitbox 27 32 0 0)
+         (mirror-action "walk-right"))
+
+       (action
+         (name "stand-right")
+         (fps 15.0)
+         (hitbox 5 32 0 0)
+         (images "head-ice-stand-0.png"))
+
+       (action
+         (name "stand-left")
+         (fps 15.0)
+         (hitbox 27 32 0 0)
+         (mirror-action "stand-right"))
+
+       (action
+         (name "jump-right")
+         (fps 15.0)
+         (hitbox 5 30 0 0)
+         (images "head-ice-stand-0.png"))
+
+       (action
+         (name "jump-left")
+         (fps 15.0)
+         (hitbox 27 30 0 0)
+         (mirror-action "jump-right"))
+
+       (action
+         (name "duck-right")
+         (fps 15.0)
+         (hitbox 5 62 0 0)
+         (images "head-ice-duck-0.png"))
+
+       (action
+         (name "duck-left")
+         (fps 15.0)
+         (hitbox 27 62 0 0)
+         (mirror-action "duck-right"))
+
+       (action
+         (name "skid-right")
+         (hitbox 6 31 0 0)
+         (images "head-ice-skid-0.png"))
+
+       (action
+         (name "skid-left")
+         (hitbox 27 31 0 0)
+         (mirror-action "skid-right"))
+
+       (action
+         (name "kick-right")
+         (hitbox 5 32 0 0)
+         (images "head-ice-stand-0.png"))
+
+       (action
+         (name "kick-left")
+         (hitbox 27 32 0 0)
+         (mirror-action "kick-right"))
+
+       (action
+         (name "buttjump-right")
+         (hitbox 5 32 0 0)
+         (images "head-ice-stand-0.png"))
+
+       (action
+         (name "buttjump-left")
+         (hitbox 27 32 0 0)
+         (mirror-action "buttjump-right"))
+
+       (action
+         (name "idle-right")
+         (fps 1.0)
+         (hitbox 6 31 0 0)
+         (images "head-idle-blink-0.png"
+                 "head-idle-blink-1.png"))
+
+       (action
+         (name "idle-left")
+         (fps 1.0)
+         (hitbox 27 31 0 0)
+         (mirror-action "idle-right")))
diff --git a/data/images/creatures/tux_big/head-ice-duck-0.png b/data/images/creatures/tux_big/head-ice-duck-0.png
new file mode 100644 (file)
index 0000000..3ab94a2
Binary files /dev/null and b/data/images/creatures/tux_big/head-ice-duck-0.png differ
diff --git a/data/images/creatures/tux_big/head-ice-skid-0.png b/data/images/creatures/tux_big/head-ice-skid-0.png
new file mode 100644 (file)
index 0000000..65dc805
Binary files /dev/null and b/data/images/creatures/tux_big/head-ice-skid-0.png differ
diff --git a/data/images/creatures/tux_big/head-ice-stand-0.png b/data/images/creatures/tux_big/head-ice-stand-0.png
new file mode 100644 (file)
index 0000000..2ca5337
Binary files /dev/null and b/data/images/creatures/tux_big/head-ice-stand-0.png differ
index 9f7938c..386d8a0 100644 (file)
@@ -1,6 +1,6 @@
 (supertux-sprite
  (action
-  (hitbox 12 12 0 0)
+  (hitbox 2 2 12 10)
   (fps 20)
   (images "ice_bullet.png")
  )
diff --git a/data/images/objects/particles/icetux-cap.png b/data/images/objects/particles/icetux-cap.png
new file mode 100644 (file)
index 0000000..edc4923
Binary files /dev/null and b/data/images/objects/particles/icetux-cap.png differ
diff --git a/data/images/objects/particles/icetux-cap.sprite b/data/images/objects/particles/icetux-cap.sprite
new file mode 100644 (file)
index 0000000..772fc3e
--- /dev/null
@@ -0,0 +1,14 @@
+(supertux-sprite
+ (action
+  (name "right")
+  (fps 1)
+  (images 
+    "icetux-cap.png"
+  )
+ )
+ (action
+  (name "left")
+  (fps 1)
+  (mirror-action "right")
+ )
+)
index 131ef43..5da3775 100644 (file)
@@ -24,6 +24,11 @@ function fire()
        sector.Tux.add_bonus("fireflower");
 }
 
+function ice()
+{
+       sector.Tux.add_bonus("iceflower");
+}
+
 function shrink()
 {
        sector.Tux.add_bonus("none");
index 299dece..f99b808 100644 (file)
@@ -34,7 +34,7 @@ static const float X_OFFSCREEN_DISTANCE = 1600;
 static const float Y_OFFSCREEN_DISTANCE = 1200;
 
 BadGuy::BadGuy(const Vector& pos, const std::string& sprite_name, int layer)
-  : MovingSprite(pos, sprite_name, layer, COLGROUP_DISABLED), countMe(true), dir(LEFT), start_dir(AUTO), state(STATE_INIT), on_ground_flag(false)
+  : MovingSprite(pos, sprite_name, layer, COLGROUP_DISABLED), countMe(true), dir(LEFT), start_dir(AUTO), frozen(false), state(STATE_INIT), on_ground_flag(false)
 {
   start_position = bbox.p1;
 
@@ -43,7 +43,7 @@ BadGuy::BadGuy(const Vector& pos, const std::string& sprite_name, int layer)
 }
 
 BadGuy::BadGuy(const Vector& pos, Direction direction, const std::string& sprite_name, int layer)
-  : MovingSprite(pos, sprite_name, layer, COLGROUP_DISABLED), countMe(true), dir(direction), start_dir(direction), state(STATE_INIT), on_ground_flag(false)
+  : MovingSprite(pos, sprite_name, layer, COLGROUP_DISABLED), countMe(true), dir(direction), start_dir(direction), frozen(false), state(STATE_INIT), on_ground_flag(false)
 {
   start_position = bbox.p1;
 
@@ -52,7 +52,7 @@ BadGuy::BadGuy(const Vector& pos, Direction direction, const std::string& sprite
 }
 
 BadGuy::BadGuy(const lisp::Lisp& reader, const std::string& sprite_name, int layer)
-  : MovingSprite(reader, sprite_name, layer, COLGROUP_DISABLED), countMe(true), dir(LEFT), start_dir(AUTO), state(STATE_INIT), on_ground_flag(false)
+  : MovingSprite(reader, sprite_name, layer, COLGROUP_DISABLED), countMe(true), dir(LEFT), start_dir(AUTO), frozen(false), state(STATE_INIT), on_ground_flag(false)
 {
   start_position = bbox.p1;
 
@@ -222,6 +222,8 @@ BadGuy::collision_player(Player& player, const CollisionHit& )
     return ABORT_MOVE;
   }
 
+  if(frozen)
+    unfreeze();
   player.kill(false);
   return FORCE_MOVE;
 }
@@ -241,8 +243,16 @@ BadGuy::collision_squished(Player& )
 HitResponse
 BadGuy::collision_bullet(Bullet& bullet, const CollisionHit& )
 {
+  if(frozen) {
+    if(bullet.get_type() == FIRE_BONUS)
+      unfreeze();
+    else
+      return FORCE_MOVE;
+  } else if(bullet.get_type() == ICE_BONUS && is_freezable()) {
+    freeze();
+  } else
+    kill_fall();
   bullet.remove_me();
-  kill_fall();
   return ABORT_MOVE;
 }
 
@@ -425,3 +435,29 @@ BadGuy::on_ground()
 {
   return on_ground_flag;
 }
+
+void
+BadGuy::freeze()
+{
+  set_group(COLGROUP_MOVING_STATIC);
+  frozen = true;
+}
+
+void
+BadGuy::unfreeze()
+{
+  set_group(COLGROUP_MOVING);
+  frozen = false;
+}
+
+bool
+BadGuy::is_freezable() const
+{
+  return false;
+}
+
+bool
+BadGuy::is_frozen() const
+{
+  return frozen;
+}
index d5cf873..bbcbad8 100644 (file)
@@ -93,6 +93,20 @@ public:
    * during runtime. */
   bool countMe;
 
+  /**
+   * Called when hit by an ice bullet, and is_freezable() returns true.
+   */
+  virtual void freeze();
+
+  /**
+   * Called to unfreeze the badguy.
+   */
+  virtual void unfreeze();
+
+  virtual bool is_freezable() const;
+
+  bool is_frozen() const;
+
 protected:
   enum State {
     STATE_INIT,
@@ -185,6 +199,8 @@ protected:
    */
   bool on_ground();
 
+  bool frozen;
+
 private:
   void try_activate();
 
index 67ef6fc..c0fdbf8 100644 (file)
@@ -60,6 +60,8 @@ Dispenser::write(lisp::Writer& writer)
 void
 Dispenser::activate()
 {
+   if(frozen)
+     return;
    dispense_timer.start(cycle, true);
    launch_badguy();
 }
@@ -122,4 +124,23 @@ Dispenser::launch_badguy()
   }
 }
 
+void
+Dispenser::freeze()
+{
+  BadGuy::freeze();
+  dispense_timer.stop();
+}
+
+void
+Dispenser::unfreeze()
+{
+  BadGuy::unfreeze();
+  activate();
+}
+
+bool
+Dispenser::is_freezable() const
+{
+  return true;
+}
 IMPLEMENT_FACTORY(Dispenser, "dispenser")
index c01e19e..90f2a3a 100644 (file)
@@ -32,6 +32,10 @@ public:
   void write(lisp::Writer& writer);
   void active_update(float elapsed_time);
 
+  void freeze();
+  void unfreeze();
+  bool is_freezable() const;
+
   virtual Dispenser* clone() const { return new Dispenser(*this); }
 
 protected:
index b603125..8035120 100644 (file)
@@ -91,7 +91,8 @@ Fish::collision_tile(uint32_t tile_attributes)
 
     // stop when we have reached the stop position
     if (get_pos().y >= stop_y) {
-      start_waiting();
+      if(!frozen)
+        start_waiting();
       movement = Vector(0, 0);
     }
 
@@ -109,7 +110,8 @@ Fish::active_update(float elapsed_time)
   }
 
   // set sprite
-  sprite->set_action(physic.get_velocity_y() < 0 ? "normal" : "down");
+  if(!frozen)
+    sprite->set_action(physic.get_velocity_y() < 0 ? "normal" : "down");
 
   // we can't afford flying out of the tilemap, 'cause the engine would remove us.
   if ((get_pos().y - 31.8) < 0) // too high, let us fall
@@ -136,4 +138,25 @@ Fish::jump()
   set_group(COLGROUP_MOVING);
 }
 
+void
+Fish::freeze()
+{
+  BadGuy::freeze();
+  sprite->set_action(physic.get_velocity_y() < 0 ? "iced" : "iced-down");
+  waiting.stop();
+}
+
+void
+Fish::unfreeze()
+{ // does this happen at all? (or do fishes die when they fall frozen?)
+  BadGuy::unfreeze();
+  start_waiting();
+}
+
+bool
+Fish::is_freezable() const
+{
+  return true;
+}
+
 IMPLEMENT_FACTORY(Fish, "fish")
index 413b5c2..fa36dee 100644 (file)
@@ -37,6 +37,10 @@ public:
   void write(lisp::Writer& );
   void active_update(float);
 
+  void freeze();
+  void unfreeze();
+  bool is_freezable() const;
+
   virtual Fish* clone() const { return new Fish(*this); }
 
 private:
index 012adaa..706a7d7 100644 (file)
@@ -63,7 +63,7 @@ Jumpy::hit(const CollisionHit& chit)
       groundhit_pos_set = true;
     }
 
-    physic.set_velocity_y(JUMPSPEED);
+    physic.set_velocity_y(frozen ? 0 : JUMPSPEED);
     // TODO create a nice sound for this...
     //sound_manager->play("sounds/skid.wav");
   } else if(chit.top) {
@@ -78,6 +78,9 @@ Jumpy::active_update(float elapsed_time)
 {
   BadGuy::active_update(elapsed_time);
 
+  if(frozen)
+    return;
+
   Player* player = this->get_nearest_player();
   if (player)
   {
@@ -99,4 +102,18 @@ Jumpy::active_update(float elapsed_time)
     sprite->set_action(dir == LEFT ? "left-down" : "right-down");
 }
 
+void
+Jumpy::freeze()
+{
+  BadGuy::freeze();
+  physic.set_velocity_y(std::max(0.0f, physic.get_velocity_y()));
+  sprite->set_action(dir == LEFT ? "left-iced" : "right-iced");
+}
+
+bool
+Jumpy::is_freezable() const
+{
+  return true;
+}
+
 IMPLEMENT_FACTORY(Jumpy, "jumpy")
index fa39085..b0f9e3e 100644 (file)
@@ -33,6 +33,9 @@ public:
   void write(lisp::Writer& writer);
   void active_update(float);
 
+  void freeze();
+  bool is_freezable() const;
+
   virtual Jumpy* clone() const { return new Jumpy(*this); }
 
 private:
index 68e0768..0526c95 100644 (file)
@@ -28,6 +28,7 @@ MrBomb::MrBomb(const lisp::Lisp& reader)
 {
   walk_speed = 80;
   max_drop_height = 0;
+  grabbed = false;
 
   //Check if we need another sprite
   if( !reader.get( "sprite", sprite_name ) ){
@@ -47,6 +48,7 @@ MrBomb::MrBomb(const Vector& pos, Direction d)
 {
   walk_speed = 80;
   max_drop_height = 0;
+  grabbed = false;
 }
 
 void
@@ -57,6 +59,22 @@ MrBomb::write(lisp::Writer& writer)
   writer.end_list("mrbomb");
 }
 
+HitResponse
+MrBomb::collision(GameObject& object, const CollisionHit& hit)
+{
+  if(grabbed)
+    return FORCE_MOVE;
+  return WalkingBadguy::collision(object, hit);
+}
+
+HitResponse
+MrBomb::collision_player(Player& player, const CollisionHit& hit)
+{
+  if(grabbed)
+    return FORCE_MOVE;
+  return WalkingBadguy::collision_player(player, hit);
+}
+
 bool
 MrBomb::collision_squished(Player& player)
 {
@@ -67,6 +85,14 @@ MrBomb::collision_squished(Player& player)
 }
 
 void
+MrBomb::active_update(float elapsed_time)
+{
+  if(grabbed)
+    return;
+  WalkingBadguy::active_update(elapsed_time);
+}
+
+void
 MrBomb::kill_fall()
 {
   remove_me();
@@ -75,4 +101,42 @@ MrBomb::kill_fall()
   bomb->explode();
 }
 
+void
+MrBomb::grab(MovingObject&, const Vector& pos, Direction dir)
+{
+  assert(frozen);
+  movement = pos - get_pos();
+  this->dir = dir;
+  sprite->set_action(dir == LEFT ? "iced-left" : "iced-right");
+  set_group(COLGROUP_DISABLED);
+  grabbed = true;
+}
+
+void
+MrBomb::ungrab(MovingObject& , Direction dir)
+{
+  this->dir = dir;
+  set_group(COLGROUP_MOVING);
+  grabbed = false;
+}
+
+void
+MrBomb::freeze()
+{
+  WalkingBadguy::freeze();
+  sprite->set_action(dir == LEFT ? "iced-left" : "iced-right");
+}
+
+bool
+MrBomb::is_freezable() const
+{
+  return true;
+}
+
+bool
+MrBomb::is_portable() const
+{
+  return frozen;
+}
+
 IMPLEMENT_FACTORY(MrBomb, "mrbomb")
index 845c063..3a0adaf 100644 (file)
@@ -21,8 +21,9 @@
 #define __MRBOMB_H__
 
 #include "walking_badguy.hpp"
+#include "object/portable.hpp"
 
-class MrBomb : public WalkingBadguy
+class MrBomb : public WalkingBadguy, public Portable
 {
 public:
   MrBomb(const lisp::Lisp& reader);
@@ -30,11 +31,25 @@ public:
 
   void write(lisp::Writer& writer);
   void kill_fall();
+  HitResponse collision(GameObject& object, const CollisionHit& hit);
+  HitResponse collision_player(Player& player, const CollisionHit& hit);
+
+  void active_update(float elapsed_time);
+
+  void grab(MovingObject& object, const Vector& pos, Direction dir);
+  void ungrab(MovingObject& object, Direction dir);
+  bool is_portable() const;
+
+  void freeze();
+  bool is_freezable() const;
 
   virtual MrBomb* clone() const { return new MrBomb(*this); }
 
 protected:
   bool collision_squished(Player& player);
+
+private:
+  bool grabbed;
 };
 
 #endif
index f2b42ac..eebf19a 100644 (file)
@@ -36,4 +36,17 @@ Spiky::write(lisp::Writer& writer)
   writer.end_list("spiky");
 }
 
+void
+Spiky::freeze()
+{
+  WalkingBadguy::freeze();
+  sprite->set_action(dir == LEFT ? "iced-left" : "iced-right");
+}
+
+bool
+Spiky::is_freezable() const
+{
+  return true;
+}
+
 IMPLEMENT_FACTORY(Spiky, "spiky")
index 98f7e28..b90a0ec 100644 (file)
@@ -30,6 +30,9 @@ public:
   void write(lisp::Writer& writer);
   virtual Spiky* clone() const { return new Spiky(*this); }
 
+  void freeze();
+  bool is_freezable() const;
+
 private:
 };
 
index c81ea1d..ad80b8d 100644 (file)
@@ -106,4 +106,18 @@ SSpiky::active_update(float elapsed_time) {
   }
 }
 
+void
+SSpiky::freeze()
+{
+  WalkingBadguy::freeze();
+  sprite->set_action(dir == LEFT ? "iced-left" : "iced-right");
+  state = SSPIKY_WALKING; // if we get hit while sleeping, wake up :)
+}
+
+bool
+SSpiky::is_freezable() const
+{
+  return true;
+}
+
 IMPLEMENT_FACTORY(SSpiky, "sspiky")
index d99629d..8e346cd 100644 (file)
@@ -33,6 +33,9 @@ public:
   HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
   void active_update(float elapsed_time);
 
+  void freeze();
+  bool is_freezable() const;
+
   virtual SSpiky* clone() const { return new SSpiky(*this); }
 
 protected:
index 66cc3f9..74c2fd3 100644 (file)
@@ -48,6 +48,8 @@ WalkingBadguy::write(lisp::Writer& writer)
 void
 WalkingBadguy::activate()
 {
+  if(frozen)
+    return;
   sprite->set_action(dir == LEFT ? walk_left_action : walk_right_action);
   bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
   physic.set_velocity_x(dir == LEFT ? -walk_speed : walk_speed);
@@ -97,7 +99,23 @@ WalkingBadguy::collision_badguy(BadGuy& , const CollisionHit& hit)
 void
 WalkingBadguy::turn_around()
 {
+  if(frozen)
+    return;
   dir = dir == LEFT ? RIGHT : LEFT;
   sprite->set_action(dir == LEFT ? walk_left_action : walk_right_action);
-  physic.set_velocity_x(dir == LEFT ? -walk_speed : walk_speed);
+  physic.set_velocity_x(-physic.get_velocity_x());
+}
+
+void
+WalkingBadguy::freeze()
+{
+  BadGuy::freeze();
+  physic.set_velocity_x(0);
+}
+
+void
+WalkingBadguy::unfreeze()
+{
+  BadGuy::unfreeze();
+  WalkingBadguy::activate();
 }
index 6f023a8..313a529 100644 (file)
@@ -37,6 +37,8 @@ public:
   void active_update(float elapsed_time);
   void collision_solid(const CollisionHit& hit);
   HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
+  void freeze();
+  void unfreeze();
 
 protected:
   void turn_around();
index b6145e6..3a35faf 100644 (file)
@@ -33,17 +33,21 @@ namespace {
   const float BULLET_STARTING_YM = 0;
 }
 
-Bullet::Bullet(const Vector& pos, float xm, int dir)
-  : life_count(3)
+Bullet::Bullet(const Vector& pos, float xm, int dir, BonusType type)
+  : life_count(3), type(type)
 {
-  sprite.reset(sprite_manager->create("images/objects/bullets/firebullet.sprite"));
+  float speed = dir == RIGHT ? BULLET_XM : -BULLET_XM;
+  physic.set_velocity_x(speed + xm);
+
+  if(type == FIRE_BONUS) {
+    sprite.reset(sprite_manager->create("images/objects/bullets/firebullet.sprite"));
+  } else if(type == ICE_BONUS) {
+    life_count = 10;
+    sprite.reset(sprite_manager->create("images/objects/bullets/icebullet.sprite"));
+  }
 
   bbox.set_pos(pos);
   bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
-
-  float speed = dir == RIGHT ? BULLET_XM : -BULLET_XM;
-  physic.set_velocity_x(speed + xm);
-  physic.set_velocity_y(BULLET_STARTING_YM);
 }
 
 Bullet::~Bullet()
@@ -83,7 +87,11 @@ Bullet::collision_solid(const CollisionHit& hit)
     physic.set_velocity_y(-physic.get_velocity_y());
     life_count--;
   } else if(hit.left || hit.right) {
-    remove_me();
+    if(type == ICE_BONUS) {
+      physic.set_velocity_x(-physic.get_velocity_x());
+      life_count--;
+    } else
+      remove_me();
   }
 }
 
index c5eb76d..90547a3 100644 (file)
 #include "moving_object.hpp"
 #include "physic.hpp"
 #include "sprite/sprite.hpp"
+#include "player_status.hpp"
 
 class Bullet : public MovingObject
 {
 public:
-  Bullet(const Vector& pos, float xm, int dir);
+  Bullet(const Vector& pos, float xm, int dir, BonusType type);
   ~Bullet();
 
   void update(float elapsed_time);
   void draw(DrawingContext& context);
   void collision_solid(const CollisionHit& hit);
   HitResponse collision(GameObject& other, const CollisionHit& hit);
+  
+  BonusType get_type()
+  {
+    return type;
+  }
 
 private:
   int life_count;
   Physic physic;
   std::auto_ptr<Sprite> sprite;
+  BonusType type;
 };
 
 #endif
index 0379da3..12d440a 100644 (file)
@@ -591,7 +591,7 @@ Player::handle_input()
   handle_vertical_input();
 
   /* Shoot! */
-  if (controller->pressed(Controller::ACTION) && player_status->bonus == FIRE_BONUS) {
+  if (controller->pressed(Controller::ACTION) && (player_status->bonus == FIRE_BONUS || player_status->bonus == ICE_BONUS)) {
     if(Sector::current()->add_bullet(
          get_pos() + ((dir == LEFT)? Vector(0, bbox.get_height()/2)
                       : Vector(32, bbox.get_height()/2)),
@@ -757,6 +757,14 @@ Player::set_bonus(BonusType type, bool animate)
       std::string action = (dir==LEFT)?"left":"right";
       Sector::current()->add_object(new SpriteParticle("images/objects/particles/firetux-helmet.sprite", action, ppos, ANCHOR_TOP, pspeed, paccel, LAYER_OBJECTS-1));
     }
+    if ((player_status->bonus == ICE_BONUS) && (animate)) {
+      // visually lose cap
+      Vector ppos = Vector((bbox.p1.x + bbox.p2.x) / 2, bbox.p1.y);
+      Vector pspeed = Vector(((dir==LEFT) ? +100 : -100), -300);
+      Vector paccel = Vector(0, 1000);
+      std::string action = (dir==LEFT)?"left":"right";
+      Sector::current()->add_object(new SpriteParticle("images/objects/particles/icetux-cap.sprite", action, ppos, ANCHOR_TOP, pspeed, paccel, LAYER_OBJECTS-1));
+    }
     player_status->max_fire_bullets = 0;
     player_status->max_ice_bullets = 0;
   }
index 5c49081..215d6d5 100644 (file)
@@ -99,7 +99,7 @@ void load_shared()
   fire_tux->feet = sprite_manager->create("images/creatures/tux_big/big-tux-feet.sprite");
 
   ice_tux = new TuxBodyParts();
-  ice_tux->head = sprite_manager->create("images/creatures/tux_big/big-tux-head.sprite");
+  ice_tux->head = sprite_manager->create("images/creatures/tux_big/big-ice-tux-head.sprite");
   ice_tux->body = sprite_manager->create("images/creatures/tux_big/big-tux-body.sprite");
   ice_tux->arms = sprite_manager->create("images/creatures/tux_big/big-tux-arms.sprite");
   ice_tux->feet = sprite_manager->create("images/creatures/tux_big/big-tux-feet.sprite");
index ddc62a2..eede80b 100644 (file)
@@ -1283,9 +1283,12 @@ Sector::add_bullet(const Vector& pos, float xm, Direction dir)
   // TODO remove this function and move these checks elsewhere...
 
   Bullet* new_bullet = 0;
-  if((int)bullets.size() >= player_status->max_fire_bullets)
+  if((player_status->bonus == FIRE_BONUS &&
+      (int)bullets.size() >= player_status->max_fire_bullets) ||
+     (player_status->bonus == ICE_BONUS &&
+      (int)bullets.size() >= player_status->max_ice_bullets))
     return false;
-  new_bullet = new Bullet(pos, xm, dir);
+  new_bullet = new Bullet(pos, xm, dir, player_status->bonus);
   add_object(new_bullet);
 
   sound_manager->play("sounds/shoot.wav");