+
+void
+Player::start_climbing(Climbable& climbable)
+{
+ if (climbing == &climbable) return;
+
+ climbing = &climbable;
+ physic.enable_gravity(false);
+ physic.set_velocity(0, 0);
+ physic.set_acceleration(0, 0);
+}
+
+void
+Player::stop_climbing(Climbable& /*climbable*/)
+{
+ if (!climbing) return;
+
+ climbing = 0;
+
+ if (grabbed_object) {
+ grabbed_object->ungrab(*this, dir);
+ grabbed_object = NULL;
+ }
+
+ physic.enable_gravity(true);
+ physic.set_velocity(0, 0);
+ physic.set_acceleration(0, 0);
+
+ if ((controller->hold(Controller::JUMP)) || (controller->hold(Controller::UP))) {
+ on_ground_flag = true;
+ // TODO: This won't help. Why?
+ do_jump(-300);
+ }
+}
+
+void
+Player::handle_input_climbing()
+{
+ if (!climbing) {
+ log_warning << "handle_input_climbing called with climbing set to 0. Input handling skipped" << std::endl;
+ return;
+ }
+
+ float vx = 0;
+ float vy = 0;
+ if (controller->hold(Controller::LEFT)) {
+ dir = LEFT;
+ vx -= MAX_CLIMB_XM;
+ }
+ if (controller->hold(Controller::RIGHT)) {
+ dir = RIGHT;
+ vx += MAX_CLIMB_XM;
+ }
+ if (controller->hold(Controller::UP)) {
+ vy -= MAX_CLIMB_YM;
+ }
+ if (controller->hold(Controller::DOWN)) {
+ vy += MAX_CLIMB_YM;
+ }
+ if (controller->hold(Controller::JUMP)) {
+ if (can_jump) {
+ stop_climbing(*climbing);
+ return;
+ }
+ } else {
+ can_jump = true;
+ }
+ if (controller->hold(Controller::ACTION)) {
+ stop_climbing(*climbing);
+ return;
+ }
+ physic.set_velocity(vx, vy);
+ physic.set_acceleration(0, 0);
+}
+
+