Merge branch 'master' of https://code.google.com/p/supertux
authorBenjamin Leduc <g.benjamin.leduc@gmail.com>
Sat, 16 Aug 2014 03:01:20 +0000 (03:01 +0000)
committerBenjamin Leduc <g.benjamin.leduc@gmail.com>
Sat, 16 Aug 2014 03:01:20 +0000 (03:01 +0000)
37 files changed:
src/control/controller.cpp
src/control/controller.hpp
src/control/game_controller_manager.cpp
src/control/keyboard_manager.cpp
src/gui/menu.cpp
src/gui/menu.hpp
src/gui/menu_manager.cpp
src/gui/menu_manager.hpp
src/supertux/game_session.cpp
src/supertux/menu/addon_menu.cpp
src/supertux/menu/addon_menu.hpp
src/supertux/menu/cheat_menu.cpp [new file with mode: 0644]
src/supertux/menu/cheat_menu.hpp [new file with mode: 0644]
src/supertux/menu/contrib_levelset_menu.cpp
src/supertux/menu/contrib_levelset_menu.hpp
src/supertux/menu/contrib_menu.cpp
src/supertux/menu/contrib_menu.hpp
src/supertux/menu/game_menu.cpp
src/supertux/menu/game_menu.hpp
src/supertux/menu/joystick_menu.hpp
src/supertux/menu/keyboard_menu.hpp
src/supertux/menu/language_menu.hpp
src/supertux/menu/main_menu.cpp
src/supertux/menu/main_menu.hpp
src/supertux/menu/menu_storage.cpp
src/supertux/menu/menu_storage.hpp
src/supertux/menu/options_menu.hpp
src/supertux/menu/profile_menu.hpp
src/supertux/menu/worldmap_cheat_menu.cpp [new file with mode: 0644]
src/supertux/menu/worldmap_cheat_menu.hpp [new file with mode: 0644]
src/supertux/menu/worldmap_menu.cpp
src/supertux/menu/worldmap_menu.hpp
src/supertux/title_screen.cpp
src/worldmap/level.cpp
src/worldmap/level.hpp
src/worldmap/worldmap.cpp
src/worldmap/worldmap.hpp

index 6a3882e..a25c39b 100644 (file)
@@ -26,6 +26,7 @@ const char* Controller::controlNames[] = {
   "pause-menu",
   "menu-select",
   "menu-back",
+  "cheat-menu",
   "console",
   "peek-left",
   "peek-right",
index b73695d..8d8543e 100644 (file)
@@ -35,6 +35,7 @@ public:
     MENU_SELECT,
     MENU_BACK,
 
+    CHEAT_MENU,
     CONSOLE,
 
     PEEK_LEFT,
index e7ca81d..4c9ccbf 100644 (file)
@@ -67,10 +67,11 @@ GameControllerManager::process_button_event(const SDL_ControllerButtonEvent& ev)
       break;
 
     case SDL_CONTROLLER_BUTTON_BACK:
+      set_control(Controller::CONSOLE, ev.state);
       break;
 
     case SDL_CONTROLLER_BUTTON_GUIDE:
-      set_control(Controller::CONSOLE, ev.state);
+      set_control(Controller::CHEAT_MENU, ev.state);
       break;
 
     case SDL_CONTROLLER_BUTTON_START:
index d46e4f6..0fe55b6 100644 (file)
@@ -51,6 +51,7 @@ KeyboardManager::KeyboardManager(InputManager* parent) :
   keymap[SDLK_PAGEDOWN] = Controller::PEEK_RIGHT;
   keymap[SDLK_HOME]     = Controller::PEEK_UP;
   keymap[SDLK_END]      = Controller::PEEK_DOWN;
+  keymap[SDLK_TAB]      = Controller::CHEAT_MENU;
 }
 
 KeyboardManager::~KeyboardManager()
index d6dff24..ec3c9db 100644 (file)
@@ -36,9 +36,7 @@ static const float MENU_REPEAT_INITIAL = 0.4f;
 static const float MENU_REPEAT_RATE    = 0.1f;
 
 Menu::Menu() :
-  hit_item(),
   pos(),
-  menuaction(),
   delete_character(),
   mn_input_char(),
   menu_repeat_time(),
@@ -46,8 +44,6 @@ Menu::Menu() :
   arrange_left(),
   active_item()
 {
-  hit_item = -1;
-  menuaction = MENU_ACTION_NONE;
   delete_character = 0;
   mn_input_char = '\0';
 
@@ -172,7 +168,6 @@ Menu::clear()
   active_item = -1;
 }
 
-/* Process actions done on the menu */
 void
 Menu::process_input()
 {
@@ -183,6 +178,7 @@ Menu::process_input()
     pos.y = SCREEN_HEIGHT/2 - scroll_offset * ((float(active_item) / (items.size()-1)) - 0.5f) * 2.0f;
   }
 
+  MenuAction menuaction = MENU_ACTION_NONE;
   Controller* controller = g_input_manager->get_controller();
   /** check main input controller... */
   if(controller->pressed(Controller::UP)) {
@@ -234,10 +230,18 @@ Menu::process_input()
     menuaction = MENU_ACTION_BACK;
   }
 
-  hit_item = -1;
   if(items.size() == 0)
     return;
 
+  // The menu_action() call can pop() the menu from the stack and thus
+  // delete it, so it's important that no further member variables are
+  // accessed after this call
+  process_action(menuaction);
+}
+
+void
+Menu::process_action(MenuAction menuaction)
+{
   int last_active_item = active_item;
   switch(menuaction) {
     case MENU_ACTION_UP:
@@ -289,7 +293,6 @@ Menu::process_input()
       break;
 
     case MENU_ACTION_HIT: {
-      hit_item = active_item;
       switch (items[active_item]->kind) {
         case MN_GOTO:
           assert(items[active_item]->target_menu != 0);
@@ -367,30 +370,9 @@ Menu::process_input()
     case MENU_ACTION_NONE:
       break;
   }
-  menuaction = MENU_ACTION_NONE;
-
-  assert(active_item < int(items.size()));
-}
-
-int
-Menu::check()
-{
-  if (hit_item != -1)
-  {
-    int id = items[hit_item]->id;
-    // Clear event when checked out.. (we would end up in a loop when we try to leave "fake" submenu like Addons or Contrib)
-    hit_item = -1;
-    return id;
-  }
-  else
-    return -1;
 }
 
 void
-Menu::menu_action(MenuItem* )
-{}
-
-void
 Menu::draw_item(DrawingContext& context, int index)
 {
   float menu_height = get_height();
@@ -674,7 +656,6 @@ Menu::set_toggled(int id, bool toggled)
   get_item_by_id(id).toggled = toggled;
 }
 
-/* Check for menu event */
 void
 Menu::event(const SDL_Event& event)
 {
@@ -691,7 +672,7 @@ Menu::event(const SDL_Event& event)
          y > pos.y - get_height()/2 &&
          y < pos.y + get_height()/2)
       {
-        menuaction = MENU_ACTION_HIT;
+        process_action(MENU_ACTION_HIT);
       }
     }
     break;
index 6ff1ed7..5ecd3f8 100644 (file)
@@ -28,8 +28,6 @@
 class DrawingContext;
 class MenuItem;
 
-bool confirm_dialog(Surface* background, std::string text);
-
 class Menu
 {
   static Color default_color;
@@ -67,7 +65,7 @@ public:
                              const std::string& mapping = "");
   MenuItem* add_string_select(int id, const std::string& text);
 
-  virtual void menu_action(MenuItem* item);
+  virtual void menu_action(MenuItem* item) = 0;
 
   void process_input();
 
@@ -77,8 +75,6 @@ public:
   /** Remove all entries from the menu */
   void clear();
 
-  virtual void check_menu() =0;
-
   MenuItem& get_item(int index)
   {
     return *(items[index]);
@@ -105,27 +101,17 @@ public:
   virtual void on_window_resize();
 
 protected:
-  /** Return the index of the menu item that was 'hit' (ie. the user
-      clicked on it) in the last event() call */
-  int check ();
-
   MenuItem* add_item(std::unique_ptr<MenuItem> menu_item);
 
 private:
+  void process_action(MenuAction menuaction);
   void check_controlfield_change_event(const SDL_Event& event);
   void draw_item(DrawingContext& context, int index);
 
 private:
-  /** Number of the item that got 'hit' (ie. pressed) in the last
-      event()/update() call, -1 if none */
-  int hit_item;
-
   // position of the menu (ie. center of the menu, not top/left)
   Vector pos;
 
-  /** input event for the menu (up, down, left, right, etc.) */
-  MenuAction menuaction;
-
   /* input implementation variables */
   int   delete_character;
   char  mn_input_char;
index d30f065..aae71e9 100644 (file)
@@ -201,20 +201,6 @@ MenuManager::draw(DrawingContext& context)
   }
 }
 
-bool
-MenuManager::check_menu()
-{
-  if (current())
-  {
-    current()->check_menu();
-    return true;
-  }
-  else
-  {
-    return false;
-  }
-}
-
 void
 MenuManager::push_menu(int id)
 {
@@ -261,6 +247,7 @@ MenuManager::set_menu(std::unique_ptr<Menu> menu)
   {
     transition(m_menu_stack.empty() ? nullptr : m_menu_stack.back().get(),
                menu.get());
+    m_menu_stack.clear();
     m_menu_stack.push_back(std::move(menu));
   }
   else
index af86297..643841b 100644 (file)
@@ -49,7 +49,6 @@ public:
   void refresh();
 
   void draw(DrawingContext& context);
-  bool check_menu();
 
   void set_menu(int id);
   void set_menu(std::unique_ptr<Menu> menu);
index 8fb7427..b83453d 100644 (file)
@@ -242,7 +242,8 @@ void
 GameSession::toggle_pause()
 {
   // pause
-  if(!game_pause) {
+  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);
@@ -417,10 +418,20 @@ GameSession::update(float elapsed_time)
 {
   // handle controller
   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();
-  MenuManager::instance().check_menu();
 
   // Unpause the game if the menu has been closed
   if (game_pause && !MenuManager::instance().is_active()) {
index 3494062..a32d783 100644 (file)
@@ -22,6 +22,8 @@
 
 #include "addon/addon.hpp"
 #include "addon/addon_manager.hpp"
+#include "gui/menu.hpp"
+#include "gui/menu_item.hpp"
 #include "util/gettext.hpp"
 
 namespace {
@@ -120,9 +122,9 @@ AddonMenu::refresh()
 }
 
 void
-AddonMenu::check_menu()
+AddonMenu::menu_action(MenuItem* item)
 {
-  int index = check();
+  int index = item->id;
 
   if (index == -1)
   {
index a3b62a7..640c5bc 100644 (file)
@@ -34,7 +34,7 @@ public:
   AddonMenu();
 
   void refresh();
-  void check_menu();
+  void menu_action(MenuItem* item) override;
 
 private:
   AddonMenu(const AddonMenu&);
diff --git a/src/supertux/menu/cheat_menu.cpp b/src/supertux/menu/cheat_menu.cpp
new file mode 100644 (file)
index 0000000..f31d80d
--- /dev/null
@@ -0,0 +1,109 @@
+//  SuperTux
+//  Copyright (C) 2014 Ingo Ruhnke <grumbel@gmail.com>
+//
+//  This program is free software: you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation, either version 3 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  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, see <http://www.gnu.org/licenses/>.
+
+#include "supertux/menu/cheat_menu.hpp"
+
+#include "gui/menu_item.hpp"
+#include "gui/menu_manager.hpp"
+#include "object/player.hpp"
+#include "supertux/game_session.hpp"
+#include "supertux/player_status.hpp"
+#include "supertux/sector.hpp"
+#include "util/gettext.hpp"
+
+CheatMenu::CheatMenu()
+{
+  add_label(_("Cheats"));
+  add_hl();
+  add_entry(MNID_GROW, _("Bonus: Grow"));
+  add_entry(MNID_FIRE, _("Bonus: Fire"));
+  add_entry(MNID_ICE, _("Bonus: Ice"));
+  add_entry(MNID_STAR, _("Bonus: Star"));
+  add_entry(MNID_SHRINK, _("Shrink Tux"));
+  add_entry(MNID_KILL, _("Kill Tux"));
+  add_entry(MNID_FINISH, _("Finish Level"));
+  add_hl();
+  add_back(_("Back"));
+}
+
+void
+CheatMenu::menu_action(MenuItem* item)
+{
+  if (Sector::current())
+  {
+    std::vector<Player*> players = Sector::current()->get_players();
+    Player* player = players.empty() ? nullptr : players[0];
+
+    switch(item->id)
+    {
+      case MNID_GROW:
+        if (player)
+        {
+          player->set_bonus(GROWUP_BONUS);
+        }
+        break;
+
+      case MNID_FIRE:
+        if (player)
+        {
+          player->set_bonus(FIRE_BONUS);
+        }
+        break;
+
+      case MNID_ICE:
+        if (player)
+        {
+          player->set_bonus(ICE_BONUS);
+        }
+        break;
+
+      case MNID_STAR:
+        if (player)
+        {
+          player->make_invincible();
+        }
+        break;
+
+      case MNID_SHRINK:
+        if (player)
+        {
+          player->kill(false);
+        }
+        break;
+
+      case MNID_KILL:
+        if (player)
+        {
+          player->kill(true);
+        }
+        break;
+
+      case MNID_FINISH:
+        if (GameSession::current())
+        {
+          GameSession::current()->finish(true);
+        }
+        break;
+
+      default:
+        break;
+    }
+  }
+
+  MenuManager::instance().clear_menu_stack();
+}
+
+/* EOF */
diff --git a/src/supertux/menu/cheat_menu.hpp b/src/supertux/menu/cheat_menu.hpp
new file mode 100644 (file)
index 0000000..55a147f
--- /dev/null
@@ -0,0 +1,47 @@
+//  SuperTux
+//  Copyright (C) 2014 Ingo Ruhnke <grumbel@gmail.com>
+//
+//  This program is free software: you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation, either version 3 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_SUPERTUX_MENU_CHEAT_MENU_HPP
+#define HEADER_SUPERTUX_SUPERTUX_MENU_CHEAT_MENU_HPP
+
+#include "gui/menu.hpp"
+
+class CheatMenu : public Menu
+{
+private:
+  enum MenuIDs {
+    MNID_GROW,
+    MNID_FIRE,
+    MNID_ICE,
+    MNID_STAR,
+    MNID_SHRINK,
+    MNID_KILL,
+    MNID_FINISH
+  };
+
+public:
+  CheatMenu();
+
+  void menu_action(MenuItem* item) override;
+
+private:
+  CheatMenu(const CheatMenu&) = delete;
+  CheatMenu& operator=(const CheatMenu&) = delete;
+};
+
+#endif
+
+/* EOF */
index 3ef0b3b..b0197d4 100644 (file)
@@ -69,20 +69,16 @@ ContribLevelsetMenu::ContribLevelsetMenu(std::unique_ptr<World> world) :
 }
 
 void
-ContribLevelsetMenu::check_menu()
+ContribLevelsetMenu::menu_action(MenuItem* item)
 {
-  int index = check();
-  if (index != -1)
+  if (item->kind == MN_ACTION)
   {
-    if (get_item_by_id(index).kind == MN_ACTION)
-    {
-      sound_manager->stop_music();
+    sound_manager->stop_music();
 
-      // reload the World so that we have something that we can safely
-      // std::move() around without wreaking the ContribMenu
-      std::unique_ptr<World> world = World::load(m_world->get_basedir());
-      GameManager::current()->start_level(std::move(world), m_levelset->get_level_filename(index));
-    }
+    // reload the World so that we have something that we can safely
+    // std::move() around without wreaking the ContribMenu
+    std::unique_ptr<World> world = World::load(m_world->get_basedir());
+    GameManager::current()->start_level(std::move(world), m_levelset->get_level_filename(item->id));
   }
 }
 
index 0374e92..7e1eae5 100644 (file)
@@ -31,7 +31,7 @@ private:
 public:
   ContribLevelsetMenu(std::unique_ptr<World> current_world);
 
-  void check_menu();
+  void menu_action(MenuItem* item) override;
 
 private:
   ContribLevelsetMenu(const ContribLevelsetMenu&);
index d4ae767..802c0ea 100644 (file)
@@ -19,6 +19,7 @@
 #include <physfs.h>
 #include <sstream>
 
+#include "gui/menu_item.hpp"
 #include "gui/menu_manager.hpp"
 #include "supertux/game_manager.hpp"
 #include "supertux/gameconfig.hpp"
@@ -134,9 +135,9 @@ ContribMenu::~ContribMenu()
 }
 
 void
-ContribMenu::check_menu()
+ContribMenu::menu_action(MenuItem* item)
 {
-  int index = check();
+  int index = item->id;
   if (index != -1)
   {
     // reload the World so that we have something that we can safely
index d83f8c2..f655c88 100644 (file)
@@ -31,7 +31,7 @@ public:
   ContribMenu();
   ~ContribMenu();
 
-  void check_menu();
+  void menu_action(MenuItem* item) override;
 
 private:
   ContribMenu(const ContribMenu&);
index 2398338..b73f249 100644 (file)
 
 #include "supertux/menu/game_menu.hpp"
 
+#include "gui/menu.hpp"
+#include "gui/menu_item.hpp"
 #include "gui/menu_manager.hpp"
 #include "supertux/game_session.hpp"
-#include "supertux/screen_manager.hpp"
 #include "supertux/level.hpp"
 #include "supertux/menu/menu_storage.hpp"
 #include "supertux/menu/options_menu.hpp"
+#include "supertux/screen_manager.hpp"
 #include "util/gettext.hpp"
 
 GameMenu::GameMenu()
@@ -37,9 +39,9 @@ GameMenu::GameMenu()
 }
 
 void
-GameMenu::check_menu()
+GameMenu::menu_action(MenuItem* item)
 {
-  switch (check())
+  switch (item->id)
   {
     case MNID_CONTINUE:
       MenuManager::instance().clear_menu_stack();
index 5b34851..4ffaac9 100644 (file)
@@ -32,7 +32,7 @@ private:
 public:
   GameMenu();
 
-  void check_menu() override;
+  void menu_action(MenuItem* item) override;
 
 private:
   GameMenu(const GameMenu&);
index dd4ba14..469ed0d 100644 (file)
@@ -31,8 +31,7 @@ public:
   void refresh_menu_item(Controller::Control id);
 
   std::string get_button_name(int button);
-  virtual void menu_action(MenuItem* item);
-  void check_menu() {}
+  void menu_action(MenuItem* item) override;
 
 private:
   void recreate_menu();
index 054a9ed..83f8f59 100644 (file)
@@ -29,9 +29,9 @@ public:
 
   void refresh();
   std::string get_key_name(SDL_Keycode key);
-  virtual void menu_action(MenuItem* item);
+  void menu_action(MenuItem* item) override;
   InputManager* controller;
-  void check_menu() {}
+
 private:
   KeyboardMenu(const KeyboardMenu&);
   KeyboardMenu& operator=(const KeyboardMenu&);
index 0c4fade..991ce45 100644 (file)
@@ -26,8 +26,7 @@ class LanguageMenu : public Menu
 public:
   LanguageMenu();
 
-  void menu_action(MenuItem* item);
-  void check_menu() {}
+  void menu_action(MenuItem* item) override;
 };
 
 #endif
index a93ff54..acd9b29 100644 (file)
@@ -17,6 +17,7 @@
 #include "supertux/menu/main_menu.hpp"
 
 #include "audio/sound_manager.hpp"
+#include "gui/menu_item.hpp"
 #include "gui/menu_manager.hpp"
 #include "supertux/fadeout.hpp"
 #include "supertux/game_manager.hpp"
@@ -51,9 +52,9 @@ MainMenu::on_window_resize()
 }
 
 void
-MainMenu::check_menu()
+MainMenu::menu_action(MenuItem* item)
 {
-  switch (check())
+  switch (item->id)
   {
     case MNID_STARTGAME:
       {
index 3f0f778..54f8187 100644 (file)
@@ -39,7 +39,7 @@ public:
   MainMenu();
 
   void on_window_resize() override;
-  void check_menu();
+  void menu_action(MenuItem* item) override;
 
 private:
   MainMenu(const MainMenu&);
index a0706ff..daf0474 100644 (file)
@@ -18,6 +18,7 @@
 
 #include "supertux/globals.hpp"
 #include "supertux/menu/addon_menu.hpp"
+#include "supertux/menu/cheat_menu.hpp"
 #include "supertux/menu/contrib_menu.hpp"
 #include "supertux/menu/game_menu.hpp"
 #include "supertux/menu/joystick_menu.hpp"
@@ -27,6 +28,7 @@
 #include "supertux/menu/options_menu.hpp"
 #include "supertux/menu/profile_menu.hpp"
 #include "supertux/menu/worldmap_menu.hpp"
+#include "supertux/menu/worldmap_cheat_menu.hpp"
 
 MenuStorage* MenuStorage::s_instance = 0;
 
@@ -77,9 +79,15 @@ MenuStorage::create(MenuId menu_id)
     case WORLDMAP_MENU:
       return std::unique_ptr<Menu>(new WorldmapMenu);
 
+    case WORLDMAP_CHEAT_MENU:
+      return std::unique_ptr<Menu>(new WorldmapCheatMenu);
+
     case GAME_MENU:
       return std::unique_ptr<Menu>(new GameMenu);
 
+    case CHEAT_MENU:
+      return std::unique_ptr<Menu>(new CheatMenu);
+
     case CONTRIB_MENU:
       return std::unique_ptr<Menu>(new ContribMenu);
 
index 44aaf51..dbd622d 100644 (file)
@@ -46,7 +46,9 @@ public:
     KEYBOARD_MENU,
     JOYSTICK_MENU,
     WORLDMAP_MENU,
-    GAME_MENU
+    WORLDMAP_CHEAT_MENU,
+    GAME_MENU,
+    CHEAT_MENU
   };
 
 public:
index 9980e06..84ee8ae 100644 (file)
@@ -26,7 +26,7 @@ public:
   OptionsMenu(bool complete);
   virtual ~OptionsMenu();
 
-  void menu_action(MenuItem* item);
+  void menu_action(MenuItem* item) override;
   void check_menu();
 };
 
index 5ed4648..1e89545 100644 (file)
@@ -24,7 +24,7 @@ class ProfileMenu : public Menu
 public:
   ProfileMenu();
 
-  void menu_action(MenuItem* item);
+  void menu_action(MenuItem* item) override;
 
   void check_menu() {}
 };
diff --git a/src/supertux/menu/worldmap_cheat_menu.cpp b/src/supertux/menu/worldmap_cheat_menu.cpp
new file mode 100644 (file)
index 0000000..f566b07
--- /dev/null
@@ -0,0 +1,110 @@
+//  SuperTux
+//  Copyright (C) 2014 Ingo Ruhnke <grumbel@gmail.com>
+//
+//  This program is free software: you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation, either version 3 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  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, see <http://www.gnu.org/licenses/>.
+
+#include "supertux/menu/worldmap_cheat_menu.hpp"
+
+#include "gui/menu_item.hpp"
+#include "gui/menu_manager.hpp"
+#include "supertux/player_status.hpp"
+#include "supertux/savegame.hpp"
+#include "util/gettext.hpp"
+#include "worldmap/level.hpp"
+#include "worldmap/worldmap.hpp"
+
+WorldmapCheatMenu::WorldmapCheatMenu()
+{
+  add_label(_("Cheats"));
+  add_hl();
+  add_entry(MNID_GROW, _("Bonus: Grow"));
+  add_entry(MNID_FIRE, _("Bonus: Fire"));
+  add_entry(MNID_ICE, _("Bonus: Ice"));
+  add_entry(MNID_SHRINK, _("Bonus: None"));
+  add_hl();
+  add_entry(MNID_FINISH_LEVEL, _("Finish Level"));
+  add_entry(MNID_RESET_LEVEL, _("Reset Level"));
+  add_hl();
+  add_entry(MNID_FINISH_WORLDMAP, _("Finish WorldMap"));
+  add_entry(MNID_RESET_WORLDMAP, _("Reset WorldMap"));
+  add_hl();
+  add_back(_("Back"));
+}
+
+void
+WorldmapCheatMenu::menu_action(MenuItem* item)
+{
+  worldmap::WorldMap* worldmap = worldmap::WorldMap::current();
+  if (!worldmap)
+  {
+    log_warning << "couldn't access WorldMap::current()" << std::endl;
+  }
+  else
+  {
+    PlayerStatus* status = worldmap->get_savegame().get_player_status();
+
+    switch(item->id)
+    {
+      case MNID_GROW:
+        status->bonus = GROWUP_BONUS;
+        break;
+
+      case MNID_FIRE:
+        status->bonus = FIRE_BONUS;
+        break;
+
+      case MNID_ICE:
+        status->bonus = ICE_BONUS;
+        break;
+
+      case MNID_SHRINK:
+        status->bonus = NO_BONUS;
+        break;
+
+      case MNID_FINISH_LEVEL:
+        {
+          worldmap::LevelTile* level_tile = worldmap->at_level();
+          if (level_tile)
+          {
+            level_tile->set_solved(true);
+            level_tile->set_perfect(false);
+          }
+        }
+        break;
+
+      case MNID_RESET_LEVEL:
+        {
+          worldmap::LevelTile* level_tile = worldmap->at_level();
+          if (level_tile)
+          {
+            level_tile->set_solved(false);
+            level_tile->set_perfect(false);
+          }
+        }
+        break;
+
+      case MNID_FINISH_WORLDMAP:
+        worldmap->set_levels_solved(true, false);
+        break;
+
+      case MNID_RESET_WORLDMAP:
+        worldmap->set_levels_solved(false, false);
+        break;
+    }
+  }
+
+  MenuManager::instance().clear_menu_stack();
+}
+
+/* EOF */
diff --git a/src/supertux/menu/worldmap_cheat_menu.hpp b/src/supertux/menu/worldmap_cheat_menu.hpp
new file mode 100644 (file)
index 0000000..15433df
--- /dev/null
@@ -0,0 +1,49 @@
+//  SuperTux
+//  Copyright (C) 2014 Ingo Ruhnke <grumbel@gmail.com>
+//
+//  This program is free software: you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation, either version 3 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_SUPERTUX_MENU_WORLDMAP_CHEAT_MENU_HPP
+#define HEADER_SUPERTUX_SUPERTUX_MENU_WORLDMAP_CHEAT_MENU_HPP
+
+#include "gui/menu.hpp"
+
+class WorldmapCheatMenu : public Menu
+{
+private:
+private:
+  enum MenuIDs {
+    MNID_GROW,
+    MNID_FIRE,
+    MNID_ICE,
+    MNID_SHRINK,
+    MNID_FINISH_LEVEL,
+    MNID_RESET_LEVEL,
+    MNID_FINISH_WORLDMAP,
+    MNID_RESET_WORLDMAP
+  };
+
+public:
+  WorldmapCheatMenu();
+
+  void menu_action(MenuItem* item) override;
+
+private:
+  WorldmapCheatMenu(const WorldmapCheatMenu&) = delete;
+  WorldmapCheatMenu& operator=(const WorldmapCheatMenu&) = delete;
+};
+
+#endif
+
+/* EOF */
index 68a7ab2..f252325 100644 (file)
@@ -16,6 +16,7 @@
 
 #include "supertux/menu/worldmap_menu.hpp"
 
+#include "gui/menu_item.hpp"
 #include "gui/menu_manager.hpp"
 #include "supertux/menu/menu_storage.hpp"
 #include "supertux/menu/options_menu.hpp"
@@ -34,9 +35,9 @@ WorldmapMenu::WorldmapMenu()
 }
 
 void
-WorldmapMenu::check_menu()
+WorldmapMenu::menu_action(MenuItem* item)
 {
-  switch (check())
+  switch (item->id)
   {
     case MNID_RETURNWORLDMAP:
       MenuManager::instance().clear_menu_stack();
index 2ddfd2b..358dabb 100644 (file)
@@ -30,7 +30,7 @@ private:
 public:
   WorldmapMenu();
 
-  void check_menu() override;
+  void menu_action(MenuItem* item) override;
 
 private:
   WorldmapMenu(const WorldmapMenu&);
index ec22c8b..3f7f845 100644 (file)
@@ -137,8 +137,6 @@ TitleScreen::update(float elapsed_time)
 
   make_tux_jump();
 
-  MenuManager::instance().check_menu();
-
   // reopen menu if user closed it (so that the app doesn't close when user
   // accidently hit ESC)
   if(!MenuManager::instance().is_active() && !g_screen_manager->has_pending_fadeout())
index dd4dbef..997f709 100644 (file)
@@ -78,6 +78,37 @@ LevelTile::update(float )
 {
 }
 
+void
+LevelTile::update_sprite_action()
+{
+  if (perfect)
+  {
+    sprite->set_action("perfect");
+  }
+  else if (solved)
+  {
+    sprite->set_action("perfect");
+  }
+  else
+  {
+    sprite->set_action("default");
+  }
+}
+
+void
+LevelTile::set_solved(bool v)
+{
+  solved = v;
+  update_sprite_action();
+}
+
+void
+LevelTile::set_perfect(bool v)
+{
+  perfect = v;
+  update_sprite_action();
+}
+
 } // namespace worldmap
 
 /* EOF */
index c71aa39..7c3ed78 100644 (file)
@@ -22,6 +22,7 @@
 #include <string>
 
 #include "math/vector.hpp"
+#include "sprite/sprite_ptr.hpp"
 #include "supertux/game_object.hpp"
 #include "supertux/statistics.hpp"
 #include "video/surface.hpp"
@@ -39,6 +40,12 @@ public:
   virtual void draw(DrawingContext& context);
   virtual void update(float elapsed_time);
 
+  void set_solved(bool v);
+  void set_perfect(bool v);
+
+private:
+  void update_sprite_action();
+
 public:
   Vector pos;
   std::string title;
index ca70b83..12ffc5d 100644 (file)
@@ -568,12 +568,8 @@ WorldMap::clamp_camera_position(Vector& c) {
 void
 WorldMap::update(float delta)
 {
-  if(!in_level) {
-    if (MenuManager::instance().check_menu())
-    {
-      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];
@@ -646,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());
@@ -957,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;
index d0d15d5..b0e56ac 100644 (file)
@@ -220,6 +220,11 @@ public:
    */
   float get_height() const;
 
+  /**
+   * Mark all levels as solved or unsolved
+   */
+  void set_levels_solved(bool solved, bool perfect);
+
 private:
   void get_level_title(LevelTile& level);
   void get_level_target_time(LevelTile& level);