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 SNAIL_KICK_SPEED = 500;
28 const int MAX_SNAIL_SQUISHES = 10;
29 const float SNAIL_KICK_SPEED_Y = -500; /**< y-velocity gained when kicked */
32 Snail::Snail(const Reader& reader) :
33 WalkingBadguy(reader, "images/creatures/snail/snail.sprite", "left", "right"),
39 max_drop_height = 600;
40 sound_manager->preload("sounds/iceblock_bump.wav");
41 sound_manager->preload("sounds/stomp.wav");
42 sound_manager->preload("sounds/kick.wav");
45 Snail::Snail(const Vector& pos, Direction d) :
46 WalkingBadguy(pos, d, "images/creatures/snail/snail.sprite", "left", "right"),
52 max_drop_height = 600;
53 sound_manager->preload("sounds/iceblock_bump.wav");
54 sound_manager->preload("sounds/stomp.wav");
55 sound_manager->preload("sounds/kick.wav");
61 WalkingBadguy::initialize();
68 if (state == STATE_NORMAL) return;
71 WalkingBadguy::initialize();
78 sprite->set_action(dir == LEFT ? "flat-left" : "flat-right", 1);
80 physic.set_velocity_x(0);
81 physic.set_velocity_y(0);
87 state = STATE_KICKED_DELAY;
88 sprite->set_action(dir == LEFT ? "flat-left" : "flat-right", 1);
90 physic.set_velocity_x(dir == LEFT ? -SNAIL_KICK_SPEED : SNAIL_KICK_SPEED);
91 physic.set_velocity_y(0);
93 // start a timer to delay addition of upward movement until we are (hopefully) out from under the player
94 kicked_delay_timer.start(0.05f);
99 return state == STATE_KICKED;
103 Snail::active_update(float elapsed_time)
108 WalkingBadguy::active_update(elapsed_time);
112 if (sprite->animation_done()) {
117 case STATE_KICKED_DELAY:
118 if (kicked_delay_timer.check()) {
119 physic.set_velocity_x(dir == LEFT ? -SNAIL_KICK_SPEED : SNAIL_KICK_SPEED);
120 physic.set_velocity_y(SNAIL_KICK_SPEED_Y);
121 state = STATE_KICKED;
126 physic.set_velocity_x(physic.get_velocity_x() * pow(0.99, elapsed_time/0.02));
127 if (sprite->animation_done() || (fabsf(physic.get_velocity_x()) < walk_speed)) be_normal();
132 BadGuy::active_update(elapsed_time);
136 Snail::collision_solid(const CollisionHit& hit)
140 WalkingBadguy::collision_solid(hit);
143 if(hit.left || hit.right) {
144 sound_manager->play("sounds/iceblock_bump.wav", get_pos());
146 if( ( dir == LEFT && hit.left ) || ( dir == RIGHT && hit.right) ){
147 dir = (dir == LEFT) ? RIGHT : LEFT;
148 sprite->set_action(dir == LEFT ? "flat-left" : "flat-right");
150 physic.set_velocity_x(-physic.get_velocity_x());
155 case STATE_KICKED_DELAY:
156 if(hit.top || hit.bottom) {
157 physic.set_velocity_y(0);
162 update_on_ground_flag(hit);
167 Snail::collision_badguy(BadGuy& badguy, const CollisionHit& hit)
171 return WalkingBadguy::collision_badguy(badguy, hit);
173 case STATE_KICKED_DELAY:
186 Snail::collision_player(Player& player, const CollisionHit& hit)
188 // handle kicks from left or right side
189 if(state == STATE_FLAT && (hit.left || hit.right)) {
192 } else if(hit.right) {
200 return BadGuy::collision_player(player, hit);
204 Snail::collision_squished(GameObject& object)
206 Player* player = dynamic_cast<Player*>(&object);
207 if(player && (player->does_buttjump || player->is_invincible())) {
209 player->bounce(*this);
218 // Can't stomp in midair
223 if (squishcount >= MAX_SNAIL_SQUISHES) {
227 sound_manager->play("sounds/stomp.wav", get_pos());
232 sound_manager->play("sounds/kick.wav", get_pos());
234 MovingObject* movingobject = dynamic_cast<MovingObject*>(&object);
235 if (movingobject && (movingobject->get_pos().x < get_pos().x)) {
244 case STATE_KICKED_DELAY:
249 if (player) player->bounce(*this);