1 // SuperTux - Badguy "Snail"
2 // Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
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.
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.
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/>.
17 #include "badguy/snail.hpp"
19 #include "audio/sound_manager.hpp"
20 #include "object/player.hpp"
21 #include "sprite/sprite.hpp"
22 #include "supertux/object_factory.hpp"
27 const float KICKSPEED = 500;
28 const int MAXSQUISHES = 10;
29 const float KICKSPEED_Y = -500; /**< y-velocity gained when kicked */
32 Snail::Snail(const Reader& reader) :
33 WalkingBadguy(reader, "images/creatures/snail/snail.sprite", "left", "right"),
40 max_drop_height = 600;
41 sound_manager->preload("sounds/iceblock_bump.wav");
42 sound_manager->preload("sounds/stomp.wav");
43 sound_manager->preload("sounds/kick.wav");
46 Snail::Snail(const Vector& pos, Direction d) :
47 WalkingBadguy(pos, d, "images/creatures/snail/snail.sprite", "left", "right"),
54 max_drop_height = 600;
55 sound_manager->preload("sounds/iceblock_bump.wav");
56 sound_manager->preload("sounds/stomp.wav");
57 sound_manager->preload("sounds/kick.wav");
63 WalkingBadguy::initialize();
70 if (state == STATE_NORMAL) return;
73 WalkingBadguy::initialize();
80 sprite->set_action(dir == LEFT ? "flat-left" : "flat-right");
83 physic.set_velocity_x(0);
84 physic.set_velocity_y(0);
92 state = STATE_KICKED_DELAY;
93 sprite->set_action(dir == LEFT ? "flat-left" : "flat-right");
96 physic.set_velocity_x(0);
97 physic.set_velocity_y(0);
99 // start a timer to delay addition of upward movement until we are (hopefully) out from under the player
100 kicked_delay_timer.start(0.05f);
105 return state == STATE_KICKED;
109 Snail::active_update(float elapsed_time)
114 WalkingBadguy::active_update(elapsed_time);
118 if (flat_timer.started()) {
119 sprite->set_fps(64 - 15 * flat_timer.get_timegone());
121 if (flat_timer.check()) {
124 BadGuy::active_update(elapsed_time);
127 case STATE_KICKED_DELAY:
128 if (kicked_delay_timer.check()) {
129 physic.set_velocity_x(dir == LEFT ? -KICKSPEED : KICKSPEED);
130 physic.set_velocity_y(KICKSPEED_Y);
131 state = STATE_KICKED;
133 BadGuy::active_update(elapsed_time);
137 physic.set_velocity_x(physic.get_velocity_x() * pow(0.99, elapsed_time/0.02));
138 if (fabsf(physic.get_velocity_x()) < walk_speed) be_normal();
139 BadGuy::active_update(elapsed_time);
146 Snail::collision_solid(const CollisionHit& hit)
148 update_on_ground_flag(hit);
152 WalkingBadguy::collision_solid(hit);
155 if(hit.top || hit.bottom) {
156 physic.set_velocity_y(0);
158 if(hit.left || hit.right) {
161 case STATE_KICKED_DELAY:
162 if(hit.top || hit.bottom) {
163 physic.set_velocity_y(0);
165 if(hit.left || hit.right) {
166 physic.set_velocity_x(0);
170 if(hit.top || hit.bottom) {
171 physic.set_velocity_y(0);
173 if(hit.left || hit.right) {
174 sound_manager->play("sounds/iceblock_bump.wav", get_pos());
176 if( ( dir == LEFT && hit.left ) || ( dir == RIGHT && hit.right) ){
177 dir = (dir == LEFT) ? RIGHT : LEFT;
178 sprite->set_action(dir == LEFT ? "flat-left" : "flat-right");
180 physic.set_velocity_x(-physic.get_velocity_x()*0.75);
181 if (fabsf(physic.get_velocity_x()) < walk_speed) be_normal();
191 Snail::collision_badguy(BadGuy& badguy, const CollisionHit& hit)
195 return WalkingBadguy::collision_badguy(badguy, hit);
197 case STATE_KICKED_DELAY:
210 Snail::collision_squished(GameObject& object)
217 Player* player = dynamic_cast<Player*>(&object);
219 if ((squishcount >= MAXSQUISHES) || (player && player->does_buttjump)) {
225 sound_manager->play("sounds/stomp.wav", get_pos());
230 sound_manager->play("sounds/kick.wav", get_pos());
232 MovingObject* movingobject = dynamic_cast<MovingObject*>(&object);
233 if (movingobject && (movingobject->get_pos().x < get_pos().x)) {
242 case STATE_KICKED_DELAY:
247 Player* player = dynamic_cast<Player*>(&object);
248 if (player) player->bounce(*this);
252 IMPLEMENT_FACTORY(Snail, "snail");