load() should work, save() not yet, as there is nobody updating the state after completing a level
}
void
-GameManager::start_level(const std::string& level_filename)
+GameManager::start_level(std::unique_ptr<World> world, const std::string& level_filename)
{
-#ifdef GRUMBEL
m_world = std::move(world);
- m_savegame.reset(new Savegame);
- m_savegame->load(m_world->get_savegame_filename());
+ m_savegame.reset(new Savegame(m_world->get_savegame_filename()));
+ m_savegame->load();
- std::unique_ptr<Screen> screen(new GameSession(level_filename,
- &m_savegame));
+ std::unique_ptr<Screen> screen(new GameSession(FileSystem::join(m_world->get_basedir(), level_filename),
+ *m_savegame));
g_screen_manager->push_screen(std::move(screen));
-#endif
}
void
~GameManager();
void start_game(std::unique_ptr<World> world);
- void start_level(const std::string& level_filename);
+ void start_level(std::unique_ptr<World> world, const std::string& level_filename);
std::string get_level_name(const std::string& levelfile) const;
}
void
+GameSession::leave()
+{
+ m_savegame.save();
+}
+
+void
GameSession::update(float elapsed_time)
{
// handle controller
void draw(DrawingContext& context);
void update(float frame_ratio);
- void setup();
+ void setup() override;
+ void leave() override;
/// ends the current level
void finish(bool win = true);
return static_cast<int>(m_levels.size());
}
+std::string
+Levelset::get_level_filename(int i) const
+{
+ return m_levels[i];
+}
+
/* EOF */
Levelset(const std::string& basedir);
int get_num_levels() const;
+ std::string get_level_filename(int i) const;
private:
Levelset(const Levelset&) = delete;
--- /dev/null
+// SuperTux
+// Copyright (C) 2009 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/menu/contrib_levelset_menu.hpp"
+
+#include <sstream>
+
+#include "audio/sound_manager.hpp"
+#include "gui/menu_item.hpp"
+#include "supertux/game_manager.hpp"
+#include "supertux/globals.hpp"
+#include "supertux/levelset.hpp"
+#include "supertux/screen_fade.hpp"
+#include "supertux/screen_manager.hpp"
+#include "supertux/title_screen.hpp"
+#include "supertux/world.hpp"
+#include "util/file_system.hpp"
+#include "util/gettext.hpp"
+
+ContribLevelsetMenu::ContribLevelsetMenu(std::unique_ptr<World> world) :
+ m_world(std::move(world)),
+ m_levelset()
+{
+ assert(m_world->is_levelset());
+
+ m_levelset = std::unique_ptr<Levelset>(new Levelset(m_world->get_basedir()));
+
+ Savegame savegame(m_world->get_savegame_filename());
+ savegame.load();
+ LevelsetState state = savegame.get_levelset_state(m_world->get_basedir());
+
+ add_label(m_world->get_title());
+ add_hl();
+
+ for (int i = 0; i < m_levelset->get_num_levels(); ++i)
+ {
+ std::string filename = FileSystem::join(m_world->get_basedir(), m_levelset->get_level_filename(i));
+ std::string title = GameManager::current()->get_level_name(filename);
+ LevelState level_state = state.get_level_state(filename);
+
+ std::ostringstream out;
+ if (level_state.solved)
+ {
+ out << title << " [*]";
+ }
+ else
+ {
+ out << title << " [ ]";
+ }
+ add_entry(i, out.str());
+ }
+
+ add_hl();
+ add_back(_("Back"));
+}
+
+void
+ContribLevelsetMenu::check_menu()
+{
+ int index = check();
+ if (index != -1)
+ {
+ if (get_item_by_id(index).kind == MN_ACTION)
+ {
+ sound_manager->stop_music();
+
+ // reload the World so that we have something that we can safely
+ // std::move() around without wreaking the ContribMenu
+ std::unique_ptr<World> world = World::load(m_world->get_basedir());
+ GameManager::current()->start_level(std::move(world), m_levelset->get_level_filename(index));
+ }
+ }
+}
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2009 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_MENU_CONTRIB_WORLD_MENU_HPP
+#define HEADER_SUPERTUX_SUPERTUX_MENU_CONTRIB_WORLD_MENU_HPP
+
+#include "gui/menu.hpp"
+
+class Levelset;
+class World;
+
+class ContribLevelsetMenu : public Menu
+{
+private:
+ std::unique_ptr<World> m_world;
+ std::unique_ptr<Levelset> m_levelset;
+
+public:
+ ContribLevelsetMenu(std::unique_ptr<World> current_world);
+
+ void check_menu();
+
+private:
+ ContribLevelsetMenu(const ContribLevelsetMenu&);
+ ContribLevelsetMenu& operator=(const ContribLevelsetMenu&);
+};
+
+#endif
+
+/* EOF */
#include "gui/menu_manager.hpp"
#include "supertux/game_manager.hpp"
#include "supertux/gameconfig.hpp"
-#include "supertux/menu/contrib_world_menu.hpp"
+#include "supertux/menu/contrib_levelset_menu.hpp"
#include "supertux/menu/menu_storage.hpp"
#include "supertux/title_screen.hpp"
#include "supertux/world.hpp"
}
level_count += 1;
}
-
+
std::ostringstream title;
title << "[" << world->get_title() << "]";
if (level_count == 0)
}
level_count += 1;
}
-
+
std::ostringstream title;
title << world->get_title();
if (level_count == 0)
}
else
{
- MenuManager::instance().push_menu(std::unique_ptr<Menu>(new ContribWorldMenu(std::move(world))));
+ MenuManager::instance().push_menu(std::unique_ptr<Menu>(new ContribLevelsetMenu(std::move(world))));
}
}
}
+++ /dev/null
-// SuperTux
-// Copyright (C) 2009 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/menu/contrib_world_menu.hpp"
-
-#include "audio/sound_manager.hpp"
-#include "gui/menu_item.hpp"
-#include "supertux/game_manager.hpp"
-#include "supertux/globals.hpp"
-#include "supertux/screen_fade.hpp"
-#include "supertux/screen_manager.hpp"
-#include "supertux/title_screen.hpp"
-#include "supertux/world.hpp"
-#include "util/gettext.hpp"
-
-ContribWorldMenu::ContribWorldMenu(std::unique_ptr<World> world) :
- m_world(std::move(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 */
- std::string filename = m_world->get_level_filename(i);
- std::string title = GameManager::current()->get_level_name(filename);
- add_entry(i, title);
- }
-#endif
-
- add_hl();
- add_back(_("Back"));
-}
-
-void
-ContribWorldMenu::check_menu()
-{
- int index = check();
- if (index != -1) {
- 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
- }
- }
-}
-
-/* EOF */
+++ /dev/null
-// SuperTux
-// Copyright (C) 2009 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_MENU_CONTRIB_WORLD_MENU_HPP
-#define HEADER_SUPERTUX_SUPERTUX_MENU_CONTRIB_WORLD_MENU_HPP
-
-#include "gui/menu.hpp"
-
-class World;
-
-class ContribWorldMenu : public Menu
-{
-private:
- std::unique_ptr<World> m_world;
-
-public:
- ContribWorldMenu(std::unique_ptr<World> current_world);
-
- void check_menu();
-
-private:
- ContribWorldMenu(const ContribWorldMenu&);
- ContribWorldMenu& operator=(const ContribWorldMenu&);
-};
-
-#endif
-
-/* EOF */
#include "supertux/globals.hpp"
#include "supertux/menu/addon_menu.hpp"
#include "supertux/menu/contrib_menu.hpp"
-#include "supertux/menu/contrib_world_menu.hpp"
#include "supertux/menu/game_menu.hpp"
#include "supertux/menu/joystick_menu.hpp"
#include "supertux/menu/keyboard_menu.hpp"
else
{
// successfully placed result on stack
- }
+ }
}
std::vector<std::string> get_table_keys(HSQUIRRELVM vm)
{
//here -1 is the value and -2 is the key
const char* result;
- if(SQ_FAILED(sq_getstring(vm, -2, &result)))
+ if(SQ_FAILED(sq_getstring(vm, -2, &result)))
{
std::ostringstream msg;
msg << "Couldn't get string value for key";
{
//here -1 is the value and -2 is the key
const char* result;
- if(SQ_FAILED(sq_getstring(vm, -2, &result)))
+ if(SQ_FAILED(sq_getstring(vm, -2, &result)))
{
std::ostringstream msg;
msg << "Couldn't get string value";
} // namespace
+LevelState
+LevelsetState::get_level_state(const std::string& filename)
+{
+ auto it = std::find_if(level_states.begin(), level_states.end(),
+ [filename](const LevelState& state)
+ {
+ return state.filename == filename;
+ });
+ if (it != level_states.end())
+ {
+ return *it;
+ }
+ else
+ {
+ log_warning << "failed to retrieve level state for " << filename << std::endl;
+ LevelState state;
+ state.filename = filename;
+ return state;
+ }
+}
+
Savegame::Savegame(const std::string& filename) :
m_filename(filename),
m_player_status(new PlayerStatus)
return;
}
+ clear_state_table();
+
if(!PHYSFS_exists(m_filename.c_str()))
{
log_info << m_filename << ": doesn't exist, not loading state" << std::endl;
}
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);
+ get_table_entry(vm, "state");
- // create a new empty state table
- sq_pushstring(vm, "state", -1);
- sq_newtable(vm);
scripting::load_squirrel_table(vm, -1, *state);
if(SQ_FAILED(sq_createslot(vm, -3)))
+ {
+ sq_pop(vm, 1);
throw std::runtime_error("Couldn't create state table");
+ }
sq_pop(vm, 1);
}
}
}
void
+Savegame::clear_state_table()
+{
+ HSQUIRRELVM vm = scripting::global_vm;
+
+ // 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);
+ if(SQ_FAILED(sq_newslot(vm, -3, SQFalse)))
+ {
+ throw std::runtime_error("Couldn't create state table");
+ }
+ }
+ sq_pop(vm, 1);
+}
+
+void
Savegame::save()
{
if (m_filename.empty())
{}
std::string directory;
std::vector<LevelState> level_states;
+
+ LevelState get_level_state(const std::string& filename);
};
struct WorldmapState
void load();
private:
+ void clear_state_table();
+
+private:
Savegame(const Savegame&) = delete;
Savegame& operator=(const Savegame&) = delete;
};