Bug 456: Avoid hurting Tux in a ravine.
[supertux.git] / src / object / unstable_tile.cpp
index 9f22448..5002d89 100644 (file)
@@ -1,99 +1,86 @@
-//  $Id$
-// 
-//  SuperTux
-//  Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//  SuperTux - Unstable Tile
+//  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//  Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
 //
-//  This program is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU General Public License
-//  as published by the Free Software Foundation; either version 2
-//  of the License, or (at your option) any later version.
+//  This program is free software: you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation, either version 3 of the License, or
+//  (at your option) any later version.
 //
 //  This program is distributed in the hope that it will be useful,
 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 //  GNU General Public License for more details.
-// 
+//
 //  You should have received a copy of the GNU General Public License
-//  along with this program; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-//  02111-1307, USA.
-
-#include <config.h>
+//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-#include "unstable_tile.h"
-#include "lisp/lisp.h"
-#include "object_factory.h"
-#include "player.h"
-#include "sector.h"
-#include "resources.h"
-#include "sprite/sprite_manager.h"
-#include "sprite/sprite.h"
+#include "object/unstable_tile.hpp"
 
-static const float CRACKTIME = 0.3;
-static const float FALLTIME = 0.8;
-
-UnstableTile::UnstableTile(const lisp::Lisp& lisp)
-  : hit(false), falling(false)
-{
-  lisp.get("x", bbox.p1.x);
-  lisp.get("y", bbox.p1.y);
-  bbox.set_size(32, 32);
-  sprite = sprite_manager->create("unstable_tile");
-  flags |= FLAG_SOLID;
-}
+#include "object/explosion.hpp"
+#include "object/player.hpp"
+#include "sprite/sprite.hpp"
+#include "supertux/constants.hpp"
+#include "supertux/object_factory.hpp"
 
-UnstableTile::~UnstableTile()
+UnstableTile::UnstableTile(const Reader& lisp) :
+  MovingSprite(lisp, LAYER_TILES, COLGROUP_STATIC), 
+  physic(),
+  state(STATE_NORMAL)
 {
-  delete sprite;
+  sprite->set_action("normal");
 }
 
 HitResponse
-UnstableTile::collision(GameObject& other, const CollisionHit& hitdata)
+UnstableTile::collision(GameObject& other, const CollisionHit& )
 {
-  if(hitdata.normal.y < 0.8)
-    return FORCE_MOVE;
-
-  Player* player = dynamic_cast<Player*> (&other);
-  if(player)
-    hit = true;
+  if(state == STATE_NORMAL) {
+    Player* player = dynamic_cast<Player*> (&other);
+    if(player != NULL &&
+       player->get_bbox().get_bottom() < get_bbox().get_top() + SHIFT_DELTA) {
+      startCrumbling();
+    }
 
+    if (dynamic_cast<Explosion*> (&other)) {
+      startCrumbling();
+    }
+  }
   return FORCE_MOVE;
 }
 
 void
-UnstableTile::draw(DrawingContext& context)
+UnstableTile::startCrumbling()
 {
-  Vector pos = get_pos();
-  // shacking
-  if(timer.get_timegone() > CRACKTIME) {
-    pos.x += (rand() % 6) - 3;
-  } 
-
-  sprite->draw(context, pos, LAYER_TILES);
+  if (state != STATE_NORMAL) return;
+  state = STATE_CRUMBLING;
+  sprite->set_action("crumbling", 1);
 }
 
 void
-UnstableTile::action(float elapsed_time)
+UnstableTile::update(float elapsed_time)
 {
-  if(falling) {
-    movement = physic.get_movement(elapsed_time);
-    if(!Sector::current()->inside(bbox)) {
-      remove_me();
-      return;
-    }
-  } else if(hit) {
-    if(timer.check()) {
-      falling = true;
-      physic.enable_gravity(true);      
-      flags &= ~FLAG_SOLID;
-      timer.stop();
-    } else if(!timer.started()) {
-      timer.start(FALLTIME);
-    }
-  } else {
-    timer.stop();
+  switch (state) {
+
+    case STATE_NORMAL:
+      break;
+
+    case STATE_CRUMBLING:
+      if (sprite->animation_done()) {
+        state = STATE_DISINTEGRATING;
+        sprite->set_action("disintegrating", 1);
+        set_group(COLGROUP_DISABLED);
+        physic.enable_gravity(true);
+      }
+      break;
+
+    case STATE_DISINTEGRATING:
+      movement = physic.get_movement(elapsed_time);
+      if (sprite->animation_done()) {
+        remove_me();
+        return;
+      }
+      break;
   }
-  hit = false;
 }
 
-IMPLEMENT_FACTORY(UnstableTile, "unstable_tile");
+/* EOF */