Owl: Implement carrying around of "Portable" objects.
authorFlorian Forster <supertux@octo.it>
Sat, 6 Mar 2010 16:49:53 +0000 (16:49 +0000)
committerFlorian Forster <supertux@octo.it>
Sat, 6 Mar 2010 16:49:53 +0000 (16:49 +0000)
Owls now bring a "rock" by default.

SVN-Revision: 6561

data/levels/test/owl.stl
src/badguy/owl.cpp
src/badguy/owl.hpp

index 62d7201..da47c91 100644 (file)
@@ -17,6 +17,7 @@
     (owl
       (x 1312)
       (y 832)
+      (carry "trampoline")
     )
     (owl
       (x 2400)
index 0813209..6389f71 100644 (file)
 
 #include "badguy/owl.hpp"
 
-#include "audio/sound_manager.hpp"
 #include "sprite/sprite.hpp"
 #include "supertux/object_factory.hpp"
+#include "supertux/sector.hpp"
+#include "object/rock.hpp"
+#include "util/reader.hpp"
+#include "util/log.hpp"
 
 #define FLYING_SPEED 120.0
 
 Owl::Owl(const Reader& reader) :
-  BadGuy(reader, "images/creatures/owl/owl.sprite")
+  BadGuy(reader, "images/creatures/owl/owl.sprite"),
+  carried_obj_name("rock"),
+  carried_object(NULL)
 {
+  reader.get("carry", carried_obj_name);
   set_action (dir == LEFT ? "left" : "right", /* loops = */ -1);
 }
 
-Owl::Owl(const Vector& pos, Direction d)
-  : BadGuy(pos, d, "images/creatures/owl/owl.sprite")
+Owl::Owl(const Vector& pos, Direction d) :
+  BadGuy(pos, d, "images/creatures/owl/owl.sprite"),
+  carried_obj_name("rock"),
+  carried_object(NULL)
 {
   set_action (dir == LEFT ? "left" : "right", /* loops = */ -1);
 }
@@ -38,14 +46,48 @@ Owl::Owl(const Vector& pos, Direction d)
 void
 Owl::initialize()
 {
+  GameObject *game_object;
+
   physic.set_velocity_x(dir == LEFT ? -FLYING_SPEED : FLYING_SPEED);
   physic.enable_gravity(false);
   sprite->set_action(dir == LEFT ? "left" : "right");
+
+  game_object = ObjectFactory::instance().create(carried_obj_name, get_pos(), dir);
+  if (game_object == NULL) {
+    log_fatal << "Creating \"" << carried_obj_name << "\" object failed." << std::endl;
+    return;
+  }
+
+  carried_object = dynamic_cast<Portable *> (game_object);
+  if (carried_object == NULL) {
+    log_warning << "Object is not portable: " << carried_obj_name << std::endl;
+    delete game_object;
+    return;
+  }
+
+  Sector::current ()->add_object (game_object);
+} /* void initialize */
+
+void
+Owl::active_update (float elapsed_time)
+{
+  BadGuy::active_update (elapsed_time);
+
+  if (carried_object != NULL) {
+    Vector obj_pos = get_pos ();
+    
+    obj_pos.y += bbox.get_height ();
+    carried_object->grab (*this, obj_pos, dir);
+  }
 }
 
 bool
 Owl::collision_squished(GameObject&)
 {
+  if (carried_object != NULL) {
+    carried_object->ungrab (*this, dir);
+    carried_object = NULL;
+  }
   kill_fall ();
   return true;
 }
@@ -73,6 +115,10 @@ Owl::collision_player(Player& player, const CollisionHit& hit)
   //Hack to tell if we should die
   HitResponse response = BadGuy::collision_player(player, hit);
   if(response == FORCE_MOVE) {
+    if (carried_object != NULL) {
+      carried_object->ungrab (*this, dir);
+      carried_object = NULL;
+    }
     kill_fall ();
   }
 
index b5f2b86..7510cae 100644 (file)
@@ -19,6 +19,7 @@
 #define HEADER_SUPERTUX_BADGUY_OWL_HPP
 
 #include "badguy/badguy.hpp"
+#include "object/portable.hpp"
 
 class Owl : public BadGuy
 {
@@ -30,8 +31,12 @@ public:
   void collision_solid(const CollisionHit& hit);
 
 protected:
+  void active_update (float elapsed_time);
   bool collision_squished(GameObject& object);
   HitResponse collision_player(Player& player, const CollisionHit& hit);
+
+  std::string carried_obj_name;
+  Portable *carried_object;
 };
 
 #endif /* HEADER_SUPERTUX_BADGUY_OWL_HPP */