1 /* 2 * Copyright (C) 2011-2016 OpenDungeons Team 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (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, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #ifndef PLAYER_H 19 #define PLAYER_H 20 21 #include <OgrePrerequisites.h> 22 23 #include <string> 24 #include <vector> 25 #include <cstdint> 26 27 class Creature; 28 class GameMap; 29 class GameEntity; 30 class ODPacket; 31 class Skill; 32 class Seat; 33 class Tile; 34 35 enum class CreatureActionType; 36 enum class SpellType; 37 38 enum class PlayerEventType 39 { 40 nullType, 41 fight 42 }; 43 44 ODPacket& operator<<(ODPacket& os, const PlayerEventType& type); 45 ODPacket& operator>>(ODPacket& is, PlayerEventType& type); 46 47 //! Class that represents the events where the player can zoom 48 class PlayerEvent 49 { 50 public: PlayerEvent()51 PlayerEvent() : 52 mType(PlayerEventType::nullType), 53 mTile(nullptr), 54 mTimeRemain(0.0) 55 { 56 } 57 PlayerEvent(PlayerEventType type,Tile * tile,Ogre::Real timeRemain)58 PlayerEvent(PlayerEventType type, Tile* tile, Ogre::Real timeRemain) : 59 mType(type), 60 mTile(tile), 61 mTimeRemain(timeRemain) 62 { 63 } 64 getType()65 inline PlayerEventType getType() const 66 { return mType; } 67 getTile()68 inline Tile* getTile() const 69 { return mTile; } 70 getTimeRemain()71 inline float getTimeRemain() const 72 { return mTimeRemain; } 73 setTimeRemain(float timeRemain)74 inline void setTimeRemain(float timeRemain) 75 { mTimeRemain = timeRemain; } 76 77 static PlayerEvent* getPlayerEventFromPacket(GameMap* gameMap, ODPacket& is); 78 static void exportPlayerEventToPacket(PlayerEvent* event, GameMap* gameMap, ODPacket& is); 79 80 protected: 81 void exportToPacket(GameMap* gameMap, ODPacket& os); 82 void importFromPacket(GameMap* gameMap, ODPacket& is); 83 84 private: 85 PlayerEventType mType; 86 Tile* mTile; 87 float mTimeRemain; 88 }; 89 90 class PlayerSpellData 91 { 92 public: PlayerSpellData(uint32_t cooldownNbTurnPending,float cooldownTimePendingTurn)93 PlayerSpellData(uint32_t cooldownNbTurnPending, float cooldownTimePendingTurn) : 94 mCooldownNbTurnPending(cooldownNbTurnPending), 95 mCooldownTimePendingTurn(cooldownTimePendingTurn) 96 {} 97 98 uint32_t mCooldownNbTurnPending; 99 float mCooldownTimePendingTurn; 100 }; 101 102 /*! \brief The player class contains information about a human, or computer, player in the game. 103 * 104 * When a new player joins a game being hosted on a server the server will 105 * allocate a new Player structure and fill it in with the appropriate values. 106 * Its relevant information will then be sent to the other players in the game 107 * so they are aware of its presence. 108 */ 109 class Player 110 { 111 friend class Seat; 112 public: 113 enum class Direction 114 { 115 left = -1, 116 right = 1 117 }; 118 119 Player(GameMap* gameMap, int32_t id); 120 getId()121 inline int32_t getId() const 122 { return mId; } 123 getNick()124 const std::string& getNick() const 125 { return mNickname; } 126 getSeat()127 Seat* getSeat() 128 { return mSeat; } 129 getSeat()130 const Seat* getSeat() const 131 { return mSeat; } 132 setNick(const std::string & nick)133 void setNick (const std::string& nick) 134 { mNickname = nick; } 135 136 //! \brief A simple accessor function to return the number of creatures 137 //! this player is holding in his/her hand that belongs to seat seat. 138 //! If seat is nullptr, then returns the total number of creatures 139 unsigned int numCreaturesInHand(const Seat* seat = nullptr) const; 140 unsigned int numObjectsInHand() const; 141 142 /*! \brief Check to see if it is the user or another player picking up the creature and act accordingly. 143 * 144 * This function takes care of all of the operations required for a player to 145 * pick up an object (creature, treasury, ...). If the player is the user we need to move the creature 146 * oncreen to the "hand" as well as add the creature to the list of creatures 147 * in our own hand, this is done by setting moveToHand to true. If move to 148 * hand is false we just hide the creature (and stop its AI, etc.), rather than 149 * making it follow the cursor. 150 */ 151 void pickUpEntity(GameEntity *entity); 152 153 //! \brief Check to see the first object in hand can be dropped on Tile t and do so if possible. 154 bool isDropHandPossible(Tile *t, unsigned int index = 0); 155 156 //! \brief Drops the creature on tile t. Returns the dropped creature 157 void dropHand(Tile *t, unsigned int index = 0); 158 159 void rotateHand(Direction d); 160 161 //! \brief Clears all creatures that a player might have in his hand 162 void clearObjectsInHand(); 163 164 //! \brief Clears all creatures that a player might have in his hand 165 void notifyNoMoreDungeonTemple(); 166 getIsHuman()167 inline bool getIsHuman() const 168 { return mIsHuman; } 169 setIsHuman(bool isHuman)170 inline void setIsHuman(bool isHuman) 171 { mIsHuman = isHuman; } 172 getObjectsInHand()173 inline const std::vector<GameEntity*>& getObjectsInHand() 174 { return mObjectsInHand; } 175 getHasLost()176 inline bool getHasLost() const 177 { return mHasLost; } 178 179 //! \brief Notify the player is fighting 180 //! Should be called on the server game map for human players only. tile represents 181 //! the place where the fight is happening and player is the Player actually fighting 182 void notifyTeamFighting(Player* player, Tile* tile); 183 184 //! \brief Notify the player that they are not skill anything 185 //! Should be called on the server game map for human players only 186 void notifyNoSkillInQueue(); 187 188 //! \brief Notify the player that he has no worker 189 void notifyNoWorker(); 190 191 //! \brief Notify the player that no treasury tiles are available for gold storage 192 //! Should be called on the server game map for human players only 193 void notifyNoTreasuryAvailable(); 194 195 //! \brief Notify the player that a creature cannot find a bed 196 void notifyCreatureCannotFindBed(Creature& creature); 197 198 //! \brief Notify the player that a creature cannot find a bed 199 void notifyCreatureCannotFindFood(Creature& creature); 200 201 void fireEvents(); 202 203 //! \brief Called on client side to update the current list of events. Note that 204 //! the time remaining of PlayerEvent class is not relevant on client side 205 void updateEvents(const std::vector<PlayerEvent*>& events); 206 207 //! \brief Get the next event. After index. If index > events size, the first one is 208 //! sent. When the function returns, index is set to the index of the returned event 209 //! and it returns the PlayerEvent if any (nullptr is none). 210 //! Note that on client side, PlayerEvent::mTimeRemain is not relevant 211 const PlayerEvent* getNextEvent(uint32_t& index) const; 212 213 //! \brief Marks the tiles for digging and send the refresh event to concerned player if human 214 void markTilesForDigging(bool marked, const std::vector<Tile*>& tiles, bool asyncMsg); 215 216 //! \brief Gets the spell cooldown in turns for the given spell 217 uint32_t getSpellCooldownTurns(SpellType spellType) const; 218 219 //! \brief Gets the spell cooldown as a smooth value 0 being no cooldown and 1 220 //! max cooldown for the given spell 221 float getSpellCooldownSmooth(SpellType spellType) const; 222 float getSpellCooldownSmoothTime(SpellType spellType) const; 223 224 void setSpellCooldownTurns(SpellType spellType, uint32_t cooldown); 225 226 //! \brief Called each turn, it should handle Player upkeep on server side 227 void upkeepPlayer(double timeSinceLastUpkeep); 228 229 //! \brief Decreases cooldown for all spells. Used on both server and client sides 230 void decreaseSpellCooldowns(); 231 232 //! \brief Called each time a frame is displayed. Called on client side 233 void frameStarted(float timeSinceLastFrame); 234 235 //! \brief Called when a worker picks up a new action 236 void notifyWorkerAction(Creature& worker, CreatureActionType actionType); 237 void notifyWorkerStopsAction(Creature& worker, CreatureActionType actionType); 238 239 //! \brief Returns how many workers are doing the given action 240 uint32_t getNbWorkersDoing(CreatureActionType actionType) const; 241 242 //! \brief Returns a list of the actions the worker should do based on what the other workers 243 //! of this seat are doing. The worker should try the actions on the given order 244 std::vector<CreatureActionType> getWorkerPreferredActions(Creature& worker) const; 245 246 private: 247 //! \brief Player ID is only used during seat configuration phase 248 //! During the game, one should use the seat ID to identify a player because 249 //! every AI player has an id = 0. 250 //! ID is unique only for human players 251 int32_t mId; 252 253 GameMap* mGameMap; 254 Seat *mSeat; 255 256 //! \brief The nickname used in chat, etc. 257 std::string mNickname; 258 259 //! \brief The creature the player has got in hand. 260 std::vector<GameEntity*> mObjectsInHand; 261 262 //! True: player is human. False: player is a computer/inactive. 263 bool mIsHuman; 264 265 //! \brief This counter tells for how much time is left before considering 266 //! the player should be notified again that he has not queued a skill. 267 float mNoSkillInQueueTime; 268 269 //! \brief This counter tells for how much time is left before considering 270 //! the player should be notified again that he has no worker. 271 float mNoWorkerTime; 272 273 //! \brief This counter tells for how much time is left before considering 274 //! the player should be notified again that he has no free space to store gold. 275 float mNoTreasuryAvailableTime; 276 277 //! \brief This counter tells how much time is left before considering 278 //! the player should be notified again that a creature cannot find place in a dormitory. 279 float mCreatureCannotFindBed; 280 281 //! \brief This counter tells how much time is left before considering 282 //! the player should be notified again that a creature cannot find place in a hatchery. 283 float mCreatureCannotFindFood; 284 285 bool mHasLost; 286 287 //! \brief List of tiles there is an event on. Used on client and server 288 std::vector<PlayerEvent*> mEvents; 289 290 //! \brief Cooldown for every spells. Used on client and server. 291 //! the first value is the cooldown in turn. The second is the smooth time (set to 292 //! 1 turn duration at each refresh) 293 //! Note that the second value is used on client side only 294 std::vector<PlayerSpellData> mSpellsCooldown; 295 296 //! \brief Used to know what the workers are doing. That will help to change 297 //! probability to choose the action to do 298 std::vector<uint32_t> mWorkersActions; 299 300 //! \brief A simple mutator function to put the given entity into the player's hand, 301 //! note this should NOT be called directly for creatures on the map, 302 //! for that you should use the correct function like pickUpEntity() instead. 303 void addEntityToHand(GameEntity *entity); 304 }; 305 306 #endif // PLAYER_H 307