-Apply door fix to hatch as well (evil code duplication here...)
[supertux.git] / src / badguy / stalactite.cpp
1 #include <config.h>
2
3 #include "stalactite.h"
4
5 static const int SHAKE_RANGE = 40;
6 static const float SHAKE_TIME = .8;
7 static const float SQUISH_TIME = 2;
8
9 Stalactite::Stalactite(const lisp::Lisp& lisp)
10 {
11   lisp.get("x", start_position.x);
12   lisp.get("y", start_position.y);
13   bbox.set_size(31.8, 31.8);
14   sprite = sprite_manager->create("stalactite");
15   state = STALACTITE_HANGING;
16 }
17
18 void
19 Stalactite::write(lisp::Writer& writer)
20 {
21   writer.start_list("stalactite");
22   writer.write_float("x", start_position.x);
23   writer.write_float("y", start_position.y);
24   writer.end_list("stalactite");
25 }
26
27 void
28 Stalactite::active_action(float elapsed_time)
29 {
30   if(state == STALACTITE_HANGING) {
31     Player* player = Sector::current()->player;
32     if(player->get_bbox().p2.x > bbox.p1.x - SHAKE_RANGE
33         && player->get_bbox().p1.x < bbox.p2.x + SHAKE_RANGE
34         && player->get_bbox().p2.y > bbox.p1.y) {
35       timer.start(SHAKE_TIME);
36       state = STALACTITE_SHAKING;
37     }
38   } else if(state == STALACTITE_SHAKING) {
39     if(timer.check()) {
40       state = STALACTITE_FALLING;
41       physic.enable_gravity(true);
42     }
43   } else if(state == STALACTITE_FALLING || state == STALACTITE_SQUISHED) {
44     movement = physic.get_movement(elapsed_time);
45     if(state == STALACTITE_SQUISHED && timer.check())
46       remove_me();
47   }
48 }
49
50 HitResponse
51 Stalactite::collision_solid(GameObject& , const CollisionHit& hit)
52 {
53   if(state != STALACTITE_FALLING && state != STALACTITE_SQUISHED)
54     return FORCE_MOVE;
55   
56   if(fabsf(hit.normal.y) > .5) { // hit floor or roof?
57     state = STALACTITE_SQUISHED;
58     physic.set_velocity_y(0);
59     sprite->set_action("squished");
60     if(!timer.started())
61       timer.start(SQUISH_TIME);
62   }
63
64   return CONTINUE;
65 }
66
67 HitResponse
68 Stalactite::collision_player(Player& player, const CollisionHit& )
69 {
70   if(state != STALACTITE_SQUISHED) {
71     player.kill(Player::SHRINK);
72   }
73
74   return FORCE_MOVE;
75 }
76
77 void
78 Stalactite::kill_fall()
79 {
80 }
81
82 void
83 Stalactite::draw(DrawingContext& context)
84 {
85   if(get_state() != STATE_ACTIVE)
86     return;
87     
88   if(state == STALACTITE_SHAKING) {
89     sprite->draw(context, get_pos() + Vector((rand() % 6)-3, 0), LAYER_OBJECTS);
90   } else {
91     sprite->draw(context, get_pos(), LAYER_OBJECTS);
92   }
93 }
94
95 void
96 Stalactite::deactivate()
97 {
98   if(state != STALACTITE_HANGING)
99     remove_me();
100 }
101
102 IMPLEMENT_FACTORY(Stalactite, "stalactite")