e68b1d17c3576e7c765d70c9b57b013483b816c0
[supertux.git] / src / badguy / walking_badguy.cpp
1 //  $Id$
2 //
3 //  SuperTux - WalkingBadguy
4 //  Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.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 "walking_badguy.hpp"
23
24 #include "log.hpp"
25 #include "timer.hpp"
26 #include "lisp/writer.hpp"
27 #include "sprite/sprite.hpp"
28
29 WalkingBadguy::WalkingBadguy(const Vector& pos, const std::string& sprite_name, const std::string& walk_left_action, const std::string& walk_right_action, int layer)
30   : BadGuy(pos, sprite_name, layer), walk_left_action(walk_left_action), walk_right_action(walk_right_action), walk_speed(80), max_drop_height(-1)
31 {
32 }
33
34 WalkingBadguy::WalkingBadguy(const Vector& pos, Direction direction, const std::string& sprite_name, const std::string& walk_left_action, const std::string& walk_right_action, int layer)
35   : BadGuy(pos, direction, sprite_name, layer), walk_left_action(walk_left_action), walk_right_action(walk_right_action), walk_speed(80), max_drop_height(-1)
36 {
37 }
38
39 WalkingBadguy::WalkingBadguy(const lisp::Lisp& reader, const std::string& sprite_name, const std::string& walk_left_action, const std::string& walk_right_action, int layer)
40   : BadGuy(reader, sprite_name, layer), walk_left_action(walk_left_action), walk_right_action(walk_right_action), walk_speed(80), max_drop_height(-1)
41 {
42 }
43
44 void
45 WalkingBadguy::write(lisp::Writer& writer)
46 {
47   writer.write("x", start_position.x);
48   writer.write("y", start_position.y);
49 }
50
51 void
52 WalkingBadguy::initialize()
53 {
54   if(frozen)
55     return;
56   sprite->set_action(dir == LEFT ? walk_left_action : walk_right_action);
57   bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
58   physic.set_velocity_x(dir == LEFT ? -walk_speed : walk_speed);
59 }
60
61 void
62 WalkingBadguy::active_update(float elapsed_time)
63 {
64   BadGuy::active_update(elapsed_time);
65
66   if (max_drop_height > -1) {
67     if (on_ground() && might_fall(max_drop_height+1))
68     {
69       turn_around();
70     }
71   }
72
73 }
74
75 void
76 WalkingBadguy::collision_solid(const CollisionHit& hit)
77 {
78
79   update_on_ground_flag(hit);
80
81   if (hit.top) {
82     if (physic.get_velocity_y() < 0) physic.set_velocity_y(0);
83   }
84   if (hit.bottom) {
85     if (physic.get_velocity_y() > 0) physic.set_velocity_y(0);
86   }
87
88   if ((hit.left && (hit.slope_normal.y == 0) && (dir == LEFT)) || (hit.right && (hit.slope_normal.y == 0) && (dir == RIGHT))) {
89     turn_around();
90   }
91
92 }
93
94 HitResponse
95 WalkingBadguy::collision_badguy(BadGuy& , const CollisionHit& hit)
96 {
97
98   if ((hit.left && (dir == LEFT)) || (hit.right && (dir == RIGHT))) {
99     turn_around();
100   }
101
102   return CONTINUE;
103 }
104
105 void
106 WalkingBadguy::turn_around()
107 {
108   if(frozen)
109     return;
110   dir = dir == LEFT ? RIGHT : LEFT;
111   sprite->set_action(dir == LEFT ? walk_left_action : walk_right_action);
112   physic.set_velocity_x(-physic.get_velocity_x());
113
114   // if we get dizzy, we fall off the screen
115   if (turn_around_timer.started()) {
116     if (turn_around_counter++ > 10) kill_fall();
117   } else {
118     turn_around_timer.start(1);
119     turn_around_counter = 0;
120   }
121
122 }
123
124 void
125 WalkingBadguy::freeze()
126 {
127   BadGuy::freeze();
128   physic.set_velocity_x(0);
129 }
130
131 void
132 WalkingBadguy::unfreeze()
133 {
134   BadGuy::unfreeze();
135   WalkingBadguy::initialize();
136 }
137
138
139 float
140 WalkingBadguy::get_velocity_y() const
141 {
142   return physic.get_velocity_y();
143 }
144
145 void
146 WalkingBadguy::set_velocity_y(float vy)
147 {
148   physic.set_velocity_y(vy);
149 }