1 /***************************************************************************
2  *      Mechanized Assault and Exploration Reloaded Projectfile            *
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 2 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, write to the                         *
16  *   Free Software Foundation, Inc.,                                       *
17  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
18  ***************************************************************************/
19 
20 #ifndef game_data_units_buildingH
21 #define game_data_units_buildingH
22 
23 #include <vector>
24 #include <array>
25 
26 #include <SDL.h>
27 
28 #include "defines.h"
29 #include "maxrconfig.h"
30 #include "main.h" // for sUnitData, sID
31 #include "game/data/units/unit.h"
32 #include "sound.h"
33 #include "utility/signal/signal.h"
34 #include "utility/signal/signalconnectionmanager.h"
35 #include "game/logic/upgradecalculator.h" // cResearch::ResearchArea
36 
37 class cBase;
38 class cPlayer;
39 class cVehicle;
40 class cMap;
41 class cMapField;
42 class cServer;
43 
44 //--------------------------------------------------------------------------
45 /** Struct for one upgrade (one kind of value, e.g. hitpointsMax) */
46 //--------------------------------------------------------------------------
47 struct sUpgrade
48 {
49 	bool active; // is this upgrade buyable for the player
50 	int NextPrice; // what will the next upgrade cost
51 	int Purchased;
52 	int* value; // what is the current value
53 	int StartValue; // the initial value for this unit type
54 	std::string name; // the name of this upgrade type, e.g. Ammo
55 };
56 
57 //--------------------------------------------------------------------------
58 /** Struct for one upgrade (one kind of value, e.g. hitpointsMax)
59 	When the hangar is made nice code, too, the sUpgradeNew and the sUpgrade have to be united, again. */
60 //--------------------------------------------------------------------------
61 struct sUpgradeNew
62 {
63 	bool active; // is this upgrade buyable for the player
64 	int nextPrice; // what will the next upgrade cost
65 	int purchased; // how many upgrades of this type has the player purchased
66 	int curValue; // what is the current value
67 	int startValue; // the value that this unit would have without all upgrades
68 	std::string name; // the name of this upgrade type, e.g. Ammo
69 };
70 
71 //--------------------------------------------------------------------------
72 /** struct for the images and sounds */
73 //--------------------------------------------------------------------------
74 struct sBuildingUIData
75 {
76 	AutoSurface img, img_org; // Surface of the building
77 	AutoSurface shw, shw_org; // Surfaces of the shadow
78 	AutoSurface eff, eff_org; // Surfaces of the effects
79 	AutoSurface video;  // video
80 	AutoSurface info;   // info image
81 
82 	// Die Sounds:
83 	cSoundChunk Start;
84 	cSoundChunk Running;
85 	cSoundChunk Stop;
86 	cSoundChunk Attack;
87 	cSoundChunk Wait;
88 
89 	sBuildingUIData();
90 	sBuildingUIData (sBuildingUIData&& other);
91 	sBuildingUIData& operator= (sBuildingUIData && other);
92 	void scaleSurfaces (float faktor);
93 
94 private:
95 	sBuildingUIData (const sBuildingUIData& other) MAXR_DELETE_FUNCTION;
96 	sBuildingUIData& operator= (const sBuildingUIData& other) MAXR_DELETE_FUNCTION;
97 };
98 
99 // enum for the upgrade symbols
100 #ifndef D_eSymbols
101 #define D_eSymbols
102 enum eSymbols {SSpeed, SHits, SAmmo, SMetal, SEnergy, SShots, SOil, SGold, STrans, SHuman, SAir};
103 enum eSymbolsBig {SBSpeed, SBHits, SBAmmo, SBAttack, SBShots, SBRange, SBArmor, SBScan, SBMetal, SBOil, SBGold, SBEnergy, SBHuman};
104 #endif
105 
106 //--------------------------------------------------------------------------
107 /** struct for the building order list */
108 //--------------------------------------------------------------------------
109 class cBuildListItem
110 {
111 public:
112 	cBuildListItem();
113 	cBuildListItem (sID type, int remainingMetal);
114 	cBuildListItem (const cBuildListItem& other);
115 	cBuildListItem (cBuildListItem&& other);
116 
117 	cBuildListItem& operator= (const cBuildListItem& other);
118 	cBuildListItem& operator= (cBuildListItem && other);
119 
120 	const sID& getType() const;
121 	void setType (const sID& type);
122 
123 	int getRemainingMetal() const;
124 	void setRemainingMetal (int value);
125 
126 	cSignal<void ()> typeChanged;
127 	cSignal<void ()> remainingMetalChanged;
128 private:
129 	sID type;
130 	int remainingMetal;
131 };
132 
133 //--------------------------------------------------------------------------
134 enum ResourceKind
135 {
136 	TYPE_METAL = 0,
137 	TYPE_OIL   = 1,
138 	TYPE_GOLD  = 2
139 };
140 
141 //--------------------------------------------------------------------------
142 /** Class cBuilding for one building. */
143 //--------------------------------------------------------------------------
144 class cBuilding : public cUnit
145 {
146 public:
147 	cBuilding (const sUnitData* b, cPlayer* Owner, unsigned int ID);
148 	virtual ~cBuilding();
149 
isAVehicle()150 	virtual bool isAVehicle() const { return false; }
isABuilding()151 	virtual bool isABuilding() const { return true; }
152 
153 	const sBuildingUIData* uiData;
154 	mutable int effectAlpha; // alpha value for the effect
155 
156 	int RubbleTyp;     // Typ des Drecks
157 	int RubbleValue;   // Wert des Drecks
158 	bool BaseN, BaseE, BaseS, BaseW; // is the building connected in this direction?
159 	bool BaseBN, BaseBE, BaseBS, BaseBW; // is the building connected in this direction (only for big buildings)
160 	struct sSubBase* SubBase;     // the subbase to which this building belongs
161 	int MaxMetalProd, MaxOilProd, MaxGoldProd; // the maximum possible production of the building
162 	int DamageFXPointX, DamageFXPointY, DamageFXPointX2, DamageFXPointY2; // the points, where smoke will be generated when the building is damaged
163 	/** true if the building was has been working before it was disabled */
164 	bool wasWorking;
165 	int points;     // accumulated eco-sphere points
166 
167 	int playStream();
168 	virtual std::string getStatusStr (const cPlayer* player) const MAXR_OVERRIDE_FUNCTION;
169 
170 	virtual void makeReport (cSoundManager& soundManager) const MAXR_OVERRIDE_FUNCTION;
171 
172 	/**
173 	* refreshes the shotsCur of this building
174 	*@author alzi alias DoctorDeath
175 	*@return 1 if there has been refreshed something, else 0.
176 	*/
177 	bool refreshData();
178 	void DrawSymbolBig (eSymbolsBig sym, int x, int y, int maxx, int value, int orgvalue, SDL_Surface* sf);
179 	void updateNeighbours (const cMap& map);
180 	void CheckNeighbours (const cMap& Map);
181 	void ServerStartWork (cServer& server);
182 	void clientStartWork();
183 	void ServerStopWork (cServer& server, bool override);
184 	void clientStopWork();
185 	/** check whether a transfer to a unit on the field is possible */
186 	virtual bool canTransferTo (const cPosition& position, const cMapField& overUnitField) const MAXR_OVERRIDE_FUNCTION;
187 	void CheckRessourceProd (const cServer& server);
188 	void calcTurboBuild (std::array<int, 3>& turboBuildRounds, std::array<int, 3>& turboBuildCosts, int vehicleCosts, int remainingMetal = -1) const;
189 	virtual bool canExitTo (const cPosition& position, const cMap& map, const sUnitData& unitData) const MAXR_OVERRIDE_FUNCTION;
190 	bool canLoad (const cPosition& position, const cMap& map, bool checkPosition = true) const;
191 	bool canLoad (const cVehicle* Vehicle, bool checkPosition = true) const;
192 	void storeVehicle (cVehicle& vehicle, cMap& map);
193 	void exitVehicleTo (cVehicle& vehicle, const cPosition& position, cMap& map);
194 
195 	/**
196 	* returns whether this player has detected this unit or not
197 	*@author alzi alias DoctorDeath
198 	*@param player player for which the status should be checked
199 	*@return true if the player has detected the unit
200 	*/
201 	bool isDetectedByPlayer (const cPlayer* player) const;
202 	/**
203 	* removes a player from the detectedByPlayerList
204 	*/
205 	void resetDetectedByPlayer (const cPlayer* player);
206 	/**
207 	* adds a player to the DetecedByPlayerList
208 	*/
209 	virtual void setDetectedByPlayer (cServer& server, cPlayer* player, bool addToDetectedInThisTurnList = true);
210 	/**
211 	* - checks whether the building has been detected by an other unit
212 	* the detection maps have to be up to date, when calling this function
213 	* this function has to be called on the server
214 	* every time a building is added
215 	*/
216 	void makeDetection (cServer& server);
217 
218 	/**
219 	* draws the main image of the building onto the given surface
220 	*/
221 	void render (unsigned long long animationTime, SDL_Surface* surface, const SDL_Rect& dest, float zoomFactor, bool drawShadow, bool drawConcrete) const;
222 	void render_simple (SDL_Surface* surface, const SDL_Rect& dest, float zoomFactor, int animationTime = 0, int alpha = 254) const;
223 	static void render_simple (SDL_Surface* surface, const SDL_Rect& dest, float zoomFactor, const sUnitData& data, const sBuildingUIData& uiData, const cPlayer* owner, int frameNr = 0, int alpha = 254);
224 
225 	void executeUpdateBuildingCommmand (const cClient& client, bool updateAllOfSameType) const;
226 
isUnitWorking()227 	virtual bool isUnitWorking() const { return isWorking; }
228 	virtual bool factoryHasJustFinishedBuilding() const;
229 	virtual bool buildingCanBeStarted() const;
230 	virtual bool buildingCanBeUpgraded() const;
canBeStoppedViaUnitMenu()231 	virtual bool canBeStoppedViaUnitMenu() const { return isUnitWorking(); }
232 
233 	bool isBuildListEmpty() const;
234 	size_t getBuildListSize() const;
235 	const cBuildListItem& getBuildListItem (size_t index) const;
236 	cBuildListItem& getBuildListItem (size_t index);
237 	void setBuildList (std::vector<cBuildListItem> buildList);
238 	void addBuildListItem (cBuildListItem item);
239 	void removeBuildListItem (size_t index);
240 
241 	int getBuildSpeed() const;
242 	int getMetalPerRound() const;
243 	bool getRepeatBuild() const;
244 
245 	void setWorking (bool value);
246 	void setBuildSpeed(int value);
247 	void setMetalPerRound(int value);
248 	void setRepeatBuild(bool value);
249 
250 	void setResearchArea (cResearch::ResearchArea area);
251 	cResearch::ResearchArea getResearchArea() const;
252 
253 	cSignal<void ()> buildListChanged;
254 	cSignal<void ()> buildListFirstItemDataChanged;
255 	cSignal<void ()> researchAreaChanged;
256 
257 	cSignal<void()> buildSpeedChanged;
258 	cSignal<void()> metalPerRoundChanged;
259 	cSignal<void()> repeatBuildChanged;
260 private:
261 	cSignalConnectionManager buildListFirstItemSignalConnectionManager;
262 	cSignalConnectionManager ownerSignalConnectionManager;
263 
264 	/**
265 	* draws the connectors onto the given surface
266 	*/
267 	void drawConnectors (SDL_Surface* surface, SDL_Rect dest, float zoomFactor, bool drawShadow) const;
268 
269 	void render_rubble (SDL_Surface* surface, const SDL_Rect& dest, float zoomFactor, bool drawShadow) const;
270 	void render_beton (SDL_Surface* surface, const SDL_Rect& dest, float zoomFactor) const;
271 
272 	bool isWorking;  // is the building currently working?
273 
274 	int buildSpeed;
275 	int metalPerRound;
276 	bool repeatBuild;
277 
278 	cResearch::ResearchArea researchArea; ///< if the building can research, this is the area the building last researched or is researching
279 
280 	std::vector<cBuildListItem> buildList; // list with the units to be build by this factory
281 
282 	void registerOwnerEvents();
283 
284 	//-----------------------------------------------------------------------------
285 protected:
286 	//-- methods, that have been extracted during cUnit refactoring ---------------
287 
288 	// methods needed for execution of unit menu commands
289 	virtual void executeStopCommand (const cClient& client) const MAXR_OVERRIDE_FUNCTION;
290 };
291 
292 #endif // game_data_units_buildingH
293