X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Fobject%2Fplatform.cpp;h=258a5864e65529d9e3442b017845f0119f77ee4f;hb=HEAD;hp=9bbc5fe17f833c97e1492bb2553b2cb2cc6ec495;hpb=ce0795230a1fbf9d4867f966aa6909d19975bfcf;p=supertux.git diff --git a/src/object/platform.cpp b/src/object/platform.cpp index 9bbc5fe17..258a5864e 100644 --- a/src/object/platform.cpp +++ b/src/object/platform.cpp @@ -1,92 +1,147 @@ -// $Id$ -// // SuperTux -// Copyright (C) 2005 Marek Moeckel +// Copyright (C) 2006 Matthias Braun // -// 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 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 3 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. +// along with this program. If not, see . -#include +#include "object/platform.hpp" -#include "platform.hpp" -#include "video/drawing_context.hpp" -#include "resources.hpp" -#include "player.hpp" -#include "sprite/sprite_manager.hpp" -#include "lisp/lisp.hpp" -#include "object_factory.hpp" +#include "object/player.hpp" +#include "scripting/platform.hpp" +#include "scripting/squirrel_util.hpp" +#include "supertux/object_factory.hpp" +#include "supertux/sector.hpp" +#include "util/reader.hpp" -Platform::Platform(const lisp::Lisp& reader) +Platform::Platform(const Reader& reader) : + MovingSprite(reader, Vector(0,0), LAYER_OBJECTS, COLGROUP_STATIC), + path(), + walker(), + speed(Vector(0,0)), + automatic(false), + player_contact(false), + last_player_contact(false) { - std::string use_path; - std::string type; - - reader.get("x", bbox.p1.x); - reader.get("y", bbox.p1.y); - reader.get("type", type); - reader.get("use_path", use_path); - sprite = sprite_manager->create("platform"); - sprite->set_action(type); - bbox.set_size(sprite->get_width(), sprite->get_height()); - - flags |= FLAG_SOLID; - - path = Path::GetByName(use_path); - if (path == NULL) { - std::cerr << "Warning: Path for moving platform not found! Make sure that the name is spelled correctly,\nand that the path is initialized before the platform in the level file!\n"; - } - - path_offset = bbox.p1 - path->GetStart(); + bool running = true; + reader.get("name", name); + reader.get("running", running); + if ((name == "") && (!running)) automatic=true; + const lisp::Lisp* pathLisp = reader.get_lisp("path"); + if(pathLisp == NULL) + throw std::runtime_error("No path specified for platform"); + path.reset(new Path()); + path->read(*pathLisp); + walker.reset(new PathWalker(path.get(), running)); + bbox.set_pos(path->get_base()); } -Platform::~Platform() +/* + Platform::Platform(const Platform& other) : + MovingSprite(other), + ScriptInterface(other), + speed(other.speed), + automatic(other.automatic), + player_contact(false), + last_player_contact(false) + { + name = other.name; + path.reset(new Path(*other.path)); + walker.reset(new PathWalker(*other.walker)); + walker->path = &*path; + } +*/ + +HitResponse +Platform::collision(GameObject& other, const CollisionHit& ) { - delete sprite; + if (dynamic_cast(&other)) player_contact = true; + return FORCE_MOVE; } -//TODO: Squish Tux when standing between platform and solid tile/object -// Improve collision handling -// Move all MovingObjects lying on the platform instead of only the player -HitResponse -Platform::collision(GameObject& other, const CollisionHit& hit) +void +Platform::update(float elapsed_time) { - if (typeid(other) == typeid(Player)) { - Player* player = (Player*) &other; - if ((hit.normal.x == 0) && (hit.normal.y == 1)) { - //Tux is standing on the platform - player->movement += path->GetLastMovement(); + // check if Platform should automatically pick a destination + if (automatic) { + + if (!player_contact && !walker->is_moving()) { + // Player doesn't touch platform and Platform is not moving + + // Travel to node nearest to nearest player + // FIXME: does not really use nearest player + Player* player = 0; + std::vector players = Sector::current()->get_players(); + for (std::vector::iterator playerIter = players.begin(); playerIter != players.end(); ++playerIter) { + player = *playerIter; + } + if (player) { + int nearest_node_id = path->get_nearest_node_no(player->get_bbox().p2); + if (nearest_node_id != -1) { + goto_node(nearest_node_id); + } + } } + + if (player_contact && !last_player_contact && !walker->is_moving()) { + // Player touched platform, didn't touch last frame and Platform is not moving + + // Travel to node farthest from current position + int farthest_node_id = path->get_farthest_node_no(get_pos()); + if (farthest_node_id != -1) { + goto_node(farthest_node_id); + } + } + + // Clear player_contact flag set by collision() method + last_player_contact = player_contact; + player_contact = false; } - if(other.get_flags() & FLAG_SOLID) { - //Collision with a solid tile - //does nothing, because the movement vector isn't used at the moment - return ABORT_MOVE; - } - return FORCE_MOVE; + + movement = walker->advance(elapsed_time) - get_pos(); + speed = movement / elapsed_time; +} + +void +Platform::goto_node(int node_no) +{ + walker->goto_node(node_no); +} + +void +Platform::start_moving() +{ + walker->start_moving(); +} + +void +Platform::stop_moving() +{ + walker->stop_moving(); } void -Platform::update(float ) +Platform::expose(HSQUIRRELVM vm, SQInteger table_idx) { - set_pos(path->GetPosition() + path_offset); + if (name.empty()) return; + scripting::Platform* _this = new scripting::Platform(this); + expose_object(vm, table_idx, _this, name, true); } void -Platform::draw(DrawingContext& context) +Platform::unexpose(HSQUIRRELVM vm, SQInteger table_idx) { - sprite->draw(context, get_pos(), LAYER_OBJECTS); + if (name.empty()) return; + scripting::unexpose_object(vm, table_idx, name); } -IMPLEMENT_FACTORY(Platform, "platform"); +/* EOF */