From: Christoph Sommer Date: Tue, 20 Jun 2006 15:24:58 +0000 (+0000) Subject: Experiments with new Teleporter Worldmap Tile X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=6141e1672ec08427b989ca245508f0c1648ce68b;p=supertux.git Experiments with new Teleporter Worldmap Tile SVN-Revision: 3682 --- diff --git a/src/worldmap/teleporter.cpp b/src/worldmap/teleporter.cpp new file mode 100644 index 000000000..6cce11d28 --- /dev/null +++ b/src/worldmap/teleporter.cpp @@ -0,0 +1,57 @@ +// $Id$ +// +// SuperTux - Teleporter Worldmap Tile +// Copyright (C) 2006 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 "worldmap/teleporter.hpp" +#include "sprite/sprite_manager.hpp" +#include "sprite/sprite.hpp" +#include "video/drawing_context.hpp" + +namespace WorldMapNS +{ + +Teleporter::Teleporter(const lisp::Lisp* lisp) + : interactive(false) +{ + lisp->get("x", pos.x); + lisp->get("y", pos.y); + + std::string spritefile = ""; + if (lisp->get("sprite", spritefile)) { + sprite.reset(sprite_manager->create(spritefile)); + } + + lisp->get("worldmap", worldmap); + lisp->get("spawnpoint", spawnpoint); + lisp->get("interactive", interactive); +} + +void +Teleporter::draw(DrawingContext& context) +{ + if (sprite.get() != 0) sprite->draw(context, pos*32 + Vector(16, 16), LAYER_OBJECTS - 1); +} + +void +Teleporter::update(float ) +{ +} + +} + diff --git a/src/worldmap/teleporter.hpp b/src/worldmap/teleporter.hpp new file mode 100644 index 000000000..243b36a43 --- /dev/null +++ b/src/worldmap/teleporter.hpp @@ -0,0 +1,61 @@ +// $Id$ +// +// SuperTux - Teleporter Worldmap Tile +// Copyright (C) 2006 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 __WORLDMAP_TELEPORTER_HPP__ +#define __WORLDMAP_TELEPORTER_HPP__ + +#include +#include +#include "game_object.hpp" +#include "math/vector.hpp" +#include "lisp/lisp.hpp" + +class Sprite; + +namespace WorldMapNS +{ + +class Teleporter : public GameObject +{ +public: + Teleporter(const lisp::Lisp* lisp); + + virtual void draw(DrawingContext& context); + virtual void update(float elapsed_time); + + /** Position (in tiles, not pixels) */ + Vector pos; + + /** Sprite to render, or 0 for no sprite */ + std::auto_ptr sprite; + + /** Worldmap filename (relative to data root) to teleport to. Leave empty to use current word */ + std::string worldmap; + + /** Spawnpoint to teleport to. Leave empty to use "main" or last one */ + std::string spawnpoint; + + /** true if this teleporter needs to be activated */ + bool interactive; + +}; + +} + +#endif + diff --git a/src/worldmap/tux.cpp b/src/worldmap/tux.cpp index 6a3a8bbec..6964c6631 100644 --- a/src/worldmap/tux.cpp +++ b/src/worldmap/tux.cpp @@ -173,6 +173,15 @@ Tux::tryContinueWalking(float elapsed_time) sprite_change->in_stay_action = false; } + Teleporter* teleporter = worldmap->at_teleporter(tile_pos); + if (teleporter) { + if (teleporter->worldmap != "") { + worldmap->change(teleporter->worldmap, teleporter->spawnpoint); + } else { + worldmap->move_to_spawnpoint(teleporter->spawnpoint); + } + } + // if this is a special_tile with passive_message, display it SpecialTile* special_tile = worldmap->at_special_tile(); if(special_tile) diff --git a/src/worldmap/worldmap.cpp b/src/worldmap/worldmap.cpp index a8cd5e4a3..ba81b1e6c 100644 --- a/src/worldmap/worldmap.cpp +++ b/src/worldmap/worldmap.cpp @@ -128,8 +128,8 @@ string_to_direction(const std::string& directory) //--------------------------------------------------------------------------- -WorldMap::WorldMap(const std::string& filename) - : tux(0), solids(0) +WorldMap::WorldMap(const std::string& filename, const std::string& force_spawnpoint) + : tux(0), solids(0), force_spawnpoint(force_spawnpoint) { tile_manager.reset(new TileManager("images/worldmap.strf")); @@ -209,6 +209,30 @@ WorldMap::add_object(GameObject* object) } void +WorldMap::move_to_spawnpoint(const std::string& spawnpoint) +{ + for(SpawnPoints::iterator i = spawn_points.begin(); i != spawn_points.end(); ++i) { + SpawnPoint* sp = *i; + if(sp->name == spawnpoint) { + Vector p = sp->pos; + tux->set_tile_pos(p); + return; + } + } + log_warning << "Spawnpoint '" << spawnpoint << "' not found." << std::endl; + if (spawnpoint != "main") { + move_to_spawnpoint("main"); + } +} + +void +WorldMap::change(const std::string& filename, const std::string& force_spawnpoint) +{ + main_loop->exit_screen(); + main_loop->push_screen(new WorldMap(filename, force_spawnpoint)); +} + +void WorldMap::load(const std::string& filename) { map_filename = filename; @@ -253,6 +277,10 @@ WorldMap::load(const std::string& filename) SpriteChange* sprite_change = new SpriteChange(iter.lisp()); sprite_changes.push_back(sprite_change); add_object(sprite_change); + } else if(iter.item() == "teleporter") { + Teleporter* teleporter = new Teleporter(iter.lisp()); + teleporters.push_back(teleporter); + add_object(teleporter); } else if(iter.item() == "name") { // skip } else { @@ -262,16 +290,7 @@ WorldMap::load(const std::string& filename) if(solids == 0) throw std::runtime_error("No solid tilemap specified"); - // search for main spawnpoint - for(SpawnPoints::iterator i = spawn_points.begin(); - i != spawn_points.end(); ++i) { - SpawnPoint* sp = *i; - if(sp->name == "main") { - Vector p = sp->pos; - tux->set_tile_pos(p); - break; - } - } + move_to_spawnpoint("main"); } catch(std::exception& e) { std::stringstream msg; @@ -591,6 +610,17 @@ WorldMap::at_sprite_change(const Vector& pos) return NULL; } +Teleporter* +WorldMap::at_teleporter(const Vector& pos) +{ + for(std::vector::iterator i = teleporters.begin(); i != teleporters.end(); ++i) { + Teleporter* teleporter = *i; + if(teleporter->pos == pos) return teleporter; + } + + return NULL; +} + void WorldMap::draw(DrawingContext& context) { @@ -680,6 +710,9 @@ WorldMap::setup() current_ = this; load_state(); + // if force_spawnpoint was set, move Tux there + if (force_spawnpoint != "") move_to_spawnpoint(force_spawnpoint); + // register worldmap_table as worldmap in scripting using namespace Scripting; diff --git a/src/worldmap/worldmap.hpp b/src/worldmap/worldmap.hpp index 75d8f8f9f..9bf35b28e 100644 --- a/src/worldmap/worldmap.hpp +++ b/src/worldmap/worldmap.hpp @@ -33,6 +33,9 @@ #include "game_object.hpp" #include "console.hpp" #include "../level.hpp" +#include "worldmap/special_tile.hpp" +#include "worldmap/sprite_change.hpp" +#include "worldmap/teleporter.hpp" class Sprite; class Menu; @@ -103,15 +106,18 @@ private: SpriteChanges sprite_changes; typedef std::vector SpawnPoints; SpawnPoints spawn_points; + std::vector teleporters; Statistics total_stats; HSQOBJECT worldmap_table; typedef std::vector ScriptList; - ScriptList scripts; + ScriptList scripts; + + std::string force_spawnpoint; /**< if set, spawnpoint will be forced to this value */ public: - WorldMap(const std::string& filename); + WorldMap(const std::string& filename, const std::string& force_spawnpoint = ""); ~WorldMap(); void add_object(GameObject* object); @@ -142,6 +148,7 @@ public: LevelTile* at_level(); SpecialTile* at_special_tile(); SpriteChange* at_sprite_change(const Vector& pos); + Teleporter* at_teleporter(const Vector& pos); /** Check if it is possible to walk from \a pos into \a direction, if possible, write the new position to \a new_pos */ @@ -165,7 +172,18 @@ public: * the script (so the script gets destroyed when the worldmap is destroyed) */ HSQUIRRELVM run_script(std::istream& in, const std::string& sourcename); - + + /** + * switch to another worldmap. + * filename is relative to current world's path + */ + void change(const std::string& filename, const std::string& force_spawnpoint=""); + + /** + * moves Tux to the given spawnpoint + */ + void move_to_spawnpoint(const std::string& spawnpoint); + private: void get_level_title(LevelTile& level); void draw_status(DrawingContext& context); @@ -173,8 +191,7 @@ private: void load(const std::string& filename); void on_escape_press(); - void parse_special_tile(const lisp::Lisp* lisp); - void parse_sprite_change(const lisp::Lisp* lisp); + }; } // namespace WorldMapNS