Moved Levelset into it's own class, pass WorldState around instead of PlayerState...
authorIngo Ruhnke <grumbel@gmail.com>
Wed, 13 Aug 2014 05:26:41 +0000 (07:26 +0200)
committerIngo Ruhnke <grumbel@gmail.com>
Thu, 14 Aug 2014 00:59:02 +0000 (02:59 +0200)
Some code is currently disabled with "#ifdef GRUMBEL"

19 files changed:
src/supertux/game_manager.cpp
src/supertux/game_manager.hpp
src/supertux/game_session.cpp
src/supertux/game_session.hpp
src/supertux/levelset.cpp [new file with mode: 0644]
src/supertux/levelset.hpp [new file with mode: 0644]
src/supertux/main.cpp
src/supertux/menu/contrib_menu.cpp
src/supertux/menu/contrib_world_menu.cpp
src/supertux/sector.cpp
src/supertux/title_screen.cpp
src/supertux/title_screen.hpp
src/supertux/world.cpp
src/supertux/world.hpp
src/supertux/world_state.cpp
src/supertux/world_state.hpp
src/worldmap/tux.cpp
src/worldmap/worldmap.cpp
src/worldmap/worldmap.hpp

index 1d20184..baa82e2 100644 (file)
 #include "supertux/screen_fade.hpp"
 #include "supertux/screen_manager.hpp"
 #include "supertux/world.hpp"
+#include "supertux/world_state.hpp"
 #include "util/file_system.hpp"
 #include "util/log.hpp"
+#include "worldmap/worldmap.hpp"
 
 GameManager::GameManager() :
-  m_world()
+  m_world(),
+  m_world_state()
 {
 }
 
@@ -41,25 +44,32 @@ GameManager::~GameManager()
 }
 
 void
-GameManager::start_level(std::unique_ptr<World> world, int index)
+GameManager::start_level(const std::string& level_filename)
 {
+  /*
   m_world = std::move(world);
+  m_world_state.reset(new WorldState);
+  m_world_state->load(m_world->get_savegame_filename());
 
-  std::unique_ptr<Screen> screen(new GameSession(m_world->get_level_filename(index),
-                                                 m_world->get_player_status()));
+  std::unique_ptr<Screen> screen(new GameSession(level_filename,
+                                                 &m_world_state));
   g_screen_manager->push_screen(std::move(screen));
+  */
 }
 
 void
 GameManager::start_game(std::unique_ptr<World> world)
 {
-  m_world = std::move(world);
-
-  MenuManager::instance().clear_menu_stack();
-
   try
   {
-    m_world->run();
+    m_world = std::move(world);
+    m_world_state.reset(new WorldState);
+
+    m_world_state->load(m_world->get_savegame_filename());
+
+    g_screen_manager->push_screen(std::unique_ptr<Screen>(
+                                    new worldmap::WorldMap(m_world->get_worldmap_filename(),
+                                                           *m_world_state)));
   }
   catch(std::exception& e)
   {
index f349032..5e21f88 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <memory>
 
+#include "supertux/world_state.hpp"
 #include "util/currenton.hpp"
 
 class World;
@@ -27,13 +28,14 @@ class GameManager : public Currenton<GameManager>
 {
 private:
   std::unique_ptr<World> m_world;
+  std::unique_ptr<WorldState> m_world_state;
 
 public:
   GameManager();
   ~GameManager();
 
   void start_game(std::unique_ptr<World> world);
-  void start_level(std::unique_ptr<World> world, int index);
+  void start_level(const std::string& level_filename);
 
   std::string get_level_name(const std::string& levelfile) const;
 
index 008f3f4..d0cc127 100644 (file)
 #include "supertux/screen_fade.hpp"
 #include "supertux/screen_manager.hpp"
 #include "supertux/sector.hpp"
+#include "supertux/world_state.hpp"
 #include "util/file_system.hpp"
 #include "util/gettext.hpp"
 #include "worldmap/worldmap.hpp"
 
-GameSession::GameSession(const std::string& levelfile_, PlayerStatus* player_status, Statistics* statistics) :
+GameSession::GameSession(const std::string& levelfile_, WorldState& world_state, Statistics* statistics) :
   level(),
   statistics_backdrop(Surface::create("images/engine/menu/score-backdrop.png")),
   scripts(),
@@ -60,7 +61,7 @@ GameSession::GameSession(const std::string& levelfile_, PlayerStatus* player_sta
   newsector(),
   newspawnpoint(),
   best_level_statistics(statistics),
-  player_status(player_status),
+  m_world_state(world_state),
   capture_demo_stream(0),
   capture_file(),
   playback_demo_stream(0),
@@ -80,7 +81,7 @@ GameSession::GameSession(const std::string& levelfile_, PlayerStatus* player_sta
 int
 GameSession::restart_level()
 {
-    PlayerStatus* currentStatus = get_player_status();
+    PlayerStatus* currentStatus = m_world_state.get_player_status();
     coins_at_start = currentStatus->coins;
     bonus_at_start = currentStatus->bonus;
     max_fire_bullets_at_start = currentStatus->max_fire_bullets;
@@ -256,7 +257,7 @@ GameSession::abort_level()
   MenuManager::instance().clear_menu_stack();
   g_screen_manager->pop_screen();
   currentsector->player->set_bonus(bonus_at_start);
-  PlayerStatus *currentStatus = get_player_status();
+  PlayerStatus *currentStatus = m_world_state.get_player_status();
   currentStatus->coins = coins_at_start;
   currentStatus->max_fire_bullets = max_fire_bullets_at_start;
   currentStatus->max_ice_bullets = max_ice_bullets_at_start;
@@ -574,7 +575,7 @@ GameSession::start_sequence(const std::string& sequencename)
 void
 GameSession::drawstatus(DrawingContext& context)
 {
-  player_status->draw(context);
+  m_world_state.get_player_status()->draw(context);
 
   // draw level stats while end_sequence is running
   if (end_sequence) {
index af2b778..2d61b0e 100644 (file)
 #include "util/currenton.hpp"
 #include "video/surface.hpp"
 
+class CodeController;
+class DrawingContext;
 class Level;
+class Menu;
+class PlayerStatus;
 class Sector;
 class Statistics;
-class PlayerStatus;
-class DrawingContext;
-class CodeController;
-class Menu;
+class WorldState;
 
 /**
  * Screen that runs a Level, where Players run and jump through Sectors.
@@ -42,7 +43,7 @@ class GameSession : public Screen,
                     public Currenton<GameSession>
 {
 public:
-  GameSession(const std::string& levelfile, PlayerStatus* player_status, Statistics* statistics = NULL);
+  GameSession(const std::string& levelfile, WorldState& world_state, Statistics* statistics = NULL);
   ~GameSession();
 
   void record_demo(const std::string& filename);
@@ -69,9 +70,6 @@ public:
   Level* get_current_level()
   { return level.get(); }
 
-  PlayerStatus* get_player_status()
-  { return player_status; }
-
   void start_sequence(const std::string& sequencename);
 
   /**
@@ -95,6 +93,8 @@ public:
    */
   void force_ghost_mode();
 
+  WorldState& get_world_state() { return m_world_state; }
+
 private:
   void check_end_conditions();
   void process_events();
@@ -134,7 +134,7 @@ private:
   std::string newspawnpoint;
 
   Statistics* best_level_statistics;
-  PlayerStatus* player_status;
+  WorldState& m_world_state;
 
   std::ostream* capture_demo_stream;
   std::string capture_file;
diff --git a/src/supertux/levelset.cpp b/src/supertux/levelset.cpp
new file mode 100644 (file)
index 0000000..8b19446
--- /dev/null
@@ -0,0 +1,54 @@
+//  SuperTux
+//  Copyright (C) 2014 Ingo Ruhnke <grumbel@gmail.com>
+//
+//  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, see <http://www.gnu.org/licenses/>.
+
+#include "supertux/levelset.hpp"
+
+#include <physfs.h>
+#include <algorithm>
+
+#include "util/log.hpp"
+#include "util/string_util.hpp"
+
+Levelset::Levelset(const std::string& basedir) :
+  m_basedir(basedir),
+  m_levels()
+{
+  char** files = PHYSFS_enumerateFiles(m_basedir.c_str());
+  if (!files)
+  {
+    log_warning << "Couldn't read subset dir '" << m_basedir << "'" << std::endl;
+    return;
+  }
+
+  for(const char* const* filename = files; *filename != 0; ++filename)
+  {
+    if(StringUtil::has_suffix(*filename, ".stl"))
+    {
+      m_levels.push_back(*filename);
+    }
+  }
+  PHYSFS_freeList(files);
+
+  std::sort(m_levels.begin(), m_levels.end(), StringUtil::numeric_less);
+}
+
+int
+Levelset::get_num_levels() const
+{
+  return static_cast<int>(m_levels.size());
+}
+
+/* EOF */
diff --git a/src/supertux/levelset.hpp b/src/supertux/levelset.hpp
new file mode 100644 (file)
index 0000000..b8618f7
--- /dev/null
@@ -0,0 +1,41 @@
+//  SuperTux
+//  Copyright (C) 2014 Ingo Ruhnke <grumbel@gmail.com>
+//
+//  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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_SUPERTUX_LEVELSET_HPP
+#define HEADER_SUPERTUX_SUPERTUX_LEVELSET_HPP
+
+#include <string>
+#include <vector>
+
+class Levelset
+{
+private:
+  std::string m_basedir;
+  std::vector<std::string> m_levels;
+
+public:
+  Levelset(const std::string& basedir);
+
+  int get_num_levels() const;
+
+private:
+  Levelset(const Levelset&) = delete;
+  Levelset& operator=(const Levelset&) = delete;
+};
+
+#endif
+
+/* EOF */
index 2262d16..75c7544 100644 (file)
@@ -358,7 +358,7 @@ Main::run(int argc, char** argv)
 
     timelog(0);
 
-    const std::unique_ptr<PlayerStatus> default_playerstatus(new PlayerStatus());
+    const std::unique_ptr<WorldState> default_world_state(new WorldState);
 
     GameManager game_manager;
     g_screen_manager = new ScreenManager();
@@ -381,10 +381,10 @@ Main::run(int argc, char** argv)
          g_config->start_level.compare(g_config->start_level.size() - 5, 5, ".stwm") == 0) {
         g_screen_manager->push_screen(std::unique_ptr<Screen>(
                                         new worldmap::WorldMap(
-                                          FileSystem::basename(g_config->start_level), default_playerstatus.get())));
+                                          FileSystem::basename(g_config->start_level), *default_world_state)));
       } else {
         std::unique_ptr<GameSession> session (
-          new GameSession(FileSystem::basename(g_config->start_level), default_playerstatus.get()));
+          new GameSession(FileSystem::basename(g_config->start_level), *default_world_state));
 
         g_config->random_seed =session->get_demo_random_seed(g_config->start_demo);
         init_rand();//initialise generator with seed from session
@@ -397,7 +397,7 @@ Main::run(int argc, char** argv)
         g_screen_manager->push_screen(std::move(session));
       }
     } else {
-      g_screen_manager->push_screen(std::unique_ptr<Screen>(new TitleScreen(default_playerstatus.get())));
+      g_screen_manager->push_screen(std::unique_ptr<Screen>(new TitleScreen(*default_world_state)));
     }
 
     g_screen_manager->run(context);
index e36b1a0..8e2937f 100644 (file)
@@ -54,10 +54,12 @@ ContribMenu::ContribMenu() :
 
       if (!world->hide_from_contribs())
       {
+#ifdef GRUMBEL
         world->load_state();
+#endif
 
         std::ostringstream title;
-        title << world->get_title() << " (" << world->get_num_solved_levels() << "/" << world->get_num_levels() << ")";
+        title << world->get_title(); // << " (" << world->get_num_solved_levels() << "/" << world->get_num_levels() << ")";
         add_entry(i++, title.str());
         m_contrib_worlds.push_back(std::move(world));
       }
index 548fab3..4ad9523 100644 (file)
@@ -32,6 +32,7 @@ ContribWorldMenu::ContribWorldMenu(std::unique_ptr<World> world) :
   add_label(m_world->get_title());
   add_hl();
 
+#ifdef GRUMBEL
   for (int i = 0; i < m_world->get_num_levels(); ++i)
   {
     /** get level's title */
@@ -39,6 +40,7 @@ ContribWorldMenu::ContribWorldMenu(std::unique_ptr<World> world) :
     std::string title = GameManager::current()->get_level_name(filename);
     add_entry(i, title);
   }
+#endif
 
   add_hl();
   add_back(_("Back"));
@@ -52,7 +54,9 @@ ContribWorldMenu::check_menu()
     if (get_item_by_id(index).kind == MN_ACTION)
     {
       sound_manager->stop_music();
+#ifdef GRUMBEL
       GameManager::current()->start_level(std::move(m_world), index);
+#endif
     }
   }
 }
index 38e66ad..1cbffc6 100644 (file)
@@ -54,6 +54,7 @@
 #include "supertux/level.hpp"
 #include "supertux/object_factory.hpp"
 #include "supertux/player_status.hpp"
+#include "supertux/world_state.hpp"
 #include "supertux/spawn_point.hpp"
 #include "supertux/tile.hpp"
 #include "trigger/sequence_trigger.hpp"
@@ -85,7 +86,7 @@ Sector::Sector(Level* parent) :
   camera(0),
   effect(0)
 {
-  add_object(new Player(GameSession::current()->get_player_status(), "Tux"));
+  add_object(new Player(GameSession::current()->get_world_state().get_player_status(), "Tux"));
   add_object(new DisplayEffect("Effect"));
   add_object(new TextObject("Text"));
 
index 368ac4a..8488bff 100644 (file)
 #include <sstream>
 #include <version.h>
 
-TitleScreen::TitleScreen(PlayerStatus* player_status) :
+TitleScreen::TitleScreen(WorldState& world_state) :
   frame(),
   controller(),
   titlesession(),
   copyright_text()
 {
   controller.reset(new CodeController());
-  titlesession.reset(new GameSession("levels/misc/menu.stl", player_status));
+  titlesession.reset(new GameSession("levels/misc/menu.stl", world_state));
 
   Player* player = titlesession->get_current_sector()->player;
   player->set_controller(controller.get());
index 7df4078..40c6d86 100644 (file)
@@ -27,6 +27,7 @@ class ContribWorldMenu;
 class Menu;
 class PlayerStatus;
 class World;
+class WorldState;
 
 /**
  * Screen that displays the SuperTux logo, lets players start a new game, etc.
@@ -34,7 +35,7 @@ class World;
 class TitleScreen : public Screen
 {
 public:
-  TitleScreen(PlayerStatus* player_status);
+  TitleScreen(WorldState& world_state);
   virtual ~TitleScreen();
 
   virtual void setup();
index c2063a7..02c5b15 100644 (file)
@@ -52,23 +52,20 @@ World::load(const std::string& directory)
 }
 
 World::World() :
-  m_levels(),
   m_basedir(),
   m_worldmap_filename(),
   m_savegame_filename(),
-  m_world_thread(),
   m_title(),
   m_description(),
-  m_world_state(new WorldState),
   m_hide_from_contribs(false),
   m_is_levelset(true)
 {
-  sq_resetobject(&m_world_thread);
+  std::cout << this << " World()" << std::endl;
 }
 
 World::~World()
 {
-  sq_release(scripting::global_vm, &m_world_thread);
+  std::cout << this << " ~World()" << std::endl;
 }
 
 void
@@ -93,155 +90,6 @@ World::load_(const std::string& directory)
   info->get("description", m_description);
   info->get("levelset", m_is_levelset);
   info->get("hide-from-contribs", m_hide_from_contribs);
-
-  // Level info file doesn't define any levels, so read the
-  // directory to see what we can find
-
-  char** files = PHYSFS_enumerateFiles(m_basedir.c_str());
-  if(!files)
-  {
-    log_warning << "Couldn't read subset dir '" << m_basedir << "'" << std::endl;
-    return;
-  }
-
-  for(const char* const* filename = files; *filename != 0; ++filename)
-  {
-    if(StringUtil::has_suffix(*filename, ".stl"))
-    {
-      m_levels.push_back(*filename);
-    }
-  }
-  PHYSFS_freeList(files);
-
-  std::sort(m_levels.begin(), m_levels.end(), StringUtil::numeric_less);
-}
-
-void
-World::run()
-{
-  // create new squirrel table for persistent game state
-  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");
-  }
-  else
-  {
-    sq_pop(vm, 1);
-
-    load_state();
-
-    std::string filename = m_basedir + "/world.nut";
-    try
-    {
-      IFileStreambuf ins(filename);
-      std::istream in(&ins);
-
-      sq_release(scripting::global_vm, &m_world_thread);
-      m_world_thread = scripting::create_thread(scripting::global_vm);
-      scripting::compile_and_run(scripting::object_to_vm(m_world_thread), in, filename);
-    }
-    catch(const std::exception& )
-    {
-      // fallback: try to load worldmap worldmap.stwm
-      g_screen_manager->push_screen(std::unique_ptr<Screen>(
-                                      new worldmap::WorldMap(m_worldmap_filename,
-                                                             get_player_status())));
-    }
-  }
-}
-
-void
-World::save_state()
-{
-  m_world_state->save(m_savegame_filename);
-}
-
-void
-World::load_state()
-{
-  m_world_state->load(m_savegame_filename);
-}
-
-std::string
-World::get_level_filename(unsigned int i) const
-{
-  return FileSystem::join(m_basedir, m_levels[i]);
-}
-
-int
-World::get_num_levels() const
-{
-  return static_cast<int>(m_levels.size());
-}
-
-int
-World::get_num_solved_levels() const
-{
-  int num_solved_levels = 0;
-
-  HSQUIRRELVM vm = scripting::global_vm;
-  int oldtop = sq_gettop(vm);
-
-  sq_pushroottable(vm);
-  sq_pushstring(vm, "state", -1);
-  if(SQ_FAILED(sq_get(vm, -2)))
-  {
-    log_warning << "failed to get 'state' table" << std::endl;
-  }
-  else
-  {
-    sq_pushstring(vm, "worlds", -1);
-    if(SQ_FAILED(sq_get(vm, -2)))
-    {
-      log_warning << "failed to get 'state.worlds' table" << std::endl;
-    }
-    else
-    {
-      sq_pushstring(vm, m_worldmap_filename.c_str(), -1);
-      if(SQ_FAILED(sq_get(vm, -2)))
-      {
-        log_warning << "failed to get state.worlds['" << m_worldmap_filename << "']" << std::endl;
-      }
-      else
-      {
-        sq_pushstring(vm, "levels", -1);
-        if(SQ_FAILED(sq_get(vm, -2)))
-        {
-          log_warning << "failed to get state.worlds['" << m_worldmap_filename << "'].levels" << std::endl;
-        }
-        else
-        {
-          for(auto level : m_levels)
-          {
-            sq_pushstring(vm, level.c_str(), -1);
-            if(SQ_FAILED(sq_get(vm, -2)))
-            {
-              log_warning << "failed to get state.worlds['" << m_worldmap_filename << "'].levels['"
-                          << level << "']" << std::endl;
-            }
-            else
-            {
-              bool solved = scripting::read_bool(vm, "solved");
-              if (solved)
-              {
-                num_solved_levels += 1;
-              }
-              sq_pop(vm, 1);
-            }
-          }
-        }
-      }
-    }
-  }
-
-  sq_settop(vm, oldtop);
-
-  return num_solved_levels;
 }
 
 std::string
index a952640..47bf2dc 100644 (file)
@@ -43,33 +43,24 @@ public:
 public:
   ~World();
 
-  void save_state();
-  void load_state();
-
-  int get_num_levels() const;
-  int get_num_solved_levels() const;
-
-  std::string get_level_filename(unsigned int i) const;
   std::string get_basedir() const;
   std::string get_title() const;
 
-  PlayerStatus* get_player_status() const { return m_world_state->get_player_status(); }
-
-  void run();
-
   bool hide_from_contribs() const { return m_hide_from_contribs; }
+
   bool is_levelset() const { return m_is_levelset; }
+  bool is_worldmap() const { return !m_is_levelset; }
+
+  std::string get_worldmap_filename() const { return m_worldmap_filename; }
+  std::string get_savegame_filename() const { return m_savegame_filename; }
 
 private:
-  std::vector<std::string> m_levels;
   std::string m_basedir;
   std::string m_worldmap_filename;
   std::string m_savegame_filename;
-  HSQOBJECT m_world_thread;
+
   std::string m_title;
   std::string m_description;
-  std::unique_ptr<WorldState> m_world_state;
-
   bool m_hide_from_contribs;
   bool m_is_levelset;
 
index d0dbd8b..fc927d6 100644 (file)
@@ -80,11 +80,13 @@ WorldState::load(const std::string& filename)
           }
           else
           {
+            // delete existing state table, if it exists
             sq_pushroottable(vm);
             sq_pushstring(vm, "state", -1);
             if(SQ_FAILED(sq_deleteslot(vm, -2, SQFalse)))
               sq_pop(vm, 1);
 
+            // create a new empty state table
             sq_pushstring(vm, "state", -1);
             sq_newtable(vm);
             scripting::load_squirrel_table(vm, -1, *state);
@@ -162,4 +164,80 @@ WorldState::save(const std::string& filename)
   writer.end_list("supertux-savegame");
 }
 
+int
+WorldState::get_num_levels() const
+{
+#ifdef GRUMBEL
+#endif
+  return 5;
+}
+
+int
+WorldState::get_num_solved_levels() const
+{
+  return 3;
+#ifdef GRUMBEL
+  int num_solved_levels = 0;
+
+  HSQUIRRELVM vm = scripting::global_vm;
+  int oldtop = sq_gettop(vm);
+
+  sq_pushroottable(vm);
+  sq_pushstring(vm, "state", -1);
+  if(SQ_FAILED(sq_get(vm, -2)))
+  {
+    log_warning << "failed to get 'state' table" << std::endl;
+  }
+  else
+  {
+    sq_pushstring(vm, "worlds", -1);
+    if(SQ_FAILED(sq_get(vm, -2)))
+    {
+      log_warning << "failed to get 'state.worlds' table" << std::endl;
+    }
+    else
+    {
+      sq_pushstring(vm, m_worldmap_filename.c_str(), -1);
+      if(SQ_FAILED(sq_get(vm, -2)))
+      {
+        log_warning << "failed to get state.worlds['" << m_worldmap_filename << "']" << std::endl;
+      }
+      else
+      {
+        sq_pushstring(vm, "levels", -1);
+        if(SQ_FAILED(sq_get(vm, -2)))
+        {
+          log_warning << "failed to get state.worlds['" << m_worldmap_filename << "'].levels" << std::endl;
+        }
+        else
+        {
+          for(auto level : m_levels)
+          {
+            sq_pushstring(vm, level.c_str(), -1);
+            if(SQ_FAILED(sq_get(vm, -2)))
+            {
+              log_warning << "failed to get state.worlds['" << m_worldmap_filename << "'].levels['"
+                          << level << "']" << std::endl;
+            }
+            else
+            {
+              bool solved = scripting::read_bool(vm, "solved");
+              if (solved)
+              {
+                num_solved_levels += 1;
+              }
+              sq_pop(vm, 1);
+            }
+          }
+        }
+      }
+    }
+  }
+
+  sq_settop(vm, oldtop);
+
+  return num_solved_levels;
+#endif
+}
+
 /* EOF */
index a3d2c3e..d78d9d5 100644 (file)
@@ -33,6 +33,9 @@ public:
 
   PlayerStatus* get_player_status() const { return m_player_status.get(); }
 
+  int get_num_levels() const;
+  int get_num_solved_levels() const;
+
   void save(const std::string& filename);
   void load(const std::string& filename);
 
index 35e98e2..eda5b4f 100644 (file)
@@ -21,6 +21,7 @@
 #include "sprite/sprite_manager.hpp"
 #include "supertux/globals.hpp"
 #include "supertux/player_status.hpp"
+#include "supertux/world_state.hpp"
 #include "supertux/tile.hpp"
 #include "worldmap/level.hpp"
 #include "worldmap/tux.hpp"
@@ -59,7 +60,7 @@ Tux::~Tux()
 void
 Tux::draw(DrawingContext& context)
 {
-  switch (worldmap->get_player_status()->bonus) {
+  switch (worldmap->get_world_state().get_player_status()->bonus) {
     case GROWUP_BONUS:
       sprite->set_action(moving ? "large-walking" : "large-stop");
       break;
index dfc3bfc..998695f 100644 (file)
@@ -59,6 +59,7 @@
 #include "supertux/tile_manager.hpp"
 #include "supertux/tile_set.hpp"
 #include "supertux/world.hpp"
+#include "supertux/world_state.hpp"
 #include "util/file_system.hpp"
 #include "util/gettext.hpp"
 #include "util/log.hpp"
@@ -77,9 +78,9 @@ namespace worldmap {
 
 WorldMap* WorldMap::current_ = NULL;
 
-WorldMap::WorldMap(const std::string& filename, PlayerStatus* player_status, const std::string& force_spawnpoint) :
-  tux(0),
-  player_status(player_status),
+WorldMap::WorldMap(const std::string& filename, WorldState& world_state, const std::string& force_spawnpoint) :
+  tux(),
+  m_world_state(world_state),
   tileset(NULL),
   free_tileset(false),
   camera_offset(),
@@ -239,7 +240,7 @@ void
 WorldMap::change(const std::string& filename, const std::string& force_spawnpoint)
 {
   g_screen_manager->pop_screen();
-  g_screen_manager->push_screen(std::unique_ptr<Screen>(new WorldMap(filename, player_status, force_spawnpoint)));
+  g_screen_manager->push_screen(std::unique_ptr<Screen>(new WorldMap(filename, m_world_state, force_spawnpoint)));
 }
 
 void
@@ -694,7 +695,7 @@ WorldMap::update(float delta)
           // update state and savegame
           save_state();
 
-          g_screen_manager->push_screen(std::unique_ptr<Screen>(new GameSession(levelfile, player_status, &level->statistics)),
+          g_screen_manager->push_screen(std::unique_ptr<Screen>(new GameSession(levelfile, m_world_state, &level->statistics)),
                                         std::unique_ptr<ScreenFade>(new ShrinkFade(shrinkpos, 1.0f)));
           in_level = true;
         } catch(std::exception& e) {
@@ -829,7 +830,7 @@ WorldMap::draw_status(DrawingContext& context)
   context.push_transform();
   context.set_translation(Vector(0, 0));
 
-  player_status->draw(context);
+  m_world_state.get_player_status()->draw(context);
 
   if (!tux->is_moving()) {
     for(LevelTiles::iterator i = levels.begin(); i != levels.end(); ++i) {
@@ -1031,8 +1032,16 @@ WorldMap::save_state()
 
   sq_settop(vm, oldtop);
 
-  if(World::current() != NULL)
-    World::current()->save_state();
+  if (!World::current())
+  {
+    log_fatal << "no World::current(), so can't savegame" << std::endl;
+  }
+  else
+  {
+#ifdef GRUMBEL
+    m_world_state->save_state();
+#endif
+  }
 }
 
 void
index 4e5d43f..db0749c 100644 (file)
 #include "worldmap/sprite_change.hpp"
 #include "worldmap/teleporter.hpp"
 
-class Sprite;
 class GameObject;
-class TileMap;
 class PlayerStatus;
+class Sprite;
+class TileMap;
+class WorldState;
 
 namespace worldmap {
 
@@ -77,7 +78,7 @@ private:
 
   Tux* tux;
 
-  PlayerStatus* player_status;
+  WorldState& m_world_state;
 
   TileSet *tileset;
   bool     free_tileset;
@@ -123,7 +124,7 @@ private:
   bool panning;
 
 public:
-  WorldMap(const std::string& filename, PlayerStatus* player_status, const std::string& force_spawnpoint = "");
+  WorldMap(const std::string& filename, WorldState& world_state, const std::string& force_spawnpoint = "");
   ~WorldMap();
 
   void add_object(GameObject* object);
@@ -168,8 +169,7 @@ public:
   /** returns current Tux incarnation */
   Tux* get_tux() { return tux; }
 
-  /** returns player status */
-  PlayerStatus* get_player_status() { return player_status; }
+  WorldState& get_world_state() { return m_world_state; }
 
   LevelTile* at_level();
   SpecialTile* at_special_tile();