X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Fworldmap.cpp;h=7f87ad4aee6e759906fdf4a17accb085c88dec8e;hb=6ed1900da4edf7d7922f7a4626f95a83e34dff82;hp=546db1edd1a62bf108400e7b9138ee7510a2a46e;hpb=e43b147d6a1557b535b035ef5c8c4a3a1cb898f1;p=supertux.git diff --git a/src/worldmap.cpp b/src/worldmap.cpp index 546db1edd..7f87ad4ae 100644 --- a/src/worldmap.cpp +++ b/src/worldmap.cpp @@ -23,18 +23,21 @@ #include #include -#include "globals.h" -#include "screen/surface.h" -#include "screen/screen.h" -#include "screen/drawing_context.h" -#include "lispreader.h" +#include "app/globals.h" +#include "video/surface.h" +#include "video/screen.h" +#include "video/drawing_context.h" +#include "utils/lispreader.h" #include "gameloop.h" -#include "setup.h" +#include "app/setup.h" #include "sector.h" #include "worldmap.h" -#include "sound_manager.h" +#include "audio/sound_manager.h" #include "resources.h" -#include "gettext.h" +#include "app/gettext.h" +#include "misc.h" + +Menu* worldmap_menu = 0; namespace WorldMapNS { @@ -95,7 +98,7 @@ TileManager::TileManager() lisp_object_t* root_obj = lisp_read_from_file(stwt_filename); if (!root_obj) - st_abort("Couldn't load file", stwt_filename); + Termination::abort("Couldn't load file", stwt_filename); if (strcmp(lisp_symbol(lisp_car(root_obj)), "supertux-worldmap-tiles") == 0) { @@ -130,7 +133,7 @@ TileManager::TileManager() tile->sprite = new Surface( datadir + "/images/worldmap/" + filename, - USE_ALPHA); + true); if (id >= int(tiles.size())) tiles.resize(id+1); @@ -171,14 +174,14 @@ TileManager::get(int i) Tux::Tux(WorldMap* worldmap_) : worldmap(worldmap_) { - largetux_sprite = new Surface(datadir + "/images/worldmap/tux.png", USE_ALPHA); - firetux_sprite = new Surface(datadir + "/images/worldmap/firetux.png", USE_ALPHA); - smalltux_sprite = new Surface(datadir + "/images/worldmap/smalltux.png", USE_ALPHA); + largetux_sprite = new Surface(datadir + "/images/worldmap/tux.png", true); + firetux_sprite = new Surface(datadir + "/images/worldmap/firetux.png", true); + smalltux_sprite = new Surface(datadir + "/images/worldmap/smalltux.png", true); offset = 0; moving = false; - tile_pos.x = 4; - tile_pos.y = 5; + tile_pos.x = worldmap->get_start_x(); + tile_pos.y = worldmap->get_start_y(); direction = D_NONE; input_direction = D_NONE; } @@ -349,19 +352,22 @@ Tile::~Tile() WorldMap::WorldMap() { tile_manager = new TileManager(); - tux = new Tux(this); - + //tux = new Tux(this); + width = 20; height = 15; - - level_sprite = new Surface(datadir + "/images/worldmap/levelmarker.png", USE_ALPHA); - leveldot_green = new Surface(datadir + "/images/worldmap/leveldot_green.png", USE_ALPHA); - leveldot_red = new Surface(datadir + "/images/worldmap/leveldot_red.png", USE_ALPHA); + + start_x = 4; + start_y = 5; + + level_sprite = new Surface(datadir + "/images/worldmap/levelmarker.png", true); + leveldot_green = new Surface(datadir + "/images/worldmap/leveldot_green.png", true); + leveldot_red = new Surface(datadir + "/images/worldmap/leveldot_red.png", true); input_direction = D_NONE; enter_level = false; - name = ""; + name = ""; music = "SALCON.MOD"; } @@ -378,11 +384,9 @@ WorldMap::~WorldMap() void WorldMap::load_map() { - std::cout << "Loading map: " << datadir + "/levels/worldmap/" + map_filename << std::endl; - lisp_object_t* root_obj = lisp_read_from_file(datadir + "/levels/worldmap/" + map_filename); if (!root_obj) - st_abort("Couldn't load file", datadir + "/levels/worldmap/" + map_filename); + Termination::abort("Couldn't load file", datadir + "/levels/worldmap/" + map_filename); if (strcmp(lisp_symbol(lisp_car(root_obj)), "supertux-worldmap") == 0) { @@ -404,6 +408,8 @@ WorldMap::load_map() LispReader reader(lisp_cdr(element)); reader.read_string("name", name, true); reader.read_string("music", music); + reader.read_int("start_pos_x", start_x); + reader.read_int("start_pos_y", start_y); } else if (strcmp(lisp_symbol(lisp_car(element)), "levels") == 0) { @@ -412,8 +418,39 @@ WorldMap::load_map() while(!lisp_nil_p(cur)) { lisp_object_t* element = lisp_car(cur); - - if (strcmp(lisp_symbol(lisp_car(element)), "level") == 0) + + if (strcmp(lisp_symbol(lisp_car(element)), "special-tile") == 0) + { + Level level; + LispReader reader(lisp_cdr(element)); + level.solved = false; + + level.north = true; + level.east = true; + level.south = true; + level.west = true; + + reader.read_string("extro-filename", level.extro_filename); + reader.read_string("map-message", level.display_map_message); + reader.read_string("next-world", level.next_worldmap); + reader.read_string("level", level.name, true); + reader.read_int("x", level.x); + reader.read_int("y", level.y); + level.auto_path = true; + reader.read_bool("auto-path", level.auto_path); + level.swap_x = level.swap_y = -1; + reader.read_int("swap-x", level.swap_x); + reader.read_int("swap-y", level.swap_y); + level.vertical_flip = false; + reader.read_bool("flip-level", level.vertical_flip); + level.quit_worldmap = false; + reader.read_bool("exit-game", level.quit_worldmap); + + levels.push_back(level); + } + + /* Kept for backward compability */ + else if (strcmp(lisp_symbol(lisp_car(element)), "level") == 0) { Level level; LispReader reader(lisp_cdr(element)); @@ -425,11 +462,13 @@ WorldMap::load_map() level.west = true; reader.read_string("extro-filename", level.extro_filename); + if(!level.extro_filename.empty()) + level.quit_worldmap = true; reader.read_string("name", level.name, true); reader.read_int("x", level.x); reader.read_int("y", level.y); level.vertical_flip = false; - reader.read_bool("flip", level.vertical_flip); + level.swap_x = level.swap_y = -1; levels.push_back(level); } @@ -447,6 +486,7 @@ WorldMap::load_map() } lisp_free(root_obj); + tux = new Tux(this); } void WorldMap::get_level_title(Level& level) @@ -454,33 +494,15 @@ void WorldMap::get_level_title(Level& level) /** get level's title */ level.title = ""; - FILE * fi; - lisp_object_t* root_obj = 0; - fi = fopen((datadir + "/levels/" + level.name).c_str(), "r"); - if (fi == NULL) - { - perror((datadir + "/levels/" + level.name).c_str()); + LispReader* reader = LispReader::load(datadir + "/levels/" + level.name, "supertux-level"); + if(!reader) + { + std::cerr << "Error: Could not open level file. Ignoring...\n"; return; - } - - lisp_stream_t stream; - lisp_stream_init_file (&stream, fi); - root_obj = lisp_read (&stream); - - if (root_obj->type == LISP_TYPE_EOF || root_obj->type == LISP_TYPE_PARSE_ERROR) - { - printf("World: Parse Error in file %s", level.name.c_str()); - } - - if (strcmp(lisp_symbol(lisp_car(root_obj)), "supertux-level") == 0) - { - LispReader reader(lisp_cdr(root_obj)); - reader.read_string("name", level.title, true); - } - - lisp_free(root_obj); + } - fclose(fi); + reader->read_string("name", level.title, true); + delete reader; } void @@ -511,7 +533,7 @@ WorldMap::get_input() switch(event.type) { case SDL_QUIT: - st_abort("Received window close", ""); + Termination::abort("Received window close", ""); break; case SDL_KEYDOWN: @@ -635,8 +657,17 @@ WorldMap::update(float delta) { if (enter_level && !tux->is_moving()) { + bool level_finished = true; Level* level = at_level(); - if (level) + if (!level) + { + std::cout << "Nothing to enter at: " + << tux->get_tile_pos().x << ", " << tux->get_tile_pos().y << std::endl; + return; + } + + + if(!level->name.empty()) { if (level->x == tux->get_tile_pos().x && level->y == tux->get_tile_pos().y) @@ -654,6 +685,7 @@ WorldMap::update(float delta) { case GameSession::ES_LEVEL_FINISHED: { + level_finished = true; bool old_level_state = level->solved; level->solved = true; @@ -665,7 +697,7 @@ WorldMap::update(float delta) else player_status.bonus = PlayerStatus::NO_BONUS; - if (old_level_state != level->solved) + if (old_level_state != level->solved && level->auto_path) { // Try to detect the next direction to which we should walk // FIXME: Mostly a hack Direction dir = D_NONE; @@ -689,32 +721,22 @@ WorldMap::update(float delta) std::cout << "Walk to dir: " << dir << std::endl; } - - if (!level->extro_filename.empty()) - { - MusicRef theme = - sound_manager->load_music(datadir + "/music/theme.mod"); - sound_manager->play_music(theme); - // Display final credits and go back to the main menu - display_text_file(level->extro_filename, - "/images/background/extro.jpg", SCROLL_SPEED_MESSAGE); - display_text_file("CREDITS", - "/images/background/oiltux.jpg", SCROLL_SPEED_CREDITS); - quit = true; - } } break; case GameSession::ES_LEVEL_ABORT: + level_finished = false; /* In case the player's abort the level, keep it using the old status. But the minimum lives and no bonus. */ player_status.score = old_player_status.score; player_status.distros = old_player_status.distros; player_status.lives = std::min(old_player_status.lives, player_status.lives); player_status.bonus = player_status.NO_BONUS; + break; case GameSession::ES_GAME_OVER: - { + { + level_finished = false; /* draw an end screen */ /* in the future, this should make a dialog a la SuperMario, asking if the player wants to restart the world map with no score and from @@ -722,7 +744,7 @@ WorldMap::update(float delta) char str[80]; DrawingContext context; - context.draw_gradient(Color (0, 255, 0), Color (255, 0, 255), + context.draw_gradient(Color (200,240,220), Color(200,200,220), LAYER_BACKGROUND0); context.draw_text_center(blue_text, _("GAMEOVER"), @@ -730,7 +752,7 @@ WorldMap::update(float delta) sprintf(str, _("SCORE: %d"), player_status.score); context.draw_text_center(gold_text, str, - Vector(0, 224), LAYER_FOREGROUND1); + Vector(0, 230), LAYER_FOREGROUND1); sprintf(str, _("COINS: %d"), player_status.distros); context.draw_text_center(gold_text, str, @@ -744,24 +766,40 @@ WorldMap::update(float delta) quit = true; player_status.reset(); break; - } + } case GameSession::ES_NONE: assert(false); // Should never be reached break; } - sound_manager->play_music(song); + SoundManager::get()->play_music(song); Menu::set_current(0); if (!savegame_file.empty()) savegame(savegame_file); - return; } } - else + /* The porpose of the next checking is that if the player lost + the level (in case there is one), don't show anything */ + if(level_finished) { - std::cout << "Nothing to enter at: " - << tux->get_tile_pos().x << ", " << tux->get_tile_pos().y << std::endl; + if (!level->extro_filename.empty()) + { + // Display a text file + display_text_file(level->extro_filename, SCROLL_SPEED_MESSAGE, white_big_text , white_text, white_small_text, blue_text ); + } + if (level->swap_x != -1 && level->swap_y != -1) + { + // TODO: add an effect, like a camera scrolling, or at least, a fading + tux->set_tile_pos(Vector(level->swap_x, level->swap_y)); + } + if (!level->next_worldmap.empty()) + { + // Load given worldmap + loadmap(level->next_worldmap); + } + if (level->quit_worldmap) + quit = true; } } else @@ -833,6 +871,9 @@ WorldMap::draw(DrawingContext& context, const Vector& offset) for(Levels::iterator i = levels.begin(); i != levels.end(); ++i) { + if(i->name.empty()) + continue; + if (i->solved) context.draw_surface(leveldot_green, Vector(i->x*32 + offset.x, i->y*32 + offset.y), LAYER_TILES+1); @@ -887,13 +928,21 @@ WorldMap::draw_status(DrawingContext& context) if (i->x == tux->get_tile_pos().x && i->y == tux->get_tile_pos().y) { - if(i->title == "") - get_level_title(*i); + if(!i->name.empty()) + { + if(i->title == "") + get_level_title(*i); + + context.draw_text_center(white_text, i->title, + Vector(0, screen->h - white_text->get_height() - 30), + LAYER_FOREGROUND1); + } - context.draw_text(white_text, i->title, - Vector(screen->w/2 - white_text->get_text_width(i->title)/2, - screen->h - white_text->get_height() - 30), - LAYER_FOREGROUND1); + /* Display a message in the map, if any as been selected */ + if(!i->display_map_message.empty()) + context.draw_text_center(gold_text, i->display_map_message, + Vector(0, screen->h - white_text->get_height() - 60), + LAYER_FOREGROUND1); break; } } @@ -907,13 +956,13 @@ WorldMap::display() quit = false; - song = sound_manager->load_music(datadir + "/music/" + music); - sound_manager->play_music(song); + song = SoundManager::get()->load_music(datadir + "/music/" + music); + SoundManager::get()->play_music(song); unsigned int last_update_time; unsigned int update_time; - last_update_time = update_time = st_get_ticks(); + last_update_time = update_time = Ticks::get(); DrawingContext context; while(!quit) @@ -926,7 +975,7 @@ WorldMap::display() delta = .3f; last_update_time = update_time; - update_time = st_get_ticks(); + update_time = Ticks::get(); Vector tux_pos = tux->get_pos(); if (1)