* Use overloading in Lisp and Writer
[supertux.git] / src / badguy / jumpy.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 "jumpy.hpp"
23
24 static const float JUMPSPEED=-600;
25 static const float JUMPY_MID_TOLERANCE=4;
26 static const float JUMPY_LOW_TOLERANCE=2;
27
28 Jumpy::Jumpy(const lisp::Lisp& reader)
29     : BadGuy(reader, "images/creatures/snowjumpy/snowjumpy.sprite"), groundhit_pos_set(false)
30 {
31   // TODO create a nice sound for this...
32   //sound_manager->preload("sounds/skid.wav");
33 }
34
35 void
36 Jumpy::write(lisp::Writer& writer)
37 {
38   writer.start_list("jumpy");
39
40   writer.write("x", start_position.x);
41   writer.write("y", start_position.y);
42
43   writer.end_list("jumpy");
44 }
45
46 void
47 Jumpy::collision_solid(const CollisionHit& chit)
48 {
49   hit(chit);
50 }
51
52 HitResponse
53 Jumpy::collision_badguy(BadGuy& , const CollisionHit& chit)
54 {
55   return hit(chit);
56 }
57
58 HitResponse
59 Jumpy::hit(const CollisionHit& chit)
60 {
61   if(chit.bottom) {
62     if (!groundhit_pos_set)
63     {
64       pos_groundhit = get_pos();
65       groundhit_pos_set = true;
66     }
67
68     physic.set_velocity_y((frozen || get_state() == STATE_FALLING) ? 0 : JUMPSPEED);
69     // TODO create a nice sound for this...
70     //sound_manager->play("sounds/skid.wav");
71   } else if(chit.top) {
72     physic.set_velocity_y(0);
73   }
74
75   return CONTINUE;
76 }
77
78 void
79 Jumpy::active_update(float elapsed_time)
80 {
81   BadGuy::active_update(elapsed_time);
82
83   if(frozen)
84     return;
85
86   Player* player = this->get_nearest_player();
87   if (player)
88   {
89     dir = (player->get_pos().x > get_pos().x) ? RIGHT : LEFT;
90   }
91
92   if (!groundhit_pos_set)
93   {
94     sprite->set_action(dir == LEFT ? "left-middle" : "right-middle");
95     return;
96   }
97
98   if ( get_pos().y < (pos_groundhit.y - JUMPY_MID_TOLERANCE ) )
99     sprite->set_action(dir == LEFT ? "left-up" : "right-up");
100   else if ( get_pos().y >= (pos_groundhit.y - JUMPY_MID_TOLERANCE) &&
101       get_pos().y < (pos_groundhit.y - JUMPY_LOW_TOLERANCE) )
102     sprite->set_action(dir == LEFT ? "left-middle" : "right-middle");
103   else
104     sprite->set_action(dir == LEFT ? "left-down" : "right-down");
105 }
106
107 void
108 Jumpy::freeze()
109 {
110   BadGuy::freeze();
111   physic.set_velocity_y(std::max(0.0f, physic.get_velocity_y()));
112   sprite->set_action(dir == LEFT ? "left-iced" : "right-iced");
113 }
114
115 bool
116 Jumpy::is_freezable() const
117 {
118   return true;
119 }
120
121 IMPLEMENT_FACTORY(Jumpy, "jumpy")