#include <fstream>
#include "audio/sound_manager.hpp"
-#include "control/joystickkeyboardcontroller.hpp"
+#include "control/input_manager.hpp"
#include "gui/menu.hpp"
#include "gui/menu_manager.hpp"
#include "math/random_generator.hpp"
#include "object/player.hpp"
#include "scripting/squirrel_util.hpp"
#include "supertux/gameconfig.hpp"
-#include "supertux/levelintro.hpp"
#include "supertux/globals.hpp"
-#include "supertux/mainloop.hpp"
+#include "supertux/levelintro.hpp"
+#include "supertux/levelset_screen.hpp"
#include "supertux/menu/menu_storage.hpp"
#include "supertux/menu/options_menu.hpp"
+#include "supertux/player_status.hpp"
+#include "supertux/savegame.hpp"
+#include "supertux/screen_fade.hpp"
+#include "supertux/screen_manager.hpp"
#include "supertux/sector.hpp"
#include "util/file_system.hpp"
#include "util/gettext.hpp"
#include "worldmap/worldmap.hpp"
-enum GameMenuIDs {
- MNID_CONTINUE,
- MNID_ABORTLEVEL
-};
-
-GameSession::GameSession(const std::string& levelfile_, Statistics* statistics) :
- level(0),
- statistics_backdrop(),
+GameSession::GameSession(const std::string& levelfile_, Savegame& savegame, Statistics* statistics) :
+ level(),
+ statistics_backdrop(Surface::create("images/engine/menu/score-backdrop.png")),
scripts(),
- currentsector(0),
+ currentsector(nullptr),
levelnb(),
pause_menu_frame(),
end_sequence(0),
- game_pause(),
- speed_before_pause(),
- levelfile(levelfile_),
+ game_pause(false),
+ speed_before_pause(g_screen_manager->get_speed()),
+ levelfile(levelfile_),
reset_sector(),
reset_pos(),
newsector(),
newspawnpoint(),
best_level_statistics(statistics),
- capture_demo_stream(0),
+ m_savegame(savegame),
+ capture_demo_stream(0),
capture_file(),
- playback_demo_stream(0),
+ playback_demo_stream(0),
demo_controller(0),
- game_menu(),
- play_time(0),
- edit_mode(false),
- levelintro_shown(false)
+ play_time(0),
+ edit_mode(false),
+ levelintro_shown(false),
+ coins_at_start(),
+ bonus_at_start(),
+ max_fire_bullets_at_start(),
+ max_ice_bullets_at_start()
{
- currentsector = NULL;
-
- game_pause = false;
- speed_before_pause = g_main_loop->get_speed();
-
- statistics_backdrop.reset(new Surface("images/engine/menu/score-backdrop.png"));
-
- restart_level();
-
- game_menu.reset(new Menu());
- game_menu->add_label(level->name);
- game_menu->add_hl();
- game_menu->add_entry(MNID_CONTINUE, _("Continue"));
- game_menu->add_submenu(_("Options"), MenuStorage::get_options_menu());
- game_menu->add_hl();
- game_menu->add_entry(MNID_ABORTLEVEL, _("Abort Level"));
+ if (restart_level() != 0)
+ throw std::runtime_error ("Initializing the level failed.");
}
-void
+int
GameSession::restart_level()
{
+ PlayerStatus* currentStatus = m_savegame.get_player_status();
+ coins_at_start = currentStatus->coins;
+ bonus_at_start = currentStatus->bonus;
+ max_fire_bullets_at_start = currentStatus->max_fire_bullets;
+ max_ice_bullets_at_start = currentStatus->max_ice_bullets;
if (edit_mode) {
force_ghost_mode();
- return;
+ return (-1);
}
game_pause = false;
end_sequence = 0;
- g_main_controller->reset();
+ g_input_manager->reset();
currentsector = 0;
msg << "Couldn't find sector '" << reset_sector << "' for resetting tux.";
throw std::runtime_error(msg.str());
}
- level->stats.declare_invalid();
currentsector->activate(reset_pos);
} else {
currentsector = level->get_sector("main");
}
} catch(std::exception& e) {
log_fatal << "Couldn't start level: " << e.what() << std::endl;
- g_main_loop->exit_screen();
+ g_screen_manager->pop_screen();
+ return (-1);
}
sound_manager->stop_music();
if(capture_file != "") {
int newSeed=0; // next run uses a new seed
while (newSeed == 0) // which is the next non-zero random num.
- newSeed = systemRandom.rand();
- g_config->random_seed = systemRandom.srand(newSeed);
+ newSeed = gameRandom.rand();
+ g_config->random_seed = gameRandom.srand(newSeed);
log_info << "Next run uses random seed " << g_config->random_seed <<std::endl;
record_demo(capture_file);
}
+
+ return (0);
}
GameSession::~GameSession()
delete capture_demo_stream;
delete playback_demo_stream;
delete demo_controller;
- MenuStorage::free_options_menu();
}
void
else
log_info << "Demo file contains no random number" << std::endl;
}
+ delete test_stream;
+ test_stream = nullptr;
return 0;
}
GameSession::toggle_pause()
{
// pause
- if(!game_pause) {
- speed_before_pause = g_main_loop->get_speed();
- g_main_loop->set_speed(0);
- MenuManager::set_current(game_menu.get());
- game_menu->set_active_item(MNID_CONTINUE);
+ if (!game_pause && !MenuManager::instance().is_active())
+ {
+ speed_before_pause = g_screen_manager->get_speed();
+ g_screen_manager->set_speed(0);
+ MenuManager::instance().set_menu(MenuStorage::GAME_MENU);
game_pause = true;
}
}
void
-GameSession::set_editmode(bool edit_mode)
+GameSession::abort_level()
{
- if (this->edit_mode == edit_mode) return;
- this->edit_mode = edit_mode;
+ MenuManager::instance().clear_menu_stack();
+ g_screen_manager->pop_screen();
+ currentsector->player->set_bonus(bonus_at_start);
+ PlayerStatus *currentStatus = m_savegame.get_player_status();
+ currentStatus->coins = coins_at_start;
+ currentStatus->max_fire_bullets = max_fire_bullets_at_start;
+ currentStatus->max_ice_bullets = max_ice_bullets_at_start;
+}
- currentsector->get_players()[0]->set_edit_mode(edit_mode);
+void
+GameSession::set_editmode(bool edit_mode_)
+{
+ if (this->edit_mode == edit_mode_) return;
+ this->edit_mode = edit_mode_;
- if (edit_mode) {
+ currentsector->get_players()[0]->set_edit_mode(edit_mode_);
+
+ if (edit_mode_) {
// entering edit mode
HSQUIRRELVM
GameSession::run_script(std::istream& in, const std::string& sourcename)
{
- using namespace Scripting;
+ using namespace scripting;
// garbage collect thread list
for(ScriptList::iterator i = scripts.begin();
void
GameSession::process_events()
{
- // end of pause mode?
- // XXX this looks like a fail-safe to unpause the game if there's no menu
- // XXX having it enabled causes some unexpected problems
- // XXX hopefully disabling it won't...
- /*
- if(!Menu::current() && game_pause) {
- game_pause = false;
- }
- */
-
// playback a demo?
if(playback_demo_stream != 0) {
demo_controller->update();
// save input for demo?
if(capture_demo_stream != 0) {
- capture_demo_stream ->put(g_main_controller->hold(Controller::LEFT));
- capture_demo_stream ->put(g_main_controller->hold(Controller::RIGHT));
- capture_demo_stream ->put(g_main_controller->hold(Controller::UP));
- capture_demo_stream ->put(g_main_controller->hold(Controller::DOWN));
- capture_demo_stream ->put(g_main_controller->hold(Controller::JUMP));
- capture_demo_stream ->put(g_main_controller->hold(Controller::ACTION));
+ Controller *controller = g_input_manager->get_controller();
+ capture_demo_stream ->put(controller->hold(Controller::LEFT));
+ capture_demo_stream ->put(controller->hold(Controller::RIGHT));
+ capture_demo_stream ->put(controller->hold(Controller::UP));
+ capture_demo_stream ->put(controller->hold(Controller::DOWN));
+ capture_demo_stream ->put(controller->hold(Controller::JUMP));
+ capture_demo_stream ->put(controller->hold(Controller::ACTION));
}
}
}
void
-GameSession::process_menu()
-{
- Menu* menu = MenuManager::current();
- if(menu) {
- if(menu == game_menu.get()) {
- switch (game_menu->check()) {
- case MNID_CONTINUE:
- MenuManager::set_current(0);
- toggle_pause();
- break;
- case MNID_ABORTLEVEL:
- MenuManager::set_current(0);
- g_main_loop->exit_screen();
- break;
- }
- }
- }
-}
-
-void
GameSession::setup()
{
+ if (currentsector == NULL)
+ return;
+
if(currentsector != Sector::current()) {
currentsector->activate(currentsector->player->get_pos());
}
currentsector->play_music(LEVEL_MUSIC);
- // Eat unneeded events
- SDL_Event event;
- while(SDL_PollEvent(&event))
- {}
-
- if (!levelintro_shown) {
+ int total_stats_to_be_collected = level->stats.total_coins + level->stats.total_badguys + level->stats.total_secrets;
+ if ((!levelintro_shown) && (total_stats_to_be_collected > 0)) {
levelintro_shown = true;
- g_main_loop->push_screen(new LevelIntro(level.get(), best_level_statistics));
+ g_screen_manager->push_screen(std::unique_ptr<Screen>(new LevelIntro(level.get(), best_level_statistics)));
}
}
void
+GameSession::leave()
+{
+}
+
+void
GameSession::update(float elapsed_time)
{
// handle controller
- if(g_main_controller->pressed(Controller::PAUSE_MENU))
+ if(g_input_manager->get_controller()->pressed(Controller::PAUSE_MENU))
+ {
on_escape_press();
+ }
+
+ if(g_input_manager->get_controller()->pressed(Controller::CHEAT_MENU))
+ {
+ if (!MenuManager::instance().is_active())
+ {
+ game_pause = true;
+ MenuManager::instance().set_menu(MenuStorage::CHEAT_MENU);
+ }
+ }
process_events();
- process_menu();
// Unpause the game if the menu has been closed
- if (game_pause && !MenuManager::current()) {
- g_main_loop->set_speed(speed_before_pause);
+ if (game_pause && !MenuManager::instance().is_active()) {
+ g_screen_manager->set_speed(speed_before_pause);
game_pause = false;
}
void
GameSession::finish(bool win)
{
- using namespace WorldMapNS;
+ using namespace worldmap;
if (edit_mode) {
force_ghost_mode();
if(win) {
if(WorldMap::current())
+ {
WorldMap::current()->finished_level(level.get());
+ }
+
+ if (LevelsetScreen::current())
+ {
+ LevelsetScreen::current()->finished_level(win);
+ }
}
- g_main_loop->exit_screen();
+ g_screen_manager->pop_screen();
}
void
}
/* slow down the game for end-sequence */
- g_main_loop->set_speed(0.5f);
+ g_screen_manager->set_speed(0.5f);
currentsector->add_object(end_sequence);
end_sequence->start();
- sound_manager->play_music("music/leveldone.music", false);
- currentsector->player->invincible_timer.start(10000.0f);
+ sound_manager->play_music("music/leveldone.ogg", false);
+ currentsector->player->set_winning();
// Stop all clocks.
for(std::vector<GameObject*>::iterator i = currentsector->gameobjects.begin();
void
GameSession::drawstatus(DrawingContext& context)
{
- player_status->draw(context);
+ m_savegame.get_player_status()->draw(context);
// draw level stats while end_sequence is running
if (end_sequence) {
- level->stats.draw_endseq_panel(context, best_level_statistics, statistics_backdrop.get());
+ level->stats.draw_endseq_panel(context, best_level_statistics, statistics_backdrop);
}
}