/** * \brief Cancels the current game-over sequence. */ void Game::stop_game_over() { Debug::check_assertion(is_showing_game_over(), "The game-over sequence is not running"); get_lua_context().game_on_game_over_finished(*this); showing_game_over = false; if (!restarting && !get_main_loop().is_resetting()) { // The hero gets back to life. current_map->check_suspended(); // To unsuspend the hero before making him blink. hero->notify_game_over_finished(); } }
/** * \brief Simulates one tick of the main loop. */ void TestEnvironment::step() { get_main_loop().step(); }
/** * \brief Runs the main loop on the specified map. * \param map_id Id of the map to open. */ void TestEnvironment::run_map(const std::string& map_id) { this->map_id = map_id; get_game(); // Create a game and start it on the map. get_main_loop().run(); }
/** * \brief Handles the transitions. * * This functions changes the map when needed and plays the * transitions between the two maps. This function is called * by the update() function. * Note that the two maps can actually be the same. */ void Game::update_transitions() { if (transition != NULL) { transition->update(); } // if the map has just changed, close the current map if any and play an out transition if (next_map != NULL && transition == NULL) { // the map has changed (i.e. set_current_map has been called) if (current_map == NULL) { // special case: no map was playing, so we don't have any out transition to do current_map = next_map; next_map = NULL; } else { // normal case: stop the control and play an out transition before leaving the current map transition = Transition::create( transition_style, Transition::TRANSITION_CLOSING, current_map->get_visible_surface(), this); transition->start(); } } Rectangle previous_map_location = current_map->get_location(); // if a transition was playing and has just been finished if (transition != NULL && transition->is_finished()) { Transition::Direction transition_direction = transition->get_direction(); bool needs_previous_surface = transition->needs_previous_surface(); delete transition; transition = NULL; MainLoop& main_loop = get_main_loop(); if (restarting) { current_map->unload(); main_loop.set_game(new Game(main_loop, savegame)); RefCountable::unref(savegame); savegame = NULL; // The new game is the owner. } else if (transition_direction == Transition::TRANSITION_CLOSING) { if (next_map == current_map) { // same map hero->place_on_destination(*current_map, previous_map_location); transition = Transition::create( transition_style, Transition::TRANSITION_OPENING, current_map->get_visible_surface(), this); transition->start(); next_map = NULL; } else { // change the map current_map->leave(); // special treatments for a transition between two different worlds // (e.g. outside world to a dungeon) if (!next_map->has_world() || next_map->get_world() != current_map->get_world()) { // reset the crystal blocks crystal_state = false; // Save the location except if this is a special destination. const std::string& destination_name = next_map->get_destination_name(); if (destination_name != "_same" && destination_name.substr(0,5) != "_side") { get_savegame().set_string(Savegame::KEY_STARTING_MAP, next_map->get_id()); get_savegame().set_string(Savegame::KEY_STARTING_POINT, destination_name); } } // before closing the map, draw it on a backup surface for transition effects // that want to display both maps at the same time if (needs_previous_surface) { previous_map_surface = Surface::create( Video::get_quest_size() ); previous_map_surface->set_software_destination(false); RefCountable::ref(previous_map_surface); current_map->draw(); current_map->get_visible_surface().draw(*previous_map_surface); } // set the next map current_map->unload(); RefCountable::unref(current_map); current_map = next_map; next_map = NULL; } } else { current_map->notify_opening_transition_finished(); RefCountable::unref(previous_map_surface); previous_map_surface = NULL; } } // if a map has just been set as the current map, start it and play the in transition if (started && !current_map->is_started()) { Debug::check_assertion(current_map->is_loaded(), "This map is not loaded"); transition = Transition::create( transition_style, Transition::TRANSITION_OPENING, current_map->get_visible_surface(), this); if (previous_map_surface != NULL) { // some transition effects need to display both maps simultaneously transition->set_previous_surface(previous_map_surface); } hero->place_on_destination(*current_map, previous_map_location); transition->start(); current_map->start(); notify_map_changed(); } }