Experiments with new Teleporter Worldmap Tile
authorChristoph Sommer <mail@christoph-sommer.de>
Tue, 20 Jun 2006 15:24:58 +0000 (15:24 +0000)
committerChristoph Sommer <mail@christoph-sommer.de>
Tue, 20 Jun 2006 15:24:58 +0000 (15:24 +0000)
SVN-Revision: 3682

src/worldmap/teleporter.cpp [new file with mode: 0644]
src/worldmap/teleporter.hpp [new file with mode: 0644]
src/worldmap/tux.cpp
src/worldmap/worldmap.cpp
src/worldmap/worldmap.hpp

diff --git a/src/worldmap/teleporter.cpp b/src/worldmap/teleporter.cpp
new file mode 100644 (file)
index 0000000..6cce11d
--- /dev/null
@@ -0,0 +1,57 @@
+//  $Id$
+//
+//  SuperTux - Teleporter Worldmap Tile
+//  Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
+//
+//  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 <config.h>
+
+#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 (file)
index 0000000..243b36a
--- /dev/null
@@ -0,0 +1,61 @@
+//  $Id$
+//
+//  SuperTux - Teleporter Worldmap Tile
+//  Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
+//
+//  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 <memory>
+#include <string>
+#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> 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
+
index 6a3a8bb..6964c66 100644 (file)
@@ -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)
index a8cd5e4..ba81b1e 100644 (file)
@@ -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<Teleporter*>::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;
   
index 75d8f8f..9bf35b2 100644 (file)
@@ -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<SpawnPoint*> SpawnPoints;
   SpawnPoints spawn_points;
+  std::vector<Teleporter*> teleporters;
 
   Statistics total_stats;
 
   HSQOBJECT worldmap_table;
   typedef std::vector<HSQOBJECT> 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