Happy Easter! Played with fireflower bonus: Carrying multiple fireflowers now means...
authorChristoph Sommer <mail@christoph-sommer.de>
Sun, 16 Apr 2006 14:43:57 +0000 (14:43 +0000)
committerChristoph Sommer <mail@christoph-sommer.de>
Sun, 16 Apr 2006 14:43:57 +0000 (14:43 +0000)
SVN-Revision: 3350

src/object/flower.cpp
src/object/growup.cpp
src/object/player.cpp
src/object/player.hpp
src/object/powerup.cpp
src/player_status.cpp
src/player_status.hpp
src/scripting/player.hpp
src/scripting/wrapper.cpp
src/sector.cpp

index 539366a..5bfbfc4 100644 (file)
@@ -65,9 +65,9 @@ Flower::collision(GameObject& other, const CollisionHit& )
     return ABORT_MOVE;
 
   if(type == FIREFLOWER)
-    player->set_bonus(FIRE_BONUS, true);
+    player->add_bonus(FIRE_BONUS, true);
   else
-    player->set_bonus(ICE_BONUS, true);
+    player->add_bonus(ICE_BONUS, true);
   
   sound_manager->play("sounds/fire-flower.wav");
   remove_me();
index 3b413e4..6b9ac4e 100644 (file)
@@ -64,7 +64,7 @@ GrowUp::collision(GameObject& other, const CollisionHit& hit)
   
   Player* player = dynamic_cast<Player*>(&other);
   if(player != 0) {
-    player->set_bonus(GROWUP_BONUS, true);
+    player->add_bonus(GROWUP_BONUS, true);
     sound_manager->play("sounds/grow.wav");
     remove_me();
     
index b0579d2..369ca83 100644 (file)
@@ -542,16 +542,16 @@ Player::add_coins(int count)
 }
 
 void
-Player::set_bonus(const std::string& bonustype)
+Player::add_bonus(const std::string& bonustype)
 {
   if(bonustype == "grow")
-    set_bonus(GROWUP_BONUS);
+    add_bonus(GROWUP_BONUS);
   else if(bonustype == "fireflower")
-    set_bonus(FIRE_BONUS);
+    add_bonus(FIRE_BONUS);
   else if(bonustype == "iceflower")
-    set_bonus(ICE_BONUS);
+    add_bonus(ICE_BONUS);
   else if(bonustype == "none")
-    set_bonus(NO_BONUS);
+    add_bonus(NO_BONUS);
   
   
   std::ostringstream msg;
@@ -560,17 +560,39 @@ Player::set_bonus(const std::string& bonustype)
 }
 
 void
-Player::set_bonus(BonusType type, bool animate)
+Player::add_bonus(BonusType type, bool animate)
 {
-  if(player_status->bonus >= type)
+  // always ignore NO_BONUS
+  if (type == NO_BONUS) {
     return;
-  
+  }
+
+  // ignore GROWUP_BONUS if we're already big
+  if (type == GROWUP_BONUS) {
+    if (player_status->bonus == GROWUP_BONUS) return; 
+    if (player_status->bonus == FIRE_BONUS) return;
+    if (player_status->bonus == ICE_BONUS) return;
+  }
+
+  set_bonus(type, animate);
+}
+
+void
+Player::set_bonus(BonusType type, bool animate)
+{
   if(player_status->bonus == NO_BONUS) {
     adjust_height = 62.8;
     if(animate)
       growing_timer.start(GROWING_TIME);
   }
-  
+
+  if ((type == NO_BONUS) || (type == GROWUP_BONUS)) {
+    player_status->max_fire_bullets = 0;
+    player_status->max_ice_bullets = 0;
+  }
+  if (type == FIRE_BONUS) player_status->max_fire_bullets++;
+  if (type == ICE_BONUS) player_status->max_ice_bullets++;
+
   player_status->bonus = type;
 }
 
@@ -869,7 +891,7 @@ Player::kill(HurtMode mode)
           || player_status->bonus == ICE_BONUS)
         {
           safe_timer.start(TUX_SAFE_TIME);
-          player_status->bonus = GROWUP_BONUS;
+         set_bonus(GROWUP_BONUS);
         }
       else 
         {
@@ -877,7 +899,7 @@ Player::kill(HurtMode mode)
           safe_timer.start(TUX_SAFE_TIME /* + GROWING_TIME */);
           adjust_height = 30.8;
           duck = false;
-          player_status->bonus = NO_BONUS;
+          set_bonus(NO_BONUS);
         }
     }
   else
@@ -893,7 +915,7 @@ Player::kill(HurtMode mode)
       physic.set_acceleration(0, 0);
       physic.set_velocity(0, 700);
       player_status->coins -= 25;
-      player_status->bonus = NO_BONUS;
+      set_bonus(NO_BONUS);
       dying = true;
       dying_timer.start(3.0);
       set_group(COLGROUP_DISABLED);
index 09b95dd..019fbd2 100644 (file)
@@ -148,9 +148,10 @@ public:
   void check_bounds(Camera* camera);
   void move(const Vector& vector);
 
-  virtual void set_bonus(const std::string& bonus);
+  virtual void add_bonus(const std::string& bonus);
   virtual void add_coins(int count);
-  void set_bonus(BonusType type, bool animate = false);
+  void add_bonus(BonusType type, bool animate = false); /**< picks up a bonus, taking care not to pick up lesser bonus items than we already have */
+  void set_bonus(BonusType type, bool animate = false); /**< like add_bonus, but can also downgrade the bonus items carried */
   PlayerStatus* get_status()
   {
     return player_status;
index 2e401ae..5551e07 100644 (file)
@@ -76,10 +76,10 @@ PowerUp::collision(GameObject& other, const CollisionHit& hit)
 
   // some defaults if no script has been set
   if (sprite_name == "images/powerups/egg/egg.sprite") {
-    player->set_bonus(GROWUP_BONUS, true);
+    player->add_bonus(GROWUP_BONUS, true);
     sound_manager->play("sounds/grow.wav");
   } else if (sprite_name == "images/powerups/fireflower/fireflower.sprite") {
-    player->set_bonus(FIRE_BONUS, true);
+    player->add_bonus(FIRE_BONUS, true);
     sound_manager->play("sounds/fire-flower.wav");
   } else if (sprite_name == "images/powerups/star/star.sprite") {
     player->make_invincible();
index 3fe09f2..432640c 100644 (file)
@@ -39,6 +39,8 @@ PlayerStatus* player_status = 0;
 PlayerStatus::PlayerStatus()
   : coins(START_COINS),
     bonus(NO_BONUS),
+    max_fire_bullets(0),
+    max_ice_bullets(0),
     score_multiplier(1),
     max_score_multiplier(1)
 {
@@ -113,6 +115,9 @@ PlayerStatus::write(lisp::Writer& writer)
       log_warning << "Unknown bonus type." << std::endl;
       writer.write_string("bonus", "none");
   }
+  writer.write_int("fireflowers", max_fire_bullets);
+  writer.write_int("iceflowers", max_ice_bullets);
+  
   writer.write_bool("key-brass", keys & KEY_BRASS);
   writer.write_bool("key-iron", keys & KEY_IRON);
   writer.write_bool("key-bronze", keys & KEY_BRONZE);
@@ -143,6 +148,9 @@ PlayerStatus::read(const lisp::Lisp& lisp)
       bonus = NO_BONUS;
     }
   }
+  lisp.get("fireflowers", max_fire_bullets);
+  lisp.get("iceflowers", max_ice_bullets);
+
   bool val = false;
   if(lisp.get("key-brass", val) && val == true)
     set_keys(KEY_BRASS);
index 5595d97..0e768ae 100644 (file)
@@ -59,6 +59,8 @@ public:
   
   int  coins;
   BonusType bonus;
+  int max_fire_bullets; /**< maximum number of fire bullets in play */
+  int max_ice_bullets; /**< maximum number of ice bullets in play */
 
   int score_multiplier;
   int max_score_multiplier;
@@ -77,7 +79,8 @@ private:
   // don't use this
   PlayerStatus(const PlayerStatus& other);
   
-  int  keys;
+  int keys;
+
   std::auto_ptr<Sprite> tux_life;
   std::auto_ptr<Sprite> key_iron;
   std::auto_ptr<Sprite> key_brass;
index 0a33769..63cea9b 100644 (file)
@@ -35,7 +35,7 @@ public:
    * Set tux bonus.
    * This can be "grow", "fireflower" or "iceflower" at the moment
    */
-  virtual void set_bonus(const std::string& bonus) = 0;
+  virtual void add_bonus(const std::string& bonus) = 0;
   /**
    * Give tux more coins
    */
index 26ac54a..fcef548 100644 (file)
@@ -999,11 +999,11 @@ static int Player_release_hook(SQUserPointer ptr, int )
   return 0;
 }
 
-static int Player_set_bonus_wrapper(HSQUIRRELVM vm)
+static int Player_add_bonus_wrapper(HSQUIRRELVM vm)
 {
   Scripting::Player* _this;
   if(SQ_FAILED(sq_getinstanceup(vm, 1, reinterpret_cast<SQUserPointer*> (&_this), 0))) {
-    sq_throwerror(vm, _SC("'set_bonus' called without instance"));
+    sq_throwerror(vm, _SC("'add_bonus' called without instance"));
     return SQ_ERROR;
   }
   const char* arg0;
@@ -1013,7 +1013,7 @@ static int Player_set_bonus_wrapper(HSQUIRRELVM vm)
   }
   
   try {
-    _this->set_bonus(arg0);
+    _this->add_bonus(arg0);
   
     return 0;
   
@@ -1021,7 +1021,7 @@ static int Player_set_bonus_wrapper(HSQUIRRELVM vm)
     sq_throwerror(vm, e.what());
     return SQ_ERROR;
   } catch(...) {
-    sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_bonus'"));
+    sq_throwerror(vm, _SC("Unexpected exception while executing function 'add_bonus'"));
     return SQ_ERROR;
   }
   
@@ -2645,10 +2645,10 @@ void register_supertux_wrapper(HSQUIRRELVM v)
     msg << "Couldn't create new class 'Player'";
     throw SquirrelError(v, msg.str());
   }
-  sq_pushstring(v, "set_bonus", -1);
-  sq_newclosure(v, &Player_set_bonus_wrapper, 0);
+  sq_pushstring(v, "add_bonus", -1);
+  sq_newclosure(v, &Player_add_bonus_wrapper, 0);
   if(SQ_FAILED(sq_createslot(v, -3))) {
-    throw SquirrelError(v, "Couldn't register function 'set_bonus'");
+    throw SquirrelError(v, "Couldn't register function 'add_bonus'");
   }
 
   sq_pushstring(v, "add_coins", -1);
index 93a0858..f746eec 100644 (file)
@@ -1087,16 +1087,14 @@ bool
 Sector::add_bullet(const Vector& pos, float xm, Direction dir)
 {
   // TODO remove this function and move these checks elsewhere...
-  static const size_t MAX_FIRE_BULLETS = 2;
-  static const size_t MAX_ICE_BULLETS = 1;
 
   Bullet* new_bullet = 0;
   if(player_status->bonus == FIRE_BONUS) {
-    if(bullets.size() > MAX_FIRE_BULLETS-1)
+    if((int)bullets.size() >= player_status->max_fire_bullets)
       return false;
     new_bullet = new Bullet(pos, xm, dir, FIRE_BULLET);
   } else if(player_status->bonus == ICE_BONUS) {
-    if(bullets.size() > MAX_ICE_BULLETS-1)
+    if((int)bullets.size() >= player_status->max_ice_bullets)
       return false;
     new_bullet = new Bullet(pos, xm, dir, ICE_BULLET);
   } else {