1 // SuperTuxKart - a fun racing game with go-kart 2 // Copyright (C) 2009-2015 Marianne Gagnon 3 // 4 // This program is free software; you can redistribute it and/or 5 // modify it under the terms of the GNU General Public License 6 // as published by the Free Software Foundation; either version 3 7 // of the License, or (at your option) any later version. 8 // 9 // This program is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with this program; if not, write to the Free Software 16 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 18 19 #ifndef STATE_MANAGER_HPP 20 #define STATE_MANAGER_HPP 21 22 /** 23 * \defgroup states_screens 24 * Contains the various screens and dialogs of the STK user interface, 25 * using the facilities of the guiengine module. 26 */ 27 28 #include <string> 29 30 #include "config/player_profile.hpp" 31 #include "guiengine/abstract_state_manager.hpp" 32 #include "utils/ptr_vector.hpp" 33 34 class AbstractKart; 35 class InputDevice; 36 struct Input; 37 namespace Online 38 { 39 class OnlineProfile; 40 } 41 42 namespace GUIEngine 43 { 44 class Widget; 45 } 46 47 /** 48 * \brief the player ID of the "game master" player 49 * the game master is the player that can perform the game setup 50 * \ingroup states_screens 51 */ 52 const static int PLAYER_ID_GAME_MASTER = 0; 53 54 /** 55 * \brief A concrete scene manager, derived from GUIEngine's 56 * AbastractSceneManager 57 * \ingroup states_screens 58 */ 59 class StateManager : public GUIEngine::AbstractStateManager 60 { 61 62 void updateActivePlayerIDs(); 63 64 65 public: 66 67 /** 68 * Represents a player that is currently playing. 69 * Ties together : 70 * - a player's identity (and thus his/her highscores) 71 * - which input device is used by which player 72 * (we're very flexible on this; ActivePlayer #1 73 * can choose to e.g. use profile #5 and device #2) 74 */ 75 class ActivePlayer 76 { 77 friend class StateManager; 78 79 PlayerProfile *m_player; 80 InputDevice *m_device; 81 82 /** Pointer to the kart of this player, only valid during the game. */ 83 AbstractKart *m_kart; 84 85 /** ID of this player within the list of active players */ 86 int m_id; 87 88 ActivePlayer(PlayerProfile* player, InputDevice* device); 89 90 #ifdef DEBUG 91 unsigned int m_magic_number; 92 #endif 93 94 public: 95 96 ~ActivePlayer(); 97 98 #ifdef DEBUG ok()99 bool ok() 100 { 101 return (m_magic_number == 0xAC1EF1AE); 102 } // ok 103 #endif 104 // -------------------------------------------------------------------- 105 /** \return the identity of this active player */ getProfile()106 PlayerProfile* getProfile() 107 { 108 #ifdef DEBUG 109 assert(m_magic_number == 0xAC1EF1AE); 110 #endif 111 return m_player; 112 } // getProfile 113 114 // -------------------------------------------------------------------- 115 /** \return the identity of this active player */ getConstProfile() const116 const PlayerProfile* getConstProfile() const 117 { 118 #ifdef DEBUG 119 assert(m_magic_number == 0xAC1EF1AE); 120 #endif 121 return m_player; 122 } // getConstProfile 123 124 // -------------------------------------------------------------------- 125 /** Call to change the identity of this player (useful when player is 126 * selecting his identity) */ 127 void setPlayerProfile(PlayerProfile* player); 128 129 // -------------------------------------------------------------------- 130 /** ID of this player within the list of active players */ getID() const131 int getID() const 132 { 133 #ifdef DEBUG 134 assert(m_magic_number == 0xAC1EF1AE); 135 #endif 136 return m_id; 137 } // getID 138 // -------------------------------------------------------------------- 139 140 /** \return Which input device this player is using, or NULL if none 141 * is set yet */ getDevice() const142 InputDevice* getDevice() const 143 { 144 #ifdef DEBUG 145 assert(m_magic_number == 0xAC1EF1AE); 146 #endif 147 return m_device; 148 } // getDevice 149 150 // -------------------------------------------------------------------- 151 void setDevice(InputDevice* device); 152 153 // -------------------------------------------------------------------- 154 /** Sets the kart for this player. */ setKart(AbstractKart * kart)155 void setKart(AbstractKart *kart) 156 { 157 #ifdef DEBUG 158 assert(m_magic_number == 0xAC1EF1AE); 159 #endif 160 m_kart = kart; 161 } // setKart 162 163 // -------------------------------------------------------------------- 164 /** \return the kart of this player. Only valid while world exists. */ getKart()165 AbstractKart* getKart() 166 { 167 #ifdef DEBUG 168 assert(m_magic_number == 0xAC1EF1AE); 169 #endif 170 return m_kart; 171 } // getKart 172 173 }; // ActivePlayer 174 175 // ======================================================================== getActivePlayers()176 const PtrVector<ActivePlayer, HOLD>& getActivePlayers() 177 { return m_active_players; } 178 ActivePlayer* getActivePlayer(const int id); 179 180 /** \return the PlayerProfile of a given ActivePlayer. 181 * \param id the ID of the active player for whichyou want the profile 182 */ 183 const PlayerProfile* getActivePlayerProfile(const int id); 184 185 int createActivePlayer(PlayerProfile *profile, InputDevice *device); 186 void removeActivePlayer(int id); 187 188 unsigned int activePlayerCount(); 189 void resetActivePlayers(); 190 191 /** \return whether to reduce FPS at the moment 192 * \note this can be useful to avoid being too CPU/GPU intensive in 193 * parts of the game that don't require high framerates, like 194 * menus 195 */ 196 bool throttleFPS(); 197 198 /** \brief implementing callback from base class AbstractStateManager */ 199 void escapePressed(); 200 201 /** \brief implementing callback from base class AbstractStateManager */ 202 virtual void onGameStateChange(GUIEngine::GameState new_state); 203 204 /** \brief implementing callback from base class AbstractStateManager */ 205 virtual void onStackEmptied(); 206 207 /** \brief implementing callback from base class AbstractStateManager */ 208 virtual void onTopMostScreenChanged(); 209 210 // singleton 211 static StateManager* get(); 212 static void deallocate(); 213 static void clear(); clearMenuStack()214 void clearMenuStack() { m_menu_stack.clear(); } 215 private: 216 /** 217 * A list of all currently playing players. 218 */ 219 PtrVector<ActivePlayer, HOLD> m_active_players; 220 }; 221 222 #endif 223