Skip to content

Commit

Permalink
Display number of solved levels in ContribMenu, kind of ugly patch, s…
Browse files Browse the repository at this point in the history
…ave system needs a refactor
  • Loading branch information
Grumbel committed Aug 10, 2014
1 parent 094e387 commit fb4786d
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 7 deletions.
20 changes: 18 additions & 2 deletions src/supertux/menu/contrib_menu.cpp
Expand Up @@ -17,13 +17,16 @@
#include "supertux/menu/contrib_menu.hpp"

#include <physfs.h>
#include <sstream>

#include "gui/menu_manager.hpp"
#include "supertux/game_manager.hpp"
#include "supertux/gameconfig.hpp"
#include "supertux/menu/contrib_world_menu.hpp"
#include "supertux/menu/menu_storage.hpp"
#include "supertux/title_screen.hpp"
#include "supertux/world.hpp"
#include "util/file_system.hpp"
#include "util/gettext.hpp"

ContribMenu::ContribMenu() :
Expand All @@ -47,11 +50,24 @@ ContribMenu::ContribMenu() :
{
try
{
std::unique_ptr<World> world (new World());
std::unique_ptr<World> world (new World);

world->load(*it + "/info");

if (!world->hide_from_contribs)
{
add_entry(i++, world->get_title());
{ // FIXME: yuck, this should be easier
std::ostringstream stream;
std::string worlddirname = FileSystem::basename(*it);
stream << "profile" << g_config->profile << "/" << worlddirname << ".stsg";
std::string slotfile = stream.str();
world->set_savegame_filename(stream.str());
world->load_state();
}

std::ostringstream title;
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));
}
}
Expand Down
87 changes: 83 additions & 4 deletions src/supertux/world.cpp
Expand Up @@ -34,6 +34,7 @@
World* World::current_ = NULL;

World::World() :
worldname(),
levels(),
basedir(),
savegame_filename(),
Expand Down Expand Up @@ -85,6 +86,7 @@ void
World::load(const std::string& filename)
{
basedir = FileSystem::dirname(filename);
worldname = basedir + "worldmap.stwm";

lisp::Parser parser;
const lisp::Lisp* root = parser.parse(filename);
Expand Down Expand Up @@ -115,12 +117,19 @@ World::load(const std::string& filename)

for(const char* const* filename = files; *filename != 0; ++filename) {
if(StringUtil::has_suffix(*filename, ".stl")) {
levels.push_back(path + *filename);
Level level;
level.fullpath = path + *filename;
level.name = *filename;
levels.push_back(level);
}
}
PHYSFS_freeList(files);

std::sort(levels.begin(), levels.end(), StringUtil::numeric_less);
std::sort(levels.begin(), levels.end(),
[](const Level& lhs, const Level& rhs)
{
return StringUtil::numeric_less(lhs.fullpath, rhs.fullpath);
});
}

void
Expand Down Expand Up @@ -197,7 +206,12 @@ World::load_state()
{
using namespace scripting;

if(PHYSFS_exists(savegame_filename.c_str())) {
if(!PHYSFS_exists(savegame_filename.c_str()))
{
log_info << savegame_filename << ": doesn't exist, not loading state" << std::endl;
}
else
{
try {
lisp::Parser parser;
const lisp::Lisp* root = parser.parse(savegame_filename);
Expand Down Expand Up @@ -240,7 +254,7 @@ World::load_state()
const std::string&
World::get_level_filename(unsigned int i) const
{
return levels[i];
return levels[i].fullpath;
}

unsigned int
Expand All @@ -249,6 +263,71 @@ World::get_num_levels() const
return 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, worldname.c_str(), -1);
if(SQ_FAILED(sq_get(vm, -2)))
{
log_warning << "failed to get state.worlds['" << worldname << "']" << std::endl;
}
else
{
sq_pushstring(vm, "levels", -1);
if(SQ_FAILED(sq_get(vm, -2)))
{
log_warning << "failed to get state.worlds['" << worldname << "'].levels" << std::endl;
}
else
{
for(auto level : levels)
{
sq_pushstring(vm, level.name.c_str(), -1);
if(SQ_FAILED(sq_get(vm, -2)))
{
log_warning << "failed to get state.worlds['" << worldname << "'].levels['"
<< level.name << "']" << 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;
}

const std::string&
World::get_basedir() const
{
Expand Down
10 changes: 9 additions & 1 deletion src/supertux/world.hpp
Expand Up @@ -45,6 +45,7 @@ class World
void load_state();

unsigned int get_num_levels() const;
int get_num_solved_levels() const;

const std::string& get_level_filename(unsigned int i) const;
const std::string& get_basedir() const;
Expand All @@ -55,7 +56,14 @@ class World
void run();

private:
std::vector<std::string> levels;
std::string worldname;
struct Level
{
std::string fullpath;
std::string name;
};

std::vector<Level> levels;
std::string basedir;
std::string savegame_filename;
/// squirrel table that saves persistent state (about the world)
Expand Down

0 comments on commit fb4786d

Please sign in to comment.