#include "badguy/mriceblock.hpp"
#include "badguy/mrrocket.hpp"
#include "badguy/poisonivy.hpp"
-#include "badguy/snowsnail.hpp"
+#include "badguy/snail.hpp"
#include "badguy/skullyhop.hpp"
#include "random_generator.hpp"
Sector::current()->add_object(new MrBomb(get_pos().x, get_pos().y+32, dir));
else if (badguy == "mriceblock")
Sector::current()->add_object(new MrIceBlock(get_pos().x, get_pos().y+32, dir));
- else if (badguy == "snowsnail")
- Sector::current()->add_object(new SnowSnail(get_pos().x, get_pos().y+32, dir));
+ else if (badguy == "snail")
+ Sector::current()->add_object(new Snail(get_pos().x, get_pos().y+32, dir));
else if (badguy == "mrrocket") {
Sector::current()->add_object(new MrRocket(get_pos().x+(dir == LEFT ? -32 : 32), get_pos().y, dir));}
else if (badguy == "poisonivy")
case 2: Sector::current()->add_object(new MrBomb(get_pos().x, get_pos().y+32, dir)); break;
case 3: Sector::current()->add_object(new MrIceBlock(get_pos().x, get_pos().y+32, dir)); break;
case 4: Sector::current()->add_object(new PoisonIvy(get_pos().x, get_pos().y+32, dir)); break;
- case 5: Sector::current()->add_object(new SnowSnail(get_pos().x, get_pos().y+32, dir)); break;
+ case 5: Sector::current()->add_object(new Snail(get_pos().x, get_pos().y+32, dir)); break;
case 6: Sector::current()->add_object(new SkullyHop(get_pos().x, get_pos().y+44, dir)); break;
}
}
#include <config.h>
#include "nolok_01.hpp"
-#include "badguy/snowsnail.hpp"
+#include "badguy/snail.hpp"
#include "trigger/door.hpp"
#define WALK_TIME 2.5
}
case SHOOTING:
{
- Sector::current()->add_object(new SnowSnail(get_pos().x - 64, get_pos().y, LEFT));
- Sector::current()->add_object(new SnowSnail(get_pos().x + 64, get_pos().y, RIGHT));
+ Sector::current()->add_object(new Snail(get_pos().x - 64, get_pos().y, LEFT));
+ Sector::current()->add_object(new Snail(get_pos().x + 64, get_pos().y, RIGHT));
physic.set_velocity_x(dir == LEFT ? -WALKSPEED : WALKSPEED);
sprite->set_action(dir == LEFT ? "left" : "right");
action = WALKING;
--- /dev/null
+// $Id: snail.cpp 3364 2006-04-19 00:54:40Z sommer $
+//
+// SuperTux - Badguy "Snail"
+// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+#include <config.h>
+
+#include "snail.hpp"
+#include "object/block.hpp"
+
+namespace {
+ const float WALKSPEED = 80;
+ const float KICKSPEED = 500;
+ const int MAXSQUISHES = 10;
+ const float KICKSPEED_Y = 500; /**< y-velocity gained when kicked */
+}
+
+Snail::Snail(const lisp::Lisp& reader)
+ : state(STATE_NORMAL), squishcount(0)
+{
+ reader.get("x", start_position.x);
+ reader.get("y", start_position.y);
+ bbox.set_size(31.8, 31.8);
+ sprite = sprite_manager->create("images/creatures/snail/snail.sprite");
+ set_direction = false;
+}
+
+Snail::Snail(float pos_x, float pos_y, Direction d)
+ : state(STATE_NORMAL), squishcount(0)
+{
+ start_position.x = pos_x;
+ start_position.y = pos_y;
+ bbox.set_size(31.8, 31.8);
+ sprite = sprite_manager->create("images/creatures/snail/snail.sprite");
+ set_direction = true;
+ initial_direction = d;
+}
+
+void
+Snail::write(lisp::Writer& writer)
+{
+ writer.start_list("snail");
+
+ writer.write_float("x", start_position.x);
+ writer.write_float("y", start_position.y);
+
+ writer.end_list("snail");
+}
+
+void
+Snail::activate()
+{
+ if (set_direction) {dir = initial_direction;}
+
+ be_normal();
+}
+
+void
+Snail::be_normal()
+{
+ state = STATE_NORMAL;
+ sprite->set_action(dir == LEFT ? "left" : "right");
+
+ physic.set_velocity_x(dir == LEFT ? -WALKSPEED : WALKSPEED);
+}
+
+void
+Snail::be_flat()
+{
+ state = STATE_FLAT;
+ sprite->set_action(dir == LEFT ? "flat-left" : "flat-right");
+ sprite->set_fps(64);
+
+ physic.set_velocity_x(0);
+ physic.set_velocity_y(0);
+
+ flat_timer.start(4);
+}
+
+void
+Snail::be_kicked()
+{
+ state = STATE_KICKED_DELAY;
+ sprite->set_action(dir == LEFT ? "flat-left" : "flat-right");
+ sprite->set_fps(64);
+
+ physic.set_velocity_x(0);
+ physic.set_velocity_y(0);
+
+ // start a timer to delay addition of upward movement until we are (hopefully) out from under the player
+ kicked_delay_timer.start(0.05);
+}
+
+
+void
+Snail::active_update(float elapsed_time)
+{
+ switch (state) {
+
+ case STATE_NORMAL:
+ if (might_fall(601)) {
+ dir = (dir == LEFT ? RIGHT : LEFT);
+ sprite->set_action(dir == LEFT ? "left" : "right");
+ physic.set_velocity_x(-physic.get_velocity_x());
+ }
+ break;
+
+ case STATE_FLAT:
+ if (flat_timer.started()) {
+ sprite->set_fps(64 - 15 * flat_timer.get_timegone());
+ }
+ if (flat_timer.check()) {
+ be_normal();
+ }
+ break;
+
+ case STATE_KICKED_DELAY:
+ if (kicked_delay_timer.check()) {
+ physic.set_velocity_x(dir == LEFT ? -KICKSPEED : KICKSPEED);
+ physic.set_velocity_y(KICKSPEED_Y);
+ state = STATE_KICKED;
+ }
+ break;
+
+ case STATE_KICKED:
+ physic.set_velocity_x(physic.get_velocity_x() * pow(0.99, elapsed_time/0.02));
+ if (fabsf(physic.get_velocity_x()) < WALKSPEED) be_normal();
+ break;
+
+ }
+ BadGuy::active_update(elapsed_time);
+}
+
+HitResponse
+Snail::collision_solid(GameObject& object, const CollisionHit& hit)
+{
+ if(fabsf(hit.normal.y) > .5) { // floor or roof
+ physic.set_velocity_y(0);
+
+ switch (state) {
+ case STATE_NORMAL:
+ case STATE_FLAT:
+ case STATE_KICKED_DELAY:
+ break;
+ case STATE_KICKED:
+ break;
+ }
+
+ return CONTINUE;
+ }
+ // hit left or right
+ switch(state) {
+
+ case STATE_NORMAL:
+ dir = dir == LEFT ? RIGHT : LEFT;
+ sprite->set_action(dir == LEFT ? "left" : "right");
+ physic.set_velocity_x(-physic.get_velocity_x());
+ break;
+
+ case STATE_FLAT:
+ case STATE_KICKED_DELAY:
+ physic.set_velocity_x(0);
+ break;
+
+ case STATE_KICKED: {
+ sound_manager->play("sounds/iceblock_bump.wav", get_pos());
+
+ // open bonusblocks, crash bricks
+ BonusBlock* bonusblock = dynamic_cast<BonusBlock*> (&object);
+ if(bonusblock) {
+ bonusblock->try_open();
+ }
+ Brick* brick = dynamic_cast<Brick*> (&object);
+ if(brick) {
+ brick->try_break();
+ }
+
+ dir = (dir == LEFT) ? RIGHT : LEFT;
+ sprite->set_action(dir == LEFT ? "flat-left" : "flat-right");
+
+ physic.set_velocity_x(-physic.get_velocity_x()*0.75);
+ if (fabsf(physic.get_velocity_x()) < WALKSPEED) be_normal();
+ break;
+
+ }
+ }
+
+ return CONTINUE;
+}
+
+HitResponse
+Snail::collision_badguy(BadGuy& badguy, const CollisionHit& hit)
+{
+ switch(state) {
+ case STATE_NORMAL:
+ if(fabsf(hit.normal.x) > .5) {
+ dir = (dir == LEFT) ? RIGHT : LEFT;
+ sprite->set_action(dir == LEFT ? "left" : "right");
+ physic.set_velocity_x(-physic.get_velocity_x());
+ }
+ return CONTINUE;
+ case STATE_FLAT:
+ case STATE_KICKED_DELAY:
+ return FORCE_MOVE;
+ case STATE_KICKED:
+ badguy.kill_fall();
+ return FORCE_MOVE;
+ default:
+ assert(false);
+ }
+
+ return ABORT_MOVE;
+}
+
+bool
+Snail::collision_squished(Player& player)
+{
+ switch(state) {
+
+ case STATE_KICKED:
+ case STATE_NORMAL:
+ squishcount++;
+ if(squishcount >= MAXSQUISHES) {
+ kill_fall();
+ return true;
+ }
+
+ sound_manager->play("sounds/stomp.wav", get_pos());
+ be_flat();
+ break;
+
+ case STATE_FLAT:
+ sound_manager->play("sounds/kick.wav", get_pos());
+
+ if(player.get_pos().x < get_pos().x) {
+ dir = RIGHT;
+ } else {
+ dir = LEFT;
+ }
+ be_kicked();
+ break;
+
+ case STATE_KICKED_DELAY:
+ break;
+
+ }
+
+ player.bounce(*this);
+ return true;
+}
+
+IMPLEMENT_FACTORY(Snail, "snail")
--- /dev/null
+// $Id: snail.hpp 3364 2006-04-19 00:54:40Z sommer $
+//
+// SuperTux - Badguy "Snail"
+// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+#ifndef __SNAIL_H__
+#define __SNAIL_H__
+
+#include "badguy.hpp"
+
+/**
+ * Badguy "Snail" - a snail-like creature that can be flipped and tossed around at an angle
+ */
+class Snail : public BadGuy
+{
+public:
+ Snail(const lisp::Lisp& reader);
+ Snail(float pos_x, float pos_y, Direction d);
+
+ void activate();
+ void write(lisp::Writer& writer);
+ HitResponse collision_solid(GameObject& object, const CollisionHit& hit);
+ HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
+
+ void active_update(float elapsed_time);
+
+protected:
+ bool collision_squished(Player& player);
+ void be_normal(); /**< switch to state STATE_NORMAL */
+ void be_flat(); /**< switch to state STATE_FLAT */
+ void be_kicked(); /**< switch to state STATE_KICKED_DELAY */
+
+private:
+ enum State {
+ STATE_NORMAL, /**< walking around */
+ STATE_FLAT, /**< flipped upside-down */
+ STATE_KICKED_DELAY, /**< short delay before being launched */
+ STATE_KICKED /**< launched */
+ };
+ State state;
+ Timer flat_timer; /**< wait time until flipping right-side-up again */
+ Timer kicked_delay_timer; /**< wait time until switching from STATE_KICKED_DELAY to STATE_KICKED */
+ int squishcount;
+ bool set_direction;
+ Direction initial_direction;
+};
+
+#endif
+
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
-
-#include "snowsnail.hpp"
-#include "object/block.hpp"
-
-static const float WALKSPEED = 80;
-static const float KICKSPEED = 500;
-static const int MAXSQUISHES = 10;
-
-SnowSnail::SnowSnail(const lisp::Lisp& reader)
- : ice_state(ICESTATE_NORMAL), squishcount(0)
-{
- reader.get("x", start_position.x);
- reader.get("y", start_position.y);
- bbox.set_size(31.8, 31.8);
- sprite = sprite_manager->create("images/creatures/snowsnail/snowsnail.sprite");
- set_direction = false;
-}
-
-SnowSnail::SnowSnail(float pos_x, float pos_y, Direction d)
- : ice_state(ICESTATE_NORMAL), squishcount(0)
-{
- start_position.x = pos_x;
- start_position.y = pos_y;
- bbox.set_size(31.8, 31.8);
- sprite = sprite_manager->create("images/creatures/snowsnail/snowsnail.sprite");
- set_direction = true;
- initial_direction = d;
-}
-
-void
-SnowSnail::write(lisp::Writer& writer)
-{
- writer.start_list("mriceblock");
-
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
-
- writer.end_list("snowsnail");
-}
-
-void
-SnowSnail::activate()
-{
- if (set_direction) {dir = initial_direction;}
- physic.set_velocity_x(dir == LEFT ? -WALKSPEED : WALKSPEED);
- sprite->set_action(dir == LEFT ? "left" : "right");
-}
-
-void
-SnowSnail::active_update(float elapsed_time)
-{
- if((ice_state != ICESTATE_KICKED) && flat_timer.started()) {
- sprite->set_fps(64 - 15 * flat_timer.get_timegone());
- }
- if(ice_state == ICESTATE_FLAT && flat_timer.check()) {
- ice_state = ICESTATE_NORMAL;
- physic.set_velocity_x(dir == LEFT ? -WALKSPEED : WALKSPEED);
- sprite->set_action(dir == LEFT ? "left" : "right");
- }
- BadGuy::active_update(elapsed_time);
-}
-
-HitResponse
-SnowSnail::collision_solid(GameObject& object, const CollisionHit& hit)
-{
- if(fabsf(hit.normal.y) > .5) { // floor or roof
- physic.set_velocity_y(0);
- return CONTINUE;
- }
- // hit left or right
- switch(ice_state) {
- case ICESTATE_NORMAL:
- dir = dir == LEFT ? RIGHT : LEFT;
- sprite->set_action(dir == LEFT ? "left" : "right");
- physic.set_velocity_x(-physic.get_velocity_x());
- break;
- case ICESTATE_KICKED: {
- BonusBlock* bonusblock = dynamic_cast<BonusBlock*> (&object);
- if(bonusblock) {
- bonusblock->try_open();
- }
- Brick* brick = dynamic_cast<Brick*> (&object);
- if(brick) {
- brick->try_break();
- }
-
- dir = dir == LEFT ? RIGHT : LEFT;
- sprite->set_action(dir == LEFT ? "flat-left" : "flat-right");
- sprite->set_fps(64);
- physic.set_velocity_x(-physic.get_velocity_x());
- sound_manager->play("sounds/iceblock_bump.wav", get_pos());
- break;
- }
- case ICESTATE_FLAT:
- physic.set_velocity_x(0);
- break;
- }
-
- return CONTINUE;
-}
-
-HitResponse
-SnowSnail::collision_badguy(BadGuy& badguy, const CollisionHit& hit)
-{
- switch(ice_state) {
- case ICESTATE_NORMAL:
- if(fabsf(hit.normal.x) > .8) {
- dir = dir == LEFT ? RIGHT : LEFT;
- sprite->set_action(dir == LEFT ? "left" : "right");
- physic.set_velocity_x(-physic.get_velocity_x());
- }
- return CONTINUE;
- case ICESTATE_FLAT:
- return FORCE_MOVE;
- case ICESTATE_KICKED:
- badguy.kill_fall();
- return FORCE_MOVE;
- default:
- assert(false);
- }
-
- return ABORT_MOVE;
-}
-
-bool
-SnowSnail::collision_squished(Player& player)
-{
- switch(ice_state) {
- case ICESTATE_KICKED:
- case ICESTATE_NORMAL:
- squishcount++;
- if(squishcount >= MAXSQUISHES) {
- kill_fall();
- return true;
- }
-
- // flatten
- sound_manager->play("sounds/stomp.wav", get_pos());
- physic.set_velocity_x(0);
- physic.set_velocity_y(0);
-
- sprite->set_action(dir == LEFT ? "flat-left" : "flat-right");
- sprite->set_fps(64);
- flat_timer.start(4);
- ice_state = ICESTATE_FLAT;
- break;
- case ICESTATE_FLAT:
- // kick
- sound_manager->play("sounds/kick.wav", get_pos());
-
- if(player.get_pos().x < get_pos().x) {
- dir = RIGHT;
- } else {
- dir = LEFT;
- }
- physic.set_velocity_x(dir == LEFT ? -KICKSPEED : KICKSPEED);
- sprite->set_action(dir == LEFT ? "flat-left" : "flat-right");
- sprite->set_fps(64);
- ice_state = ICESTATE_KICKED;
- break;
- }
-
- player.bounce(*this);
- return true;
-}
-
-IMPLEMENT_FACTORY(SnowSnail, "snowsnail")
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#ifndef __SNOWSNAIL_H__
-#define __SNOWSNAIL_H__
-
-#include "badguy.hpp"
-
-class SnowSnail : public BadGuy
-{
-public:
- SnowSnail(const lisp::Lisp& reader);
- SnowSnail(float pos_x, float pos_y, Direction d);
-
- void activate();
- void write(lisp::Writer& writer);
- HitResponse collision_solid(GameObject& object, const CollisionHit& hit);
- HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
-
- void active_update(float elapsed_time);
-
-protected:
- bool collision_squished(Player& player);
-
-private:
- enum IceState {
- ICESTATE_NORMAL,
- ICESTATE_FLAT,
- ICESTATE_KICKED
- };
- IceState ice_state;
- Timer flat_timer;
- int squishcount;
- bool set_direction;
- Direction initial_direction;
-};
-
-#endif
-