#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() :
{
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));
}
}
World* World::current_ = NULL;
World::World() :
+ worldname(),
levels(),
basedir(),
savegame_filename(),
World::load(const std::string& filename)
{
basedir = FileSystem::dirname(filename);
+ worldname = basedir + "worldmap.stwm";
lisp::Parser parser;
const lisp::Lisp* root = parser.parse(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
{
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);
const std::string&
World::get_level_filename(unsigned int i) const
{
- return levels[i];
+ return levels[i].fullpath;
}
unsigned int
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
{