Unstable tile: Dissolve, then disappear without falling down.
[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 {
32   sprite->set_action("normal");
33 }
34
35 HitResponse
36 UnstableTile::collision(GameObject& other, const CollisionHit& )
37 {
38   if(state == STATE_NORMAL) {
39     Player* player = dynamic_cast<Player*> (&other);
40     if(player != NULL &&
41        player->get_bbox().get_bottom() < get_bbox().get_top() + SHIFT_DELTA) {
42       dissolve ();
43     }
44
45     if (dynamic_cast<Explosion*> (&other)) {
46       dissolve ();
47     }
48   }
49   return FORCE_MOVE;
50 }
51
52 void UnstableTile::dissolve (void)
53 {
54   if (state != STATE_NORMAL)
55     return;
56
57   if (sprite->has_action ("dissolve")) {
58     state = STATE_DISSOLVE;
59     this->set_action ("dissolve", /* loops = */ 1);
60   }
61   else {
62     fall_down ();
63   }
64 }
65
66 void UnstableTile::fall_down (void)
67 {
68   if ((state != STATE_NORMAL) && (state != STATE_DISSOLVE))
69     return;
70
71   if (sprite->has_action ("fall-down")) {
72     state = STATE_FALL;
73     this->set_action ("fall-down", /* loops = */ 1);
74     set_group (COLGROUP_DISABLED);
75     physic.enable_gravity (true);
76   }
77   else {
78     remove_me ();
79   }
80 }
81
82 void
83 UnstableTile::update(float elapsed_time)
84 {
85   switch (state)
86   {
87     case STATE_NORMAL:
88       break;
89
90     case STATE_DISSOLVE:
91       if (sprite->animation_done())
92         fall_down ();
93       break;
94
95     case STATE_FALL:
96       if (sprite->animation_done())
97         remove_me ();
98       else
99         movement = physic.get_movement (elapsed_time);
100       break;
101   }
102 }
103
104 /* EOF */