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