Cheating handled by Console
authorChristoph Sommer <mail@christoph-sommer.de>
Thu, 6 Apr 2006 15:04:03 +0000 (15:04 +0000)
committerChristoph Sommer <mail@christoph-sommer.de>
Thu, 6 Apr 2006 15:04:03 +0000 (15:04 +0000)
SVN-Revision: 3252

src/console.cpp
src/console.hpp
src/control/joystickkeyboardcontroller.cpp
src/control/joystickkeyboardcontroller.hpp
src/game_session.cpp
src/game_session.hpp

index 6da3a36..307f9b2 100644 (file)
@@ -78,6 +78,10 @@ Console::addLine(std::string s)
 void
 Console::parse(std::string s) 
 {
+  for (std::list<ConsoleCommandReceiver*>::iterator i = commandReceivers.begin(); i != commandReceivers.end(); i++) {
+    ConsoleCommandReceiver* ccr = *i;
+    if (ccr->consoleCommand(s) == true) return;
+  }
   addLine("unknown command: \"" + s + "\"");
 }
 
@@ -132,9 +136,23 @@ Console::draw()
   }
 }
 
+void 
+Console::registerCommandReceiver(ConsoleCommandReceiver* ccr)
+{
+  commandReceivers.push_front(ccr);
+}
+
+void 
+Console::unregisterCommandReceiver(ConsoleCommandReceiver* ccr)
+{
+  std::list<ConsoleCommandReceiver*>::iterator i = find(commandReceivers.begin(), commandReceivers.end(), ccr);
+  if (i != commandReceivers.end()) commandReceivers.erase(i);
+}
+
 int Console::height = 0;
 bool Console::focused = false;
 std::list<std::string> Console::lines;
+std::list<ConsoleCommandReceiver*> Console::commandReceivers;
 ConsoleStreamBuffer Console::inputBuffer;
 ConsoleStreamBuffer Console::outputBuffer;
 std::ostream Console::input(&Console::inputBuffer);
index 0b119f3..b4fb85a 100644 (file)
@@ -27,6 +27,7 @@
 
 class Console;
 class ConsoleStreamBuffer;
+class ConsoleCommandReceiver;
 class DrawingContext;
 class Surface;
 
@@ -45,9 +46,12 @@ class Console
     static void show(); /**< display the console */
     static void hide(); /**< hide the console */
     static bool hasFocus(); /**< true if characters should be sent to the console instead of their normal target */
+    static void registerCommandReceiver(ConsoleCommandReceiver* ccr); /**< register instance to notify of commands entered in the console */
+    static void unregisterCommandReceiver(ConsoleCommandReceiver* ccr); /**< new commands should no longer be sent to this ccr */
 
   protected:
     static std::list<std::string> lines; /**< backbuffer of lines sent to the console */
+    static std::list<ConsoleCommandReceiver*> commandReceivers; /**< list of instances to notify of new console commands */
     DrawingContext* context; /**< context to draw to */
     Surface* background; /**< console background image */
     static int height; /**< height of the console in px */
@@ -70,6 +74,18 @@ class ConsoleStreamBuffer : public std::stringbuf
     }
 };
 
-#endif
-
+class ConsoleCommandReceiver
+{
+  public:
+    ConsoleCommandReceiver()
+    {
+      //Console::registerCommandReceiver(this);
+    }
+    virtual bool consoleCommand(std::string command) = 0; /**< callback from Console; return false if command was unknown, true otherwise */
+    virtual ~ConsoleCommandReceiver()
+    {
+      //Console::unregisterCommandReceiver(this);
+    }
+};
 
+#endif
index a07bd4d..c90191c 100644 (file)
@@ -57,8 +57,6 @@ JoystickKeyboardController::JoystickKeyboardController()
   : wait_for_key(-1), wait_for_joybutton(-1), key_options_menu(0),
     joystick_options_menu(0)
 {
-  memset(last_keys, 0, sizeof(last_keys));
-
   // initialize default keyboard map
   keymap.insert(std::make_pair(SDLK_LEFT, LEFT));
   keymap.insert(std::make_pair(SDLK_RIGHT, RIGHT));
@@ -240,8 +238,6 @@ void
 JoystickKeyboardController::reset()
 {
   Controller::reset();
-  for(size_t i = 0; i < sizeof(last_keys); ++i)
-      last_keys[i] = 0;
 }
 
 void
@@ -250,12 +246,7 @@ JoystickKeyboardController::process_event(const SDL_Event& event)
   switch(event.type) {
     case SDL_KEYUP:
     case SDL_KEYDOWN:
-      // remember ascii keys for cheat codes...
-      if(event.type == SDL_KEYDOWN && 
-          (event.key.keysym.unicode & 0xFF80) == 0) {
-        memmove(last_keys, last_keys+1, sizeof(last_keys)-1);
-        last_keys[sizeof(last_keys)-1] = event.key.keysym.unicode;
-
+      if(event.type == SDL_KEYDOWN && (event.key.keysym.unicode & 0xFF80) == 0) {
        if (Console::hasFocus()) {
          // if the Console is open, send keys there
          char c = event.key.keysym.unicode;
@@ -274,9 +265,6 @@ JoystickKeyboardController::process_event(const SDL_Event& event)
            Console::show();
          }
        }
-
-        if(GameSession::current() != NULL)
-          GameSession::current()->try_cheats();
       }
 
       if(Console::hasFocus()) {
@@ -540,21 +528,6 @@ JoystickKeyboardController::get_joystick_options_menu()
   return joystick_options_menu;
 }
 
-bool
-JoystickKeyboardController::check_cheatcode(const std::string& cheatcode)
-{
-  if(cheatcode.size() > sizeof(last_keys)) {
-    msg_debug("Cheat Code too long");
-    return false;
-  }
-
-  for(size_t i = 0; i < cheatcode.size(); ++i) {
-    if(last_keys[sizeof(last_keys)-1 - i] != cheatcode[cheatcode.size()-1-i])
-      return false;
-  }
-  return true;
-}
-
 //----------------------------------------------------------------------------
 
 JoystickKeyboardController::KeyboardMenu::KeyboardMenu(
index a39f68b..3f34997 100644 (file)
@@ -42,7 +42,6 @@ public:
 
   void write(lisp::Writer& writer);
   void read(const lisp::Lisp& lisp);
-       bool check_cheatcode(const std::string& cheatcode);
   void reset();
 
   Menu* get_key_options_menu();
@@ -98,8 +97,6 @@ private:
   JoystickMenu* joystick_options_menu;
   friend class KeyboardMenu;
   friend class JoystickMenu;
-
-  char last_keys[20];
 };
 
 #endif
index cbad8be..7a124f5 100644 (file)
@@ -90,6 +90,7 @@ GameSession::GameSession(const std::string& levelfile_, GameSessionMode mode,
 
   context = new DrawingContext();
   console = new Console(context);
+  Console::registerCommandReceiver(this);
 
   restart_level();
 }
@@ -164,6 +165,7 @@ GameSession::~GameSession()
   delete end_sequence_controller;
   delete level;
   delete context;
+  Console::unregisterCommandReceiver(this);
   delete console;
 
   current_ = NULL;
@@ -332,80 +334,102 @@ GameSession::process_events()
   }
 }
 
-void
-GameSession::try_cheats()
+bool
+GameSession::consoleCommand(std::string command)
 {
-  if(currentsector == 0)
-    return;
+  if (command == "foo") {
+    msg_info("bar");
+    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(main_controller->check_cheatcode("grow")) {
+  if (command == "grow") {
     tux.set_bonus(GROWUP_BONUS, false);
+    return true;
   }
-  if(main_controller->check_cheatcode("fire")) {
+  if (command == "fire") {
     tux.set_bonus(FIRE_BONUS, false);
+    return true;
   }
-  if(main_controller->check_cheatcode("ice")) {
+  if (command == "ice") {
     tux.set_bonus(ICE_BONUS, false);
+    return true;
   }
-  if(main_controller->check_cheatcode("lifeup")) {
+  if (command == "lifeup") {
     player_status->lives++;
+    return true;
   }
-  if(main_controller->check_cheatcode("lifedown")) {
+  if (command == "lifedown") {
     player_status->lives--;
+    return true;
   }
-  if(main_controller->check_cheatcode("grease")) {
+  if (command == "grease") {
     tux.physic.set_velocity_x(tux.physic.get_velocity_x()*3);
+    return true;
   }
-  if(main_controller->check_cheatcode("invincible")) {
+  if (command == "invincible") {
     // be invincle for the rest of the level
     tux.invincible_timer.start(10000);
+    return true;
   }
-  if(main_controller->check_cheatcode("mortal")) {
+  if (command == "mortal") {
     // give up invincibility
     tux.invincible_timer.stop();
+    return true;
   }
-  if(main_controller->check_cheatcode("shrink")) {
+  if (command == "shrink") {
     // remove powerups
     tux.kill(tux.SHRINK);
+    return true;
   }
-  if(main_controller->check_cheatcode("kill")) {
+  if (command == "kill") {
     // kill Tux, but without losing a life
     player_status->lives++;
     tux.kill(tux.KILL);
+    return true;
   }
-  if(main_controller->check_cheatcode("whereami")) {
+  if (command == "whereami") {
     msg_info("You are at x " << tux.get_pos().x << ", y " << tux.get_pos().y);
+    return true;
   }
 #if 0
-  if(main_controller->check_cheatcode("grid")) {
+  if(command == "grid")) {
     // toggle debug grid
     debug_grid = !debug_grid;
+    return true;
   }
 #endif
-  if(main_controller->check_cheatcode("gotoend")) {
+  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(main_controller->check_cheatcode("flip")) {
+  if (command == "flip") {
        FlipLevelTransformer flip_transformer;
     flip_transformer.transform(GameSession::current()->get_current_level());
+    return true;
   }
-  if(main_controller->check_cheatcode("finish")) {
+  if (command == "finish") {
     // finish current sector
     exit_status = ES_LEVEL_FINISHED;
     // don't add points to stats though...
+    return true;
   }
-  if(main_controller->check_cheatcode("camera")) {
+  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
index fced5d2..d2cd2dc 100644 (file)
@@ -53,7 +53,7 @@ class CodeController;
 /** The GameSession class controlls the controll flow of a World, ie.
     present the menu on specifc keypresses, render and update it while
     keeping the speed and framerate sane, etc. */
-class GameSession
+class GameSession : public ConsoleCommandReceiver
 {
 public:
   enum ExitStatus { ES_NONE, ES_LEVEL_FINISHED, ES_GAME_OVER, ES_LEVEL_ABORT };
@@ -91,15 +91,14 @@ public:
   { return level; }
 
   void start_sequence(const std::string& sequencename);
-  /// called by JoystickKeyboardController after an ascii key has been pressed
-  void try_cheats();
 
   /** returns the "working directory" usually this is the directory where the
    * currently played level resides. This is used when locating additional
    * resources for the current level/world
    */
   std::string get_working_directory();
-  
+  bool consoleCommand(std::string command); /**< callback from Console; return false if command was unknown, true otherwise */
+
 private:
   void restart_level();