#include "falling_coin.hpp"
#include "random_generator.hpp"
#include "object/sprite_particle.hpp"
+#include "trigger/climbable.hpp"
static const int TILES_FOR_BUTTJUMP = 3;
static const float SHOOTING_TIME = .150f;
/// time before idle animation starts
static const float IDLE_TIME = 2.5f;
+/** acceleration in horizontal direction when walking
+ * (all acceleratiosn are in pixel/s^2) */
static const float WALK_ACCELERATION_X = 300;
+/** acceleration in horizontal direction when running */
static const float RUN_ACCELERATION_X = 400;
+/** acceleration when skidding */
static const float SKID_XM = 200;
+/** time of skidding in seconds */
static const float SKID_TIME = .3f;
+/** maximum walk velocity (pixel/s) */
static const float MAX_WALK_XM = 230;
+/** maximum run velcoity (pixel/s) */
static const float MAX_RUN_XM = 320;
+/** maximum horizontal climb velocity */
+static const float MAX_CLIMB_XM = 48;
+/** maximum vertical climb velocity */
+static const float MAX_CLIMB_YM = 128;
+/** instant velocity when tux starts to walk */
static const float WALK_SPEED = 100;
+/** time of the kick (kicking mriceblock) animation */
static const float KICK_TIME = .3f;
+/** time of tux cheering (currently unused) */
static const float CHEER_TIME = 1.0f;
-static const float UNDUCK_HURT_TIME = 0.25f; /**< if Tux cannot unduck for this long, he will get hurt */
+/** if Tux cannot unduck for this long, he will get hurt */
+static const float UNDUCK_HURT_TIME = 0.25f;
// growing animation
Surface* growingtux_left[GROWING_FRAMES];
}
Player::Player(PlayerStatus* _player_status, const std::string& name)
- : player_status(_player_status), grabbed_object(NULL), ghost_mode(false)
+ : player_status(_player_status), grabbed_object(NULL), ghost_mode(false), climbing(0)
{
this->name = name;
controller = main_controller;
sound_manager->preload("sounds/invincible.wav");
sound_manager->preload("sounds/splash.ogg");
-
init();
}
Player::~Player()
{
+ if (climbing) stop_climbing(*climbing);
delete smalltux_gameover;
delete smalltux_star;
delete bigtux_star;
on_ground_flag = false;
grabbed_object = NULL;
+ climbing = 0;
+
physic.reset();
}
if(new_height > bbox.get_height()) {
Rect additional_space = bbox2;
additional_space.set_height(new_height - bbox.get_height());
- if(!Sector::current()->is_free_of_statics(additional_space, this))
+ if(!Sector::current()->is_free_of_statics(additional_space, this, true))
return false;
}
void
Player::trigger_sequence(std::string sequence_name)
{
+ if (climbing) stop_climbing(*climbing);
GameSession::current()->start_sequence(sequence_name);
}
handle_input_ghost();
return;
}
+ if (climbing) {
+ handle_input_climbing();
+ return;
+ }
/* Peeking */
if( controller->released( Controller::PEEK_LEFT ) ) {
continue;
if(moving_object->get_bbox().contains(pos)) {
+ if (climbing) stop_climbing(*climbing);
grabbed_object = portable;
grabbed_object->grab(*this, get_pos(), dir);
break;
}
if(animate)
growing_timer.start(GROWING_TIME);
+ if (climbing) stop_climbing(*climbing);
}
if ((type == NO_BONUS) || (type == GROWUP_BONUS)) {
Vector paccel = Vector(0, 1000);
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 (climbing) stop_climbing(*climbing);
}
if ((player_status->bonus == ICE_BONUS) && (animate)) {
// visually lose cap
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));
+ if (climbing) stop_climbing(*climbing);
}
player_status->max_fire_bullets = 0;
player_status->max_ice_bullets = 0;
int layer = LAYER_OBJECTS + 1;
/* Set Tux sprite action */
- if (backflipping)
+ if (climbing)
+ {
+ tux_body->set_action("skid-left");
+ }
+ else if (backflipping)
{
if(dir == LEFT)
tux_body->set_action("backflip-left");
return;
sound_manager->play("sounds/hurt.wav");
+ if (climbing) stop_climbing(*climbing);
physic.set_velocity_x(0);
duck = false;
}
} else {
- for (int i = 0; (i < 5) && (i < player_status->coins); i++)
+ if (player_status->coins >= 25 && !GameSession::current()->get_reset_point_sectorname().empty())
{
- // the numbers: starting x, starting y, velocity y
- Sector::current()->add_object(new FallingCoin(get_pos() +
- Vector(systemRandom.rand(5), systemRandom.rand(-32,18)),
- systemRandom.rand(-100,100)));
+ for (int i = 0; i < 5; i++)
+ {
+ // the numbers: starting x, starting y, velocity y
+ Sector::current()->add_object(new FallingCoin(get_pos() +
+ Vector(systemRandom.rand(5), systemRandom.rand(-32,18)),
+ systemRandom.rand(-100,100)));
+ }
+ player_status->coins -= std::max(player_status->coins/10, 25);
+ }
+ else
+ {
+ GameSession::current()->set_reset_point("", Vector());
}
physic.enable_gravity(true);
physic.set_acceleration(0, 0);
physic.set_velocity(0, -700);
- player_status->coins -= 25;
set_bonus(NO_BONUS, true);
dying = true;
dying_timer.start(3.0);
set_size(31.8f, 31.8f);
duck = false;
last_ground_y = vector.y;
+ if (climbing) stop_climbing(*climbing);
physic.reset();
}
physic.set_velocity_y(0);
physic.set_acceleration_x(0);
physic.set_acceleration_y(0);
+ if (climbing) stop_climbing(*climbing);
}
void
if (ghost_mode == enable)
return;
+ if (climbing) stop_climbing(*climbing);
+
if (enable) {
ghost_mode = true;
set_group(COLGROUP_DISABLED);
log_debug << "You feel solid again." << std::endl;
}
}
+
+
+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);
+}
+
+