* "Outsourced" cheats from GameSession to scripting system.
[supertux.git] / src / game_session.cpp
index 7269678..26301fa 100644 (file)
@@ -1,9 +1,7 @@
 //  $Id$
-// 
+//
 //  SuperTux
-//  Copyright (C) 2000 Bill Kendrick <bill@newbreedsoftware.com>
-//  Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
-//  Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>
+//  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
 //
 //  This program is free software; you can redistribute it and/or
 //  modify it under the terms of the GNU General Public License
@@ -14,7 +12,7 @@
 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 //  GNU General Public License for more details.
-// 
+//
 //  You should have received a copy of the GNU General Public License
 //  along with this program; if not, write to the Free Software
 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
@@ -35,7 +33,7 @@
 #include <SDL.h>
 
 #include "game_session.hpp"
-#include "msg.hpp"
+#include "log.hpp"
 #include "worldmap.hpp"
 #include "mainloop.hpp"
 #include "video/screen.hpp"
@@ -55,7 +53,6 @@
 #include "lisp/lisp.hpp"
 #include "lisp/parser.hpp"
 #include "resources.hpp"
-#include "worldmap.hpp"
 #include "misc.hpp"
 #include "statistics.hpp"
 #include "timer.hpp"
@@ -67,7 +64,7 @@
 #include "file_system.hpp"
 #include "gameconfig.hpp"
 #include "gettext.hpp"
-#include "exceptions.hpp"
+#include "console.hpp"
 #include "flip_level_transformer.hpp"
 
 // the engine will be run with a logical framerate of 64fps.
@@ -92,7 +89,7 @@ GameSession::GameSession(const std::string& levelfile_, GameSessionMode mode,
   game_pause = false;
   fps_fps = 0;
 
-  Console::registerCommandReceiver(this);
+  statistics_backdrop.reset(new Surface("images/engine/menu/score-backdrop.png"));
 
   restart_level(true);
 }
@@ -105,10 +102,9 @@ GameSession::restart_level(bool fromBeginning)
 
   main_controller->reset();
 
-  delete level;
   currentsector = 0;
 
-  level = new Level;
+  level.reset(new Level);
   level->load(levelfile);
 
   global_stats.reset();
@@ -165,8 +161,6 @@ GameSession::~GameSession()
   delete demo_controller;
 
   delete end_sequence_controller;
-  delete level;
-  Console::unregisterCommandReceiver(this);
 
   current_ = NULL;
 }
@@ -319,118 +313,6 @@ GameSession::process_events()
   }
 }
 
-bool
-GameSession::consoleCommand(std::string command)
-{
-  if (command == "foo") {
-    msg_info("bar");
-    return true;
-  }
-
-  //TODO: Build command list automatically
-  if (command == "cmdlist") {
-    msg_info("foo, cmdlist, cheats, whereami, camera");
-    return true;
-  }
-  //TODO: remove (or at least hide) this before release
-  if (command == "cheats") {
-    msg_info("grow, fire, ice, lifeup, numberofthebeast, lifedown, grease, invincible, mortal, shrink, kill, gotoend, flip, finish");
-    return true;
-  }
-
-  if (currentsector == 0) return false;
-  Player& tux = *currentsector->player;
-  
-  // Cheating words (the goal of this is really for debugging,
-  // but could be used for some cheating, nothing wrong with that)
-  if (command == "grow") {
-    tux.set_bonus(GROWUP_BONUS, false);
-    return true;
-  }
-  if (command == "fire") {
-    tux.set_bonus(FIRE_BONUS, false);
-    return true;
-  }
-  if (command == "ice") {
-    tux.set_bonus(ICE_BONUS, false);
-    return true;
-  }
-  if (command == "lifeup") {
-    player_status->incLives();
-    return true;
-  }
-  if (command == "numberofthebeast") {
-    player_status->coins += 55;
-    return true;
-  }
-  if (command == "lifedown") {
-    player_status->coins = std::max(player_status->coins-25, 0);
-    return true;
-  }
-  if (command == "grease") {
-    tux.physic.set_velocity_x(tux.physic.get_velocity_x()*3);
-    return true;
-  }
-  if (command == "invincible") {
-    // be invincle for the rest of the level
-    tux.invincible_timer.start(10000);
-    return true;
-  }
-  if (command == "mortal") {
-    // give up invincibility
-    tux.invincible_timer.stop();
-    return true;
-  }
-  if (command == "shrink") {
-    // remove powerups
-    tux.kill(tux.SHRINK);
-    return true;
-  }
-  if (command == "kill") {
-    tux.kill(tux.KILL);
-    return true;
-  }
-  if (command == "whereami") {
-    msg_info("You are at x " << tux.get_pos().x << ", y " << tux.get_pos().y);
-    return true;
-  }
-#if 0
-  if(command == "grid")) {
-    // toggle debug grid
-    debug_grid = !debug_grid;
-    return true;
-  }
-#endif
-  if (command == "gotoend") {
-    // goes to the end of the level
-    tux.move(Vector(
-          (currentsector->solids->get_width()*32) - (SCREEN_WIDTH*2), 0));
-    currentsector->camera->reset(
-        Vector(tux.get_pos().x, tux.get_pos().y));
-    return true;
-  }
-  if (command == "flip") {
-       FlipLevelTransformer flip_transformer;
-    flip_transformer.transform(GameSession::current()->get_current_level());
-    return true;
-  }
-  if (command == "finish") {
-    if(WorldMap::current() != NULL) {
-      WorldMap::current()->finished_level(levelfile);
-    }
-
-    return true;
-  }
-  if (command == "camera") {
-    msg_info("Camera is at " 
-              << Sector::current()->camera->get_translation().x << "," 
-              << Sector::current()->camera->get_translation().y);
-    return true;
-  }
-
-  return false;
-}
-
 void
 GameSession::check_end_conditions()
 {
@@ -439,28 +321,6 @@ GameSession::check_end_conditions()
   /* End of level? */
   if(end_sequence && endsequence_timer.check()) {
     finish(true);
-    
-    // add time spent to statistics
-    int tottime = 0, remtime = 0;
-    for(std::vector<Sector*>::iterator i = level->sectors.begin(); i != level->sectors.end(); ++i)
-    {
-      Sector* sec = *i;
-
-      for(std::vector<GameObject*>::iterator j = sec->gameobjects.begin();
-          j != sec->gameobjects.end(); ++j)
-      {
-        GameObject* obj = *j;
-
-        LevelTime* lt = dynamic_cast<LevelTime*> (obj);
-        if(lt)
-        {
-          tottime += int(lt->get_level_time());
-          remtime += int(lt->get_remaining_time());
-        }
-      }
-    }
-    global_stats.set_points(TIME_NEEDED_STAT, (tottime == 0 ? -1 : (tottime-remtime)));
-
     return;
   } else if (!end_sequence && tux->is_dead()) {
     if (player_status->coins < 0) { 
@@ -511,8 +371,6 @@ GameSession::process_menu()
           main_loop->exit_screen();
           break;
       }
-    } else if(menu == options_menu) {
-      process_options_menu();
     }
   }
 }
@@ -545,7 +403,7 @@ GameSession::update(float elapsed_time)
   if(newsector != "" && newspawnpoint != "") {
     Sector* sector = level->get_sector(newsector);
     if(sector == 0) {
-      msg_warning("Sector '" << newsector << "' not found");
+      log_warning << "Sector '" << newsector << "' not found" << std::endl;
     }
     sector->activate(newspawnpoint);
     sector->play_music(LEVEL_MUSIC);
@@ -569,11 +427,17 @@ GameSession::update(float elapsed_time)
   sound_manager->set_listener_position(currentsector->player->get_pos());
 
   /* Handle music: */
-  if (currentsector->player->invincible_timer.started() && 
-      currentsector->player->invincible_timer.get_timeleft() 
-      > TUX_INVINCIBLE_TIME_WARNING && !end_sequence) {
-    currentsector->play_music(HERRING_MUSIC);
-  } else if(currentsector->get_music_type() != LEVEL_MUSIC && !end_sequence) {
+  if (end_sequence)
+    return;
+  
+  if(currentsector->player->invincible_timer.started()) {
+    if(currentsector->player->invincible_timer.get_timeleft() <=
+       TUX_INVINCIBLE_TIME_WARNING) {
+      currentsector->play_music(HERRING_WARNING_MUSIC);
+    } else {
+      currentsector->play_music(HERRING_MUSIC);
+    }
+  } else if(currentsector->get_music_type() != LEVEL_MUSIC) {
     currentsector->play_music(LEVEL_MUSIC);
   }
 }
@@ -734,12 +598,13 @@ GameSession::display_info_box(const std::string& text)
   
   while(running)  {
 
+    // TODO make a screen out of this, another mainloop is ugly
     main_controller->update();
     SDL_Event event;
     while (SDL_PollEvent(&event)) {
       main_controller->process_event(event);
       if(event.type == SDL_QUIT)
-        throw graceful_shutdown();
+        main_loop->quit();
     }
 
     if(main_controller->pressed(Controller::JUMP)
@@ -784,18 +649,38 @@ GameSession::start_sequence(const std::string& sequencename)
         lt->stop();
     }
 
+    // add time spent to statistics
+    int tottime = 0, remtime = 0;
+    for(std::vector<Sector*>::iterator i = level->sectors.begin(); i != level->sectors.end(); ++i)
+    {
+      Sector* sec = *i;
+
+      for(std::vector<GameObject*>::iterator j = sec->gameobjects.begin();
+          j != sec->gameobjects.end(); ++j)
+      {
+        GameObject* obj = *j;
+
+        LevelTime* lt = dynamic_cast<LevelTime*> (obj);
+        if(lt)
+        {
+          tottime += int(lt->get_level_time());
+          remtime += int(lt->get_remaining_time());
+        }
+      }
+    }
+    global_stats.set_points(TIME_NEEDED_STAT, (tottime == 0 ? -1 : (tottime-remtime)));
+
     if(sequencename == "fireworks") {
       currentsector->add_object(new Fireworks());
     }
   } else if(sequencename == "stoptux") {
     if(!end_sequence) {
-      msg_warning("Final target reached without "
-        << "an active end sequence");
+      log_warning << "Final target reached without an active end sequence" << std::endl;
       this->start_sequence("endsequence");
     }
     end_sequence =  ENDSEQUENCE_WAITING;
   } else {
-    msg_warning("Unknown sequence '" << sequencename << "'");
+    log_warning << "Unknown sequence '" << sequencename << "'" << std::endl;
   }
 }
 
@@ -812,5 +697,10 @@ GameSession::drawstatus(DrawingContext& context)
     context.draw_text(white_text, fpstext, Vector(SCREEN_WIDTH - white_text->get_text_width(fpstext) - gold_text->get_text_width(" 99999") - BORDER_X, BORDER_Y + 20), LEFT_ALLIGN, LAYER_FOREGROUND1);
     context.draw_text(gold_text, str, Vector(SCREEN_WIDTH - BORDER_X, BORDER_Y + 20), RIGHT_ALLIGN, LAYER_FOREGROUND1);
   }
+
+  // draw level stats while end_sequence is running
+  if (end_sequence) {
+    global_stats.draw_endseq_panel(context, best_level_statistics, statistics_backdrop.get());
+  }
 }