X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fsupertux%2Fsavegame.cpp;h=f6f456a03fc1b6fd84b3334e80a31a5f9c2af5e8;hb=05d168f5e5bbd46e44b1b1ad857d2d8c59b230c1;hp=34738c4810442acb0676f1c53c49a5475b93758b;hpb=8c15498863fba06e554f72e8b7fad16e99c6c3d4;p=supertux.git diff --git a/src/supertux/savegame.cpp b/src/supertux/savegame.cpp index 34738c481..f6f456a03 100644 --- a/src/supertux/savegame.cpp +++ b/src/supertux/savegame.cpp @@ -17,13 +17,15 @@ #include "supertux/savegame.hpp" +#include + #include "lisp/lisp.hpp" #include "lisp/parser.hpp" #include "lisp/writer.hpp" #include "physfs/ifile_streambuf.hpp" +#include "scripting/scripting.hpp" #include "scripting/serialize.hpp" #include "scripting/squirrel_util.hpp" -#include "scripting/squirrel_util.hpp" #include "supertux/player_status.hpp" #include "util/file_system.hpp" #include "util/log.hpp" @@ -44,6 +46,28 @@ void get_table_entry(HSQUIRRELVM vm, const std::string& name) } } +void get_or_create_table_entry(HSQUIRRELVM vm, const std::string& name) +{ + sq_pushstring(vm, name.c_str(), -1); + if(SQ_FAILED(sq_get(vm, -2))) + { + sq_pushstring(vm, name.c_str(), -1); + sq_newtable(vm); + if(SQ_FAILED(sq_createslot(vm, -3))) + { + throw std::runtime_error("failed to create '" + name + "' table entry"); + } + else + { + get_table_entry(vm, name); + } + } + else + { + // successfully placed result on stack + } +} + std::vector get_table_keys(HSQUIRRELVM vm) { std::vector worlds; @@ -105,6 +129,24 @@ std::vector get_level_states(HSQUIRRELVM vm) } // namespace +void +LevelsetState::store_level_state(const LevelState& in_state) +{ + auto it = std::find_if(level_states.begin(), level_states.end(), + [&in_state](const LevelState& state) + { + return state.filename == in_state.filename; + }); + if (it != level_states.end()) + { + *it = in_state; + } + else + { + level_states.push_back(in_state); + } +} + LevelState LevelsetState::get_level_state(const std::string& filename) { @@ -195,14 +237,8 @@ Savegame::load() { sq_pushroottable(vm); get_table_entry(vm, "state"); - 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); + sq_pop(vm, 2); } } } @@ -222,16 +258,10 @@ Savegame::clear_state_table() // 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))) + if(SQ_FAILED(sq_createslot(vm, -3))) { throw std::runtime_error("Couldn't create state table"); } @@ -386,7 +416,7 @@ Savegame::get_levelsets() } LevelsetState -Savegame::get_levelset_state(const std::string& name) +Savegame::get_levelset_state(const std::string& basedir) { LevelsetState result; @@ -398,7 +428,7 @@ Savegame::get_levelset_state(const std::string& name) sq_pushroottable(vm); get_table_entry(vm, "state"); get_table_entry(vm, "levelsets"); - get_table_entry(vm, name); + get_table_entry(vm, basedir); get_table_entry(vm, "levels"); result.level_states = get_level_states(vm); @@ -413,4 +443,35 @@ Savegame::get_levelset_state(const std::string& name) return result; } +void +Savegame::set_levelset_state(const std::string& basedir, + const std::string& level_filename, + bool solved) +{ + LevelsetState state = get_levelset_state(basedir); + + HSQUIRRELVM vm = scripting::global_vm; + int oldtop = sq_gettop(vm); + + try + { + sq_pushroottable(vm); + get_table_entry(vm, "state"); + get_or_create_table_entry(vm, "levelsets"); + get_or_create_table_entry(vm, basedir); + get_or_create_table_entry(vm, "levels"); + get_or_create_table_entry(vm, level_filename); + + bool old_solved = false; + scripting::get_bool(vm, "solved", old_solved); + scripting::store_bool(vm, "solved", solved || old_solved); + } + catch(const std::exception& err) + { + log_warning << err.what() << std::endl; + } + + sq_settop(vm, oldtop); +} + /* EOF */