+ if(!controller->hold(Controller::ACTION) && grabbed_object) {
+ // move the grabbed object a bit away from tux
+ Vector pos = get_pos() +
+ Vector(dir == LEFT ? -bbox.get_width()-1 : bbox.get_width()+1,
+ bbox.get_height()*0.66666 - 32);
+ Rect dest(pos, pos + Vector(32, 32));
+ if(Sector::current()->is_free_of_movingstatics(dest)) {
+ MovingObject* moving_object = dynamic_cast<MovingObject*> (grabbed_object);
+ if(moving_object) {
+ moving_object->set_pos(pos);
+ } else {
+ log_debug << "Non MovingObject grabbed?!?" << std::endl;
+ }
+ if(controller->hold(Controller::UP)) {
+ grabbed_object->ungrab(*this, UP);
+ } else {
+ grabbed_object->ungrab(*this, dir);
+ }
+ grabbed_object = NULL;
+ }
+ }
+}
+
+void
+Player::try_grab()
+{
+ if(controller->hold(Controller::ACTION) && !grabbed_object
+ && !duck) {
+ Sector* sector = Sector::current();
+ Vector pos;
+ if(dir == LEFT) {
+ pos = Vector(bbox.get_left() - 5, bbox.get_bottom() - 16);
+ } else {
+ pos = Vector(bbox.get_right() + 5, bbox.get_bottom() - 16);
+ }
+
+ for(Sector::Portables::iterator i = sector->portables.begin();
+ i != sector->portables.end(); ++i) {
+ Portable* portable = *i;
+ if(!portable->is_portable())
+ continue;
+
+ // make sure the Portable is a MovingObject
+ MovingObject* moving_object = dynamic_cast<MovingObject*> (portable);
+ assert(moving_object);
+ if(moving_object == NULL)
+ continue;
+
+ // make sure the Portable isn't currently non-solid
+ if(moving_object->get_group() == COLGROUP_DISABLED) continue;
+
+ // check if we are within reach
+ if(moving_object->get_bbox().contains(pos)) {
+ if (climbing) stop_climbing(*climbing);
+ grabbed_object = portable;
+ grabbed_object->grab(*this, get_pos(), dir);
+ break;
+ }
+ }
+ }