00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "badguy/stalactite.hpp"
00018
00019 #include "math/random_generator.hpp"
00020 #include "object/player.hpp"
00021 #include "sprite/sprite.hpp"
00022 #include "supertux/object_factory.hpp"
00023
00024 static const int SHAKE_RANGE_X = 40;
00025 static const float SHAKE_TIME = .8f;
00026 static const float SHAKE_RANGE_Y = 400;
00027
00028 Stalactite::Stalactite(const Reader& lisp) :
00029 BadGuy(lisp, "images/creatures/stalactite/stalactite.sprite", LAYER_TILES - 1),
00030 timer(),
00031 state(STALACTITE_HANGING),
00032 shake_delta()
00033 {
00034 countMe = false;
00035 set_colgroup_active(COLGROUP_TOUCHABLE);
00036 }
00037
00038 void
00039 Stalactite::active_update(float elapsed_time)
00040 {
00041 if(state == STALACTITE_HANGING) {
00042 Player* player = this->get_nearest_player();
00043 if (player) {
00044 if(player->get_bbox().p2.x > bbox.p1.x - SHAKE_RANGE_X
00045 && player->get_bbox().p1.x < bbox.p2.x + SHAKE_RANGE_X
00046 && player->get_bbox().p2.y > bbox.p1.y
00047 && player->get_bbox().p1.y < bbox.p2.y + SHAKE_RANGE_Y) {
00048 timer.start(SHAKE_TIME);
00049 state = STALACTITE_SHAKING;
00050 }
00051 }
00052 } else if(state == STALACTITE_SHAKING) {
00053 shake_delta = Vector(graphicsRandom.rand(-3,3), 0);
00054 if(timer.check()) {
00055 state = STALACTITE_FALLING;
00056 physic.enable_gravity(true);
00057 set_colgroup_active(COLGROUP_MOVING);
00058 }
00059 } else if(state == STALACTITE_FALLING) {
00060 movement = physic.get_movement(elapsed_time);
00061 }
00062 }
00063
00064 void
00065 Stalactite::squish()
00066 {
00067 state = STALACTITE_SQUISHED;
00068 physic.enable_gravity(true);
00069 physic.set_velocity_x(0);
00070 physic.set_velocity_y(0);
00071 set_state(STATE_SQUISHED);
00072 sprite->set_action("squished");
00073 set_group(COLGROUP_MOVING_ONLY_STATIC);
00074 run_dead_script();
00075 }
00076
00077 void
00078 Stalactite::collision_solid(const CollisionHit& hit)
00079 {
00080 if(state == STALACTITE_FALLING) {
00081 if (hit.bottom) squish();
00082 }
00083 if(state == STALACTITE_SQUISHED) {
00084 physic.set_velocity_y(0);
00085 }
00086 }
00087
00088 HitResponse
00089 Stalactite::collision_player(Player& player, const CollisionHit& )
00090 {
00091 if(state != STALACTITE_SQUISHED) {
00092 player.kill(false);
00093 }
00094
00095 return FORCE_MOVE;
00096 }
00097
00098 HitResponse
00099 Stalactite::collision_badguy(BadGuy& other, const CollisionHit& hit)
00100 {
00101 if (state == STALACTITE_SQUISHED) return FORCE_MOVE;
00102
00103
00104 if (dynamic_cast<Stalactite*>(&other)) return FORCE_MOVE;
00105
00106 if (state != STALACTITE_FALLING) return BadGuy::collision_badguy(other, hit);
00107
00108 if (other.is_freezable()) {
00109 other.freeze();
00110 } else {
00111 other.kill_fall();
00112 }
00113
00114 return FORCE_MOVE;
00115 }
00116
00117 void
00118 Stalactite::kill_fall()
00119 {
00120 }
00121
00122 void
00123 Stalactite::draw(DrawingContext& context)
00124 {
00125 if(get_state() == STATE_INIT || get_state() == STATE_INACTIVE)
00126 return;
00127
00128 if(state == STALACTITE_SQUISHED) {
00129 sprite->draw(context, get_pos(), LAYER_OBJECTS);
00130 } else if(state == STALACTITE_SHAKING) {
00131 sprite->draw(context, get_pos() + shake_delta, layer);
00132 } else {
00133 sprite->draw(context, get_pos(), layer);
00134 }
00135 }
00136
00137 void
00138 Stalactite::deactivate()
00139 {
00140 if(state != STALACTITE_HANGING)
00141 remove_me();
00142 }
00143
00144