X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Fworldmap%2Fworldmap.cpp;h=b34e881edd2b453623a32fc3b2e15751ae12a63d;hb=d84d73b701cc7fa2bd74f3490b9be1bf8b6f705a;hp=7f841b8f4103e84a38bff750cf34acab513b40a7;hpb=f81231933de4e2f826bd12a1433e1cef9a7fd71b;p=supertux.git diff --git a/src/worldmap/worldmap.cpp b/src/worldmap/worldmap.cpp index 7f841b8f4..b34e881ed 100644 --- a/src/worldmap/worldmap.cpp +++ b/src/worldmap/worldmap.cpp @@ -128,8 +128,8 @@ string_to_direction(const std::string& directory) //--------------------------------------------------------------------------- -WorldMap::WorldMap(const std::string& filename) - : tux(0), solids(0) +WorldMap::WorldMap(const std::string& filename, const std::string& force_spawnpoint) + : tux(0), solids(0), force_spawnpoint(force_spawnpoint) { tile_manager.reset(new TileManager("images/worldmap.strf")); @@ -185,8 +185,10 @@ WorldMap::~WorldMap() current_ = NULL; for(GameObjects::iterator i = game_objects.begin(); - i != game_objects.end(); ++i) - delete *i; + i != game_objects.end(); ++i) { + GameObject* object = *i; + object->unref(); + } for(SpawnPoints::iterator i = spawn_points.begin(); i != spawn_points.end(); ++i) { @@ -202,10 +204,35 @@ WorldMap::add_object(GameObject* object) solids = tilemap; } + object->ref(); game_objects.push_back(object); } void +WorldMap::move_to_spawnpoint(const std::string& spawnpoint) +{ + for(SpawnPoints::iterator i = spawn_points.begin(); i != spawn_points.end(); ++i) { + SpawnPoint* sp = *i; + if(sp->name == spawnpoint) { + Vector p = sp->pos; + tux->set_tile_pos(p); + return; + } + } + log_warning << "Spawnpoint '" << spawnpoint << "' not found." << std::endl; + if (spawnpoint != "main") { + move_to_spawnpoint("main"); + } +} + +void +WorldMap::change(const std::string& filename, const std::string& force_spawnpoint) +{ + main_loop->exit_screen(); + main_loop->push_screen(new WorldMap(filename, force_spawnpoint)); +} + +void WorldMap::load(const std::string& filename) { map_filename = filename; @@ -241,15 +268,19 @@ WorldMap::load(const std::string& filename) } else if(iter.item() == "level") { LevelTile* level = new LevelTile(levels_path, iter.lisp()); levels.push_back(level); - game_objects.push_back(level); + add_object(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); + add_object(special_tile); } 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); + add_object(sprite_change); + } else if(iter.item() == "teleporter") { + Teleporter* teleporter = new Teleporter(iter.lisp()); + teleporters.push_back(teleporter); + add_object(teleporter); } else if(iter.item() == "name") { // skip } else { @@ -259,16 +290,7 @@ WorldMap::load(const std::string& filename) if(solids == 0) throw std::runtime_error("No solid tilemap specified"); - // search for main spawnpoint - for(SpawnPoints::iterator i = spawn_points.begin(); - i != spawn_points.end(); ++i) { - SpawnPoint* sp = *i; - if(sp->name == "main") { - Vector p = sp->pos; - tux->set_tile_pos(p); - break; - } - } + move_to_spawnpoint("main"); } catch(std::exception& e) { std::stringstream msg; @@ -462,9 +484,8 @@ WorldMap::update(float delta) } // update GameObjects - for(GameObjects::iterator i = game_objects.begin(); - i != game_objects.end(); ++i) { - GameObject* object = *i; + for(size_t i = 0; i < game_objects.size(); ++i) { + GameObject* object = game_objects[i]; object->update(delta); } @@ -473,7 +494,7 @@ WorldMap::update(float delta) i != game_objects.end(); ) { GameObject* object = *i; if(!object->is_valid()) { - delete object; + object->unref(); i = game_objects.erase(i); } else { ++i; @@ -503,23 +524,23 @@ WorldMap::update(float delta) enter_level = true; if(main_controller->pressed(Controller::PAUSE_MENU)) on_escape_press(); - + + // check for teleporters + Teleporter* teleporter = at_teleporter(tux->get_tile_pos()); + if (teleporter && (teleporter->automatic || (enter_level && (!tux->is_moving())))) { + enter_level = false; + if (teleporter->worldmap != "") { + change(teleporter->worldmap, teleporter->spawnpoint); + } else { + // TODO: an animation, camera scrolling or a fading would be a nice touch + sound_manager->play("sounds/warp.wav"); + tux->back_direction = D_NONE; + move_to_spawnpoint(teleporter->spawnpoint); + } + } + if (enter_level && !tux->is_moving()) { - /* Check special tile action */ - SpecialTile* special_tile = at_special_tile(); - if(special_tile) - { - if (special_tile->teleport_dest != Vector(-1,-1)) - { - // TODO: an animation, camera scrolling or a fading would be a nice touch - sound_manager->play("sounds/warp.wav"); - tux->back_direction = D_NONE; - tux->set_tile_pos(special_tile->teleport_dest); - SDL_Delay(1000); - } - } - /* Check level action */ LevelTile* level = at_level(); if (!level) { @@ -589,6 +610,17 @@ WorldMap::at_sprite_change(const Vector& pos) return NULL; } +Teleporter* +WorldMap::at_teleporter(const Vector& pos) +{ + for(std::vector::iterator i = teleporters.begin(); i != teleporters.end(); ++i) { + Teleporter* teleporter = *i; + if(teleporter->pos == pos) return teleporter; + } + + return NULL; +} + void WorldMap::draw(DrawingContext& context) { @@ -626,6 +658,19 @@ WorldMap::draw_status(DrawingContext& context) SCREEN_HEIGHT - white_text->get_height() - 30), CENTER_ALLIGN, LAYER_FOREGROUND1); + // if level is solved, draw level picture behind stats + /* + if (level->solved) { + if (const Surface* picture = level->get_picture()) { + Vector pos = Vector(SCREEN_WIDTH - picture->get_width(), SCREEN_HEIGHT - picture->get_height()); + context.push_transform(); + context.set_alpha(0.5); + context.draw_surface(picture, pos, LAYER_FOREGROUND1-1); + context.pop_transform(); + } + } + */ + level->statistics.draw_worldmap_info(context); break; } @@ -645,6 +690,14 @@ WorldMap::draw_status(DrawingContext& context) break; } } + + // display teleporter messages + Teleporter* teleporter = at_teleporter(tux->get_tile_pos()); + if (teleporter && (teleporter->message != "")) { + Vector pos = Vector(SCREEN_WIDTH/2, SCREEN_HEIGHT - white_text->get_height() - 30); + context.draw_text(white_text, teleporter->message, pos, CENTER_ALLIGN, LAYER_FOREGROUND1); + } + } /* Display a passive message in the map, if needed */ @@ -665,6 +718,14 @@ WorldMap::setup() current_ = this; load_state(); + // if force_spawnpoint was set, move Tux there, then clear force_spawnpoint + if (force_spawnpoint != "") { + move_to_spawnpoint(force_spawnpoint); + force_spawnpoint = ""; + } + + tux->setup(); + // register worldmap_table as worldmap in scripting using namespace Scripting;