From 33e9fc02e91d00f7129f9369771bc6f83bb199f0 Mon Sep 17 00:00:00 2001 From: Christoph Sommer Date: Thu, 31 Jan 2008 23:22:33 +0000 Subject: [PATCH] New Badguy "IceCrusher" drops down to crush Tux and can be used as a platform to ride back up SVN-Revision: 5307 --- .../{iceblock => icecrusher}/iceblock.png | Bin data/images/creatures/icecrusher/icecrusher.sprite | 8 + src/object/icecrusher.cpp | 171 +++++++++++++++++++++ src/object/icecrusher.hpp | 64 ++++++++ 4 files changed, 243 insertions(+) rename data/images/creatures/{iceblock => icecrusher}/iceblock.png (100%) create mode 100644 data/images/creatures/icecrusher/icecrusher.sprite create mode 100644 src/object/icecrusher.cpp create mode 100644 src/object/icecrusher.hpp diff --git a/data/images/creatures/iceblock/iceblock.png b/data/images/creatures/icecrusher/iceblock.png similarity index 100% rename from data/images/creatures/iceblock/iceblock.png rename to data/images/creatures/icecrusher/iceblock.png diff --git a/data/images/creatures/icecrusher/icecrusher.sprite b/data/images/creatures/icecrusher/icecrusher.sprite new file mode 100644 index 000000000..972f5e19c --- /dev/null +++ b/data/images/creatures/icecrusher/icecrusher.sprite @@ -0,0 +1,8 @@ +(supertux-sprite + (action + (name "idle") + (hitbox 11 8 64 64) + (images "iceblock.png" + ) + ) +) diff --git a/src/object/icecrusher.cpp b/src/object/icecrusher.cpp new file mode 100644 index 000000000..421cef0e6 --- /dev/null +++ b/src/object/icecrusher.cpp @@ -0,0 +1,171 @@ +// $Id$ +// +// IceCrusher - A block to stand on, which can drop down to crush the player +// Copyright (C) 2008 Christoph Sommer +// +// 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 + +#include "icecrusher.hpp" + +#include +#include "log.hpp" +#include "video/drawing_context.hpp" +#include "resources.hpp" +#include "badguy/badguy.hpp" +#include "sprite/sprite.hpp" +#include "lisp/lisp.hpp" +#include "object_factory.hpp" +#include "sector.hpp" + +namespace { + const float DROP_SPEED = 500; + const float RECOVER_SPEED = 200; +} + +IceCrusher::IceCrusher(const lisp::Lisp& reader) + : MovingSprite(reader, "images/creatures/icecrusher/icecrusher.sprite", LAYER_OBJECTS, COLGROUP_STATIC), + state(IDLE), speed(Vector(0,0)) +{ + start_position = get_bbox().p1; + set_state(state, true); +} + +IceCrusher::IceCrusher(const IceCrusher& other) + : MovingSprite(other), + state(other.state), speed(other.speed) +{ + start_position = get_bbox().p1; + set_state(state, true); +} + +void +IceCrusher::set_state(IceCrusherState state, bool force) +{ + if ((this->state == state) && (!force)) return; + switch(state) { + case IDLE: + set_group(COLGROUP_STATIC); + speed=Vector(0,0); + sprite->set_action("idle"); + break; + case CRUSHING: + set_group(COLGROUP_MOVING_STATIC); + speed=Vector(0, DROP_SPEED); + sprite->set_action("idle"); + break; + case RECOVERING: + set_group(COLGROUP_MOVING_STATIC); + speed=Vector(0, -RECOVER_SPEED); + sprite->set_action("idle"); + break; + default: + log_debug << "IceCrusher in invalid state" << std::endl; + break; + } + this->state = state; +} + +HitResponse +IceCrusher::collision(GameObject& other, const CollisionHit& hit) +{ + Player* player = dynamic_cast(&other); + if (player && hit.bottom) { + if(player->is_invincible()) { + if (state == CRUSHING) set_state(RECOVERING); + return ABORT_MOVE; + } + player->kill(false); + if (state == CRUSHING) set_state(RECOVERING); + return FORCE_MOVE; + } + BadGuy* badguy = dynamic_cast(&other); + if (badguy) { + badguy->kill_fall(); + } + return FORCE_MOVE; +} + +void +IceCrusher::collision_solid(const CollisionHit& ) +{ + switch(state) { + case IDLE: + break; + case CRUSHING: + set_state(RECOVERING); + break; + case RECOVERING: + break; + default: + log_debug << "IceCrusher in invalid state" << std::endl; + break; + } +} + +void +IceCrusher::update(float elapsed_time) +{ + switch(state) { + case IDLE: + if (found_victim()) set_state(CRUSHING); + break; + case CRUSHING: + break; + case RECOVERING: + if (get_bbox().p1.y <= start_position.y+1) { + set_pos(start_position); + set_state(IDLE); + } + break; + default: + log_debug << "IceCrusher in invalid state" << std::endl; + break; + } + movement = speed * elapsed_time; +} + +Player* +IceCrusher::get_nearest_player() +{ + // FIXME: does not really return nearest player + + std::vector players = Sector::current()->get_players(); + for (std::vector::iterator playerIter = players.begin(); playerIter != players.end(); ++playerIter) { + Player* player = *playerIter; + if (player->is_dying() || player->is_dead()) continue; + return player; + } + + return 0; +} + +bool +IceCrusher::found_victim() +{ + Player* player = this->get_nearest_player(); + if (!player) return false; + + const Rect& pr = player->get_bbox(); + const Rect& br = get_bbox(); + if ((pr.p2.x > br.p1.x) && (pr.p1.x < br.p2.x) && (pr.p1.y >= br.p2.y)) { + return true; + } + return false; +} + +IMPLEMENT_FACTORY(IceCrusher, "icecrusher"); diff --git a/src/object/icecrusher.hpp b/src/object/icecrusher.hpp new file mode 100644 index 000000000..dfb255cfd --- /dev/null +++ b/src/object/icecrusher.hpp @@ -0,0 +1,64 @@ +// $Id$ +// +// IceCrusher - A block to stand on, which can drop down to crush the player +// Copyright (C) 2008 Christoph Sommer +// +// 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 INCLUDED_ICECRUSHER_HPP +#define INCLUDED_ICECRUSHER_HPP + +#include +#include +#include "object/moving_sprite.hpp" +#include "object/player.hpp" + +/** + * This class is the base class for icecrushers that tux can stand on + */ +class IceCrusher : public MovingSprite +{ + public: + IceCrusher(const lisp::Lisp& reader); + IceCrusher(const IceCrusher& icecrusher); + virtual IceCrusher* clone() const { return new IceCrusher(*this); } + + virtual HitResponse collision(GameObject& other, const CollisionHit& hit); + virtual void collision_solid(const CollisionHit& hit); + virtual void update(float elapsed_time); + + const Vector& get_speed() const + { + return speed; + } + + protected: + enum IceCrusherState { + IDLE, + CRUSHING, + RECOVERING + }; + IceCrusherState state; + Vector start_position; + Vector speed; + + Player* get_nearest_player(); + bool found_victim(); + void set_state(IceCrusherState state, bool force = false); + +}; + +#endif -- 2.11.0