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 ROOM_H
19 #define ROOM_H
20 
21 #include "entities/Building.h"
22 
23 #include <string>
24 #include <iosfwd>
25 
26 class BuildingObject;
27 class GameMap;
28 class InputCommand;
29 class InputManager;
30 class ODPacket;
31 class Seat;
32 
33 enum class RoomType;
34 
35 class Room : public Building
36 {
37 public:
38     // When room types are added to this enum they also need to be added to the switch statements in Room.cpp.
39 
40     // Constructors and operators
41     Room(GameMap* gameMap);
~Room()42     virtual ~Room()
43     {}
44 
45     virtual GameEntityType getObjectType() const override;
46 
isBridge()47     virtual bool isBridge() const
48     { return false; }
49 
50     virtual void addToGameMap();
51     virtual void removeFromGameMap() override;
52 
53     virtual void absorbRoom(Room* r);
54 
55     //! \brief By default, we consider that creatures using the room are working and
56     //! should be forced to work in the new room (if possible). If not, this function
57     //! should be overriden
58     virtual void handleCreatureUsingAbsorbedRoom(Creature& creature);
59 
60     static std::string getRoomStreamFormat();
61 
62     virtual RoomType getType() const = 0;
63 
64     static bool compareTile(Tile* tile1, Tile* tile2);
65 
66     //! \brief Adds a creature using the room. If the creature is allowed, true is returned
67     virtual bool addCreatureUsingRoom(Creature* c);
68     virtual void removeCreatureUsingRoom(Creature* c);
69     virtual Creature* getCreatureUsingRoom(unsigned index);
hasOpenCreatureSpot(Creature * c)70     virtual bool hasOpenCreatureSpot(Creature* c) { return false; }
71 
72     //! \brief Called by the creature during its upkeep when using the room when it is ready
73     //! to do something (no cooldown or no other action).
74     //! Returns true if the action queue should continue to be proceeded and false otherwise
useRoom(Creature & creature,bool forced)75     virtual bool useRoom(Creature& creature, bool forced)
76     { return false; }
77 
78     //! \brief Returns true if the creature should stop using the room if hungry/sleepy
shouldStopUseIfHungrySleepy(Creature & creature,bool forced)79     virtual bool shouldStopUseIfHungrySleepy(Creature& creature, bool forced)
80     { return true; }
81 
82     //! \brief Returns true if the creature should not use room if in bad mood
shouldNotUseIfBadMood(Creature & creature,bool forced)83     virtual bool shouldNotUseIfBadMood(Creature& creature, bool forced)
84     { return true; }
85 
86     //! \brief Updates the active spot lists.
87     virtual void updateActiveSpots();
88 
getNumActiveSpots()89     inline unsigned int getNumActiveSpots() const
90     { return mNumActiveSpots; }
91 
92     //! \brief Sets the name, seat and associates the given tiles with the room
93     virtual void setupRoom(const std::string& name, Seat* seat, const std::vector<Tile*>& tiles);
94 
95     //! \brief Checks on the neighboor tiles of the room if there are other rooms of the same type/same seat.
96     //! if so, it aborbs them
97     void checkForRoomAbsorbtion();
98 
99     //! \brief returns true if the room can be repaired and there are destroyed tiles. false otherwise.
100     bool canBeRepaired() const;
101 
102     virtual int getCostRepair();
103 
104     //! \brief Repairs the destroyed tiles of the room
105     virtual void repairRoom();
106 
107     virtual void restoreInitialEntityState() override;
108 
109     static bool sortForMapSave(Room* r1, Room* r2);
110 
111     //! \brief Returns the total gold that can be stored in the room
getTotalGoldStorage()112     virtual int getTotalGoldStorage() const
113     { return 0; }
114 
115     //! \brief Returns the total gold that is stored in the room
getTotalGoldStored()116     virtual int getTotalGoldStored() const
117     { return 0; }
118 
119     //! \brief Deposits the given gold in the room. Returns the gold that could
120     //! be deposited (may be less than the given amount if not enough space)
depositGold(int gold,Tile * tile)121     virtual int depositGold(int gold, Tile *tile)
122     { return 0; }
123 
124     //! \brief Tries to withdraw gold from the room. Returns the amount that could
125     //! be taken (may be less than gold if not enough gold)
withdrawGold(int gold)126     virtual int withdrawGold(int gold)
127     { return 0; }
128 
129     virtual void creatureDropped(Creature& creature) override;
130 
isInContainment(Creature & creature)131     virtual bool isInContainment(Creature& creature)
132     { return false; }
133 
134     static bool importRoomFromStream(Room& room, std::istream& is);
135 
136 protected:
137     static void fireRoomSound(Tile& tile, const std::string& soundFamily);
138 
139     /*! \brief Exports the headers needed to recreate the Room. It allows to extend Room as much as wanted.
140      * The content of the Room will be exported by exportToPacket.
141      */
142     virtual void exportHeadersToStream(std::ostream& os) const override;
143     void exportTileDataToStream(std::ostream& os, Tile* tile, TileData* tileData) const;
144     bool importTileDataFromStream(std::istream& is, Tile* tile, TileData* tileData);
145 
146     enum ActiveSpotPlace
147     {
148         activeSpotCenter,
149         activeSpotTop,
150         activeSpotBottom,
151         activeSpotLeft,
152         activeSpotRight
153     };
154     std::vector<Creature*> mCreaturesUsingRoom;
155 
156     //! \brief Lists the active spots in the middle of 3x3 squares.
157     std::vector<Tile*> mCentralActiveSpotTiles;
158     std::vector<Tile*> mLeftWallsActiveSpotTiles;
159     std::vector<Tile*> mRightWallsActiveSpotTiles;
160     std::vector<Tile*> mTopWallsActiveSpotTiles;
161     std::vector<Tile*> mBottomWallsActiveSpotTiles;
162 
163     //! \brief The number of active spots.
164     unsigned int mNumActiveSpots;
165 
166     virtual BuildingObject* notifyActiveSpotCreated(ActiveSpotPlace place, Tile* tile);
167     virtual void notifyActiveSpotRemoved(ActiveSpotPlace place, Tile* tile);
168 
169     //! \brief This function will be called when reordering room is needed (for example if another room has been absorbed)
170     static void reorderRoomTiles(std::vector<Tile*>& tiles);
171 private :
172     void activeSpotCheckChange(ActiveSpotPlace place, const std::vector<Tile*>& originalSpotTiles,
173         const std::vector<Tile*>& newSpotTiles);
174 
175 };
176 
177 #endif // ROOM_H
178