1 // IceCrusher - A block to stand on, which can drop down to crush the player
2 // Copyright (C) 2008 Christoph Sommer <christoph.sommer@2008.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 "object/icecrusher.hpp"
19 #include "badguy/badguy.hpp"
20 #include "sprite/sprite.hpp"
21 #include "object/player.hpp"
22 #include "supertux/object_factory.hpp"
23 #include "supertux/sector.hpp"
26 const float DROP_SPEED = 500;
27 const float RECOVER_SPEED = 200;
30 IceCrusher::IceCrusher(const Reader& reader)
31 : MovingSprite(reader, "images/creatures/icecrusher/icecrusher.sprite", LAYER_OBJECTS, COLGROUP_STATIC),
32 state(IDLE), speed(Vector(0,0))
34 start_position = get_bbox().p1;
35 set_state(state, true);
39 IceCrusher::IceCrusher(const IceCrusher& other)
40 : MovingSprite(other),
41 state(other.state), speed(other.speed)
43 start_position = get_bbox().p1;
44 set_state(state, true);
48 IceCrusher::set_state(IceCrusherState state, bool force)
50 if ((this->state == state) && (!force)) return;
53 set_group(COLGROUP_STATIC);
55 sprite->set_action("idle");
58 set_group(COLGROUP_MOVING_STATIC);
59 speed=Vector(0, DROP_SPEED);
60 sprite->set_action("idle");
63 set_group(COLGROUP_MOVING_STATIC);
64 speed=Vector(0, -RECOVER_SPEED);
65 sprite->set_action("idle");
68 log_debug << "IceCrusher in invalid state" << std::endl;
75 IceCrusher::collision(GameObject& other, const CollisionHit& hit)
77 Player* player = dynamic_cast<Player*>(&other);
78 if (player && hit.bottom) {
79 if(player->is_invincible()) {
80 if (state == CRUSHING) set_state(RECOVERING);
84 if (state == CRUSHING) set_state(RECOVERING);
87 BadGuy* badguy = dynamic_cast<BadGuy*>(&other);
95 IceCrusher::collision_solid(const CollisionHit& )
101 set_state(RECOVERING);
106 log_debug << "IceCrusher in invalid state" << std::endl;
112 IceCrusher::update(float elapsed_time)
116 if (found_victim()) set_state(CRUSHING);
121 if (get_bbox().p1.y <= start_position.y+1) {
122 set_pos(start_position);
127 log_debug << "IceCrusher in invalid state" << std::endl;
130 movement = speed * elapsed_time;
134 IceCrusher::get_nearest_player()
136 // FIXME: does not really return nearest player
138 std::vector<Player*> players = Sector::current()->get_players();
139 for (std::vector<Player*>::iterator playerIter = players.begin(); playerIter != players.end(); ++playerIter) {
140 Player* player = *playerIter;
141 if (player->is_dying() || player->is_dead()) continue;
149 IceCrusher::found_victim()
151 Player* player = this->get_nearest_player();
152 if (!player) return false;
154 const Rect& pr = player->get_bbox();
155 const Rect& br = get_bbox();
156 if ((pr.p2.x > br.p1.x) && (pr.p1.x < br.p2.x) && (pr.p1.y >= br.p2.y)) {
162 IMPLEMENT_FACTORY(IceCrusher, "icecrusher");