Skip to content

Commit

Permalink
Some initial work on getting load/save working for Levelsets
Browse files Browse the repository at this point in the history
load() should work, save() not yet, as there is nobody updating the state after completing a level
  • Loading branch information
Grumbel committed Aug 14, 2014
1 parent c161b88 commit 8c15498
Show file tree
Hide file tree
Showing 12 changed files with 129 additions and 42 deletions.
12 changes: 5 additions & 7 deletions src/supertux/game_manager.cpp
Expand Up @@ -44,17 +44,15 @@ GameManager::~GameManager()
}

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
Expand Down
2 changes: 1 addition & 1 deletion src/supertux/game_manager.hpp
Expand Up @@ -35,7 +35,7 @@ class GameManager : public Currenton<GameManager>
~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;

Expand Down
6 changes: 6 additions & 0 deletions src/supertux/game_session.cpp
Expand Up @@ -406,6 +406,12 @@ GameSession::setup()
}
}

void
GameSession::leave()
{
m_savegame.save();
}

void
GameSession::update(float elapsed_time)
{
Expand Down
3 changes: 2 additions & 1 deletion src/supertux/game_session.hpp
Expand Up @@ -52,7 +52,8 @@ class GameSession : public Screen,

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);
Expand Down
6 changes: 6 additions & 0 deletions src/supertux/levelset.cpp
Expand Up @@ -51,4 +51,10 @@ Levelset::get_num_levels() const
return static_cast<int>(m_levels.size());
}

std::string
Levelset::get_level_filename(int i) const
{
return m_levels[i];
}

/* EOF */
1 change: 1 addition & 0 deletions src/supertux/levelset.hpp
Expand Up @@ -30,6 +30,7 @@ class Levelset
Levelset(const std::string& basedir);

int get_num_levels() const;
std::string get_level_filename(int i) const;

private:
Levelset(const Levelset&) = delete;
Expand Down
Expand Up @@ -14,49 +14,73 @@
// 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 "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"

ContribWorldMenu::ContribWorldMenu(std::unique_ptr<World> world) :
m_world(std::move(world))
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();

#ifdef GRUMBEL
for (int i = 0; i < m_world->get_num_levels(); ++i)
for (int i = 0; i < m_levelset->get_num_levels(); ++i)
{
/** get level's title */
std::string filename = m_world->get_level_filename(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);
add_entry(i, title);
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());
}
#endif

add_hl();
add_back(_("Back"));
}

void
ContribWorldMenu::check_menu()
ContribLevelsetMenu::check_menu()
{
int index = check();
if (index != -1) {
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

// 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));
}
}
}
Expand Down
Expand Up @@ -19,21 +19,23 @@

#include "gui/menu.hpp"

class Levelset;
class World;

class ContribWorldMenu : public Menu
class ContribLevelsetMenu : public Menu
{
private:
std::unique_ptr<World> m_world;
std::unique_ptr<Levelset> m_levelset;

public:
ContribWorldMenu(std::unique_ptr<World> current_world);
ContribLevelsetMenu(std::unique_ptr<World> current_world);

void check_menu();

private:
ContribWorldMenu(const ContribWorldMenu&);
ContribWorldMenu& operator=(const ContribWorldMenu&);
ContribLevelsetMenu(const ContribLevelsetMenu&);
ContribLevelsetMenu& operator=(const ContribLevelsetMenu&);
};

#endif
Expand Down
8 changes: 4 additions & 4 deletions src/supertux/menu/contrib_menu.cpp
Expand Up @@ -22,7 +22,7 @@
#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"
Expand Down Expand Up @@ -71,7 +71,7 @@ ContribMenu::ContribMenu() :
}
level_count += 1;
}

std::ostringstream title;
title << "[" << world->get_title() << "]";
if (level_count == 0)
Expand Down Expand Up @@ -99,7 +99,7 @@ ContribMenu::ContribMenu() :
}
level_count += 1;
}

std::ostringstream title;
title << world->get_title();
if (level_count == 0)
Expand Down Expand Up @@ -148,7 +148,7 @@ ContribMenu::check_menu()
}
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))));
}
}
}
Expand Down
1 change: 0 additions & 1 deletion src/supertux/menu/menu_storage.cpp
Expand Up @@ -19,7 +19,6 @@
#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"
Expand Down
65 changes: 55 additions & 10 deletions src/supertux/savegame.cpp
Expand Up @@ -41,7 +41,7 @@ void get_table_entry(HSQUIRRELVM vm, const std::string& name)
else
{
// successfully placed result on stack
}
}
}

std::vector<std::string> get_table_keys(HSQUIRRELVM vm)
Expand All @@ -53,7 +53,7 @@ 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";
Expand All @@ -80,7 +80,7 @@ std::vector<LevelState> get_level_states(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";
Expand All @@ -105,6 +105,27 @@ std::vector<LevelState> get_level_states(HSQUIRRELVM vm)

} // 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)
Expand All @@ -124,6 +145,8 @@ Savegame::load()
return;
}

clear_state_table();

if(!PHYSFS_exists(m_filename.c_str()))
{
log_info << m_filename << ": doesn't exist, not loading state" << std::endl;
Expand Down Expand Up @@ -170,18 +193,15 @@ Savegame::load()
}
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);
}
}
Expand All @@ -194,6 +214,31 @@ Savegame::load()
}
}

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()
{
Expand Down
5 changes: 5 additions & 0 deletions src/supertux/savegame.hpp
Expand Up @@ -47,6 +47,8 @@ struct LevelsetState
{}
std::string directory;
std::vector<LevelState> level_states;

LevelState get_level_state(const std::string& filename);
};

struct WorldmapState
Expand Down Expand Up @@ -115,6 +117,9 @@ class Savegame
void save();
void load();

private:
void clear_state_table();

private:
Savegame(const Savegame&) = delete;
Savegame& operator=(const Savegame&) = delete;
Expand Down

0 comments on commit 8c15498

Please sign in to comment.