From: Florian Forster Date: Sat, 30 Jan 2010 09:36:44 +0000 (+0000) Subject: Bug 471: Fix upward release of ice block, and grabbing cleanups. X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=5114ad6ab03ce63b2f170338bfa1a5d160380a3b;p=supertux.git Bug 471: Fix upward release of ice block, and grabbing cleanups. Resolves #471. Thanks to Matt McCutchen for this patch. SVN-Revision: 6285 --- diff --git a/src/badguy/mriceblock.cpp b/src/badguy/mriceblock.cpp index eed83fed7..f4cacb55a 100644 --- a/src/badguy/mriceblock.cpp +++ b/src/badguy/mriceblock.cpp @@ -134,10 +134,6 @@ MrIceBlock::collision(GameObject& object, const CollisionHit& hit) HitResponse MrIceBlock::collision_player(Player& player, const CollisionHit& hit) { - if(dir == UP) { - return FORCE_MOVE; - } - // handle kicks from left or right side if(ice_state == ICESTATE_FLAT && get_state() == STATE_ACTIVE) { if(hit.left) { @@ -228,7 +224,7 @@ MrIceBlock::collision_squished(GameObject& object) } void -MrIceBlock::set_state(IceState state) +MrIceBlock::set_state(IceState state, bool up) { if(ice_state == state) return; @@ -238,16 +234,14 @@ MrIceBlock::set_state(IceState state) WalkingBadguy::initialize(); break; case ICESTATE_FLAT: - if(dir == UP) { + if(up) { physic.set_velocity_y(-KICKSPEED); - bbox.set_size(34, 31.8f); } else { sound_manager->play("sounds/stomp.wav", get_pos()); physic.set_velocity_x(0); physic.set_velocity_y(0); - - sprite->set_action(dir == LEFT ? "flat-left" : "flat-right"); } + sprite->set_action(dir == LEFT ? "flat-left" : "flat-right"); flat_timer.start(4); break; case ICESTATE_KICKED: @@ -280,8 +274,12 @@ MrIceBlock::grab(MovingObject&, const Vector& pos, Direction dir) void MrIceBlock::ungrab(MovingObject& , Direction dir) { - this->dir = dir; - set_state(dir == UP ? ICESTATE_FLAT : ICESTATE_KICKED); + if(dir == UP) { + set_state(ICESTATE_FLAT, true); + } else { + this->dir = dir; + set_state(ICESTATE_KICKED); + } set_colgroup_active(COLGROUP_MOVING); } diff --git a/src/badguy/mriceblock.hpp b/src/badguy/mriceblock.hpp index 1f61c1868..c08870b1c 100644 --- a/src/badguy/mriceblock.hpp +++ b/src/badguy/mriceblock.hpp @@ -51,7 +51,7 @@ protected: protected: bool collision_squished(GameObject& object); - void set_state(IceState state); + void set_state(IceState state, bool up = false); private: IceState ice_state; diff --git a/src/object/player.cpp b/src/object/player.cpp index 28a607e5f..77ef59395 100644 --- a/src/object/player.cpp +++ b/src/object/player.cpp @@ -375,9 +375,7 @@ Player::update(float elapsed_time) movement = physic.get_movement(elapsed_time); if(grabbed_object != NULL && !dying) { - Vector pos = get_pos() + - Vector(dir == LEFT ? -16 : 16, get_bbox().get_height()*0.66666 - 32); - grabbed_object->grab(*this, pos, dir); + position_grabbed_object(); } if(grabbed_object != NULL && dying){ @@ -769,29 +767,54 @@ Player::handle_input() try_grab(); 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); - Rectf dest(pos, pos + Vector(32, 32)); - if(Sector::current()->is_free_of_movingstatics(dest)) { - MovingObject* moving_object = dynamic_cast (grabbed_object); - if(moving_object) { - moving_object->set_pos(pos); + MovingObject* moving_object = dynamic_cast (grabbed_object); + if(moving_object) { + // move the grabbed object a bit away from tux + Rectf grabbed_bbox = moving_object->get_bbox(); + Rectf dest; + dest.p2.y = bbox.get_top() + bbox.get_height()*0.66666; + dest.p1.y = dest.p2.y - grabbed_bbox.get_height(); + if(dir == LEFT) { + dest.p2.x = bbox.get_left() - 1; + dest.p1.x = dest.p2.x - grabbed_bbox.get_width(); } else { - log_debug << "Non MovingObject grabbed?!?" << std::endl; + dest.p1.x = bbox.get_right() + 1; + dest.p2.x = dest.p1.x + grabbed_bbox.get_width(); } - if(controller->hold(Controller::UP)) { - grabbed_object->ungrab(*this, UP); - } else { - grabbed_object->ungrab(*this, dir); + if(Sector::current()->is_free_of_movingstatics(dest)) { + moving_object->set_pos(dest.p1); + if(controller->hold(Controller::UP)) { + grabbed_object->ungrab(*this, UP); + } else { + grabbed_object->ungrab(*this, dir); + } + grabbed_object = NULL; } - grabbed_object = NULL; + } else { + log_debug << "Non MovingObject grabbed?!?" << std::endl; } } } void +Player::position_grabbed_object() +{ + MovingObject* moving_object = dynamic_cast(grabbed_object); + assert(moving_object); + + // Position where we will hold the lower-inner corner + Vector pos(get_bbox().get_left() + get_bbox().get_width()/2, + get_bbox().get_top() + get_bbox().get_height()*0.66666); + + // Adjust to find the grabbed object's upper-left corner + if (dir == LEFT) + pos.x -= moving_object->get_bbox().get_width(); + pos.y -= moving_object->get_bbox().get_height(); + + grabbed_object->grab(*this, pos, dir); +} + +void Player::try_grab() { if(controller->hold(Controller::ACTION) && !grabbed_object @@ -823,7 +846,7 @@ Player::try_grab() if(moving_object->get_bbox().contains(pos)) { if (climbing) stop_climbing(*climbing); grabbed_object = portable; - grabbed_object->grab(*this, get_pos(), dir); + position_grabbed_object(); break; } } diff --git a/src/object/player.hpp b/src/object/player.hpp index f30e4542a..4d63ef912 100644 --- a/src/object/player.hpp +++ b/src/object/player.hpp @@ -303,6 +303,7 @@ public: SurfacePtr airarrow; /**< arrow indicating Tux' position when he's above the camera */ Vector floor_normal; + void position_grabbed_object(); void try_grab(); bool ghost_mode; /**< indicates if Tux should float around and through solid objects */