Short Fuse runs dead-script when exploding, not just when kill_fall() is called
[supertux.git] / src / badguy / dispenser.cpp
index 2c3322b..da9514b 100644 (file)
@@ -22,6 +22,9 @@
 #include "object/player.hpp"
 #include "supertux/object_factory.hpp"
 #include "supertux/sector.hpp"
+#include "util/reader.hpp"
+
+#include <stdexcept>
 
 Dispenser::Dispenser(const Reader& reader) :
   BadGuy(reader, "images/creatures/dispenser/dispenser.sprite"),
@@ -180,7 +183,7 @@ Dispenser::launch_badguy()
 
     if (badguys.size() > 1) {
       if (random) {
-        next_badguy = systemRandom.rand(badguys.size());
+        next_badguy = gameRandom.rand(badguys.size());
       }
       else {
         next_badguy++;
@@ -197,22 +200,39 @@ Dispenser::launch_badguy()
       return;
     }
 
-    GameObject* badguy_object = NULL;
-
     try {
+      GameObject *game_object;
+      MovingObject *moving_object;
       Vector spawnpoint;
+      Rectf object_bbox;
+
+      /* Need to allocate the badguy first to figure out its bounding box. */
+      game_object = ObjectFactory::instance().create(badguy, get_pos(), launchdir);
+      if (game_object == NULL)
+        throw std::runtime_error("Creating " + badguy + " object failed.");
+
+      moving_object = dynamic_cast<MovingObject *> (game_object);
+      if (moving_object == NULL)
+        throw std::runtime_error(badguy + " is not a moving object.");
 
-      if (type == "dropper")
-        spawnpoint = Vector(get_pos().x, get_pos().y+32);
-      else if (type == "cannon")
-        spawnpoint = Vector(get_pos().x + (launchdir == LEFT ? -32 : 32), get_pos().y);
-      else if (type == "rocketlauncher")
-        spawnpoint = Vector(get_pos().x + (launchdir == LEFT ? -32 : 32), get_pos().y);
+      object_bbox = moving_object->get_bbox ();
+
+      if (type == "dropper") {
+        spawnpoint = get_anchor_pos (get_bbox (), ANCHOR_BOTTOM);
+        spawnpoint.x -= 0.5 * object_bbox.get_width ();
+      }
+      else if ((type == "cannon") || (type == "rocketlauncher")) {
+        spawnpoint = get_pos (); /* top-left corner of the cannon */
+        if (launchdir == LEFT)
+          spawnpoint.x -= object_bbox.get_width () + 1;
+        else
+          spawnpoint.x += get_bbox ().get_width () + 1;
+      }
 
-      badguy_object = create_object(badguy, Vector(get_pos().x, get_pos().y+32), launchdir);
+      /* Now we set the real spawn position */
+      moving_object->set_pos (spawnpoint);
 
-      if (badguy_object)
-        Sector::current()->add_object(badguy_object);
+      Sector::current()->add_object(moving_object);
     } catch(std::exception& e) {
       log_warning << "Error dispensing badguy: " << e.what() << std::endl;
       return;
@@ -239,6 +259,5 @@ Dispenser::is_freezable() const
 {
   return true;
 }
-IMPLEMENT_FACTORY(Dispenser, "dispenser");
 
 /* EOF */