Determine language on start-up if language is set to auto detect.
[supertux.git] / src / supertux / world.cpp
index 02ac4a9..f821dd4 100644 (file)
@@ -14,6 +14,8 @@
 //  You should have received a copy of the GNU General Public License
 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+#include <algorithm>
+
 #include "lisp/parser.hpp"
 #include "lisp/writer.hpp"
 #include "physfs/ifile_stream.hpp"
 #include "supertux/world.hpp"
 #include "util/file_system.hpp"
 #include "util/reader.hpp"
+#include "util/string_util.hpp"
 #include "worldmap/worldmap.hpp"
 
-static bool has_suffix(const std::string& data, const std::string& suffix)
-{
-  if (data.length() >= suffix.length())
-    return data.compare(data.length() - suffix.length(), suffix.length(), suffix) == 0;
-  else
-    return false;
-}
-
 World* World::current_ = NULL;
 
 World::World() :
@@ -45,9 +40,12 @@ World::World() :
   world_thread(),
   title(),
   description(),
+  player_status(),
   hide_from_contribs(),
   is_levelset()
 {
+  player_status.reset(new PlayerStatus());
+
   is_levelset = true;
   hide_from_contribs = false;
   sq_resetobject(&world_thread);
@@ -55,7 +53,7 @@ World::World() :
 
 World::~World()
 {
-  sq_release(Scripting::global_vm, &world_thread);
+  sq_release(scripting::global_vm, &world_thread);
   if(current_ == this)
     current_ = NULL;
 }
@@ -67,7 +65,7 @@ World::set_savegame_filename(const std::string& filename)
   // make sure the savegame directory exists
   std::string dirname = FileSystem::dirname(filename);
   if(!PHYSFS_exists(dirname.c_str())) {
-    if(PHYSFS_mkdir(dirname.c_str())) {
+    if(!PHYSFS_mkdir(dirname.c_str())) {
       std::ostringstream msg;
       msg << "Couldn't create directory for savegames '"
           << dirname << "': " <<PHYSFS_getLastError();
@@ -102,7 +100,6 @@ World::load(const std::string& filename)
   info->get("title", title);
   info->get("description", description);
   info->get("levelset", is_levelset);
-  info->get("levels", levels);
   info->get("hide-from-contribs", hide_from_contribs);
 
   // Level info file doesn't define any levels, so read the
@@ -116,28 +113,30 @@ World::load(const std::string& filename)
   }
 
   for(const char* const* filename = files; *filename != 0; ++filename) {
-    if(has_suffix(*filename, ".stl")) {
+    if(StringUtil::has_suffix(*filename, ".stl")) {
       levels.push_back(path + *filename);
     }
   }
   PHYSFS_freeList(files);
+
+  std::sort(levels.begin(), levels.end(), StringUtil::numeric_less);
 }
 
 void
 World::run()
 {
-  using namespace Scripting;
+  using namespace scripting;
 
   current_ = this;
 
   // create new squirrel table for persistent game state
-  HSQUIRRELVM vm = Scripting::global_vm;
+  HSQUIRRELVM vm = scripting::global_vm;
 
   sq_pushroottable(vm);
   sq_pushstring(vm, "state", -1);
   sq_newtable(vm);
   if(SQ_FAILED(sq_createslot(vm, -3)))
-    throw Scripting::SquirrelError(vm, "Couldn't create state table");
+    throw scripting::SquirrelError(vm, "Couldn't create state table");
   sq_pop(vm, 1);
 
   load_state();
@@ -151,22 +150,22 @@ World::run()
     compile_and_run(object_to_vm(world_thread), in, filename);
   } catch(std::exception& ) {
     // fallback: try to load worldmap worldmap.stwm
-    using namespace WorldMapNS;
-    g_screen_manager->push_screen(new WorldMap(basedir + "worldmap.stwm"));
+    using namespace worldmap;
+    g_screen_manager->push_screen(new WorldMap(basedir + "worldmap.stwm", get_player_status()));
   }
 }
 
 void
 World::save_state()
 {
-  using namespace Scripting;
+  using namespace scripting;
 
   lisp::Writer writer(savegame_filename);
 
   writer.start_list("supertux-savegame");
   writer.write("version", 1);
 
-  using namespace WorldMapNS;
+  using namespace worldmap;
   if(WorldMap::current() != NULL) {
     std::ostringstream title;
     title << WorldMap::current()->get_title();
@@ -184,7 +183,7 @@ World::save_state()
   sq_pushroottable(global_vm);
   sq_pushstring(global_vm, "state", -1);
   if(SQ_SUCCEEDED(sq_get(global_vm, -2))) {
-    Scripting::save_squirrel_table(global_vm, -1, writer);
+    scripting::save_squirrel_table(global_vm, -1, writer);
     sq_pop(global_vm, 1);
   }
   sq_pop(global_vm, 1);
@@ -196,43 +195,45 @@ World::save_state()
 void
 World::load_state()
 {
-  using namespace Scripting;
-
-  try {
-    lisp::Parser parser;
-    const lisp::Lisp* root = parser.parse(savegame_filename);
-
-    const lisp::Lisp* lisp = root->get_lisp("supertux-savegame");
-    if(lisp == NULL)
-      throw std::runtime_error("file is not a supertux-savegame file");
-
-    int version = 1;
-    lisp->get("version", version);
-    if(version != 1)
-      throw std::runtime_error("incompatible savegame version");
-
-    const lisp::Lisp* tux = lisp->get_lisp("tux");
-    if(tux == NULL)
-      throw std::runtime_error("No tux section in savegame");
-    player_status->read(*tux);
-
-    const lisp::Lisp* state = lisp->get_lisp("state");
-    if(state == NULL)
-      throw std::runtime_error("No state section in savegame");
-
-    sq_pushroottable(global_vm);
-    sq_pushstring(global_vm, "state", -1);
-    if(SQ_FAILED(sq_deleteslot(global_vm, -2, SQFalse)))
+  using namespace scripting;
+
+  if(PHYSFS_exists(savegame_filename.c_str())) {
+    try {
+      lisp::Parser parser;
+      const lisp::Lisp* root = parser.parse(savegame_filename);
+
+      const lisp::Lisp* lisp = root->get_lisp("supertux-savegame");
+      if(lisp == NULL)
+        throw std::runtime_error("file is not a supertux-savegame file");
+
+      int version = 1;
+      lisp->get("version", version);
+      if(version != 1)
+        throw std::runtime_error("incompatible savegame version");
+
+      const lisp::Lisp* tux = lisp->get_lisp("tux");
+      if(tux == NULL)
+        throw std::runtime_error("No tux section in savegame");
+      player_status->read(*tux);
+
+      const lisp::Lisp* state = lisp->get_lisp("state");
+      if(state == NULL)
+        throw std::runtime_error("No state section in savegame");
+
+      sq_pushroottable(global_vm);
+      sq_pushstring(global_vm, "state", -1);
+      if(SQ_FAILED(sq_deleteslot(global_vm, -2, SQFalse)))
+        sq_pop(global_vm, 1);
+
+      sq_pushstring(global_vm, "state", -1);
+      sq_newtable(global_vm);
+      load_squirrel_table(global_vm, -1, *state);
+      if(SQ_FAILED(sq_createslot(global_vm, -3)))
+        throw std::runtime_error("Couldn't create state table");
       sq_pop(global_vm, 1);
-
-    sq_pushstring(global_vm, "state", -1);
-    sq_newtable(global_vm);
-    load_squirrel_table(global_vm, -1, *state);
-    if(SQ_FAILED(sq_createslot(global_vm, -3)))
-      throw std::runtime_error("Couldn't create state table");
-    sq_pop(global_vm, 1);
-  } catch(std::exception& e) {
-    log_debug << "Couldn't load savegame: " << e.what() << std::endl;
+    } catch(std::exception& e) {
+      log_fatal << "Couldn't load savegame: " << e.what() << std::endl;
+    }
   }
 }
 
@@ -254,4 +255,10 @@ World::get_basedir() const
   return basedir;
 }
 
+const std::string&
+World::get_title() const
+{
+  return title;
+}
+
 /* EOF */