X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Fworldmap%2Fworldmap.cpp;h=946b21f178c246f86be5abcdd36accbb8fcaf29a;hb=c62711567861587107d124642db29e2674ee6533;hp=39c2526f330411ec6b11cb0b605f79a5d885ca9e;hpb=fc73efa7ff699fe3c9c237845b6f4fda0d999862;p=supertux.git diff --git a/src/worldmap/worldmap.cpp b/src/worldmap/worldmap.cpp index 39c2526f3..946b21f17 100644 --- a/src/worldmap/worldmap.cpp +++ b/src/worldmap/worldmap.cpp @@ -33,8 +33,8 @@ #include "gettext.hpp" #include "log.hpp" #include "mainloop.hpp" +#include "shrinkfade.hpp" #include "video/surface.hpp" -#include "video/screen.hpp" #include "video/drawing_context.hpp" #include "sprite/sprite_manager.hpp" #include "audio/sound_manager.hpp" @@ -58,10 +58,9 @@ #include "control/joystickkeyboardcontroller.hpp" #include "object/background.hpp" #include "object/tilemap.hpp" -#include "script_manager.hpp" #include "options_menu.hpp" #include "scripting/squirrel_error.hpp" -#include "scripting/wrapper_util.hpp" +#include "scripting/squirrel_util.hpp" #include "worldmap/level.hpp" #include "worldmap/special_tile.hpp" #include "worldmap/tux.hpp" @@ -155,6 +154,14 @@ WorldMap::WorldMap(const std::string& filename) WorldMap::~WorldMap() { + using namespace Scripting; + + for(ScriptList::iterator i = scripts.begin(); + i != scripts.end(); ++i) { + HSQOBJECT& object = *i; + sq_release(global_vm, &object); + } + if(current_ == this) current_ = NULL; @@ -211,7 +218,7 @@ WorldMap::load(const std::string& filename) SpawnPoint* sp = new SpawnPoint(iter.lisp()); spawn_points.push_back(sp); } else if(iter.item() == "level") { - Level* level = new Level(levels_path, iter.lisp()); + LevelTile* level = new LevelTile(levels_path, iter.lisp()); levels.push_back(level); game_objects.push_back(level); } else if(iter.item() == "special-tile") { @@ -251,7 +258,7 @@ WorldMap::load(const std::string& filename) } void -WorldMap::get_level_title(Level& level) +WorldMap::get_level_title(LevelTile& level) { /** get special_tile's title */ level.title = ""; @@ -274,8 +281,8 @@ WorldMap::get_level_title(Level& level) void WorldMap::calculate_total_stats() { total_stats.reset(); - for(Levels::iterator i = levels.begin(); i != levels.end(); ++i) { - Level* level = *i; + for(LevelTiles::iterator i = levels.begin(); i != levels.end(); ++i) { + LevelTile* level = *i; if (level->solved) { total_stats += level->statistics; } @@ -354,18 +361,17 @@ WorldMap::path_ok(Direction direction, const Vector& old_pos, Vector* new_pos) } void -WorldMap::finished_level(const std::string& filename) +WorldMap::finished_level(Level* gamelevel) { - // TODO calculate level from filename? - (void) filename; - Level* level = at_level(); + // TODO use Level* parameter here? + LevelTile* level = at_level(); bool old_level_state = level->solved; level->solved = true; level->sprite->set_action("solved"); // deal with statistics - level->statistics.merge(global_stats); + level->statistics.merge(gamelevel->stats); calculate_total_stats(); save_state(); @@ -404,10 +410,8 @@ WorldMap::finished_level(const std::string& filename) if (level->extro_script != "") { try { - HSQUIRRELVM vm = ScriptManager::instance->create_thread(); - std::istringstream in(level->extro_script); - Scripting::compile_and_run(vm, in, "worldmap,extro_script"); + run_script(in, "worldmap:extro_script"); } catch(std::exception& e) { log_fatal << "Couldn't run level-extro-script: " << e.what() << std::endl; } @@ -496,20 +500,19 @@ WorldMap::update(float delta) } /* Check level action */ - Level* level = at_level(); + LevelTile* level = at_level(); if (!level) { log_warning << "No level to enter at: " << tux->get_tile_pos().x << ", " << tux->get_tile_pos().y << std::endl; return; } if (level->pos == tux->get_tile_pos()) { - // do a shriking fade to the level - shrink_fade(Vector((level->pos.x*32 + 16 + camera_offset.x), - (level->pos.y*32 + 16 + camera_offset.y)), 500); - try { - main_loop->push_screen(new GameSession( - levels_path + level->name, &level->statistics)); + Vector shrinkpos = Vector(level->pos.x*32 + 16 - camera_offset.x, + level->pos.y*32 + 16 - camera_offset.y); + std::string levelfile = levels_path + level->name; + main_loop->push_screen(new GameSession(levelfile, &level->statistics), + new ShrinkFade(shrinkpos, 0.5)); } catch(std::exception& e) { log_fatal << "Couldn't load level: " << e.what() << std::endl; } @@ -527,11 +530,11 @@ WorldMap::at(Vector p) return solids->get_tile((int) p.x, (int) p.y); } -Level* +LevelTile* WorldMap::at_level() { - for(Levels::iterator i = levels.begin(); i != levels.end(); ++i) { - Level* level = *i; + for(LevelTiles::iterator i = levels.begin(); i != levels.end(); ++i) { + LevelTile* level = *i; if (level->pos == tux->get_tile_pos()) return level; } @@ -590,8 +593,8 @@ WorldMap::draw_status(DrawingContext& context) player_status->draw(context); if (!tux->is_moving()) { - for(Levels::iterator i = levels.begin(); i != levels.end(); ++i) { - Level* level = *i; + for(LevelTiles::iterator i = levels.begin(); i != levels.end(); ++i) { + LevelTile* level = *i; if (level->pos == tux->get_tile_pos()) { if(level->title == "") @@ -739,7 +742,9 @@ static bool read_bool(HSQUIRRELVM vm, const char* name) void WorldMap::save_state() { - HSQUIRRELVM vm = ScriptManager::instance->get_vm(); + using namespace Scripting; + + HSQUIRRELVM vm = global_vm; int oldtop = sq_gettop(vm); try { @@ -784,8 +789,8 @@ WorldMap::save_state() sq_pushstring(vm, "levels", -1); sq_newtable(vm); - for(Levels::iterator i = levels.begin(); i != levels.end(); ++i) { - Level* level = *i; + for(LevelTiles::iterator i = levels.begin(); i != levels.end(); ++i) { + LevelTile* level = *i; if (level->solved) { sq_pushstring(vm, level->name.c_str(), -1); @@ -813,7 +818,9 @@ WorldMap::save_state() void WorldMap::load_state() { - HSQUIRRELVM vm = ScriptManager::instance->get_vm(); + using namespace Scripting; + + HSQUIRRELVM vm = global_vm; int oldtop = sq_gettop(vm); try { @@ -852,8 +859,8 @@ WorldMap::load_state() if(SQ_FAILED(sq_get(vm, -2))) throw Scripting::SquirrelError(vm, "Couldn't get levels"); - for(Levels::iterator i = levels.begin(); i != levels.end(); ++i) { - Level* level = *i; + for(LevelTiles::iterator i = levels.begin(); i != levels.end(); ++i) { + LevelTile* level = *i; sq_pushstring(vm, level->name.c_str(), -1); if(SQ_SUCCEEDED(sq_get(vm, -2))) { level->solved = read_bool(vm, "solved"); @@ -880,8 +887,8 @@ size_t WorldMap::solved_level_count() { size_t count = 0; - for(Levels::iterator i = levels.begin(); i != levels.end(); ++i) { - Level* level = *i; + for(LevelTiles::iterator i = levels.begin(); i != levels.end(); ++i) { + LevelTile* level = *i; if(level->solved) count++; @@ -889,5 +896,35 @@ WorldMap::solved_level_count() return count; } - + +HSQUIRRELVM +WorldMap::run_script(std::istream& in, const std::string& sourcename) +{ + using namespace Scripting; + + // garbage collect thread list + for(ScriptList::iterator i = scripts.begin(); + i != scripts.end(); ) { + HSQOBJECT& object = *i; + HSQUIRRELVM vm = object_to_vm(object); + + if(sq_getvmstate(vm) != SQ_VMSTATE_SUSPENDED) { + sq_release(global_vm, &object); + i = scripts.erase(i); + continue; + } + + ++i; + } + + HSQOBJECT object = create_thread(global_vm); + scripts.push_back(object); + + HSQUIRRELVM vm = object_to_vm(object); + + compile_and_run(vm, in, sourcename); + + return vm; +} + } // namespace WorldMapNS