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_unitH
21 #define game_data_units_unitH
22 
23 #include <string>
24 #include "game/data/units/unitdata.h"
25 #include "utility/signal/signal.h"
26 #include "utility/position.h"
27 
28 class cClient;
29 class cJob;
30 class cMap;
31 class cMapField;
32 class cPlayer;
33 class cServer;
34 class cVehicle;
35 template<typename> class cBox;
36 class cSoundManager;
37 
38 //-----------------------------------------------------------------------------
39 class cUnit
40 {
41 public:
42 	cUnit (const sUnitData* unitData, cPlayer* owner, unsigned int ID);
43 	virtual ~cUnit();
44 
45 	virtual bool isAVehicle() const = 0;
46 	virtual bool isABuilding() const = 0;
47 
48 	cPlayer* getOwner() const;
49 	void setOwner (cPlayer* owner);
50 
51 	virtual bool canTransferTo (const cPosition& position, const cMapField& overUnitField) const = 0;
52 	virtual bool canExitTo (const cPosition& position, const cMap& map, const sUnitData& unitData) const = 0;
53 	virtual std::string getStatusStr (const cPlayer* player) const = 0;
54 
55 	virtual void makeReport (cSoundManager& soundManager) const = 0;
56 
getMovementOffset()57 	virtual const cPosition& getMovementOffset() const { static const cPosition dummy (0, 0); return dummy; }
58 
59 	virtual void setDetectedByPlayer (cServer& server, cPlayer* player, bool addToDetectedInThisTurnList = true) = 0;
60 
61 	const cPosition& getPosition() const;
62 	void setPosition (cPosition position);
63 
64 	cBox<cPosition> getArea() const;
65 
66 	std::vector<cPosition> getAdjacentPositions() const;
67 
68 	int calcHealth (int damage) const;
69 	bool isInRange (const cPosition& position) const;
70 	/// checks whether the coordinates are next to the unit
71 	bool isNextTo (const cPosition& position) const;
isDisabled()72 	bool isDisabled() const { return turnsDisabled > 0; }
73 	bool isAbove (const cPosition& position) const;
74 
75 
getName()76 	const std::string& getName() const { return name; }
isNameOriginal()77 	bool isNameOriginal() const { return isOriginalName; }
78 	std::string getNamePrefix() const;
79 	std::string getDisplayName() const;
80 	void changeName (const std::string& newName);
81 
82 	void rotateTo (int newDir);
83 
84 	/** checks if the unit can attack something at the offset
85 	 *  when forceAttack is false, the function only returns true,
86 	 *  if there is an enemy unit
87 	 *  ATTENTION: must not be called with forceAttack == false
88 	 *             from the server thread!
89 	 */
90 	bool canAttackObjectAt (const cPosition& position, const cMap& map, bool forceAttack = false, bool checkRange = true) const;
91 
92 	/** Upgrades the unit data of this unit to the current,
93 	 * upgraded version of the player.
94 	 */
95 	void upgradeToCurrentVersion();
96 
97 	void setDisabledTurns (int turns);
98 	void setSentryActive (bool value);
99 	void setManualFireActive (bool value);
100 	void setAttacking (bool value);
101 	void setIsBeeinAttacked (bool value);
102 	void setMarkedAsDone (bool value);
103 	void setHasBeenAttacked (bool value);
104 
105 	int getDisabledTurns() const;
106 	bool isSentryActive() const;
107 	bool isManualFireActive() const;
108 	bool isAttacking() const;
109 	bool isBeeingAttacked() const;
110 	bool isMarkedAsDone() const;
111 	bool hasBeenAttacked() const;
112 
113 	//protected:
isUnitMoving()114 	virtual bool isUnitMoving() const { return false; }
isAutoMoveJobActive()115 	virtual bool isAutoMoveJobActive() const { return false; }
isUnitWorking()116 	virtual bool isUnitWorking() const { return false; }
isUnitClearing()117 	virtual bool isUnitClearing() const { return false; }
isUnitLayingMines()118 	virtual bool isUnitLayingMines() const { return false; }
isUnitClearingMines()119 	virtual bool isUnitClearingMines() const { return false; }
isUnitBuildingABuilding()120 	virtual bool isUnitBuildingABuilding() const { return false; }
factoryHasJustFinishedBuilding()121 	virtual bool factoryHasJustFinishedBuilding() const { return false; }
buildingCanBeStarted()122 	virtual bool buildingCanBeStarted() const { return false; }
buildingCanBeUpgraded()123 	virtual bool buildingCanBeUpgraded() const { return false; }
124 	virtual bool canBeStoppedViaUnitMenu() const = 0;
125 
126 	virtual void executeStopCommand (const cClient& client) const = 0;
127 
128 	// Important NOTE: This signal will be triggered when the destructor of the unit gets called.
129 	//                 This means when the signal is triggered it can not be guaranteed that all
130 	//                 of the objects attributes are still valid (especially the ones of derived classes).
131 	//                 Therefor you should not access the unit from a function that connects to this signal!
132 	mutable cSignal<void ()> destroyed;
133 
134 	mutable cSignal<void ()> ownerChanged;
135 
136 	mutable cSignal<void ()> positionChanged;
137 
138 	mutable cSignal<void ()> renamed;
139 	mutable cSignal<void ()> statusChanged;
140 
141 	mutable cSignal<void ()> disabledChanged;
142 	mutable cSignal<void ()> sentryChanged;
143 	mutable cSignal<void ()> manualFireChanged;
144 	mutable cSignal<void ()> attackingChanged;
145 	mutable cSignal<void ()> beeingAttackedChanged;
146 	mutable cSignal<void ()> markedAsDoneChanged;
147 	mutable cSignal<void ()> beenAttackedChanged;
148 	mutable cSignal<void ()> movingChanged;
149 
150 	mutable cSignal<void ()> stored;
151 	mutable cSignal<void ()> activated;
152 
153 	mutable cSignal<void ()> layingMinesChanged;
154 	mutable cSignal<void ()> clearingMinesChanged;
155 	mutable cSignal<void ()> buildingChanged;
156 	mutable cSignal<void ()> clearingChanged;
157 	mutable cSignal<void ()> workingChanged;
158 
159 public: // TODO: make protected/private and make getters/setters
160 	sUnitData data; ///< basic data of the unit
161 	const unsigned int iID; ///< the identification number of this unit
162 	int dir; // ?Frame of the unit/current direction the unit is facing?
163 
164 	std::vector<cVehicle*> storedUnits; ///< list with the vehicles, that are stored in this unit
165 
166 	std::vector<cPlayer*> seenByPlayerList; ///< a list of all players who can see this unit
167 	std::vector<cPlayer*> detectedByPlayerList; ///< a list of all players who have detected this unit
168 
169 	// little jobs, running on the vehicle.
170 	// e.g. rotating to a specific direction
171 	cJob* job;
172 
173 	mutable int alphaEffectValue;
174 
175 	//-----------------------------------------------------------------------------
176 private:
177 	cPlayer* owner;
178 	cPosition position;
179 
180 	bool isOriginalName; // indicates whether the name has been changed by the player or not
181 	std::string name;    // name of the building
182 
183 	int turnsDisabled;  ///< the number of turns this unit will be disabled, 0 if the unit is active
184 	bool sentryActive; ///< is the unit on sentry?
185 	bool manualFireActive; ///< if active, then the unit only fires by manual control and not as reaction fire
186 	bool attacking;  ///< is the unit currently attacking?
187 	bool beeingAttacked; ///< true when an attack on this unit is running
188 	bool markedAsDone; ///< the player has pressed the done button for this unit
189 	bool beenAttacked; //the unit was attacked in this turn
190 };
191 
192 template<typename T>
193 struct sUnitLess
194 {
195 	//static_assert(std::is_base_of<cUnit, T>::value, "Invalid template parameter. Has to be of a derived class of cUnit!");
196 
operatorsUnitLess197 	bool operator() (const std::shared_ptr<T>& left, const std::shared_ptr<T>& right) const
198 	{
199 		return left->iID < right->iID;
200 	}
operatorsUnitLess201 	bool operator() (const std::shared_ptr<T>& left, const T& right) const
202 	{
203 		return left->iID < right.iID;
204 	}
operatorsUnitLess205 	bool operator() (const T& left, const std::shared_ptr<T>& right) const
206 	{
207 		return left.iID < right->iID;
208 	}
operatorsUnitLess209 	bool operator() (const T& left, const T& right) const
210 	{
211 		return left.iID < right.iID;
212 	}
operatorsUnitLess213 	bool operator() (unsigned int left, const T& right) const
214 	{
215 		return left < right.iID;
216 	}
operatorsUnitLess217 	bool operator() (const T& left, unsigned int right) const
218 	{
219 		return left.iID < right;
220 	}
operatorsUnitLess221 	bool operator() (unsigned int left, const std::shared_ptr<T>& right) const
222 	{
223 		return left < right->iID;
224 	}
operatorsUnitLess225 	bool operator() (const std::shared_ptr<T>& left, unsigned int right) const
226 	{
227 		return left->iID < right;
228 	}
229 };
230 
231 #endif // game_data_units_unitH
232