3 // SuperTux - PneumaticPlatform
4 // Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 #include "pneumatic_platform.hpp"
26 #include "video/drawing_context.hpp"
27 #include "resources.hpp"
30 #include "path_walker.hpp"
31 #include "sprite/sprite.hpp"
32 #include "lisp/lisp.hpp"
33 #include "object_factory.hpp"
35 #include "object/portable.hpp"
37 PneumaticPlatform::PneumaticPlatform(const lisp::Lisp& reader)
38 : MovingSprite(reader, LAYER_OBJECTS, COLGROUP_STATIC),
39 master(0), slave(0), start_y(0), offset_y(0), speed_y(0)
41 start_y = get_pos().y;
44 PneumaticPlatform::PneumaticPlatform(PneumaticPlatform* master)
45 : MovingSprite(*master),
46 master(master), slave(this), start_y(master->start_y), offset_y(-master->offset_y), speed_y(0)
48 set_pos(get_pos() + Vector(master->get_bbox().get_width(), 0));
49 master->master = master;
53 PneumaticPlatform::~PneumaticPlatform() {
54 if ((this == master) && (master)) {
58 if ((master) && (this == slave)) {
67 PneumaticPlatform::collision(GameObject& other, const CollisionHit& )
70 // somehow the hit parameter does not get filled in, so to determine (hit.top == true) we do this:
71 MovingObject* mo = dynamic_cast<MovingObject*>(&other);
72 if (!mo) return FORCE_MOVE;
73 if ((mo->get_bbox().p2.y) > (get_bbox().p1.y + 2)) return FORCE_MOVE;
75 Player* pl = dynamic_cast<Player*>(mo);
77 if (pl->is_big()) contacts.insert(0);
78 Portable* po = pl->get_grabbed_object();
79 MovingObject* pomo = dynamic_cast<MovingObject*>(po);
80 if (pomo) contacts.insert(pomo);
83 contacts.insert(&other);
88 PneumaticPlatform::update(float elapsed_time)
91 Sector::current()->add_object(new PneumaticPlatform(this));
98 offset_y = -master->offset_y;
99 movement = Vector(0, (start_y + offset_y) - get_pos().y);
101 if (this == master) {
102 int contact_diff = contacts.size() - slave->contacts.size();
104 slave->contacts.clear();
106 speed_y += ((float)contact_diff * elapsed_time) * 128.0f;
107 speed_y -= (offset_y * elapsed_time * 0.5f);
108 speed_y *= 1 - elapsed_time;
109 offset_y += speed_y * elapsed_time;
110 if (offset_y < -256) { offset_y = -256; speed_y = 0; }
111 if (offset_y > 256) { offset_y = 256; speed_y = -0; }
112 movement = Vector(0, (start_y + offset_y) - get_pos().y);
116 IMPLEMENT_FACTORY(PneumaticPlatform, "pneumatic-platform");