Fix patch application
[supertux.git] / src / object / unstable_tile.cpp
1 //  SuperTux - Unstable Tile
2 //  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
3 //  Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
4 //  Copyright (C) 2010 Florian Forster <supertux at octo.it>
5 //
6 //  This program is free software: you can redistribute it and/or modify
7 //  it under the terms of the GNU General Public License as published by
8 //  the Free Software Foundation, either version 3 of the License, or
9 //  (at your option) any later version.
10 //
11 //  This program is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 //  GNU General Public License for more details.
15 //
16 //  You should have received a copy of the GNU General Public License
17 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
19 #include "object/unstable_tile.hpp"
20
21 #include "object/explosion.hpp"
22 #include "object/player.hpp"
23 #include "sprite/sprite.hpp"
24 #include "supertux/constants.hpp"
25 #include "supertux/object_factory.hpp"
26
27 UnstableTile::UnstableTile(const Reader& lisp) :
28   MovingSprite(lisp, LAYER_TILES, COLGROUP_STATIC),
29   physic(),
30   state(STATE_NORMAL),
31   slowfall_timer()
32 {
33   sprite->set_action("normal");
34   physic.set_gravity_modifier (.98);
35   physic.enable_gravity (false);
36 }
37
38 HitResponse
39 UnstableTile::collision(GameObject& other, const CollisionHit& )
40 {
41   if(state == STATE_NORMAL) {
42     Player* player = dynamic_cast<Player*> (&other);
43     if(player != NULL &&
44        player->get_bbox().get_bottom() < get_bbox().get_top() + SHIFT_DELTA) {
45       shake ();
46     }
47
48     if (dynamic_cast<Explosion*> (&other)) {
49       shake ();
50     }
51   }
52   return FORCE_MOVE;
53 }
54
55 void UnstableTile::shake (void)
56 {
57   if (state != STATE_NORMAL)
58     return;
59
60   if (sprite->has_action ("shake")) {
61     state = STATE_SHAKE;
62     this->set_action ("shake", /* loops = */ 1);
63   }
64   else {
65     dissolve ();
66   }
67 }
68
69 void UnstableTile::dissolve (void)
70 {
71   if ((state != STATE_NORMAL) && (state != STATE_SHAKE))
72     return;
73
74   if (sprite->has_action ("dissolve")) {
75     state = STATE_DISSOLVE;
76     this->set_action ("dissolve", /* loops = */ 1);
77   }
78   else {
79     slow_fall ();
80   }
81 }
82
83 void UnstableTile::slow_fall (void)
84 {
85   /* Only enter slow-fall if neither shake nor dissolve is available. */
86   if (state != STATE_NORMAL) {
87     this->fall_down ();
88     return;
89   }
90
91   if (sprite->has_action ("fall-down")) {
92     state = STATE_SLOWFALL;
93     this->set_action ("fall-down", /* loops = */ 1);
94     physic.set_gravity_modifier (.10);
95     physic.enable_gravity (true);
96     slowfall_timer = 0.5; /* Fall slowly for half a second. */
97   }
98   else {
99     remove_me ();
100   }
101 }
102
103 void UnstableTile::fall_down (void)
104 {
105   if ((state != STATE_NORMAL)
106       && (state != STATE_SHAKE)
107       && (state != STATE_DISSOLVE)
108       && (state != STATE_SLOWFALL))
109     return;
110
111   if (sprite->has_action ("fall-down")) {
112     state = STATE_FALL;
113     this->set_action ("fall-down", /* loops = */ 1);
114     physic.set_gravity_modifier (.98);
115     physic.enable_gravity (true);
116   }
117   else {
118     remove_me ();
119   }
120 }
121
122 void
123 UnstableTile::update(float elapsed_time)
124 {
125   switch (state)
126   {
127     case STATE_NORMAL:
128       break;
129
130     case STATE_SHAKE:
131       if (sprite->animation_done())
132         dissolve ();
133       break;
134
135     case STATE_DISSOLVE:
136       if (sprite->animation_done()) {
137         /* dissolving is done. Set to non-solid. */
138         set_group (COLGROUP_DISABLED);
139         fall_down ();
140       }
141       break;
142
143     case STATE_SLOWFALL:
144       if (slowfall_timer >= elapsed_time)
145         slowfall_timer -= elapsed_time;
146       else /* Switch to normal falling procedure */
147         fall_down ();
148       movement = physic.get_movement (elapsed_time);
149       break;
150
151     case STATE_FALL:
152       if (sprite->animation_done())
153         remove_me ();
154       else
155         movement = physic.get_movement (elapsed_time);
156       break;
157   }
158 }
159
160 /* EOF */