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");
bigtux_star = sprite_manager->create("images/creatures/tux_big/bigtux-star.sprite");
+ airarrow.reset(new Surface("images/engine/hud/airarrow.png"));
sound_manager->preload("sounds/bigjump.wav");
sound_manager->preload("sounds/jump.wav");
void
Player::expose(HSQUIRRELVM vm, SQInteger table_idx)
{
- if (name.empty()) return;
+ if (name.empty())
+ return;
+
Scripting::expose_object(vm, table_idx, dynamic_cast<Scripting::Player *>(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);
}
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;
}
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();
// extend/shrink tux collision rectangle so that we fall through/walk over 1
// tile holes
if(controller->pressed(Controller::JUMP) && (can_jump)) {
if (duck) {
// when running, only jump a little bit; else do a backflip
- if (physic.get_velocity_x() != 0) do_jump(-300); else do_backflip();
+ if ((physic.get_velocity_x() != 0) || (controller->hold(Controller::LEFT)) || (controller->hold(Controller::RIGHT))) do_jump(-300); else do_backflip();
} else {
// jump a bit higher if we are running; else do a normal jump
if (fabs(physic.get_velocity_x()) > MAX_WALK_XM) do_jump(-580); else do_jump(-520);
/* When Down is not held anymore, disable butt jump */
if(butt_jump && !controller->hold(Controller::DOWN))
butt_jump = false;
-
- // swimming
+
+ // swimming
physic.set_acceleration_y(0);
if (swimming) {
- if (controller->hold(Controller::UP) || controller->hold(Controller::JUMP)) physic.set_acceleration_y(-2000);
+ if (controller->hold(Controller::UP) || controller->hold(Controller::JUMP))
+ physic.set_acceleration_y(-2000);
physic.set_velocity_y(physic.get_velocity_y() * 0.94);
}
}
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<MovingObject*> (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;
handle_vertical_input();
/* Shoot! */
- if (controller->pressed(Controller::ACTION) && player_status->bonus == FIRE_BONUS) {
+ if (controller->pressed(Controller::ACTION) && (player_status->bonus == FIRE_BONUS || player_status->bonus == ICE_BONUS)) {
if(Sector::current()->add_bullet(
get_pos() + ((dir == LEFT)? Vector(0, bbox.get_height()/2)
: Vector(32, bbox.get_height()/2)),
}
/* Duck or Standup! */
- if (controller->hold(Controller::DOWN)) do_duck(); else do_standup();
+ if (controller->hold(Controller::DOWN)) {
+ do_duck();
+ } else {
+ do_standup();
+ }
+
+ /* grabbing */
+ 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);
+ Rect dest(pos, pos + Vector(32, 32));
+ if(Sector::current()->is_free_of_statics(dest)) {
+ MovingObject* moving_object = dynamic_cast<MovingObject*> (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
+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;
+
+ MovingObject* moving_object = dynamic_cast<MovingObject*> (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;
+ }
+ }
+ }
}
void
player_status->add_coins(count);
}
+int
+Player::get_coins()
+{
+ return player_status->coins;
+}
+
bool
Player::add_bonus(const std::string& bonustype)
{
std::string action = (dir==LEFT)?"left":"right";
Sector::current()->add_object(new SpriteParticle("images/objects/particles/firetux-helmet.sprite", action, ppos, ANCHOR_TOP, pspeed, paccel, LAYER_OBJECTS-1));
}
+ if ((player_status->bonus == ICE_BONUS) && (animate)) {
+ // visually lose cap
+ Vector ppos = Vector((bbox.p1.x + bbox.p2.x) / 2, bbox.p1.y);
+ Vector pspeed = Vector(((dir==LEFT) ? +100 : -100), -300);
+ Vector paccel = Vector(0, 1000);
+ std::string action = (dir==LEFT)?"left":"right";
+ Sector::current()->add_object(new SpriteParticle("images/objects/particles/icetux-cap.sprite", action, ppos, ANCHOR_TOP, pspeed, paccel, LAYER_OBJECTS-1));
+ }
player_status->max_fire_bullets = 0;
player_status->max_ice_bullets = 0;
}
if(!visible)
return;
+ // if Tux is above camera, draw little "air arrow" to show where he is x-wise
+ if (Sector::current() && Sector::current()->camera && (get_bbox().p2.y + 16 < Sector::current()->camera->get_translation().y)) {
+ float px = get_pos().x + (get_bbox().p2.x - get_bbox().p1.x - airarrow.get()->get_width()) / 2;
+ float py = Sector::current()->camera->get_translation().y;
+ py += std::min(((py - (get_bbox().p2.y + 16)) / 4), 16.0f);
+ context.draw_surface(airarrow.get(), Vector(px, py), LAYER_HUD - 1);
+ }
+
TuxBodyParts* tux_body;
if (player_status->bonus == GROWUP_BONUS)
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<Portable*> (&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;
+ if(hit.left || hit.right) {
+ try_grab(); //grab objects right now, in update it will be too late
}
-
#ifdef DEBUG
assert(dynamic_cast<MovingObject*> (&other) != NULL);
#endif