Badguys squish badguys.
authorChristoph Sommer <mail@christoph-sommer.de>
Sat, 4 Nov 2006 14:13:27 +0000 (14:13 +0000)
committerChristoph Sommer <mail@christoph-sommer.de>
Sat, 4 Nov 2006 14:13:27 +0000 (14:13 +0000)
Badguys keep track of floor normal they are standing on.

SVN-Revision: 4435

43 files changed:
src/badguy/badguy.cpp
src/badguy/badguy.hpp
src/badguy/bouncing_snowball.cpp
src/badguy/bouncing_snowball.hpp
src/badguy/dispenser.cpp
src/badguy/dispenser.hpp
src/badguy/flyingsnowball.cpp
src/badguy/flyingsnowball.hpp
src/badguy/igel.cpp
src/badguy/igel.hpp
src/badguy/mole.cpp
src/badguy/mole.hpp
src/badguy/mrbomb.cpp
src/badguy/mrbomb.hpp
src/badguy/mriceblock.cpp
src/badguy/mriceblock.hpp
src/badguy/mrrocket.cpp
src/badguy/mrrocket.hpp
src/badguy/mrtree.cpp
src/badguy/mrtree.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/snowball.cpp
src/badguy/snowball.hpp
src/badguy/spidermite.cpp
src/badguy/spidermite.hpp
src/badguy/stumpy.cpp
src/badguy/stumpy.hpp
src/badguy/toad.cpp
src/badguy/toad.hpp
src/badguy/totem.cpp
src/badguy/totem.hpp
src/badguy/walking_badguy.cpp
src/badguy/walkingleaf.cpp
src/badguy/walkingleaf.hpp
src/badguy/yeti.cpp
src/badguy/yeti.hpp
src/badguy/zeekling.cpp
src/badguy/zeekling.hpp

index 8d9ae8c..75e59d3 100644 (file)
@@ -185,12 +185,30 @@ BadGuy::collision(GameObject& other, const CollisionHit& hit)
       return ABORT_MOVE;
     case STATE_ACTIVE: {
       BadGuy* badguy = dynamic_cast<BadGuy*> (&other);
-      if(badguy && badguy->state == STATE_ACTIVE && badguy->get_group() == COLGROUP_MOVING)
-        return collision_badguy(*badguy, hit);
+      if(badguy && badguy->state == STATE_ACTIVE && badguy->get_group() == COLGROUP_MOVING) {
+
+       // hit from above?
+       if (badguy->get_bbox().p2.y < (bbox.p1.y + 16)) {
+         if(collision_squished(*badguy)) {
+           return ABORT_MOVE;
+         }
+       }
+
+       return collision_badguy(*badguy, hit);
+      }
 
       Player* player = dynamic_cast<Player*> (&other);
-      if(player)
+      if(player) {
+
+       // hit from above?
+       if (player->get_bbox().p2.y < (bbox.p1.y + 16)) {
+         if(collision_squished(*player)) {
+           return ABORT_MOVE;
+         }
+       }
+
         return collision_player(*player, hit);
+      }
 
       Bullet* bullet = dynamic_cast<Bullet*> (&other);
       if(bullet)
@@ -218,14 +236,6 @@ BadGuy::collision_solid(const CollisionHit& hit)
 HitResponse
 BadGuy::collision_player(Player& player, const CollisionHit& )
 {
-  // hit from above?
-  if(player.get_bbox().p2.y < (bbox.p1.y + 16)) {
-    // if it's not possible to squish us, then this will hurt
-    if(collision_squished(player)) {
-      return ABORT_MOVE;
-    }
-  }
-
   if(player.is_invincible()) {
     kill_fall();
     return ABORT_MOVE;
@@ -244,7 +254,7 @@ BadGuy::collision_badguy(BadGuy& , const CollisionHit& )
 }
 
 bool
-BadGuy::collision_squished(Player& )
+BadGuy::collision_squished(GameObject& )
 {
   return false;
 }
@@ -296,7 +306,7 @@ BadGuy::collision_bullet(Bullet& bullet, const CollisionHit& hit)
 }
 
 void
-BadGuy::kill_squished(Player& player)
+BadGuy::kill_squished(GameObject& object)
 {
   sound_manager->play("sounds/squish.wav", get_pos());
   physic.enable_gravity(true);
@@ -304,8 +314,11 @@ BadGuy::kill_squished(Player& player)
   physic.set_velocity_y(0);
   set_state(STATE_SQUISHED);
   set_group(COLGROUP_MOVING_ONLY_STATIC);
-  if (countMe) Sector::current()->get_level()->stats.badguys++;
-  player.bounce(*this);
+  Player* player = dynamic_cast<Player*>(&object);
+  if (player) {
+    if (countMe) Sector::current()->get_level()->stats.badguys++;
+    player->bounce(*this);
+  }
 }
 
 void
@@ -466,7 +479,10 @@ BadGuy::get_nearest_player()
 void
 BadGuy::update_on_ground_flag(const CollisionHit& hit)
 {
-  if (hit.bottom) on_ground_flag = true;
+  if (hit.bottom) {
+    on_ground_flag = true;
+    floor_normal = hit.slope_normal;
+  }
 }
 
 bool
@@ -475,6 +491,12 @@ BadGuy::on_ground()
   return on_ground_flag;
 }
 
+Vector
+BadGuy::get_floor_normal()
+{
+  return floor_normal;
+}
+
 void
 BadGuy::freeze()
 {
index cf0adc2..7853f8b 100644 (file)
@@ -146,7 +146,7 @@ protected:
   /** Called when the player hit the badguy from above. You should return true
    * if the badguy was squished, false if squishing wasn't possible
    */
-  virtual bool collision_squished(Player& player);
+  virtual bool collision_squished(GameObject& object);
 
   /** Called when the badguy collided with a bullet */
   virtual HitResponse collision_bullet(Bullet& bullet, const CollisionHit& hit);
@@ -164,7 +164,7 @@ protected:
   /** called when the badguy has been deactivated */
   virtual void deactivate();
 
-  void kill_squished(Player& player);
+  void kill_squished(GameObject& object);
 
   void set_state(State state);
   State get_state() const
@@ -219,6 +219,11 @@ protected:
    */
   bool on_ground();
 
+  /**
+   * Returns floor normal stored the last time when update_on_ground_flag was called and we touched something solid from above.
+   */
+  Vector get_floor_normal();
+
   bool frozen;
   bool ignited; /**< true if this badguy is currently on fire */
 
@@ -227,7 +232,9 @@ private:
 
   State state;
   Timer state_timer;
-  bool on_ground_flag;
+  bool on_ground_flag; /**< true if we touched something solid from above and update_on_ground_flag was called last frame */
+  Vector floor_normal; /**< floor normal stored the last time when update_on_ground_flag was called and we touched something solid from above */
+
 };
 
 #endif
index 72d1acf..f84561b 100644 (file)
@@ -53,10 +53,10 @@ BouncingSnowball::activate()
 }
 
 bool
-BouncingSnowball::collision_squished(Player& player)
+BouncingSnowball::collision_squished(GameObject& object)
 {
   sprite->set_action("squished");
-  kill_squished(player);
+  kill_squished(object);
   return true;
 }
 
index 371d60a..ed2c5cb 100644 (file)
@@ -36,7 +36,7 @@ public:
   virtual BouncingSnowball* clone() const { return new BouncingSnowball(*this); }
 
 protected:
-  bool collision_squished(Player& player);
+  bool collision_squished(GameObject& object);
 };
 
 #endif
index 2f3dce5..123e4aa 100644 (file)
@@ -74,13 +74,14 @@ Dispenser::deactivate()
 
 //TODO: Add launching velocity to certain badguys
 bool
-Dispenser::collision_squished(Player& player)
+Dispenser::collision_squished(GameObject& object)
 {
   //TODO: Should it act like a normal tile when killed?
   sprite->set_action(dir == LEFT ? "broken-left" : "broken-right");
   dispense_timer.start(0);
-  player.bounce(*this);
-  kill_squished(player);
+  Player* player = dynamic_cast<Player*>(&object);
+  if (player) player->bounce(*this);
+  kill_squished(object);
   return true;
 }
 
index 5313b4f..e553d54 100644 (file)
@@ -40,7 +40,7 @@ public:
   virtual Dispenser* clone() const { return new Dispenser(*this); }
 
 protected:
-  bool collision_squished(Player& player);
+  bool collision_squished(GameObject& object);
   void launch_badguy();
   float cycle;
   std::string badguy;
index 517f6b9..fd68430 100644 (file)
@@ -68,10 +68,10 @@ FlyingSnowBall::activate()
 }
 
 bool
-FlyingSnowBall::collision_squished(Player& player)
+FlyingSnowBall::collision_squished(GameObject& object)
 {
   sprite->set_action(dir == LEFT ? "squished-left" : "squished-right");
-  kill_squished(player);
+  kill_squished(object);
   return true;
 }
 
index 9b24434..43e9324 100644 (file)
@@ -41,7 +41,7 @@ protected:
     FLY_DOWN
   };
   FlyingSnowballMode mode;
-  bool collision_squished(Player& player);
+  bool collision_squished(GameObject& object);
 private:
   Timer timer;
   Timer puff_timer; /**< time until the next smoke puff is spawned */
index 6a4e477..b8450d2 100644 (file)
@@ -34,14 +34,14 @@ Igel::Igel(const lisp::Lisp& reader)
   : WalkingBadguy(reader, "images/creatures/igel/igel.sprite", "walking-left", "walking-right")
 {
   walk_speed = WALKSPEED;
-  max_drop_height = 0;
+  max_drop_height = 16;
 }
 
 Igel::Igel(const Vector& pos, Direction d)
   : WalkingBadguy(pos, d, "images/creatures/igel/igel.sprite", "walking-left", "walking-right")
 {
   walk_speed = WALKSPEED;
-  max_drop_height = 0;
+  max_drop_height = 16;
 }
 
 void
@@ -118,7 +118,7 @@ Igel::collision_bullet(Bullet& bullet, const CollisionHit& hit)
 }
 
 bool
-Igel::collision_squished(Player& )
+Igel::collision_squished(GameObject& )
 {
   // this will hurt
   return false;
index 0c83cef..4d2b82f 100644 (file)
@@ -40,7 +40,7 @@ public:
   virtual Igel* clone() const { return new Igel(*this); }
 
 protected:
-  bool collision_squished(Player& player);
+  bool collision_squished(GameObject& object);
   void be_normal(); /**< switch to state STATE_NORMAL */
   void turn_around(); /**< reverse direction, assumes we are in STATE_NORMAL */
   bool can_see(const MovingObject& o); /**< check if we can see o */
index 765319d..d3e4e46 100644 (file)
@@ -74,7 +74,7 @@ Mole::collision_badguy(BadGuy& , const CollisionHit& )
 }
 
 bool
-Mole::collision_squished(Player& )
+Mole::collision_squished(GameObject& )
 {
   set_state(DEAD);
   sound_manager->play("sounds/squish.wav", get_pos());
index 378a21e..2a1fa0f 100644 (file)
@@ -30,7 +30,7 @@ public:
 
   void kill_fall();
   HitResponse collision_badguy(BadGuy& , const CollisionHit& );
-  bool collision_squished(Player& player);
+  bool collision_squished(GameObject& object);
 
   void activate();
   void write(lisp::Writer& );
index 0526c95..dcd7198 100644 (file)
@@ -27,7 +27,7 @@ MrBomb::MrBomb(const lisp::Lisp& reader)
        : WalkingBadguy(reader, "images/creatures/mr_bomb/mr_bomb.sprite", "left", "right")
 {
   walk_speed = 80;
-  max_drop_height = 0;
+  max_drop_height = 16;
   grabbed = false;
 
   //Check if we need another sprite
@@ -47,7 +47,7 @@ MrBomb::MrBomb(const Vector& pos, Direction d)
        : WalkingBadguy(pos, d, "images/creatures/mr_bomb/mr_bomb.sprite", "left", "right")
 {
   walk_speed = 80;
-  max_drop_height = 0;
+  max_drop_height = 16;
   grabbed = false;
 }
 
@@ -76,11 +76,11 @@ MrBomb::collision_player(Player& player, const CollisionHit& hit)
 }
 
 bool
-MrBomb::collision_squished(Player& player)
+MrBomb::collision_squished(GameObject& object)
 {
   remove_me();
   Sector::current()->add_object(new Bomb(get_pos(), dir, sprite_name ));
-  kill_squished(player);
+  kill_squished(object);
   return true;
 }
 
index 3a0adaf..14f326d 100644 (file)
@@ -46,7 +46,7 @@ public:
   virtual MrBomb* clone() const { return new MrBomb(*this); }
 
 protected:
-  bool collision_squished(Player& player);
+  bool collision_squished(GameObject& object);
 
 private:
   bool grabbed;
index 7b954bf..697fed9 100644 (file)
@@ -174,7 +174,7 @@ MrIceBlock::collision_badguy(BadGuy& badguy, const CollisionHit& hit)
 }
 
 bool
-MrIceBlock::collision_squished(Player& player)
+MrIceBlock::collision_squished(GameObject& object)
 {
   switch(ice_state) {
     case ICESTATE_KICKED:
@@ -188,10 +188,13 @@ MrIceBlock::collision_squished(Player& player)
       set_state(ICESTATE_FLAT);
       break;
     case ICESTATE_FLAT:
-      if(player.get_pos().x < get_pos().x) {
-        dir = RIGHT;
-      } else {
-        dir = LEFT;
+      {
+       MovingObject* movingobject = dynamic_cast<MovingObject*>(&object);
+       if (movingobject && (movingobject->get_pos().x < get_pos().x)) {
+         dir = RIGHT;
+       } else {
+         dir = LEFT;
+       }
       }
       set_state(ICESTATE_KICKED);
       break;
@@ -200,7 +203,8 @@ MrIceBlock::collision_squished(Player& player)
       break;
   }
 
-  player.bounce(*this);
+  Player* player = dynamic_cast<Player*>(&object);
+  if (player) player->bounce(*this);
   return true;
 }
 
index 93aba4e..a00c5e7 100644 (file)
@@ -47,7 +47,7 @@ public:
   virtual MrIceBlock* clone() const { return new MrIceBlock(*this); }
 
 protected:
-  bool collision_squished(Player& player);
+  bool collision_squished(GameObject& object);
 
 private:
   enum IceState {
index cbf5d31..3f6cc3b 100644 (file)
@@ -66,10 +66,10 @@ MrRocket::active_update(float elapsed_time)
 }
 
 bool
-MrRocket::collision_squished(Player& player)
+MrRocket::collision_squished(GameObject& object)
 {
   sprite->set_action(dir == LEFT ? "squished-left" : "squished-right");
-  kill_squished(player);
+  kill_squished(object);
   kill_fall();
   return true;
 }
index 11ae037..bb95805 100644 (file)
@@ -38,7 +38,7 @@ public:
   virtual MrRocket* clone() const { return new MrRocket(*this); }
 
 protected:
-  bool collision_squished(Player& player);
+  bool collision_squished(GameObject& object);
   Timer collision_timer;
 };
 
index bf79234..ddcc43a 100644 (file)
@@ -37,7 +37,7 @@ MrTree::MrTree(const lisp::Lisp& reader)
   : WalkingBadguy(reader, "images/creatures/mr_tree/mr_tree.sprite","left","right")
 {
   walk_speed = WALKSPEED;
-  max_drop_height = 0;
+  max_drop_height = 16;
   sound_manager->preload("sounds/mr_tree.ogg");
 }
 
@@ -50,7 +50,7 @@ MrTree::write(lisp::Writer& writer)
 }
 
 bool
-MrTree::collision_squished(Player& player)
+MrTree::collision_squished(GameObject& object)
 {
   // replace with Stumpy
   Vector stumpy_pos = get_pos();
@@ -62,7 +62,8 @@ MrTree::collision_squished(Player& player)
 
   // give Feedback
   sound_manager->play("sounds/mr_tree.ogg", get_pos());
-  player.bounce(*this);
+  Player* player = dynamic_cast<Player*>(&object);
+  if (player) player->bounce(*this);
 
   // spawn some particles
   // TODO: provide convenience function in MovingSprite or MovingObject?
index 4eae549..0b884a1 100644 (file)
@@ -30,7 +30,7 @@ public:
   virtual MrTree* clone() const { return new MrTree(*this); }
 
 protected:
-  bool collision_squished(Player& player);
+  bool collision_squished(GameObject& object);
 
 };
 
index e881933..67b4c7f 100644 (file)
@@ -44,7 +44,7 @@ PoisonIvy::write(lisp::Writer& writer)
 }
 
 bool
-PoisonIvy::collision_squished(Player& player)
+PoisonIvy::collision_squished(GameObject& object)
 {
   sprite->set_action(dir == LEFT ? "squished-left" : "squished-right");
   // spawn some particles
@@ -59,7 +59,7 @@ PoisonIvy::collision_squished(Player& player)
     Vector paccel = Vector(0, 100);
     Sector::current()->add_object(new SpriteParticle("images/objects/particles/poisonivy.sprite", "default", ppos, ANCHOR_MIDDLE, pspeed, paccel, LAYER_OBJECTS-1));
   }
-  kill_squished(player);
+  kill_squished(object);
   return true;
 }
 
index 908a788..783f232 100644 (file)
@@ -32,7 +32,7 @@ public:
   virtual PoisonIvy* clone() const { return new PoisonIvy(*this); }
 
 protected:
-  bool collision_squished(Player& player);
+  bool collision_squished(GameObject& object);
 
 };
 
index 8d2dbca..8bf61d7 100644 (file)
@@ -84,10 +84,10 @@ SkullyHop::set_state(SkullyHopState newState)
 }
 
 bool
-SkullyHop::collision_squished(Player& player)
+SkullyHop::collision_squished(GameObject& object)
 {
   sprite->set_action(dir == LEFT ? "squished-left" : "squished-right");
-  kill_squished(player);
+  kill_squished(object);
   return true;
 }
 
index 1ceab05..0569722 100644 (file)
@@ -36,7 +36,7 @@ public:
   void write(lisp::Writer& writer);
   void collision_solid(const CollisionHit& hit);
   HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
-  bool collision_squished(Player& player);
+  bool collision_squished(GameObject& object);
   void active_update(float elapsed_time);
 
   virtual SkullyHop* clone() const { return new SkullyHop(*this); }
index e40a24d..1f21922 100644 (file)
@@ -206,7 +206,7 @@ Snail::collision_badguy(BadGuy& badguy, const CollisionHit& hit)
 }
 
 bool
-Snail::collision_squished(Player& player)
+Snail::collision_squished(GameObject& object)
 {
   switch(state) {
 
@@ -224,11 +224,13 @@ Snail::collision_squished(Player& player)
 
     case STATE_FLAT:
       sound_manager->play("sounds/kick.wav", get_pos());
-
-      if(player.get_pos().x < get_pos().x) {
-        dir = RIGHT;
-      } else {
-        dir = LEFT;
+      {
+       MovingObject* movingobject = dynamic_cast<MovingObject*>(&object);
+       if (movingobject && (movingobject->get_pos().x < get_pos().x)) {
+         dir = RIGHT;
+       } else {
+         dir = LEFT;
+       }
       }
       be_kicked();
       break;
@@ -238,7 +240,8 @@ Snail::collision_squished(Player& player)
 
   }
 
-  player.bounce(*this);
+  Player* player = dynamic_cast<Player*>(&object);
+  if (player) player->bounce(*this);
   return true;
 }
 
index 0e80409..642df55 100644 (file)
@@ -42,7 +42,7 @@ public:
   virtual Snail* clone() const { return new Snail(*this); }
 
 protected:
-  bool collision_squished(Player& player);
+  bool collision_squished(GameObject& object);
   void be_normal(); /**< switch to state STATE_NORMAL */
   void be_flat(); /**< switch to state STATE_FLAT */
   void be_kicked(); /**< switch to state STATE_KICKED_DELAY */
index 2876357..8e690cb 100644 (file)
@@ -42,10 +42,10 @@ SnowBall::write(lisp::Writer& writer)
 }
 
 bool
-SnowBall::collision_squished(Player& player)
+SnowBall::collision_squished(GameObject& object)
 {
   sprite->set_action(dir == LEFT ? "squished-left" : "squished-right");
-  kill_squished(player);
+  kill_squished(object);
   return true;
 }
 
index a68bc3e..ef32818 100644 (file)
@@ -32,7 +32,7 @@ public:
   virtual SnowBall* clone() const { return new SnowBall(*this); }
 
 protected:
-  bool collision_squished(Player& player);
+  bool collision_squished(GameObject& object);
 
 };
 
index 42210d2..ee9eac9 100644 (file)
@@ -58,10 +58,10 @@ SpiderMite::activate()
 }
 
 bool
-SpiderMite::collision_squished(Player& player)
+SpiderMite::collision_squished(GameObject& object)
 {
   sprite->set_action(dir == LEFT ? "squished-left" : "squished-right");
-  kill_squished(player);
+  kill_squished(object);
   return true;
 }
 
index 91333aa..ee36b5b 100644 (file)
@@ -41,7 +41,7 @@ protected:
     FLY_DOWN
   };
   SpiderMiteMode mode;
-  bool collision_squished(Player& player);
+  bool collision_squished(GameObject& object);
 private:
   Timer timer;
 };
index 282b3a6..f451546 100644 (file)
@@ -31,7 +31,7 @@ Stumpy::Stumpy(const lisp::Lisp& reader)
   : WalkingBadguy(reader, "images/creatures/mr_tree/stumpy.sprite","left","right"), mystate(STATE_NORMAL)
 {
   walk_speed = WALKSPEED;
-  max_drop_height = 0;
+  max_drop_height = 16;
   sound_manager->preload("sounds/mr_tree.ogg");
   sound_manager->preload("sounds/mr_treehit.ogg");
 }
@@ -40,7 +40,7 @@ Stumpy::Stumpy(const Vector& pos, Direction d)
   : WalkingBadguy(pos, d, "images/creatures/mr_tree/stumpy.sprite","left","right"), mystate(STATE_INVINCIBLE)
 {
   walk_speed = WALKSPEED;
-  max_drop_height = 0;
+  max_drop_height = 16;
   sound_manager->preload("sounds/mr_treehit.ogg");
   invincible_timer.start(INVINCIBLE_TIME);
 }
@@ -87,13 +87,14 @@ Stumpy::active_update(float elapsed_time)
 }
 
 bool
-Stumpy::collision_squished(Player& player)
+Stumpy::collision_squished(GameObject& object)
 {
 
   // if we're still invincible, we ignore the hit
   if (mystate == STATE_INVINCIBLE) {
     sound_manager->play("sounds/mr_treehit.ogg", get_pos());
-    player.bounce(*this);
+    Player* player = dynamic_cast<Player*>(&object);
+    if (player) player->bounce(*this);
     return true;
   }
 
@@ -101,7 +102,7 @@ Stumpy::collision_squished(Player& player)
   if (mystate == STATE_NORMAL) {
     sprite->set_action(dir == LEFT ? "squished-left" : "squished-right");
     set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
-    kill_squished(player);
+    kill_squished(object);
     // spawn some particles
     // TODO: provide convenience function in MovingSprite or MovingObject?
     for (int i = 0; i < 25; i++) {
index 25ca246..212e8c7 100644 (file)
@@ -44,7 +44,7 @@ protected:
 
   Timer invincible_timer;
 
-  bool collision_squished(Player& player);
+  bool collision_squished(GameObject& object);
 };
 
 #endif
index 9115e33..1657a9b 100644 (file)
@@ -86,10 +86,10 @@ Toad::set_state(ToadState newState)
 }
 
 bool
-Toad::collision_squished(Player& player)
+Toad::collision_squished(GameObject& object)
 {
   sprite->set_action(dir == LEFT ? "squished-left" : "squished-right");
-  kill_squished(player);
+  kill_squished(object);
   return true;
 }
 
index 7460757..b7c6746 100644 (file)
@@ -36,7 +36,7 @@ public:
   void write(lisp::Writer& writer);
   void collision_solid(const CollisionHit& hit);
   HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
-  bool collision_squished(Player& player);
+  bool collision_squished(GameObject& object);
   void active_update(float elapsed_time);
 
   virtual Toad* clone() const { return new Toad(*this); }
index 279038b..139aa14 100644 (file)
@@ -139,18 +139,19 @@ Totem::active_update(float elapsed_time)
 }
 
 bool
-Totem::collision_squished(Player& player)
+Totem::collision_squished(GameObject& object)
 {
   if (carrying) carrying->jump_off();
   if (carried_by) {
-    player.bounce(*this);
+    Player* player = dynamic_cast<Player*>(&object);
+    if (player) player->bounce(*this);
     jump_off();
   }
 
   sprite->set_action(dir == LEFT ? "squished-left" : "squished-right");
   bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
 
-  kill_squished(player);
+  kill_squished(object);
   return true;
 }
 
index 89ef732..682fe45 100644 (file)
@@ -46,7 +46,7 @@ protected:
   Totem* carrying; /**< Totem we are currently carrying (or 0) */
   Totem* carried_by; /**< Totem by which we are currently carried (or 0) */
 
-  bool collision_squished(Player& player);
+  bool collision_squished(GameObject& object);
   void kill_fall();
 
   void jump_on(Totem* target); /**< jump on target */
index e57a9b7..37816dc 100644 (file)
@@ -75,11 +75,14 @@ WalkingBadguy::collision_solid(const CollisionHit& hit)
 
   update_on_ground_flag(hit);
 
-  if (hit.top || hit.bottom) {
-    physic.set_velocity_y(0);
+  if (hit.top) {
+    if (physic.get_velocity_y() < 0) physic.set_velocity_y(0);
+  }
+  if (hit.bottom) {
+    if (physic.get_velocity_y() > 0) physic.set_velocity_y(0);
   }
 
-  if ((hit.left && dir == LEFT) || (hit.right && dir == RIGHT)) {
+  if ((hit.left && (hit.slope_normal.y == 0) && (dir == LEFT)) || (hit.right && (hit.slope_normal.y == 0) && (dir == RIGHT))) {
     turn_around();
   }
 
index 9f9778a..a057441 100644 (file)
@@ -27,21 +27,21 @@ WalkingLeaf::WalkingLeaf(const lisp::Lisp& reader)
        : WalkingBadguy(reader, "images/creatures/walkingleaf/walkingleaf.sprite", "left", "right")
 {
   walk_speed = 60;
-  max_drop_height = 0;
+  max_drop_height = 16;
 }
 
 WalkingLeaf::WalkingLeaf(const Vector& pos, Direction d)
        : WalkingBadguy(pos, d, "images/creatures/walkingleaf/walkingleaf.sprite", "left", "right")
 {
   walk_speed = 60;
-  max_drop_height = 0;
+  max_drop_height = 16;
 }
 
 bool
-WalkingLeaf::collision_squished(Player& player)
+WalkingLeaf::collision_squished(GameObject& object)
 {
   sprite->set_action(dir == LEFT ? "squished-left" : "squished-right");
-  kill_squished(player);
+  kill_squished(object);
   return true;
 }
 
index a221865..e2b84b1 100644 (file)
@@ -34,7 +34,7 @@ public:
   virtual WalkingLeaf* clone() const { return new WalkingLeaf(*this); }
 
 protected:
-  bool collision_squished(Player& player);
+  bool collision_squished(GameObject& object);
 
 };
 
index 2b18b98..51f9c13 100644 (file)
@@ -164,18 +164,21 @@ Yeti::summon_snowball()
 }
 
 bool
-Yeti::collision_squished(Player& player)
+Yeti::collision_squished(GameObject& object)
 {
-  kill_squished(player);
+  kill_squished(object);
 
   return true;
 }
 
 void
-Yeti::kill_squished(Player& player)
+Yeti::kill_squished(GameObject& object)
 {
-    player.bounce(*this);
-    take_hit(player);
+  Player* player = dynamic_cast<Player*>(&object);
+  if (player) {
+    player->bounce(*this);
+    take_hit(*player);
+  }
 }
 
 void Yeti::take_hit(Player& )
index d7e16ce..62e0909 100644 (file)
@@ -34,8 +34,8 @@ public:
   void activate();
   void active_update(float elapsed_time);
   void collision_solid(const CollisionHit& hit);
-  bool collision_squished(Player& player);
-  void kill_squished(Player& player);
+  bool collision_squished(GameObject& object);
+  void kill_squished(GameObject& object);
   void kill_fall();
 
   virtual Yeti* clone() const { return new Yeti(*this); }
index 85b2d47..8a17c4d 100644 (file)
@@ -58,10 +58,10 @@ Zeekling::activate()
 }
 
 bool
-Zeekling::collision_squished(Player& player)
+Zeekling::collision_squished(GameObject& object)
 {
   sprite->set_action(dir == LEFT ? "squished-left" : "squished-right");
-  kill_squished(player);
+  kill_squished(object);
   kill_fall();
   return true;
 }
index fd0f287..b851368 100644 (file)
@@ -38,7 +38,7 @@ public:
   virtual Zeekling* clone() const { return new Zeekling(*this); }
 
 protected:
-  bool collision_squished(Player& player);
+  bool collision_squished(GameObject& object);
   float speed;
 
   Timer diveRecoverTimer;