New Badguy "IceCrusher" drops down to crush Tux and can be used as a platform to...
authorChristoph Sommer <mail@christoph-sommer.de>
Thu, 31 Jan 2008 23:22:33 +0000 (23:22 +0000)
committerChristoph Sommer <mail@christoph-sommer.de>
Thu, 31 Jan 2008 23:22:33 +0000 (23:22 +0000)
SVN-Revision: 5307

data/images/creatures/iceblock/iceblock.png [deleted file]
data/images/creatures/icecrusher/iceblock.png [new file with mode: 0644]
data/images/creatures/icecrusher/icecrusher.sprite [new file with mode: 0644]
src/object/icecrusher.cpp [new file with mode: 0644]
src/object/icecrusher.hpp [new file with mode: 0644]

diff --git a/data/images/creatures/iceblock/iceblock.png b/data/images/creatures/iceblock/iceblock.png
deleted file mode 100644 (file)
index 98b0c79..0000000
Binary files a/data/images/creatures/iceblock/iceblock.png and /dev/null differ
diff --git a/data/images/creatures/icecrusher/iceblock.png b/data/images/creatures/icecrusher/iceblock.png
new file mode 100644 (file)
index 0000000..98b0c79
Binary files /dev/null and b/data/images/creatures/icecrusher/iceblock.png differ
diff --git a/data/images/creatures/icecrusher/icecrusher.sprite b/data/images/creatures/icecrusher/icecrusher.sprite
new file mode 100644 (file)
index 0000000..972f5e1
--- /dev/null
@@ -0,0 +1,8 @@
+(supertux-sprite
+ (action
+  (name "idle")
+  (hitbox 11 8 64 64)
+  (images "iceblock.png"
+  )
+ )
+)
diff --git a/src/object/icecrusher.cpp b/src/object/icecrusher.cpp
new file mode 100644 (file)
index 0000000..421cef0
--- /dev/null
@@ -0,0 +1,171 @@
+//  $Id$
+//
+//  IceCrusher - A block to stand on, which can drop down to crush the player
+//  Copyright (C) 2008 Christoph Sommer <christoph.sommer@2008.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 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>
+
+#include "icecrusher.hpp"
+
+#include <stdexcept>
+#include "log.hpp"
+#include "video/drawing_context.hpp"
+#include "resources.hpp"
+#include "badguy/badguy.hpp"
+#include "sprite/sprite.hpp"
+#include "lisp/lisp.hpp"
+#include "object_factory.hpp"
+#include "sector.hpp"
+
+namespace {
+  const float DROP_SPEED = 500;
+  const float RECOVER_SPEED = 200;
+}
+
+IceCrusher::IceCrusher(const lisp::Lisp& reader)
+       : MovingSprite(reader, "images/creatures/icecrusher/icecrusher.sprite", LAYER_OBJECTS, COLGROUP_STATIC), 
+       state(IDLE), speed(Vector(0,0))
+{
+  start_position = get_bbox().p1;
+  set_state(state, true);
+}
+
+IceCrusher::IceCrusher(const IceCrusher& other)
+       : MovingSprite(other), 
+       state(other.state), speed(other.speed) 
+{
+  start_position = get_bbox().p1;
+  set_state(state, true);
+}
+
+void 
+IceCrusher::set_state(IceCrusherState state, bool force) 
+{
+  if ((this->state == state) && (!force)) return;
+  switch(state) {
+    case IDLE:
+      set_group(COLGROUP_STATIC);
+      speed=Vector(0,0);
+      sprite->set_action("idle");
+      break;
+    case CRUSHING:
+      set_group(COLGROUP_MOVING_STATIC);
+      speed=Vector(0, DROP_SPEED);
+      sprite->set_action("idle");
+      break;
+    case RECOVERING:
+      set_group(COLGROUP_MOVING_STATIC);
+      speed=Vector(0, -RECOVER_SPEED);
+      sprite->set_action("idle");
+      break;
+    default:
+      log_debug << "IceCrusher in invalid state" << std::endl;
+      break;
+  }
+  this->state = state;
+}
+
+HitResponse
+IceCrusher::collision(GameObject& other, const CollisionHit& hit)
+{
+  Player* player = dynamic_cast<Player*>(&other);
+  if (player && hit.bottom) {
+    if(player->is_invincible()) {
+      if (state == CRUSHING) set_state(RECOVERING);
+      return ABORT_MOVE;
+    }
+    player->kill(false);
+    if (state == CRUSHING) set_state(RECOVERING);
+    return FORCE_MOVE;
+  }
+  BadGuy* badguy = dynamic_cast<BadGuy*>(&other);
+  if (badguy) {
+    badguy->kill_fall();
+  }
+  return FORCE_MOVE;
+}
+    
+void 
+IceCrusher::collision_solid(const CollisionHit& )
+{
+  switch(state) {
+    case IDLE:
+      break;
+    case CRUSHING:
+      set_state(RECOVERING);
+      break;
+    case RECOVERING:
+      break;
+    default:
+      log_debug << "IceCrusher in invalid state" << std::endl;
+      break;
+  }
+}
+
+void
+IceCrusher::update(float elapsed_time)
+{
+  switch(state) {
+    case IDLE:
+      if (found_victim()) set_state(CRUSHING);
+      break;
+    case CRUSHING:
+      break;
+    case RECOVERING:
+      if (get_bbox().p1.y <= start_position.y+1) {
+        set_pos(start_position);
+        set_state(IDLE);
+      }
+      break;
+    default:
+      log_debug << "IceCrusher in invalid state" << std::endl;
+      break;
+  }
+  movement = speed * elapsed_time;
+}
+
+Player*
+IceCrusher::get_nearest_player()
+{
+  // FIXME: does not really return nearest player
+
+  std::vector<Player*> players = Sector::current()->get_players();
+  for (std::vector<Player*>::iterator playerIter = players.begin(); playerIter != players.end(); ++playerIter) {
+    Player* player = *playerIter;
+    if (player->is_dying() || player->is_dead()) continue;
+    return player;
+  }
+
+  return 0;
+}
+
+bool
+IceCrusher::found_victim()
+{
+  Player* player = this->get_nearest_player();
+  if (!player) return false;
+
+  const Rect& pr = player->get_bbox();
+  const Rect& br = get_bbox();
+  if ((pr.p2.x > br.p1.x) && (pr.p1.x < br.p2.x) && (pr.p1.y >= br.p2.y)) {
+    return true;
+  }
+  return false;
+}
+
+IMPLEMENT_FACTORY(IceCrusher, "icecrusher");
diff --git a/src/object/icecrusher.hpp b/src/object/icecrusher.hpp
new file mode 100644 (file)
index 0000000..dfb255c
--- /dev/null
@@ -0,0 +1,64 @@
+//  $Id$
+//
+//  IceCrusher - A block to stand on, which can drop down to crush the player
+//  Copyright (C) 2008 Christoph Sommer <christoph.sommer@2008.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 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.
+
+#ifndef INCLUDED_ICECRUSHER_HPP
+#define INCLUDED_ICECRUSHER_HPP
+
+#include <memory>
+#include <string>
+#include "object/moving_sprite.hpp"
+#include "object/player.hpp"
+
+/**
+ * This class is the base class for icecrushers that tux can stand on
+ */
+class IceCrusher : public MovingSprite
+{
+  public:
+    IceCrusher(const lisp::Lisp& reader);
+    IceCrusher(const IceCrusher& icecrusher);
+    virtual IceCrusher* clone() const { return new IceCrusher(*this); }
+
+    virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
+    virtual void collision_solid(const CollisionHit& hit);
+    virtual void update(float elapsed_time);
+
+    const Vector& get_speed() const
+    {
+      return speed;
+    }
+
+  protected:
+    enum IceCrusherState {
+      IDLE,
+      CRUSHING,
+      RECOVERING
+    };
+    IceCrusherState state;
+    Vector start_position;
+    Vector speed;
+
+    Player* get_nearest_player();
+    bool found_victim();
+    void set_state(IceCrusherState state, bool force = false);
+
+};
+
+#endif