Powerup: Iceflower improvements
[supertux.git] / src / badguy / fish.cpp
1 //  SuperTux
2 //  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
3 //
4 //  This program is free software: you can redistribute it and/or modify
5 //  it under the terms of the GNU General Public License as published by
6 //  the Free Software Foundation, either version 3 of the License, or
7 //  (at your option) any later version.
8 //
9 //  This program is distributed in the hope that it will be useful,
10 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 //  GNU General Public License for more details.
13 //
14 //  You should have received a copy of the GNU General Public License
15 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
17 #include "badguy/fish.hpp"
18
19 #include "sprite/sprite.hpp"
20 #include "supertux/object_factory.hpp"
21 #include "supertux/tile.hpp"
22
23 static const float FISH_JUMP_POWER = -600;
24 static const float FISH_WAIT_TIME = 1;
25
26 Fish::Fish(const Reader& reader) :
27   BadGuy(reader, "images/creatures/fish/fish.sprite", LAYER_TILES-1), 
28   waiting(),
29   stop_y(0)
30 {
31   physic.enable_gravity(true);
32 }
33
34 Fish::Fish(const Vector& pos) :
35   BadGuy(pos, "images/creatures/fish/fish.sprite", LAYER_TILES-1), 
36   waiting(),
37   stop_y(0)
38 {
39   physic.enable_gravity(true);
40 }
41
42 void
43 Fish::collision_solid(const CollisionHit& chit)
44 {
45   hit(chit);
46 }
47
48 HitResponse
49 Fish::collision_badguy(BadGuy& , const CollisionHit& chit)
50 {
51   return hit(chit);
52 }
53
54 void
55 Fish::draw(DrawingContext& context)
56 {
57   if(waiting.started())
58     return;
59
60   if (get_state() == STATE_FALLING) {
61     sprite->set_action("down");
62     sprite->draw(context, get_pos(), layer);
63   }
64   else if (get_state() == STATE_ACTIVE) {
65     sprite->draw(context, get_pos(), layer);
66   }
67 }
68
69 HitResponse
70 Fish::hit(const CollisionHit& hit)
71 {
72   if(hit.top) {
73     physic.set_velocity_y(0);
74   }
75
76   return CONTINUE;
77 }
78
79 void
80 Fish::collision_tile(uint32_t tile_attributes)
81 {
82   if ((tile_attributes & Tile::WATER) && (physic.get_velocity_y() >= 0)) {
83
84     // initialize stop position if uninitialized
85     if (stop_y == 0) stop_y = get_pos().y + get_bbox().get_height();
86
87     // stop when we have reached the stop position
88     if (get_pos().y >= stop_y) {
89       if(!frozen)
90         start_waiting();
91       movement = Vector(0, 0);
92     }
93
94   }
95 }
96
97 void
98 Fish::active_update(float elapsed_time)
99 {
100   BadGuy::active_update(elapsed_time);
101
102   // waited long enough?
103   if(waiting.check()) {
104     jump();
105   }
106
107   // set sprite
108   if(!frozen)
109     sprite->set_action(physic.get_velocity_y() < 0 ? "normal" : "down");
110
111   // we can't afford flying out of the tilemap, 'cause the engine would remove us.
112   if ((get_pos().y - 31.8) < 0) // too high, let us fall
113   {
114     physic.set_velocity_y(0);
115     physic.enable_gravity(true);
116   }
117 }
118
119 void
120 Fish::start_waiting()
121 {
122   waiting.start(FISH_WAIT_TIME);
123   set_colgroup_active(COLGROUP_DISABLED);
124   physic.enable_gravity(false);
125   physic.set_velocity_y(0);
126 }
127
128 void
129 Fish::jump()
130 {
131   physic.set_velocity_y(FISH_JUMP_POWER);
132   physic.enable_gravity(true);
133   set_colgroup_active(COLGROUP_MOVING);
134 }
135
136 void
137 Fish::freeze()
138 {
139   BadGuy::freeze();
140   sprite->set_action(physic.get_velocity_y() < 0 ? "iced" : "iced-down");
141   sprite->set_color(Color(1.0f, 1.0f, 1.0f));
142   waiting.stop();
143 }
144
145 void
146 Fish::unfreeze()
147 { // does this happen at all? (or do fishes die when they fall frozen?)
148   BadGuy::unfreeze();
149   start_waiting();
150 }
151
152 bool
153 Fish::is_freezable() const
154 {
155   return true;
156 }
157
158 /* EOF */