Powerup: Iceflower improvements
authorLMH <lmh.0013@gmail.com>
Sat, 14 Jun 2014 22:08:35 +0000 (12:08 -1000)
committerLMH <lmh.0013@gmail.com>
Sat, 14 Jun 2014 22:16:11 +0000 (12:16 -1000)
Generalized code for changing frozen badguy sprite to iced, and added a default behavior for freezable badguys without iced graphics.  Frozen badguys no longer unfreeze on touch.  Added ice vulnerability to forest badguys.
Note: there are some mild bugs as a result of this change, which should be fixed in subsequent improvements to make Iceflower a more viable powerup.

37 files changed:
data/images/creatures/jumpy/jumpy.sprite
data/images/creatures/snowjumpy/snowjumpy.sprite
src/badguy/badguy.cpp
src/badguy/fish.cpp
src/badguy/goldbomb.cpp
src/badguy/haywire.cpp
src/badguy/haywire.hpp
src/badguy/igel.cpp
src/badguy/igel.hpp
src/badguy/jumpy.cpp
src/badguy/mole.cpp
src/badguy/mole.hpp
src/badguy/mrbomb.cpp
src/badguy/mrbomb.hpp
src/badguy/mrtree.cpp
src/badguy/mrtree.hpp
src/badguy/owl.cpp
src/badguy/owl.hpp
src/badguy/poisonivy.cpp
src/badguy/poisonivy.hpp
src/badguy/skullyhop.cpp
src/badguy/skullyhop.hpp
src/badguy/snail.cpp
src/badguy/snail.hpp
src/badguy/spidermite.cpp
src/badguy/spidermite.hpp
src/badguy/spiky.cpp
src/badguy/spiky.hpp
src/badguy/sspiky.cpp
src/badguy/stumpy.cpp
src/badguy/stumpy.hpp
src/badguy/toad.cpp
src/badguy/toad.hpp
src/badguy/walkingleaf.cpp
src/badguy/walkingleaf.hpp
src/badguy/zeekling.cpp
src/badguy/zeekling.hpp

index 0f0bd89..85d8460 100644 (file)
   (mirror-action "left-middle"))
  
  (action
-  (name "left-iced")
+  (name "iced-left")
   (hitbox 7 8 31.8 31.8)
   (images "iced-left-up.png"))
  
  (action
-  (name "right-iced")
+  (name "iced-right")
   (hitbox 7 8 31.8 31.8)
-  (mirror-action "left-iced"))
+  (mirror-action "iced-left"))
 )
 
index 0f0bd89..85d8460 100644 (file)
   (mirror-action "left-middle"))
  
  (action
-  (name "left-iced")
+  (name "iced-left")
   (hitbox 7 8 31.8 31.8)
   (images "iced-left-up.png"))
  
  (action
-  (name "right-iced")
+  (name "iced-right")
   (hitbox 7 8 31.8 31.8)
-  (mirror-action "left-iced"))
+  (mirror-action "iced-left"))
 )
 
index 68187b6..99a5618 100644 (file)
@@ -219,6 +219,8 @@ void
 BadGuy::active_update(float elapsed_time)
 {
   movement = physic.get_movement(elapsed_time);
+  if(frozen)
+    sprite->stop_animation();
 }
 
 void
@@ -302,8 +304,11 @@ BadGuy::collision_player(Player& player, const CollisionHit& )
     return ABORT_MOVE;
   }
 
+  //TODO: unfreeze timer
   if(frozen)
-    unfreeze();
+    //unfreeze();
+    return FORCE_MOVE;
+
   player.kill(false);
   return FORCE_MOVE;
 }
@@ -548,6 +553,15 @@ BadGuy::freeze()
 {
   set_group(COLGROUP_MOVING_STATIC);
   frozen = true;
+
+  if(sprite->has_action("iced-left"))
+    sprite->set_action(dir == LEFT ? "iced-left" : "iced-right", 1);
+  // when no iced action exists, default to shading badguy blue
+  else
+  {
+    sprite->set_color(Color(0.60, 0.72, 0.88f));
+    sprite->stop_animation();
+  }
 }
 
 void
@@ -555,6 +569,13 @@ BadGuy::unfreeze()
 {
   set_group(colgroup_active);
   frozen = false;
+
+  // restore original color if needed
+  if(!sprite->has_action("iced-left"))
+  {
+    sprite->set_color(Color(1.00, 1.00, 1.00f));
+    sprite->set_animation_loops();
+  }
 }
 
 bool
index c8bf809..f6d3f7c 100644 (file)
@@ -138,6 +138,7 @@ Fish::freeze()
 {
   BadGuy::freeze();
   sprite->set_action(physic.get_velocity_y() < 0 ? "iced" : "iced-down");
+  sprite->set_color(Color(1.0f, 1.0f, 1.0f));
   waiting.stop();
 }
 
index 59911a7..60cc90f 100644 (file)
@@ -221,7 +221,6 @@ GoldBomb::freeze()
 {
   if(tstate == STATE_NORMAL){
     WalkingBadguy::freeze();
-    sprite->set_action(dir == LEFT ? "iced-left" : "iced-right");
   }
 }
 
index 97d1ead..b968de5 100644 (file)
@@ -178,13 +178,6 @@ Haywire::kill_fall()
   run_dead_script();
 }
 
-void
-Haywire::freeze()
-{
-  WalkingBadguy::freeze();
-  sprite->set_action(dir == LEFT ? "iced-left" : "iced-right");
-}
-
 bool
 Haywire::is_freezable() const
 {
index ae944e8..83d0401 100644 (file)
@@ -33,7 +33,6 @@ public:
 
   void active_update(float elapsed_time);
 
-  void freeze();
   bool is_freezable() const;
 
 protected:
index 857023d..c1769a4 100644 (file)
@@ -99,8 +99,9 @@ Igel::active_update(float elapsed_time)
 HitResponse
 Igel::collision_bullet(Bullet& bullet, const CollisionHit& hit)
 {
-  // default reaction if hit on front side
-  if (((dir == LEFT) && hit.left) || ((dir == RIGHT) && hit.right)) {
+  // default reaction if hit on front side or for freeze and unfreeze
+  if (((dir == LEFT) && hit.left) || ((dir == RIGHT) && hit.right) ||
+    (bullet.get_type() == ICE_BONUS) || ((bullet.get_type() == FIRE_BONUS) && (frozen))) {
     return BadGuy::collision_bullet(bullet, hit);
   }
 
@@ -110,6 +111,12 @@ Igel::collision_bullet(Bullet& bullet, const CollisionHit& hit)
 }
 
 bool
+Igel::is_freezable() const
+{
+  return true;
+}
+
+bool
 Igel::collision_squished(GameObject& )
 {
   // this will hurt
index c63d766..dbade8a 100644 (file)
@@ -32,6 +32,8 @@ public:
 
   void active_update(float elapsed_time);
 
+  bool is_freezable() const;
+
 protected:
   bool collision_squished(GameObject& object);
   void be_normal(); /**< switch to state STATE_NORMAL */
index 1117d64..272e6ae 100644 (file)
@@ -99,7 +99,6 @@ 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
index c9a40cd..46daf14 100644 (file)
@@ -76,6 +76,9 @@ Mole::collision_badguy(BadGuy& , const CollisionHit& )
 bool
 Mole::collision_squished(GameObject& )
 {
+  if (frozen)
+    return true;
+
   set_state(DEAD);
   sound_manager->play("sounds/squish.wav", get_pos());
   run_dead_script();
@@ -101,6 +104,9 @@ Mole::active_update(float elapsed_time)
 {
   BadGuy::active_update(elapsed_time);
 
+  if (frozen)
+    return;
+
   switch (state) {
     case PRE_THROWING:
       if (timer.check()) {
@@ -132,9 +138,18 @@ Mole::active_update(float elapsed_time)
 
 }
 
+bool
+Mole::is_freezable() const
+{
+  return true;
+}
+
 void
 Mole::set_state(MoleState new_state)
 {
+  if (frozen)
+    return;
+
   switch (new_state) {
     case PRE_THROWING:
       sprite->set_action("idle");
index a6e62c4..cca93cd 100644 (file)
@@ -32,6 +32,8 @@ public:
   void activate();
   void active_update(float);
 
+  bool is_freezable() const;
+
 private:
   enum MoleState {
     PRE_THROWING,
index 8b41189..438d328 100644 (file)
@@ -131,13 +131,6 @@ MrBomb::ungrab(MovingObject& , Direction dir)
   grabbed = false;
 }
 
-void
-MrBomb::freeze()
-{
-  WalkingBadguy::freeze();
-  sprite->set_action(dir == LEFT ? "iced-left" : "iced-right");
-}
-
 bool
 MrBomb::is_freezable() const
 {
index 4ad45f3..8c06a36 100644 (file)
@@ -36,7 +36,6 @@ public:
   void ungrab(MovingObject& object, Direction dir);
   bool is_portable() const;
 
-  void freeze();
   bool is_freezable() const;
 
 protected:
index a5023ac..cc8feb8 100644 (file)
@@ -42,6 +42,12 @@ MrTree::MrTree(const Reader& reader)
 }
 
 bool
+MrTree::is_freezable() const
+{
+  return true;
+}
+
+bool
 MrTree::collision_squished(GameObject& object)
 {
   // replace with Stumpy
index 8b78ab9..e57a931 100644 (file)
@@ -24,6 +24,8 @@ class MrTree : public WalkingBadguy
 public:
   MrTree(const Reader& reader);
 
+  bool is_freezable() const;
+
 protected:
   bool collision_squished(GameObject& object);
 
index f379153..f31fe9c 100644 (file)
@@ -99,6 +99,9 @@ Owl::active_update (float elapsed_time)
 {
   BadGuy::active_update (elapsed_time);
 
+  if(frozen)
+    return;
+
   if (carried_object != NULL) {
     if (!is_above_player ()) {
       Vector obj_pos = get_anchor_pos (bbox, ANCHOR_BOTTOM);
@@ -156,8 +159,39 @@ Owl::kill_fall()
 }
 
 void
+Owl::freeze()
+{
+  if (carried_object != NULL) {
+    carried_object->ungrab (*this, dir);
+    carried_object = NULL;
+  }
+  physic.enable_gravity(true);
+  BadGuy::freeze();
+}
+
+void
+Owl::unfreeze()
+{
+  BadGuy::unfreeze();
+  physic.set_velocity_x(dir == LEFT ? -FLYING_SPEED : FLYING_SPEED);
+  physic.enable_gravity(false);
+  sprite->set_action(dir == LEFT ? "left" : "right");
+}
+
+bool
+Owl::is_freezable() const
+{
+  return true;
+}
+
+void
 Owl::collision_solid(const CollisionHit& hit)
 {
+  if(frozen)
+  {
+    BadGuy::collision_solid(hit);
+    return;
+  }
   if(hit.top || hit.bottom) {
     physic.set_velocity_y(0);
   } else if(hit.left || hit.right) {
index 6614fe1..83b38b9 100644 (file)
@@ -31,6 +31,10 @@ public:
   void collision_solid(const CollisionHit& hit);
   void kill_fall();
 
+  void freeze();
+  void unfreeze();
+  bool is_freezable() const;
+
 protected:
   bool is_above_player (void);
   void active_update (float elapsed_time);
index 3347465..c8973af 100644 (file)
@@ -35,6 +35,12 @@ PoisonIvy::PoisonIvy(const Vector& pos, Direction d)
 }
 
 bool
+PoisonIvy::is_freezable() const
+{
+  return true;
+}
+
+bool
 PoisonIvy::collision_squished(GameObject& object)
 {
   sprite->set_action(dir == LEFT ? "squished-left" : "squished-right");
index 3e93c4f..a1bafa3 100644 (file)
@@ -25,6 +25,8 @@ public:
   PoisonIvy(const Reader& reader);
   PoisonIvy(const Vector& pos, Direction d);
 
+  bool is_freezable() const;
+
 protected:
   bool collision_squished(GameObject& object);
 
index f7a1c67..2d2fc89 100644 (file)
@@ -80,6 +80,9 @@ const float VERTICAL_SPEED = -450;   /**< y-speed when jumping */
 bool
 SkullyHop::collision_squished(GameObject& object)
 {
+  if (frozen)
+    return BadGuy::collision_squished(object);
+
   sprite->set_action(dir == LEFT ? "squished-left" : "squished-right");
   kill_squished(object);
   return true;
@@ -88,6 +91,12 @@ SkullyHop::collision_squished(GameObject& object)
 void
 SkullyHop::collision_solid(const CollisionHit& hit)
 {
+  if (frozen)
+  {
+    BadGuy::collision_solid(hit);
+    return;
+  }
+
   // just default behaviour (i.e. stop at floor/walls) when squished
   if (BadGuy::get_state() == STATE_SQUISHED) {
     BadGuy::collision_solid(hit);
@@ -128,6 +137,10 @@ SkullyHop::active_update(float elapsed_time)
 {
   BadGuy::active_update(elapsed_time);
 
+  // no change if frozen
+  if (frozen)
+    return;
+
   // charge when fully recovered
   if ((state == STANDING) && (recover_timer.check())) {
     set_state(CHARGING);
@@ -141,4 +154,17 @@ SkullyHop::active_update(float elapsed_time)
   }
 }
 
+void
+SkullyHop::unfreeze()
+{
+  BadGuy::unfreeze();
+  initialize();
+}
+
+bool
+SkullyHop::is_freezable() const
+{
+  return true;
+}
+
 /* EOF */
index 5698fe6..6b12cb6 100644 (file)
@@ -34,6 +34,9 @@ public:
   bool collision_squished(GameObject& object);
   void active_update(float elapsed_time);
 
+  void unfreeze();
+  bool is_freezable() const;
+
 private:
   enum SkullyHopState {
     STANDING,
index faf8660..c3b3e8c 100644 (file)
@@ -102,6 +102,12 @@ Snail::can_break(){
 void
 Snail::active_update(float elapsed_time)
 {
+  if(frozen)
+  {
+    BadGuy::active_update(elapsed_time);
+    return;
+  }
+
   switch (state) {
 
     case STATE_NORMAL:
@@ -132,9 +138,21 @@ Snail::active_update(float elapsed_time)
   BadGuy::active_update(elapsed_time);
 }
 
+bool
+Snail::is_freezable() const
+{
+  return true;
+}
+
 void
 Snail::collision_solid(const CollisionHit& hit)
 {
+  if(frozen)
+  {
+    WalkingBadguy::collision_solid(hit);
+    return;
+  }
+
   switch (state) {
     case STATE_NORMAL:
       WalkingBadguy::collision_solid(hit);
@@ -166,6 +184,9 @@ Snail::collision_solid(const CollisionHit& hit)
 HitResponse
 Snail::collision_badguy(BadGuy& badguy, const CollisionHit& hit)
 {
+  if(frozen)
+    return WalkingBadguy::collision_badguy(badguy, hit);
+
   switch(state) {
     case STATE_NORMAL:
       return WalkingBadguy::collision_badguy(badguy, hit);
@@ -185,6 +206,9 @@ Snail::collision_badguy(BadGuy& badguy, const CollisionHit& hit)
 HitResponse
 Snail::collision_player(Player& player, const CollisionHit& hit)
 {
+  if(frozen)
+    return WalkingBadguy::collision_player(player, hit);
+
   // handle kicks from left or right side
   if(state == STATE_FLAT && (hit.left || hit.right)) {
     if(hit.left) {
@@ -203,6 +227,9 @@ Snail::collision_player(Player& player, const CollisionHit& hit)
 bool
 Snail::collision_squished(GameObject& object)
 {
+  if(frozen)
+    return WalkingBadguy::collision_squished(object);
+
   Player* player = dynamic_cast<Player*>(&object);
   if(player && (player->does_buttjump || player->is_invincible())) {
     kill_fall();
index 40181b9..cd62a1e 100644 (file)
@@ -36,6 +36,8 @@ public:
 
   void active_update(float elapsed_time);
 
+  bool is_freezable() const;
+
 protected:
   bool collision_squished(GameObject& object);
   void be_normal(); /**< switch to state STATE_NORMAL */
index 634088a..f8b2fc6 100644 (file)
@@ -67,6 +67,11 @@ SpiderMite::collision_solid(const CollisionHit& hit)
 void
 SpiderMite::active_update(float elapsed_time)
 {
+  if(frozen)
+  {
+    BadGuy::active_update(elapsed_time);
+    return;
+  }
   if(timer.check()) {
     if(mode == FLY_UP) {
       mode = FLY_DOWN;
@@ -86,4 +91,25 @@ SpiderMite::active_update(float elapsed_time)
   }
 }
 
+void
+SpiderMite::freeze()
+{
+  physic.enable_gravity(true);
+  BadGuy::freeze();
+}
+
+void
+SpiderMite::unfreeze()
+{
+  BadGuy::unfreeze();
+  physic.enable_gravity(false);
+  initialize();
+}
+
+bool
+SpiderMite::is_freezable() const
+{
+  return true;
+}
+
 /* EOF */
index c2e7675..4b90a46 100644 (file)
@@ -29,6 +29,10 @@ public:
   void active_update(float elapsed_time);
   void collision_solid(const CollisionHit& hit);
 
+  void freeze();
+  void unfreeze();
+  bool is_freezable() const;
+
 protected:
   enum SpiderMiteMode {
     FLY_UP,
index 3e4297f..cc2cd3c 100644 (file)
@@ -26,13 +26,6 @@ Spiky::Spiky(const Reader& reader)
   max_drop_height = 600;
 }
 
-void
-Spiky::freeze()
-{
-  WalkingBadguy::freeze();
-  sprite->set_action(dir == LEFT ? "iced-left" : "iced-right");
-}
-
 bool
 Spiky::is_freezable() const
 {
index 122d720..e1cd6f5 100644 (file)
@@ -24,7 +24,6 @@ class Spiky : public WalkingBadguy
 public:
   Spiky(const Reader& reader);
 
-  void freeze();
   bool is_freezable() const;
 
 private:
index cea68dd..013d834 100644 (file)
@@ -99,7 +99,6 @@ 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 :)
 }
 
index 8c47c66..f06f20e 100644 (file)
@@ -159,4 +159,10 @@ Stumpy::collision_badguy(BadGuy& badguy, const CollisionHit& hit)
   return CONTINUE;
 }
 
+bool
+Stumpy::is_freezable() const
+{
+  return true;
+}
+
 /* EOF */
index d85036d..37b0dc3 100644 (file)
@@ -30,6 +30,8 @@ public:
   void collision_solid(const CollisionHit& hit);
   HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
 
+  bool is_freezable() const;
+
 protected:
   enum MyState {
     STATE_INVINCIBLE, STATE_NORMAL
index 9fc27c6..f70f87a 100644 (file)
@@ -55,10 +55,12 @@ Toad::initialize()
 void
 Toad::set_state(ToadState newState)
 {
+
   if (newState == IDLE) {
     physic.set_velocity_x(0);
     physic.set_velocity_y(0);
-    sprite->set_action(dir == LEFT ? "idle-left" : "idle-right");
+    if (!frozen)
+      sprite->set_action(dir == LEFT ? "idle-left" : "idle-right");
 
     recover_timer.start(TOAD_RECOVER_TIME);
   } else
@@ -90,6 +92,13 @@ Toad::collision_squished(GameObject& object)
 void
 Toad::collision_solid(const CollisionHit& hit)
 {
+  // default behavior when frozen
+  if (frozen)
+  {
+    BadGuy::collision_solid(hit);
+    return;
+  }
+
   // just default behaviour (i.e. stop at floor/walls) when squished
   if (BadGuy::get_state() == STATE_SQUISHED) {
     BadGuy::collision_solid(hit);
@@ -141,18 +150,32 @@ Toad::active_update(float elapsed_time)
 {
   BadGuy::active_update(elapsed_time);
 
-  // change sprite when we are falling
-  if ((state == JUMPING) && (physic.get_velocity_y() > 0)) {
+
+  // change sprite when we are falling and not frozen
+  if ((state == JUMPING) && (physic.get_velocity_y() > 0) && !frozen) {
     set_state(FALLING);
     return;
   }
 
-  // jump when fully recovered
-  if ((state == IDLE) && (recover_timer.check())) {
+  // jump when fully recovered and if not frozen
+  if ((state == IDLE) && (recover_timer.check() && !frozen)) {
     set_state(JUMPING);
     return;
   }
 
 }
 
+void
+Toad::unfreeze()
+{
+  BadGuy::unfreeze();
+  initialize();
+}
+
+bool
+Toad::is_freezable() const
+{
+  return true;
+}
+
 /* EOF */
index 39a53f3..1b483b1 100644 (file)
@@ -34,6 +34,9 @@ public:
   bool collision_squished(GameObject& object);
   void active_update(float elapsed_time);
 
+  void unfreeze();
+  bool is_freezable() const;
+
 protected:
   enum ToadState {
     IDLE,
index 2593137..08c93af 100644 (file)
@@ -41,4 +41,9 @@ WalkingLeaf::collision_squished(GameObject& object)
   return true;
 }
 
+bool
+WalkingLeaf::is_freezable() const
+{
+  return true;
+}
 /* EOF */
index 88d1d71..ef7e0c2 100644 (file)
@@ -28,6 +28,8 @@ public:
   WalkingLeaf(const Reader& reader);
   WalkingLeaf(const Vector& pos, Direction d);
 
+  bool is_freezable() const;
+
 protected:
   bool collision_squished(GameObject& object);
 
index 8fff3ea..0ca8a56 100644 (file)
@@ -69,6 +69,11 @@ Zeekling::collision_squished(GameObject& object)
 
 void
 Zeekling::onBumpHorizontal() {
+  if (frozen)
+  {
+    physic.set_velocity_x(0);
+    return;
+  }
   if (state == FLYING) {
     dir = (dir == LEFT ? RIGHT : LEFT);
     sprite->set_action(dir == LEFT ? "left" : "right");
@@ -92,6 +97,12 @@ Zeekling::onBumpHorizontal() {
 
 void
 Zeekling::onBumpVertical() {
+  if (frozen)
+  {
+    physic.set_velocity_y(0);
+    physic.set_velocity_x(0);
+    return;
+  }
   if (state == FLYING) {
     physic.set_velocity_y(0);
   } else
@@ -127,6 +138,8 @@ Zeekling::collision_solid(const CollisionHit& hit)
  */
 bool
 Zeekling::should_we_dive() {
+  if (frozen)
+    return false;
 
   const MovingObject* player = this->get_nearest_player();
   if (player && last_player && (player == last_player)) {
@@ -200,4 +213,26 @@ Zeekling::active_update(float elapsed_time) {
   }
 }
 
+void
+Zeekling::freeze()
+{
+  BadGuy::freeze();
+  physic.enable_gravity(true);
+}
+
+void
+Zeekling::unfreeze()
+{
+  BadGuy::unfreeze();
+  physic.enable_gravity(false);
+  state = FLYING;
+  initialize();
+}
+
+bool
+Zeekling::is_freezable() const
+{
+  return true;
+}
+
 /* EOF */
index 0f68f8a..bd8548b 100644 (file)
@@ -30,6 +30,10 @@ public:
   void collision_solid(const CollisionHit& hit);
   void active_update(float elapsed_time);
 
+  void freeze();
+  void unfreeze();
+  bool is_freezable() const;
+
 private:
   bool collision_squished(GameObject& object);
   bool should_we_dive();