1 // SuperTuxKart - a fun racing game with go-kart 2 // 3 // Copyright (C) 2006-2015 SuperTuxKart-Team 4 // 5 // This program is free software; you can redistribute it and/or 6 // modify it under the terms of the GNU General Public License 7 // as published by the Free Software Foundation; either version 3 8 // of the License, or (at your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU General Public License for more details. 14 // 15 // You should have received a copy of the GNU General Public License 16 // along with this program; if not, write to the Free Software 17 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 19 #ifndef KART_SELECTION_INCLUDED 20 #define KART_SELECTION_INCLUDED 21 22 #include "guiengine/screen.hpp" 23 #include "guiengine/widgets/dynamic_ribbon_widget.hpp" 24 #include "guiengine/widgets/player_kart_widget.hpp" 25 #include "states_screens/state_manager.hpp" 26 27 namespace GUIEngine 28 { 29 class Widget; 30 class BubbleWidget; 31 enum EventPropagation; 32 } 33 namespace Online 34 { 35 class User; 36 class OnlineProfile; 37 } 38 39 class FocusDispatcher; 40 class InputDevice; 41 class PlayerProfile; 42 class KartHoverListener; 43 44 extern int g_root_id; 45 46 /** 47 * \brief screen where players can choose their kart 48 * \ingroup states_screens 49 */ 50 class KartSelectionScreen : public GUIEngine::Screen 51 { 52 friend class KartHoverListener; 53 friend class PlayerNameSpinner; 54 friend class FocusDispatcher; 55 protected: 56 /** Contains the custom widget shown for every player. (ref only since 57 * we're adding them to a Screen, and the Screen will take ownership 58 * of these widgets) 59 */ 60 PtrVector<GUIEngine::PlayerKartWidget, REF> m_kart_widgets; 61 62 friend class GUIEngine::ScreenSingleton<KartSelectionScreen>; 63 friend class GUIEngine::PlayerKartWidget; 64 65 bool m_multiplayer; 66 67 /** Whether this screen is being visited from overworld or not */ 68 bool m_from_overworld; 69 70 bool m_go_to_overworld_next; 71 72 bool m_must_delete_on_back; //!< To delete the screen if back is pressed 73 74 /** Stores whether any player confirmed their choice; then, some things 75 * are "frozen", for instance the selected kart group tab 76 */ 77 bool m_game_master_confirmed; 78 79 GUIEngine::PlayerKartWidget* m_removed_widget; 80 81 /** Message shown in multiplayer mode */ 82 GUIEngine::BubbleWidget* m_multiplayer_message; 83 84 FocusDispatcher *m_dispatcher; 85 86 KartSelectionScreen(const char* filename); 87 88 /** Called when all players selected their kart */ 89 virtual void allPlayersDone(); 90 91 /** Called when number/order of karts changed, so that all will keep 92 * an up-to-date ID */ 93 void renumberKarts(); 94 95 /** Checks identities chosen by players, making sure no duplicates are 96 * used. 97 * \return Whether all choices are ok 98 */ 99 bool validateIdentChoices(); 100 101 /** Checks karts chosen by players, making sure no duplicates are used. 102 * \return Whether all choices are ok 103 */ 104 bool validateKartChoices(); 105 106 /** Fill the ribbon with the karts from the currently selected group */ 107 void setKartsFromCurrentGroup(); 108 109 void playerConfirm(const int playerID); 110 111 void updateKartStats(uint8_t widget_id, 112 const std::string& selection); 113 114 /** updates model of a kart widget, to have the good selection when the 115 * user validates */ 116 void updateKartWidgetModel(int widget_id, 117 const std::string& selection, 118 const irr::core::stringw& selectionText, 119 float kart_color); 120 121 /** Adds a message to the screen which indicates that players must press fire to join. */ 122 void addMultiplayerMessage(); 123 124 /** Remove the multiplayer message. */ 125 void removeMultiplayerMessage(); 126 isIgnored(const std::string & ident) const127 virtual bool isIgnored(const std::string& ident) const { return false; } 128 129 /** Stores a pointer to the current selection screen */ 130 static KartSelectionScreen* m_instance_ptr; 131 private: 132 PtrVector<const KartProperties, REF> getUsableKarts( 133 const std::string& selected_kart_group); 134 bool useContinueButton() const; 135 public: 136 /** Returns the current instance */ 137 static KartSelectionScreen* getRunningInstance(); 138 139 /** \brief implement callback from parent class GUIEngine::Screen */ 140 virtual void loadedFromFile() OVERRIDE; 141 142 void setMultiplayer(bool multiplayer); 143 144 /** \brief Set whether this screen is being visited from overworld or not */ setFromOverworld(bool from_overworld)145 void setFromOverworld(bool from_overworld) { m_from_overworld = from_overworld; } 146 setGoToOverworldNext()147 void setGoToOverworldNext() { m_go_to_overworld_next = true; } 148 149 /** \brief Called when a player hits 'fire'/'select' on his device to 150 * join the game */ 151 bool joinPlayer(InputDevice* device, PlayerProfile* p); 152 153 /** 154 * \brief Called when a player hits 'rescue'/'cancel' on his device 155 * to leave the game 156 * \return true if event was handled succesfully 157 */ 158 virtual bool playerQuit(StateManager::ActivePlayer* player); 159 160 /** \brief implement callback from parent class GUIEngine::Screen */ 161 virtual void init() OVERRIDE; 162 163 virtual void beforeAddingWidget() OVERRIDE; 164 165 /** \brief implement callback from parent class GUIEngine::Screen */ 166 virtual void tearDown() OVERRIDE; 167 168 /** \brief implement callback from parent class GUIEngine::Screen */ 169 virtual void eventCallback(GUIEngine::Widget* widget, const std::string& name, 170 const int playerID) OVERRIDE; 171 172 /** \brief implement callback from parent class GUIEngine::Screen */ 173 virtual void onUpdate(float dt) OVERRIDE; 174 175 /** \brief implement optional callback from parent 176 * class GUIEngine::Screen */ 177 virtual void unloaded() OVERRIDE; 178 179 /** \brief implement optional callback from parent 180 * class GUIEngine::Screen */ 181 virtual bool onEscapePressed() OVERRIDE; 182 183 }; // KartSelectionScreen 184 185 //!---------------------------------------------------------------------------- 186 //! FocusDispatcher : 187 /** Currently, navigation for multiple players at the same time is implemented 188 in a somewhat clunky way. An invisible "dispatcher" widget is added above 189 kart icons. When a player moves up, he focuses the dispatcher, which in 190 turn moves the selection to the appropriate spinner. "tabbing roots" are 191 used to make navigation back down possible. (FIXME: maybe find a cleaner 192 way?) */ 193 class FocusDispatcher : public GUIEngine::Widget 194 { 195 protected: 196 KartSelectionScreen* m_parent; 197 int m_reserved_id; 198 199 bool m_is_initialised; 200 201 public: 202 203 LEAK_CHECK() 204 205 // ------------------------------------------------------------------------ 206 FocusDispatcher(KartSelectionScreen* parent); 207 // ------------------------------------------------------------------------ 208 void setRootID(const int reservedID); 209 210 // ------------------------------------------------------------------------ 211 virtual void add(); 212 213 // ------------------------------------------------------------------------ 214 215 virtual GUIEngine::EventPropagation focused(const int playerID); 216 }; // FocusDispatcher 217 218 //!---------------------------------------------------------------------------- 219 //! KartHoverListener : 220 class KartHoverListener : public GUIEngine::DynamicRibbonHoverListener 221 { 222 KartSelectionScreen* m_parent; 223 public: 224 unsigned int m_magic_number; 225 226 KartHoverListener(KartSelectionScreen* parent); 227 228 // ------------------------------------------------------------------------ 229 virtual ~KartHoverListener(); 230 231 // ------------------------------------------------------------------------ 232 void onSelectionChanged(GUIEngine::DynamicRibbonWidget* theWidget, 233 const std::string& selectionID, 234 const irr::core::stringw& selectionText, 235 const int playerID); 236 }; // KartHoverListener 237 238 #endif 239 240