From: Ryan Flegel Date: Fri, 13 Jun 2008 06:06:03 +0000 (+0000) Subject: Bomb is now portable X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=8f3c5b1261e44fdb9a8d9e37879170ae2caf5937;p=supertux.git Bomb is now portable SVN-Revision: 5568 --- diff --git a/src/badguy/bomb.cpp b/src/badguy/bomb.cpp index 5327515ab..540b28970 100644 --- a/src/badguy/bomb.cpp +++ b/src/badguy/bomb.cpp @@ -24,7 +24,7 @@ #include "object/explosion.hpp" Bomb::Bomb(const Vector& pos, Direction dir, std::string custom_sprite /*= "images/creatures/mr_bomb/mr_bomb.sprite"*/ ) - : BadGuy( pos, dir, custom_sprite ) + : BadGuy( pos, dir, custom_sprite ), grabbed(false), grabber(NULL) { state = STATE_TICKING; set_action(dir == LEFT ? "ticking-left" : "ticking-right", 1); @@ -39,7 +39,7 @@ Bomb::Bomb(const Vector& pos, Direction dir, std::string custom_sprite /*= "imag } Bomb::Bomb(const Bomb& other) - : BadGuy(other), state(other.state) + : BadGuy(other), Portable(other), state(other.state) { if (state == STATE_TICKING) { ticking.reset(sound_manager->create_sound_source("sounds/fizz.wav")); @@ -62,6 +62,8 @@ Bomb::collision_solid(const CollisionHit& hit) { if(hit.bottom) physic.set_velocity_y(0); + + update_on_ground_flag(hit); } HitResponse @@ -77,12 +79,15 @@ Bomb::collision_badguy(BadGuy& , const CollisionHit& ) } void -Bomb::active_update(float ) +Bomb::active_update(float elapsed_time) { ticking->set_position(get_pos()); if(sprite->animation_done()) { explode(); } + else if (!grabbed) { + movement = physic.get_movement(elapsed_time); + } } void @@ -90,6 +95,16 @@ Bomb::explode() { ticking->stop(); + // Make the player let go before we explode, otherwise the player is holding + // an invalid object. There's probably a better way to do this than in the + // Bomb class. + if (grabber != NULL) { + Player* player = dynamic_cast(grabber); + + if (player) + player->stop_grabbing(); + } + remove_me(); Explosion* explosion = new Explosion(get_bbox().get_middle()); Sector::current()->add_object(explosion); @@ -102,3 +117,29 @@ Bomb::kill_fall() { explode(); } + +void +Bomb::grab(MovingObject& object, const Vector& pos, Direction dir) +{ + movement = pos - get_pos(); + this->dir = dir; + + // We actually face the opposite direction of Tux here to make the fuse more + // visible instead of hiding it behind Tux + sprite->set_action_continued(dir == LEFT ? "ticking-right" : "ticking-left"); + set_colgroup_active(COLGROUP_DISABLED); + grabbed = true; + grabber = &object; +} + +void +Bomb::ungrab(MovingObject& object, Direction dir) +{ + this->dir = dir; + // portable objects are usually pushed away from Tux when dropped, but we + // don't want that, so we set the position + set_pos(object.get_pos() + Vector(dir == LEFT ? -16 : 16, get_bbox().get_height()*0.66666 - 32)); + set_colgroup_active(COLGROUP_MOVING); + grabbed = false; +} + diff --git a/src/badguy/bomb.hpp b/src/badguy/bomb.hpp index e75a32f80..aa864f5a5 100644 --- a/src/badguy/bomb.hpp +++ b/src/badguy/bomb.hpp @@ -21,8 +21,9 @@ #define __BOMB_H__ #include "badguy.hpp" +#include "object/portable.hpp" -class Bomb : public BadGuy +class Bomb : public BadGuy, public Portable { public: Bomb(const Vector& pos, Direction dir, std::string custom_sprite = "images/creatures/mr_bomb/bomb.sprite" ); @@ -35,6 +36,8 @@ public: void active_update(float elapsed_time); void kill_fall(); void explode(); + void grab(MovingObject& object, const Vector& pos, Direction dir); + void ungrab(MovingObject& object, Direction dir); private: enum State { @@ -42,6 +45,8 @@ private: }; State state; + bool grabbed; + MovingObject* grabber; std::auto_ptr ticking; }; diff --git a/src/object/player.hpp b/src/object/player.hpp index c4e0dbf13..d584a7610 100644 --- a/src/object/player.hpp +++ b/src/object/player.hpp @@ -225,6 +225,10 @@ public: { return grabbed_object; } + void stop_grabbing() + { + grabbed_object = NULL; + } /** * Switches ghost mode on/off.