New Badguy "Totem" - a variable-height stack of wooden faces
authorChristoph Sommer <mail@christoph-sommer.de>
Sun, 26 Mar 2006 01:03:24 +0000 (01:03 +0000)
committerChristoph Sommer <mail@christoph-sommer.de>
Sun, 26 Mar 2006 01:03:24 +0000 (01:03 +0000)
SVN-Revision: 3120

data/images/creatures/totem/squished.png [new file with mode: 0644]
data/images/creatures/totem/stacked.png [new file with mode: 0644]
data/images/creatures/totem/totem.sprite [new file with mode: 0644]
data/images/creatures/totem/walking1.png [new file with mode: 0644]
data/images/creatures/totem/walking2.png [new file with mode: 0644]
data/images/creatures/totem/walking3.png [new file with mode: 0644]
data/images/creatures/totem/walking4.png [new file with mode: 0644]
data/levels/test/totem.stl [new file with mode: 0644]
src/badguy/totem.cpp [new file with mode: 0644]
src/badguy/totem.hpp [new file with mode: 0644]

diff --git a/data/images/creatures/totem/squished.png b/data/images/creatures/totem/squished.png
new file mode 100644 (file)
index 0000000..aa11a33
Binary files /dev/null and b/data/images/creatures/totem/squished.png differ
diff --git a/data/images/creatures/totem/stacked.png b/data/images/creatures/totem/stacked.png
new file mode 100644 (file)
index 0000000..33fe0d2
Binary files /dev/null and b/data/images/creatures/totem/stacked.png differ
diff --git a/data/images/creatures/totem/totem.sprite b/data/images/creatures/totem/totem.sprite
new file mode 100644 (file)
index 0000000..e4e9f94
--- /dev/null
@@ -0,0 +1,27 @@
+(supertux-sprite
+  (action
+    (name "walking-left")
+    (images "walking1.png" "walking2.png" "walking3.png" "walking4.png")
+    )
+  (action
+    (name "walking-right")
+    (mirror-action "walking-left")
+    )
+  (action
+    (name "stacked-left")
+    (images "stacked.png")
+    )
+  (action
+    (name "stacked-right")
+    (mirror-action "stacked-left")
+    )
+  (action
+    (name "squished-left")
+    (images "squished.png")
+    )
+  (action
+    (name "squished-right")
+    (mirror-action "squished-left")
+    )
+
+  )
diff --git a/data/images/creatures/totem/walking1.png b/data/images/creatures/totem/walking1.png
new file mode 100644 (file)
index 0000000..f5ac92a
Binary files /dev/null and b/data/images/creatures/totem/walking1.png differ
diff --git a/data/images/creatures/totem/walking2.png b/data/images/creatures/totem/walking2.png
new file mode 100644 (file)
index 0000000..8c8024a
Binary files /dev/null and b/data/images/creatures/totem/walking2.png differ
diff --git a/data/images/creatures/totem/walking3.png b/data/images/creatures/totem/walking3.png
new file mode 100644 (file)
index 0000000..4e7ac1d
Binary files /dev/null and b/data/images/creatures/totem/walking3.png differ
diff --git a/data/images/creatures/totem/walking4.png b/data/images/creatures/totem/walking4.png
new file mode 100644 (file)
index 0000000..13559da
Binary files /dev/null and b/data/images/creatures/totem/walking4.png differ
diff --git a/data/levels/test/totem.stl b/data/levels/test/totem.stl
new file mode 100644 (file)
index 0000000..243cbb2
--- /dev/null
@@ -0,0 +1,141 @@
+;; Generated by Flexlay Editor
+(supertux-level
+  (version 2)
+  (name   (_ "Totem Test"))
+  (author "Marek")
+  (sector
+    (name  "main")
+    (gravity 10.000000)
+    (tilemap
+      (layer  "background")
+      (solid #f)
+      (speed  1.000000)
+      (width  30)
+      (height 30)
+      (tiles
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        ))
+    (tilemap
+      (layer  "interactive")
+      (solid #t)
+      (speed  1.000000)
+      (width  30)
+      (height 30)
+      (tiles
+        61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 
+        61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61 
+        61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61 
+        61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61 
+        61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61 
+        61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61 
+        61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61 
+        61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61
+        61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61
+        61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61
+        61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61 
+        61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61
+        61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61
+        61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61
+        61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61
+        61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61
+        61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61
+        61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61
+        61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61
+        61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61
+        61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61
+        61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61
+        61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61
+        61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61
+        61 61 61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61
+        61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61
+        61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61 
+        61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61 
+        61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 61 
+        61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 
+        ))
+    (tilemap
+      (layer  "foreground")
+      (solid #f)
+      (speed  1.000000)
+      (width  30)
+      (height 30)
+      (tiles
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+        ))
+    (camera
+      (mode "normal")
+    )
+
+       (background
+         (image "images/background/arctis.jpg")
+         (speed 0.500000)
+       )
+
+   (totem (x 100) (y 850))
+   (totem (x 700) (y 850))
+   (totem (x 800) (y 850))
+   (totem (x 900) (y 850))
+   (powerup (x 100) (y 700) (sprite "images/powerups/egg/egg.sprite"))
+   (spawnpoint (name "main") (x 40) (y 700))
+   )
+ )
+
+;; EOF ;;
diff --git a/src/badguy/totem.cpp b/src/badguy/totem.cpp
new file mode 100644 (file)
index 0000000..d78144d
--- /dev/null
@@ -0,0 +1,237 @@
+//  $Id: totem.cpp 3096 2006-03-17 12:03:02Z sommer $
+// 
+//  SuperTux - "Totem" Badguy
+//  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 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 "totem.hpp"
+#include "msg.hpp"
+
+static const float WALKSPEED = 100;
+static const float WALKSPEED_SMALL = 120;
+static const float INVINCIBLE_TIME = 1;
+
+static const float JUMP_OFF_SPEED_Y = 500;
+
+Totem::Totem(const lisp::Lisp& reader)
+{
+  stay_on_platform = false;
+  carrying = 0;
+  carried_by = 0;
+  bbox.set_size(48, 49);
+
+  reader.get("x", start_position.x);
+  reader.get("y", start_position.y);
+  reader.get("stay-on-platform", stay_on_platform);
+  sprite = sprite_manager->create("images/creatures/totem/totem.sprite");
+}
+
+Totem::~Totem() 
+{
+  if (carrying) carrying->jump_off();
+  if (carried_by) jump_off();
+}
+
+void
+Totem::write(lisp::Writer& writer)
+{
+  writer.start_list("totem");
+
+  writer.write_float("x", start_position.x);
+  writer.write_float("y", start_position.y);
+  writer.write_bool("stay-on-platform", stay_on_platform);
+
+  writer.end_list("totem");
+}
+
+void
+Totem::activate()
+{
+  if (!carried_by) {
+    physic.set_velocity_x(dir == LEFT ? -WALKSPEED : WALKSPEED);
+    sprite->set_action(dir == LEFT ? "walking-left" : "walking-right");
+    return;
+  } else {
+    synchronize_with(carried_by);
+    sprite->set_action(dir == LEFT ? "stacked-left" : "stacked-right");
+    return;
+  }
+}
+
+void
+Totem::active_update(float elapsed_time)
+{
+  BadGuy::active_update(elapsed_time);
+
+  if (!carried_by) {
+    if (stay_on_platform && may_fall_off_platform())
+    {
+      dir = (dir == LEFT ? RIGHT : LEFT);
+      activate();
+    }
+  }
+
+  if (carried_by) {
+    this->synchronize_with(carried_by);
+  }
+
+  if (carrying) {
+    carrying->synchronize_with(this);
+  }
+
+}
+
+bool
+Totem::collision_squished(Player& player)
+{
+  if (carrying) carrying->jump_off();
+  if (carried_by) {
+    player.bounce(*this);
+    jump_off();
+  }
+
+  sprite->set_action(dir == LEFT ? "squished-left" : "squished-right");
+  this->bbox.set_size(48, 45);
+  kill_squished(player);
+  return true;
+}
+
+HitResponse
+Totem::collision_solid(GameObject& object, const CollisionHit& hit)
+{
+  // if we are being carried around, pass event to bottom of stack and ignore it
+  if (carried_by) {
+    carried_by->collision_solid(object, hit);
+    return CONTINUE;
+  }
+
+  // If we hit something from above or below: stop moving in this direction 
+  if (hit.normal.y != 0) {
+    physic.set_velocity_y(0);
+  }
+
+  // If we are hit from the direction we are facing: turn around
+  if ((hit.normal.x > .8) && (dir == LEFT)) {
+    dir = RIGHT;
+    activate();
+  }
+  if ((hit.normal.x < -.8) && (dir == RIGHT)) {
+    dir = LEFT;
+    activate();
+  }
+
+  return CONTINUE;
+}
+
+HitResponse
+Totem::collision_badguy(BadGuy& badguy, const CollisionHit& hit)
+{
+  // if we are being carried around, pass event to bottom of stack and ignore it
+  if (carried_by) {
+    carried_by->collision_badguy(badguy, hit);
+    return CONTINUE;
+  }
+  // if we hit a Totem that is not from our stack: have our base jump on its top
+  Totem* totem = dynamic_cast<Totem*>(&badguy);
+  if (totem) {
+    Totem* thisBase = this; while (thisBase->carried_by) thisBase=thisBase->carried_by;
+    Totem* srcBase = totem; while (srcBase->carried_by)  srcBase=srcBase->carried_by;
+    Totem* thisTop = this;  while (thisTop->carrying)    thisTop=thisTop->carrying;
+    if (srcBase != thisBase) {
+      srcBase->jump_on(thisTop);
+    }
+  }
+
+  // If we are hit from the direction we are facing: turn around
+  if ((hit.normal.x > .8) && (dir == LEFT)) {
+    dir = RIGHT;
+    activate();
+  }
+  if ((hit.normal.x < -.8) && (dir == RIGHT)) {
+    dir = LEFT;
+    activate();
+  }
+
+  return CONTINUE;
+}
+
+void
+Totem::kill_fall()
+{
+  if (carrying) carrying->jump_off();
+  if (carried_by) jump_off();
+
+  BadGuy::kill_fall();
+}
+
+void 
+Totem::jump_on(Totem* target)
+{
+  if (target->carrying) {
+    msg_warning("target is already carrying someone");
+    return;
+  }
+  
+  target->carrying = this;
+
+  this->carried_by = target;
+  this->bbox.set_size(48, 45);
+  this->activate();
+  
+  this->synchronize_with(target);
+}
+
+void
+Totem::jump_off() {
+  if (!carried_by) {
+    msg_warning("not carried by anyone");
+    return;
+  }
+
+  carried_by->carrying = 0;
+
+  this->carried_by = 0;
+  this->bbox.set_size(48, 49);
+
+  this->activate();
+
+  physic.set_velocity_y(JUMP_OFF_SPEED_Y);
+}
+
+void 
+Totem::synchronize_with(Totem* base)
+{
+
+  if (dir != base->dir) {
+    dir = base->dir;
+    sprite->set_action(dir == LEFT ? "stacked-left" : "stacked-right");
+  }
+  
+  Vector pos = base->get_pos();
+  pos.y -= 45;
+  set_pos(pos);
+
+  physic.set_velocity_x(base->physic.get_velocity_x());
+  physic.set_velocity_y(base->physic.get_velocity_y());
+}
+
+
+IMPLEMENT_FACTORY(Totem, "totem")
+  
diff --git a/src/badguy/totem.hpp b/src/badguy/totem.hpp
new file mode 100644 (file)
index 0000000..40b5da1
--- /dev/null
@@ -0,0 +1,57 @@
+//  $Id: totem.cpp 3096 2006-03-17 12:03:02Z sommer $
+// 
+//  SuperTux - "Totem" Badguy
+//  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 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 __TOTEM_H__
+#define __TOTEM_H__
+
+#include "badguy.hpp"
+
+/**
+ * "Totem" Badguy - A variable-height stack of wooden blocks
+ */
+class Totem : public BadGuy
+{
+public:
+  Totem(const lisp::Lisp& reader);
+  ~Totem();
+
+  void activate();
+  void active_update(float elapsed_time);
+  void write(lisp::Writer& writer);
+  HitResponse collision_solid(GameObject& other, const CollisionHit& hit);
+  HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
+
+protected:
+  bool stay_on_platform; /**< change direction before falling off a ledge */
+
+  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);
+  void kill_fall();
+
+  void jump_on(Totem* target); /**< jump on target */
+  void jump_off(); /**< jump off current base */
+
+  void synchronize_with(Totem* baseTotem); /**< synchronize position and movement with baseTotem */
+};
+
+#endif
+