00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "badguy/owl.hpp"
00019
00020 #include "sprite/sprite.hpp"
00021 #include "supertux/object_factory.hpp"
00022 #include "supertux/sector.hpp"
00023 #include "object/anchor_point.hpp"
00024 #include "object/player.hpp"
00025 #include "object/rock.hpp"
00026 #include "util/reader.hpp"
00027 #include "util/log.hpp"
00028
00029 #define FLYING_SPEED 120.0
00030 #define ACTIVATION_DISTANCE 128.0
00031
00032 Owl::Owl(const Reader& reader) :
00033 BadGuy(reader, "images/creatures/owl/owl.sprite", LAYER_OBJECTS + 1),
00034 carried_obj_name("skydive"),
00035 carried_object(NULL)
00036 {
00037 reader.get("carry", carried_obj_name);
00038 set_action (dir == LEFT ? "left" : "right", -1);
00039 }
00040
00041 Owl::Owl(const Vector& pos, Direction d) :
00042 BadGuy(pos, d, "images/creatures/owl/owl.sprite", LAYER_OBJECTS + 1),
00043 carried_obj_name("skydive"),
00044 carried_object(NULL)
00045 {
00046 set_action (dir == LEFT ? "left" : "right", -1);
00047 }
00048
00049 void
00050 Owl::initialize()
00051 {
00052 GameObject *game_object;
00053
00054 physic.set_velocity_x(dir == LEFT ? -FLYING_SPEED : FLYING_SPEED);
00055 physic.enable_gravity(false);
00056 sprite->set_action(dir == LEFT ? "left" : "right");
00057
00058 game_object = ObjectFactory::instance().create(carried_obj_name, get_pos(), dir);
00059 if (game_object == NULL) {
00060 log_fatal << "Creating \"" << carried_obj_name << "\" object failed." << std::endl;
00061 return;
00062 }
00063
00064 carried_object = dynamic_cast<Portable *> (game_object);
00065 if (carried_object == NULL) {
00066 log_warning << "Object is not portable: " << carried_obj_name << std::endl;
00067 delete game_object;
00068 return;
00069 }
00070
00071 Sector::current ()->add_object (game_object);
00072 }
00073
00074 bool
00075 Owl::is_above_player (void)
00076 {
00077 Player* player = Sector::current()->get_nearest_player (this->get_bbox ());
00078 if (!player)
00079 return false;
00080
00081
00082
00083 float x_offset = (dir == LEFT) ? ACTIVATION_DISTANCE : -ACTIVATION_DISTANCE;
00084
00085 const Rectf& player_bbox = player->get_bbox();
00086 const Rectf& owl_bbox = get_bbox();
00087
00088 if ((player_bbox.p1.y >= owl_bbox.p2.y)
00089 && ((player_bbox.p2.x + x_offset) > owl_bbox.p1.x)
00090 && ((player_bbox.p1.x + x_offset) < owl_bbox.p2.x))
00091 return true;
00092 else
00093 return false;
00094 }
00095
00096 void
00097 Owl::active_update (float elapsed_time)
00098 {
00099 BadGuy::active_update (elapsed_time);
00100
00101 if (carried_object != NULL) {
00102 if (!is_above_player ()) {
00103 Vector obj_pos = get_anchor_pos (bbox, ANCHOR_BOTTOM);
00104 obj_pos.x -= 16.0;
00105 obj_pos.y += 3.0;
00106
00107 carried_object->grab (*this, obj_pos, dir);
00108 }
00109 else {
00110 carried_object->ungrab (*this, dir);
00111 carried_object = NULL;
00112 }
00113 }
00114 }
00115
00116 bool
00117 Owl::collision_squished(GameObject&)
00118 {
00119 Player* player = Sector::current()->get_nearest_player (this->get_bbox ());
00120 if (player)
00121 player->bounce (*this);
00122
00123 if (carried_object != NULL) {
00124 carried_object->ungrab (*this, dir);
00125 carried_object = NULL;
00126 }
00127
00128 kill_fall ();
00129 return true;
00130 }
00131
00132 void
00133 Owl::collision_solid(const CollisionHit& hit)
00134 {
00135 if(hit.top || hit.bottom) {
00136 physic.set_velocity_y(0);
00137 } else if(hit.left || hit.right) {
00138 if (dir == LEFT) {
00139 set_action ("right", -1);
00140 dir = RIGHT;
00141 physic.set_velocity_x (FLYING_SPEED);
00142 }
00143 else {
00144 set_action ("left", -1);
00145 dir = LEFT;
00146 physic.set_velocity_x (-FLYING_SPEED);
00147 }
00148 }
00149 }
00150
00151
00152