From 72325436a6b4c5eef61f4a14ef287a9520717baa Mon Sep 17 00:00:00 2001 From: Christoph Sommer Date: Sat, 19 Jan 2008 19:52:30 +0000 Subject: [PATCH] Butt Jump. As Big Tux, gain lots of speed and press down, then smash bricks, Ice Blocks and Snails SVN-Revision: 5282 --- data/images/creatures/tux/big/buttjump-0.png | Bin 0 -> 5125 bytes data/images/creatures/tux/tux.sprite | 9 +++++++++ src/badguy/mriceblock.cpp | 11 +++++++---- src/badguy/snail.cpp | 11 +++++++---- src/object/block.cpp | 22 ++++++++++++++-------- src/object/block.hpp | 2 +- src/object/player.cpp | 27 ++++++++++++++++++++++++++- 7 files changed, 64 insertions(+), 18 deletions(-) create mode 100644 data/images/creatures/tux/big/buttjump-0.png diff --git a/data/images/creatures/tux/big/buttjump-0.png b/data/images/creatures/tux/big/buttjump-0.png new file mode 100644 index 0000000000000000000000000000000000000000..6354fa983ca7407c9c1ce09422b22abb77e75dc9 GIT binary patch literal 5125 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 Sy;}w^= MAXSQUISHES) { - kill_fall(); - return true; + { + Player* player = dynamic_cast(&object); + squishcount++; + if ((squishcount >= MAXSQUISHES) || (player && player->butt_jump)) { + kill_fall(); + return true; + } } set_state(ICESTATE_FLAT); diff --git a/src/badguy/snail.cpp b/src/badguy/snail.cpp index a2695334d..d68aad7f9 100644 --- a/src/badguy/snail.cpp +++ b/src/badguy/snail.cpp @@ -212,10 +212,13 @@ Snail::collision_squished(GameObject& object) case STATE_KICKED: case STATE_NORMAL: - squishcount++; - if(squishcount >= MAXSQUISHES) { - kill_fall(); - return true; + { + Player* player = dynamic_cast(&object); + squishcount++; + if ((squishcount >= MAXSQUISHES) || (player && player->butt_jump)) { + kill_fall(); + return true; + } } sound_manager->play("sounds/stomp.wav", get_pos()); diff --git a/src/object/block.cpp b/src/object/block.cpp index fd6e2fc21..4cf7920e3 100644 --- a/src/object/block.cpp +++ b/src/object/block.cpp @@ -343,23 +343,29 @@ Brick::Brick(const Vector& pos, int data) } void -Brick::hit(Player& ) +Brick::hit(Player& player) { if(sprite->get_action() == "empty") return; - try_break(true); + try_break(&player); } HitResponse Brick::collision(GameObject& other, const CollisionHit& hit){ + + Player* player = dynamic_cast (&other); + if (player) { + if (player->butt_jump) try_break(); + } + BadGuy* badguy = dynamic_cast (&other); if(badguy) { // hit contains no information for collisions with blocks. // Badguy's bottom has to be below the top of the brick // +7 is required to slide over one tile gaps. if( badguy->can_break() && ( badguy->get_bbox().get_bottom() > get_bbox().get_top() + 7.0 ) ){ - try_break(false); + try_break(); } } Portable* portable = dynamic_cast (&other); @@ -373,24 +379,24 @@ Brick::collision(GameObject& other, const CollisionHit& hit){ } void -Brick::try_break(bool playerhit) +Brick::try_break(Player* player) { if(sprite->get_action() == "empty") return; sound_manager->play("sounds/brick.wav"); Sector* sector = Sector::current(); - Player& player = *(sector->player); + Player& player_one = *(sector->player); if(coin_counter > 0) { sector->add_object(new BouncyCoin(get_pos())); coin_counter--; - player.get_status()->add_coins(1); + player_one.get_status()->add_coins(1); if(coin_counter == 0) sprite->set_action("empty"); start_bounce(); } else if(breakable) { - if(playerhit){ - if(player.is_big()){ + if(player){ + if(player->is_big()){ start_break(); return; } else { diff --git a/src/object/block.hpp b/src/object/block.hpp index 94f87fb04..e620d481f 100644 --- a/src/object/block.hpp +++ b/src/object/block.hpp @@ -85,7 +85,7 @@ class Brick : public Block public: Brick(const Vector& pos, int data); - void try_break(bool playerhit = false); + void try_break(Player* player = false); HitResponse collision(GameObject& other, const CollisionHit& hit); protected: diff --git a/src/object/player.cpp b/src/object/player.cpp index dc5abd91b..72e4debd5 100644 --- a/src/object/player.cpp +++ b/src/object/player.cpp @@ -54,6 +54,7 @@ //#define SWIMMING static const int TILES_FOR_BUTTJUMP = 3; +static const float BUTTJUMP_MIN_VELOCITY_Y = 700.0f; static const float SHOOTING_TIME = .150f; /// time before idle animation starts static const float IDLE_TIME = 2.5f; @@ -501,6 +502,8 @@ Player::do_duck() { return; if (!on_ground()) return; + if (butt_jump) + return; if (adjust_height(31.8f)) { duck = true; @@ -591,7 +594,7 @@ Player::handle_vertical_input() /* In case the player has pressed Down while in a certain range of air, enable butt jump action */ - if (controller->hold(Controller::DOWN) && !butt_jump && !duck && is_big() && jumping) { + if (controller->hold(Controller::DOWN) && !butt_jump && !duck && is_big() && !on_ground() && (physic.get_velocity_y() >= BUTTJUMP_MIN_VELOCITY_Y)) { butt_jump = true; } @@ -835,6 +838,10 @@ Player::set_bonus(BonusType type, bool animate) if (climbing) stop_climbing(*climbing); } + if (type == NO_BONUS) { + if (butt_jump) butt_jump = false; + } + if ((type == NO_BONUS) || (type == GROWUP_BONUS)) { if ((player_status->bonus == FIRE_BONUS) && (animate)) { // visually lose helmet @@ -1005,6 +1012,24 @@ Player::collision_solid(const CollisionHit& hit) on_ground_flag = true; floor_normal = hit.slope_normal; + + // Butt Jump landed + if (butt_jump) { + butt_jump = false; + physic.set_velocity_y(-300); + on_ground_flag = false; + Sector::current()->add_object(new Particles( + Vector(get_bbox().p2.x, get_bbox().p2.y), + 270+20, 270+40, + Vector(280, -260), Vector(0, 300), 3, Color(.4f, .4f, .4f), 3, .8f, + LAYER_OBJECTS+1)); + Sector::current()->add_object(new Particles( + Vector(get_bbox().p1.x, get_bbox().p2.y), + 90-40, 90-20, + Vector(280, -260), Vector(0, 300), 3, Color(.4f, .4f, .4f), 3, .8f, + LAYER_OBJECTS+1)); + } + } else if(hit.top) { if(physic.get_velocity_y() < 0) physic.set_velocity_y(.2f); -- 2.11.0