X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Fworldmap%2Fworldmap.cpp;h=946b21f178c246f86be5abcdd36accbb8fcaf29a;hb=c62711567861587107d124642db29e2674ee6533;hp=84423f391c8285a4228cdd06c5aafab7790fb84a;hpb=112f01454123c94f5627200c6819b219026f0af0;p=supertux.git diff --git a/src/worldmap/worldmap.cpp b/src/worldmap/worldmap.cpp index 84423f391..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" @@ -46,7 +46,6 @@ #include "sector.hpp" #include "worldmap.hpp" #include "resources.hpp" -#include "misc.hpp" #include "log.hpp" #include "world.hpp" #include "player_status.hpp" @@ -59,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" @@ -130,7 +128,7 @@ string_to_direction(const std::string& directory) //--------------------------------------------------------------------------- -WorldMap::WorldMap() +WorldMap::WorldMap(const std::string& filename) : tux(0), solids(0) { tile_manager.reset(new TileManager("images/worldmap.strf")); @@ -140,7 +138,6 @@ WorldMap::WorldMap() name = ""; music = "music/salcon.ogg"; - intro_displayed = false; total_stats.reset(); @@ -151,14 +148,27 @@ WorldMap::WorldMap() worldmap_menu->add_submenu(_("Options"), get_options_menu()); worldmap_menu->add_hl(); worldmap_menu->add_entry(MNID_QUITWORLDMAP, _("Quit World")); + + load(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; - clear_objects(); + for(GameObjects::iterator i = game_objects.begin(); + i != game_objects.end(); ++i) + delete *i; + for(SpawnPoints::iterator i = spawn_points.begin(); i != spawn_points.end(); ++i) { delete *i; @@ -177,21 +187,9 @@ WorldMap::add_object(GameObject* object) } void -WorldMap::clear_objects() -{ - for(GameObjects::iterator i = game_objects.begin(); - i != game_objects.end(); ++i) - delete *i; - game_objects.clear(); - solids = 0; - tux = new Tux(this); - add_object(tux); -} - -// Don't forget to set map_filename before calling this -void -WorldMap::load_map() +WorldMap::load(const std::string& filename) { + map_filename = filename; levels_path = FileSystem::dirname(map_filename); try { @@ -208,7 +206,6 @@ WorldMap::load_map() if(!sector) throw std::runtime_error("No sector sepcified in worldmap file."); - clear_objects(); lisp::ListIterator iter(sector); while(iter.next()) { if(iter.item() == "tilemap") { @@ -217,20 +214,18 @@ WorldMap::load_map() add_object(new Background(*(iter.lisp()))); } else if(iter.item() == "music") { iter.value()->get(music); - } else if(iter.item() == "intro-script") { - iter.value()->get(intro_script); } else if(iter.item() == "worldmap-spawnpoint") { 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") { SpecialTile* special_tile = new SpecialTile(iter.lisp()); special_tiles.push_back(special_tile); game_objects.push_back(special_tile); - } else if(iter.item() == "spritechange") { + } else if(iter.item() == "sprite-change") { SpriteChange* sprite_change = new SpriteChange(iter.lisp()); sprite_changes.push_back(sprite_change); game_objects.push_back(sprite_change); @@ -263,7 +258,7 @@ WorldMap::load_map() } void -WorldMap::get_level_title(Level& level) +WorldMap::get_level_title(LevelTile& level) { /** get special_tile's title */ level.title = ""; @@ -286,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; } @@ -329,7 +324,7 @@ WorldMap::get_next_tile(Vector pos, Direction direction) } bool -WorldMap::path_ok(Direction direction, Vector old_pos, Vector* new_pos) +WorldMap::path_ok(Direction direction, const Vector& old_pos, Vector* new_pos) { *new_pos = get_next_tile(old_pos, direction); @@ -359,25 +354,24 @@ WorldMap::path_ok(Direction direction, Vector old_pos, Vector* new_pos) && at(*new_pos)->getData() & Tile::WORLDMAP_NORTH); case D_NONE: - assert(!"path_ok() can't work if direction is NONE"); + assert(!"path_ok() can't walk if direction is NONE"); } return false; } } 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(); @@ -416,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; } @@ -508,22 +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 + offset.x), - (level->pos.y*32 + 16 + offset.y)), 500); - try { - GameSession *session = - new GameSession(levels_path + level->name, - ST_GL_LOAD_LEVEL_FILE, &level->statistics); - main_loop->push_screen(session); + 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; } @@ -541,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; } @@ -567,8 +556,15 @@ WorldMap::at_special_tile() } SpriteChange* -WorldMap::at_sprite_change() +WorldMap::at_sprite_change(const Vector& pos) { + for(SpriteChanges::iterator i = sprite_changes.begin(); + i != sprite_changes.end(); ++i) { + SpriteChange* sprite_change = *i; + if(sprite_change->pos == pos) + return sprite_change; + } + return NULL; } @@ -597,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 == "") @@ -746,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 { @@ -791,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); @@ -820,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 { @@ -859,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"); @@ -887,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++; @@ -896,13 +896,35 @@ WorldMap::solved_level_count() return count; } - -void -WorldMap::loadmap(const std::string& filename) + +HSQUIRRELVM +WorldMap::run_script(std::istream& in, const std::string& sourcename) { - savegame_file = ""; - map_filename = filename; - load_map(); -} + 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