86821a84479a9afe8bfb67c1e63a98e477af4940
[supertux.git] / src / badguy / fish.cpp
1 //  $Id$
2 //
3 //  SuperTux
4 //  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
5 //
6 //  This program is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU General Public License
8 //  as published by the Free Software Foundation; either version 2
9 //  of the License, or (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, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19
20 #include <config.h>
21
22 #include "fish.hpp"
23
24 #include "tile.hpp"
25 #include "object/tilemap.hpp"
26 #include "lisp/writer.hpp"
27 #include "object_factory.hpp"
28 #include "sprite/sprite.hpp"
29 #include "log.hpp"
30
31 static const float FISH_JUMP_POWER = -600;
32 static const float FISH_WAIT_TIME = 1;
33
34 Fish::Fish(const lisp::Lisp& reader)
35   : BadGuy(reader, "images/creatures/fish/fish.sprite", LAYER_TILES-1), stop_y(0)
36 {
37   physic.enable_gravity(true);
38 }
39
40 Fish::Fish(const Vector& pos)
41   : BadGuy(pos, "images/creatures/fish/fish.sprite", LAYER_TILES-1), stop_y(0)
42 {
43   physic.enable_gravity(true);
44 }
45
46 void
47 Fish::write(lisp::Writer& writer)
48 {
49   writer.start_list("fish");
50
51   writer.write("x", start_position.x);
52   writer.write("y", start_position.y);
53
54   writer.end_list("fish");
55 }
56
57 void
58 Fish::collision_solid(const CollisionHit& chit)
59 {
60   hit(chit);
61 }
62
63 HitResponse
64 Fish::collision_badguy(BadGuy& , const CollisionHit& chit)
65 {
66   return hit(chit);
67 }
68
69 void
70 Fish::draw(DrawingContext& context)
71 {
72   if(waiting.started())
73     return;
74
75   if (get_state() == STATE_FALLING) {
76     sprite->set_action("down");
77     sprite->draw(context, get_pos(), layer);
78   }
79   else if (get_state() == STATE_ACTIVE) {
80     sprite->draw(context, get_pos(), layer);
81   }
82 }
83
84 HitResponse
85 Fish::hit(const CollisionHit& hit)
86 {
87   if(hit.top) {
88     physic.set_velocity_y(0);
89   }
90
91   return CONTINUE;
92 }
93
94 void
95 Fish::collision_tile(uint32_t tile_attributes)
96 {
97   if ((tile_attributes & Tile::WATER) && (physic.get_velocity_y() >= 0)) {
98
99     // initialize stop position if uninitialized
100     if (stop_y == 0) stop_y = get_pos().y + get_bbox().get_height();
101
102     // stop when we have reached the stop position
103     if (get_pos().y >= stop_y) {
104       if(!frozen)
105         start_waiting();
106       movement = Vector(0, 0);
107     }
108
109   }
110 }
111
112 void
113 Fish::active_update(float elapsed_time)
114 {
115   BadGuy::active_update(elapsed_time);
116
117   // waited long enough?
118   if(waiting.check()) {
119     jump();
120   }
121
122   // set sprite
123   if(!frozen)
124     sprite->set_action(physic.get_velocity_y() < 0 ? "normal" : "down");
125
126   // we can't afford flying out of the tilemap, 'cause the engine would remove us.
127   if ((get_pos().y - 31.8) < 0) // too high, let us fall
128   {
129     physic.set_velocity_y(0);
130     physic.enable_gravity(true);
131   }
132 }
133
134 void
135 Fish::start_waiting()
136 {
137   waiting.start(FISH_WAIT_TIME);
138   set_colgroup_active(COLGROUP_DISABLED);
139   physic.enable_gravity(false);
140   physic.set_velocity_y(0);
141 }
142
143 void
144 Fish::jump()
145 {
146   physic.set_velocity_y(FISH_JUMP_POWER);
147   physic.enable_gravity(true);
148   set_colgroup_active(COLGROUP_MOVING);
149 }
150
151 void
152 Fish::freeze()
153 {
154   BadGuy::freeze();
155   sprite->set_action(physic.get_velocity_y() < 0 ? "iced" : "iced-down");
156   waiting.stop();
157 }
158
159 void
160 Fish::unfreeze()
161 { // does this happen at all? (or do fishes die when they fall frozen?)
162   BadGuy::unfreeze();
163   start_waiting();
164 }
165
166 bool
167 Fish::is_freezable() const
168 {
169   return true;
170 }
171
172 IMPLEMENT_FACTORY(Fish, "fish")