Reimplemented fish. The code quality isn't comparable to Matze or Wansti's, who I...
[supertux.git] / src / badguy / fish.cpp
1 //  $Id$
2 // 
3 //  SuperTux
4 //  Copyright (C) 2005 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
19 //  02111-1307, USA.
20 #include <config.h>
21
22 #include "fish.hpp"
23 #include "object/tilemap.hpp"
24
25 static const float FISH_JUMP_POWER = 700;
26 static const float FISH_FALL_BY_Y = 10;
27 static const float FISH_WAIT_TIME = 3;
28
29 Fish::Fish(const lisp::Lisp& reader)
30     : waiting(false)
31 {
32   reader.get("x", start_position.x);
33   reader.get("y", start_position.y);
34   bbox.set_size(31.8, 31.8);
35   sprite = sprite_manager->create("fish");
36   physic.enable_gravity(true);
37 }
38
39 Fish::Fish(float pos_x, float pos_y)
40     : waiting(false)
41 {
42   start_position.x = pos_x;
43   start_position.y = pos_y;
44   bbox.set_size(31.8, 31.8);
45   sprite = sprite_manager->create("fish");
46   physic.enable_gravity(true);
47 }
48
49 void
50 Fish::write(lisp::Writer& writer)
51 {
52   writer.start_list("fish");
53
54   writer.write_float("x", start_position.x);
55   writer.write_float("y", start_position.y);
56
57   writer.end_list("fish");
58 }
59
60 HitResponse
61 Fish::collision_solid(GameObject& other, const CollisionHit& chit)
62 {
63   return hit(chit);
64 }
65
66 HitResponse
67 Fish::collision_badguy(BadGuy& other, const CollisionHit& chit)
68 {
69   return hit(chit);
70 }
71
72 HitResponse
73 Fish::hit(const CollisionHit& chit)
74 {
75   if(chit.normal.y < .5) { // hit ceiling
76     physic.set_velocity_y(0);
77   }
78
79   return CONTINUE;
80 }
81
82 void
83 Fish::active_update(float elapsed_time)
84 {
85   BadGuy::active_update(elapsed_time);
86
87   // check state and modify accordingly
88   if (!waiting && physic.get_velocity_y() < 0
89                && (get_pos().y - start_position.y) >= FISH_FALL_BY_Y) // we fell far enough
90   {
91         start_waiting();
92   }
93   else if (waiting)
94   {
95         waiting_for += elapsed_time;
96         if (waiting_for >= FISH_WAIT_TIME) // we've been waiting long enough
97         {
98           waiting = false;
99           physic.set_velocity_y(FISH_JUMP_POWER);
100           physic.enable_gravity(true);
101         }
102   }
103   
104   // set sprite
105   sprite->set_action(physic.get_velocity_y() > 0 ? "normal" : "down");
106   
107   // we can't afford flying out of the tilemap, 'cause the engine would remove us.
108   if ((get_pos().y - 31.8) < 0) // too high, let us fall
109   {
110         physic.set_velocity_y(0);
111         physic.enable_gravity(true);
112   }
113   else if (Sector::current() && // spares us from possible segfaults
114           (get_pos().y - 31.8) > (Sector::current()->solids->get_height() * 32)) // too low, wait.
115   {
116         start_waiting();
117   }
118 }
119
120 void
121 Fish::start_waiting()
122 {
123   waiting_for = 0;
124   waiting = true;
125   physic.enable_gravity(false);
126   physic.set_velocity_y(0);
127 }
128
129 IMPLEMENT_FACTORY(Fish, "fish")