X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Fobject%2Fplayer.cpp;h=df2ca019069faa2c9a0fa3ab18a3f9a7f894db3d;hb=38f0ccbd01a1e73b7c587e241a7bc0c8443e8fe6;hp=7664a3b2dc91ff811e87a23a9fffe67e9516718d;hpb=8a627e73d824b5a14249cfe066dc2fdc643ce28d;p=supertux.git diff --git a/src/object/player.cpp b/src/object/player.cpp index 7664a3b2d..df2ca0190 100644 --- a/src/object/player.cpp +++ b/src/object/player.cpp @@ -108,10 +108,10 @@ TuxBodyParts::draw(DrawingContext& context, const Vector& pos, int layer) feet->draw(context, pos, layer-2); } -Player::Player(PlayerStatus* _player_status, std::string name) : - MovingObject(name), player_status(_player_status), grabbed_object(NULL), - ghost_mode(false) +Player::Player(PlayerStatus* _player_status, const std::string& name) + : player_status(_player_status), grabbed_object(NULL), ghost_mode(false) { + this->name = name; controller = main_controller; smalltux_gameover = sprite_manager->create("images/creatures/tux_small/smalltux-gameover.sprite"); smalltux_star = sprite_manager->create("images/creatures/tux_small/smalltux-star.sprite"); @@ -171,14 +171,18 @@ Player::init() void Player::expose(HSQUIRRELVM vm, SQInteger table_idx) { - if (name.empty()) return; + if (name.empty()) + return; + Scripting::expose_object(vm, table_idx, dynamic_cast(this), name, false); } void Player::unexpose(HSQUIRRELVM vm, SQInteger table_idx) { - if (name.empty()) return; + if (name.empty()) + return; + Scripting::unexpose_object(vm, table_idx, name); } @@ -198,7 +202,7 @@ Player::adjust_height(float new_height) if(new_height > bbox.get_height()) { Rect additional_space = bbox2; additional_space.set_height(new_height - bbox.get_height()); - if(!Sector::current()->is_free_space(additional_space)) + if(!Sector::current()->is_free_of_statics(additional_space, this)) return false; } @@ -226,7 +230,10 @@ Player::update(float elapsed_time) handle_input(); // handle_input() calls apply_friction() when Tux is not walking, so we'll have to do this ourselves - if (deactivated) apply_friction(); + if (deactivated) + apply_friction(); + + try_grab = false; // extend/shrink tux collision rectangle so that we fall through/walk over 1 // tile holes @@ -516,7 +523,6 @@ Player::do_jump(float yspeed) { void Player::handle_vertical_input() { - // Press jump key if(controller->pressed(Controller::JUMP) && (can_jump)) { if (duck) { @@ -544,34 +550,26 @@ Player::handle_vertical_input() /* When Down is not held anymore, disable butt jump */ if(butt_jump && !controller->hold(Controller::DOWN)) butt_jump = false; + + // swimming + physic.set_acceleration_y(0); + if (swimming) { + if (controller->hold(Controller::UP) || controller->hold(Controller::JUMP)) + physic.set_acceleration_y(-2000); + physic.set_velocity_y(physic.get_velocity_y() * 0.94); + } } void Player::handle_input() { + Sector* sector = Sector::current(); + if (ghost_mode) { handle_input_ghost(); return; } - 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_space(dest)) { - MovingObject* moving_object = dynamic_cast (grabbed_object); - if(moving_object) { - moving_object->set_pos(pos); - } else { - log_debug << "Non MovingObjetc grabbed?!?" << std::endl; - } - grabbed_object->ungrab(*this, dir); - grabbed_object = NULL; - } - } - /* Peeking */ if( controller->released( Controller::PEEK_LEFT ) ) { peeking = AUTO; @@ -606,8 +604,58 @@ Player::handle_input() } /* Duck or Standup! */ - if (controller->hold(Controller::DOWN)) do_duck(); else do_standup(); + if (controller->hold(Controller::DOWN)) { + do_duck(); + } else { + do_standup(); + } + + /* grabbing */ + if(controller->hold(Controller::ACTION) && !grabbed_object + && try_grab && !duck) { + Vector pos; + if(grab_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; + + MovingObject* moving_object = dynamic_cast (portable); + assert(portable); + if(moving_object == NULL) + continue; + + if(moving_object->get_bbox().contains(pos)) { + grabbed_object = portable; + grabbed_object->grab(*this, get_pos(), dir); + break; + } + } + } + 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_statics(dest)) { + MovingObject* moving_object = dynamic_cast (grabbed_object); + if(moving_object) { + moving_object->set_pos(pos); + } else { + log_debug << "Non MovingObjetc grabbed?!?" << std::endl; + } + grabbed_object->ungrab(*this, dir); + grabbed_object = NULL; + } + } } void @@ -907,6 +955,8 @@ Player::collision_solid(const CollisionHit& hit) if(hit.left || hit.right) { physic.set_velocity_x(0); + try_grab = true; + grab_dir = hit.left ? LEFT : RIGHT; } // crushed? @@ -920,21 +970,13 @@ Player::collision_solid(const CollisionHit& hit) } HitResponse -Player::collision(GameObject& other, const CollisionHit& hit) +Player::collision(GameObject& other, const CollisionHit& ) { Bullet* bullet = dynamic_cast (&other); if(bullet) { return FORCE_MOVE; } - // if we hit something from the side that is portable, the ACTION button is pressed and we are not already holding anything: grab it - Portable* portable = dynamic_cast (&other); - if ((hit.left || hit.right) && (portable && portable->is_portable()) && controller->hold(Controller::ACTION) && (!grabbed_object)) { - grabbed_object = portable; - grabbed_object->grab(*this, get_pos(), dir); - return CONTINUE; - } - #ifdef DEBUG assert(dynamic_cast (&other) != NULL); #endif