- test level for snow air tiles (created with Flexlay)
[supertux.git] / src / worldmap / worldmap.cpp
index 8cc033f..137ffd8 100644 (file)
@@ -54,6 +54,8 @@
 #include "main.hpp"
 #include "spawn_point.hpp"
 #include "file_system.hpp"
+#include "tile_manager.hpp"
+#include "tile_set.hpp"
 #include "gui/menu.hpp"
 #include "gui/mousecursor.hpp"
 #include "control/joystickkeyboardcontroller.hpp"
@@ -134,10 +136,10 @@ string_to_direction(const std::string& directory)
 //---------------------------------------------------------------------------
 
 WorldMap::WorldMap(const std::string& filename, const std::string& force_spawnpoint)
-  : tux(0), ambient_light( 1.0f, 1.0f, 1.0f, 1.0f ), force_spawnpoint(force_spawnpoint), in_level(false)
+  : tux(0), tileset(NULL), free_tileset(false),
+    ambient_light( 1.0f, 1.0f, 1.0f, 1.0f ), force_spawnpoint(force_spawnpoint),
+    in_level(false)
 {
-  tile_manager.reset(new TileManager("images/worldmap.strf"));
-
   tux = new Tux(this);
   add_object(tux);
 
@@ -169,6 +171,8 @@ WorldMap::WorldMap(const std::string& filename, const std::string& force_spawnpo
 
   sq_addref(global_vm, &worldmap_table);
   sq_pop(global_vm, 1);
+
+  sound_manager->preload("sounds/warp.wav");
   
   // load worldmap objects
   load(filename);
@@ -178,7 +182,8 @@ WorldMap::~WorldMap()
 {
   using namespace Scripting;
 
-  save_state();
+  if(free_tileset)
+    delete tileset;
 
   for(GameObjects::iterator i = game_objects.begin();
       i != game_objects.end(); ++i) {
@@ -282,20 +287,39 @@ WorldMap::load(const std::string& filename)
     lisp::Parser parser;
     const lisp::Lisp* root = parser.parse(map_filename);
 
-    const lisp::Lisp* lisp = root->get_lisp("supertux-level");
-    if(!lisp)
+    const lisp::Lisp* level = root->get_lisp("supertux-level");
+    if(level == NULL)
       throw std::runtime_error("file isn't a supertux-level file.");
 
-    lisp->get("name", name);
+    level->get("name", name);
 
-    const lisp::Lisp* sector = lisp->get_lisp("sector");
+    const lisp::Lisp* sector = level->get_lisp("sector");
     if(!sector)
       throw std::runtime_error("No sector sepcified in worldmap file.");
 
+    const lisp::Lisp* tilesets_lisp = level->get_lisp("tilesets");
+    if(tilesets_lisp != NULL) {
+      tileset      = tile_manager->parse_tileset_definition(*tilesets_lisp);
+      free_tileset = true;
+    }
+    std::string tileset_name;
+    if(level->get("tileset", tileset_name)) {
+      if(tileset != NULL) {
+        log_warning << "multiple tilesets specified in level" << std::endl;
+      } else {
+        tileset = tile_manager->get_tileset(tileset_name);
+      }
+    }
+    /* load default tileset */
+    if(tileset == NULL) {
+      tileset = tile_manager->get_tileset("images/worldmap.strf");
+    }
+    current_tileset = tileset;
+
     lisp::ListIterator iter(sector);
     while(iter.next()) {
       if(iter.item() == "tilemap") {
-        add_object(new TileMap(*(iter.lisp()), tile_manager.get()));
+        add_object(new TileMap(*(iter.lisp())));
       } else if(iter.item() == "background") {
         add_object(new Background(*(iter.lisp())));
       } else if(iter.item() == "music") {
@@ -335,6 +359,8 @@ WorldMap::load(const std::string& filename)
         log_warning << "Unknown token '" << iter.item() << "' in worldmap" << std::endl;
       }
     }
+    current_tileset = NULL;
+
     if(solid_tilemaps.size() == 0)
       throw std::runtime_error("No solid tilemap specified");
 
@@ -875,9 +901,12 @@ WorldMap::setup()
 void
 WorldMap::leave()
 {
-  // remove worldmap_table from roottable
   using namespace Scripting;
 
+  // save state of world and player
+  save_state();
+
+  // remove worldmap_table from roottable
   sq_pushroottable(global_vm);
   sq_pushstring(global_vm, "worldmap", -1);
   if(SQ_FAILED(sq_deleteslot(global_vm, -2, SQFalse)))