X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fworldmap%2Fworldmap.cpp;h=90b5055fb711784656ddc9757ae4ddf7aa4906f2;hb=22a1e0b5152a00a37c2dbf6c8549cea30330ff9c;hp=ef0500390425ff15d16e0f47b0ed9da6a410c96c;hpb=394d459a330b94ca0030673a1232d92d663e0a6b;p=supertux.git diff --git a/src/worldmap/worldmap.cpp b/src/worldmap/worldmap.cpp index ef0500390..90b5055fb 100644 --- a/src/worldmap/worldmap.cpp +++ b/src/worldmap/worldmap.cpp @@ -1,5 +1,5 @@ // SuperTux - A Jump'n Run -// Copyright (C) 2004 Ingo Ruhnke +// Copyright (C) 2004 Ingo Ruhnke // Copyright (C) 2006 Christoph Sommer // // This program is free software: you can redistribute it and/or modify @@ -29,7 +29,7 @@ #include #include "audio/sound_manager.hpp" -#include "control/joystickkeyboardcontroller.hpp" +#include "control/input_manager.hpp" #include "gui/menu.hpp" #include "gui/menu_manager.hpp" #include "gui/mousecursor.hpp" @@ -59,6 +59,7 @@ #include "supertux/tile_manager.hpp" #include "supertux/tile_set.hpp" #include "supertux/world.hpp" +#include "supertux/savegame.hpp" #include "util/file_system.hpp" #include "util/gettext.hpp" #include "util/log.hpp" @@ -77,12 +78,11 @@ namespace worldmap { WorldMap* WorldMap::current_ = NULL; -WorldMap::WorldMap(const std::string& filename, PlayerStatus* player_status, const std::string& force_spawnpoint) : - tux(0), - player_status(player_status), - tileset(NULL), +WorldMap::WorldMap(const std::string& filename, Savegame& savegame, const std::string& force_spawnpoint_) : + tux(), + m_savegame(savegame), + tileset(NULL), free_tileset(false), - worldmap_menu(), camera_offset(), name(), music(), @@ -101,11 +101,13 @@ WorldMap::WorldMap(const std::string& filename, PlayerStatus* player_status, con total_stats(), worldmap_table(), scripts(), - ambient_light( 1.0f, 1.0f, 1.0f, 1.0f ), - force_spawnpoint(force_spawnpoint), - in_level(false), + ambient_light( 1.0f, 1.0f, 1.0f, 1.0f ), + force_spawnpoint(force_spawnpoint_), + in_level(false), pan_pos(), - panning(false) + panning(false), + last_position(), + last_target_time() { tux = new Tux(this); add_object(tux); @@ -115,8 +117,6 @@ WorldMap::WorldMap(const std::string& filename, PlayerStatus* player_status, con total_stats.reset(); - worldmap_menu.reset(new WorldmapMenu()); - // create a new squirrel table for the worldmap using namespace scripting; @@ -134,7 +134,7 @@ WorldMap::WorldMap(const std::string& filename, PlayerStatus* player_status, con sq_pop(global_vm, 1); sound_manager->preload("sounds/warp.wav"); - + // load worldmap objects load(filename); } @@ -237,10 +237,10 @@ WorldMap::move_to_spawnpoint(const std::string& spawnpoint, bool pan) } void -WorldMap::change(const std::string& filename, const std::string& force_spawnpoint) +WorldMap::change(const std::string& filename, const std::string& force_spawnpoint_) { - g_screen_manager->exit_screen(); - g_screen_manager->push_screen(new WorldMap(filename, player_status, force_spawnpoint)); + g_screen_manager->pop_screen(); + g_screen_manager->push_screen(std::unique_ptr(new WorldMap(filename, m_savegame, force_spawnpoint_))); } void @@ -253,25 +253,25 @@ WorldMap::load(const std::string& filename) lisp::Parser parser; const lisp::Lisp* root = parser.parse(map_filename); - const lisp::Lisp* level = root->get_lisp("supertux-level"); - if(level == NULL) + const lisp::Lisp* level_ = root->get_lisp("supertux-level"); + if(level_ == NULL) throw std::runtime_error("file isn't a supertux-level file."); - level->get("name", name); + level_->get("name", name); - const lisp::Lisp* sector = level->get_lisp("sector"); + const lisp::Lisp* sector = level_->get_lisp("sector"); if(!sector) throw std::runtime_error("No sector specified in worldmap file."); - const lisp::Lisp* tilesets_lisp = level->get_lisp("tilesets"); + const lisp::Lisp* tilesets_lisp = level_->get_lisp("tilesets"); if(tilesets_lisp != NULL) { - tileset = tile_manager->parse_tileset_definition(*tilesets_lisp); + tileset = tile_manager->parse_tileset_definition(*tilesets_lisp).release(); free_tileset = true; } std::string tileset_name; - if(level->get("tileset", tileset_name)) { + if(level_->get("tileset", tileset_name)) { if(tileset != NULL) { - log_warning << "multiple tilesets specified in level" << std::endl; + log_warning << "multiple tilesets specified in level_" << std::endl; } else { tileset = tile_manager->get_tileset(tileset_name); } @@ -371,7 +371,7 @@ WorldMap::get_level_target_time(LevelTile& level) level.target_time = last_target_time; return; } - + try { lisp::Parser parser; const lisp::Lisp* root = parser.parse(levels_path + level.get_name()); @@ -384,6 +384,7 @@ WorldMap::get_level_target_time(LevelTile& level) last_position = level.pos; last_target_time = level.target_time; + } catch(std::exception& e) { log_warning << "Problem when reading level target time: " << e.what() << std::endl; return; @@ -405,11 +406,11 @@ void WorldMap::on_escape_press() { // Show or hide the menu - if(!MenuManager::current()) { - MenuManager::set_current(worldmap_menu.get()); + if(!MenuManager::instance().is_active()) { + MenuManager::instance().set_menu(MenuStorage::WORLDMAP_MENU); tux->set_direction(D_NONE); // stop tux movement when menu is called } else { - MenuManager::set_current(NULL); + MenuManager::instance().clear_menu_stack(); } } @@ -539,11 +540,11 @@ WorldMap::finished_level(Level* gamelevel) Vector WorldMap::get_camera_pos_for_tux() { - Vector camera_offset; + Vector camera_offset_; Vector tux_pos = tux->get_pos(); - camera_offset.x = tux_pos.x - SCREEN_WIDTH/2; - camera_offset.y = tux_pos.y - SCREEN_HEIGHT/2; - return camera_offset; + camera_offset_.x = tux_pos.x - SCREEN_WIDTH/2; + camera_offset_.y = tux_pos.y - SCREEN_HEIGHT/2; + return camera_offset_; } void @@ -567,24 +568,8 @@ WorldMap::clamp_camera_position(Vector& c) { void WorldMap::update(float delta) { - if(!in_level) { - Menu* menu = MenuManager::current(); - if(menu != NULL) { - if(menu == worldmap_menu.get()) { - switch (worldmap_menu->check()) - { - case MNID_RETURNWORLDMAP: // Return to game - MenuManager::set_current(0); - break; - case MNID_QUITWORLDMAP: // Quit Worldmap - g_screen_manager->exit_screen(); - break; - } - } - - return; - } - + if (!in_level && !MenuManager::instance().is_active()) + { // update GameObjects for(size_t i = 0; i < game_objects.size(); ++i) { GameObject* object = game_objects[i]; @@ -623,12 +608,12 @@ WorldMap::update(float delta) if(!panning) { camera_offset = get_camera_pos_for_tux(); } else { - Vector delta = pan_pos - camera_offset; - float mag = delta.norm(); + Vector delta__ = pan_pos - camera_offset; + float mag = delta__.norm(); if(mag > CAMERA_PAN_SPEED) { - delta *= CAMERA_PAN_SPEED/mag; + delta__ *= CAMERA_PAN_SPEED/mag; } - camera_offset += delta; + camera_offset += delta__; if(camera_offset == pan_pos) { panning = false; } @@ -647,7 +632,7 @@ WorldMap::update(float delta) } // handle input - Controller *controller = g_jk_controller->get_main_controller(); + Controller *controller = g_input_manager->get_controller(); bool enter_level = false; if(controller->pressed(Controller::ACTION) || controller->pressed(Controller::JUMP) @@ -657,7 +642,14 @@ WorldMap::update(float delta) enter_level = true; } if(controller->pressed(Controller::PAUSE_MENU)) + { on_escape_press(); + } + + if(controller->pressed(Controller::CHEAT_MENU)) + { + MenuManager::instance().set_menu(MenuStorage::WORLDMAP_CHEAT_MENU); + } // check for teleporters Teleporter* teleporter = at_teleporter(tux->get_tile_pos()); @@ -677,13 +669,15 @@ WorldMap::update(float delta) LevelTile* level = at_level(); if (level && (level->auto_play) && (!level->solved) && (!tux->is_moving())) { enter_level = true; + // automatically mark these levels as solved in case player aborts + level->solved = true; } if (enter_level && !tux->is_moving()) { /* Check level action */ - LevelTile* level = at_level(); - if (!level) { + LevelTile* level_ = at_level(); + if (!level_) { //Respawn if player on a tile with no level and nowhere to go. int tile_data = tile_data_at(tux->get_tile_pos()); if(!( tile_data & ( Tile::WORLDMAP_NORTH | Tile::WORLDMAP_SOUTH | Tile::WORLDMAP_WEST | Tile::WORLDMAP_EAST ))){ @@ -695,17 +689,17 @@ WorldMap::update(float delta) return; } - if (level->pos == tux->get_tile_pos()) { + if (level_->pos == tux->get_tile_pos()) { try { - Vector shrinkpos = Vector(level->pos.x*32 + 16 - camera_offset.x, - level->pos.y*32 + 8 - camera_offset.y); - std::string levelfile = levels_path + level->get_name(); + Vector shrinkpos = Vector(level_->pos.x*32 + 16 - camera_offset.x, + level_->pos.y*32 + 8 - camera_offset.y); + std::string levelfile = levels_path + level_->get_name(); // update state and savegame save_state(); - g_screen_manager->push_screen(new GameSession(levelfile, player_status, &level->statistics), - new ShrinkFade(shrinkpos, 1.0f)); + g_screen_manager->push_screen(std::unique_ptr(new GameSession(levelfile, m_savegame, &level_->statistics)), + std::unique_ptr(new ShrinkFade(shrinkpos, 1.0f))); in_level = true; } catch(std::exception& e) { log_fatal << "Couldn't load level: " << e.what() << std::endl; @@ -811,7 +805,7 @@ WorldMap::draw(DrawingContext& context) /* // FIXME: make this a runtime switch similar to draw_collrects/show_collrects? // draw visual indication of possible walk directions - static int flipme = 0; + static int flipme = 0; if (flipme++ & 0x04) for (int x = 0; x < get_width(); x++) { for (int y = 0; y < get_height(); y++) { @@ -839,7 +833,7 @@ WorldMap::draw_status(DrawingContext& context) context.push_transform(); context.set_translation(Vector(0, 0)); - player_status->draw(context); + m_savegame.get_player_status()->draw(context); if (!tux->is_moving()) { for(LevelTiles::iterator i = levels.begin(); i != levels.end(); ++i) { @@ -867,7 +861,8 @@ WorldMap::draw_status(DrawingContext& context) } */ - get_level_target_time(*level); + if (level->target_time == 0.0f) + get_level_target_time(*level); level->statistics.draw_worldmap_info(context, level->target_time); break; } @@ -910,7 +905,7 @@ void WorldMap::setup() { sound_manager->play_music(music); - MenuManager::set_current(NULL); + MenuManager::instance().clear_menu_stack(); current_ = this; load_state(); @@ -929,7 +924,7 @@ WorldMap::setup() sq_pushroottable(global_vm); sq_pushstring(global_vm, "worldmap", -1); sq_pushobject(global_vm, worldmap_table); - if(SQ_FAILED(sq_createslot(global_vm, -3))) + if(SQ_FAILED(sq_newslot(global_vm, -3, SQFalse))) throw SquirrelError(global_vm, "Couldn't set worldmap in roottable"); sq_pop(global_vm, 1); @@ -965,6 +960,16 @@ WorldMap::leave() } void +WorldMap::set_levels_solved(bool solved, bool perfect) +{ + for(auto& level : levels) + { + level->set_solved(solved); + level->set_perfect(perfect); + } +} + +void WorldMap::save_state() { using namespace scripting; @@ -984,7 +989,7 @@ WorldMap::save_state() if(SQ_FAILED(sq_get(vm, -2))) { sq_pushstring(vm, "worlds", -1); sq_newtable(vm); - if(SQ_FAILED(sq_createslot(vm, -3))) + if(SQ_FAILED(sq_newslot(vm, -3, SQFalse))) throw scripting::SquirrelError(vm, "Couldn't create state.worlds"); sq_pushstring(vm, "worlds", -1); @@ -994,7 +999,8 @@ WorldMap::save_state() sq_pushstring(vm, map_filename.c_str(), map_filename.length()); if(SQ_FAILED(sq_deleteslot(vm, -2, SQFalse))) - sq_pop(vm, 1); + { + } // construct new table for this worldmap sq_pushstring(vm, map_filename.c_str(), map_filename.length()); @@ -1008,7 +1014,7 @@ WorldMap::save_state() store_float(vm, "y", tux->get_tile_pos().y); store_string(vm, "back", direction_to_string(tux->back_direction)); - sq_createslot(vm, -3); + sq_newslot(vm, -3, SQFalse); // levels... sq_pushstring(vm, "levels", -1); @@ -1024,24 +1030,23 @@ WorldMap::save_state() store_bool(vm, "perfect", level->perfect); level->statistics.serialize_to_squirrel(vm); - sq_createslot(vm, -3); + sq_newslot(vm, -3, SQFalse); } - sq_createslot(vm, -3); + sq_newslot(vm, -3, SQFalse); // overall statistics... total_stats.serialize_to_squirrel(vm); // push world into worlds table - sq_createslot(vm, -3); + sq_newslot(vm, -3, SQFalse); } catch(std::exception& ) { sq_settop(vm, oldtop); } sq_settop(vm, oldtop); - if(World::current() != NULL) - World::current()->save_state(); + m_savegame.save(); } void