1 /*
2  *  This file is part of Dune Legacy.
3  *
4  *  Dune Legacy 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  *  Dune Legacy 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 Dune Legacy.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef OBJECTBASE_H
19 #define OBJECTBASE_H
20 
21 #include <ObjectPointer.h>
22 
23 #include <Definitions.h>
24 #include <DataTypes.h>
25 #include <fixmath/FixPoint.h>
26 #include <mmath.h>
27 
28 #include <globals.h>
29 
30 #include <algorithm>
31 
32 #include <SDL.h>
33 
34 // forward declarations
35 class House;
36 class InputStream;
37 class OutputStream;
38 class ObjectInterface;
39 class Coord;
40 template<class WidgetData> class Container;
41 
42 #define VIS_ALL -1
43 
44 /*!
45     Class from which all structure and unit classes are derived
46 */
47 class ObjectBase
48 {
49 public:
50 
51     explicit ObjectBase(House* newOwner);
52     explicit ObjectBase(InputStream& stream);
53     void init();
54     virtual ~ObjectBase();
55 
56     virtual void save(OutputStream& stream) const;
57 
58     virtual ObjectInterface* getInterfaceContainer();
59 
60     virtual void assignToMap(const Coord& pos) = 0;
61     virtual void blitToScreen() = 0;
62 
drawSelectionBox()63     virtual void drawSelectionBox() { ; };
drawOtherPlayerSelectionBox()64     virtual void drawOtherPlayerSelectionBox() { ; };
65 
66     virtual void destroy() = 0;
67 
68     virtual Coord getClosestCenterPoint(const Coord& objectLocation) const;
69 
70     virtual bool canAttack(const ObjectBase* object) const;
71 
72     virtual Coord getCenterPoint() const;
73 
74     virtual void handleDamage(int damage, Uint32 damagerID, House* damagerOwner);
75 
76     /**
77         This method is called when an object is ordered by a right click
78         \param  xPos    the x position on the map
79         \param  yPos    the y position on the map
80     */
81     virtual void handleActionClick(int xPos, int yPos) = 0;
82 
83     virtual void doRepair() = 0;
84 
85     virtual void handleInterfaceEvent(SDL_Event* event);
86 
87     virtual void playSelectSound() = 0;
88     virtual void playConfirmSound() = 0;
89 
90     void removeFromSelectionLists();
91 
92     virtual void setDestination(int newX, int newY);
93     virtual void setHealth(FixPoint newHealth);
94 
95     virtual void setLocation(int xPos, int yPos);
96 
97     void setObjectID(int newObjectID);
98 
99     virtual void setTarget(const ObjectBase* newTarget);
100     void setVisible(int team, bool status);
101 
102     /**
103         Updates this object.
104         \return true if this object still exists, false if it was destroyed
105     */
106     virtual bool update() = 0;
107 
108     void unassignFromMap(const Coord& location);
109 
110     bool isOnScreen() const;
111     bool isVisible(int team) const;
112     bool isVisible() const;
113     Uint32 getHealthColor() const;
114 
115     /**
116         This method returns the closest coordinate of this object to objectLocation. If this is a building
117         it returns the coordinate of the tile of the building that is closest to this object.
118         \param objectLocation the location of the other object
119         \return the coordinate that is closest in tile coordinates
120     */
121     virtual Coord getClosestPoint(const Coord& objectLocation) const;
122 
123     const StructureBase* findClosestTargetStructure() const;
124     const UnitBase* findClosestTargetUnit() const;
125     const ObjectBase* findClosestTarget() const;
126     virtual const ObjectBase* findTarget() const;
127 
addHealth()128     inline void addHealth() { if (health < getMaxHealth()) setHealth(health + 1); }
setActive(bool status)129     inline void setActive(bool status) { active = status; }
setForced(bool status)130     inline void setForced(bool status) { forced = status; }
setRespondable(bool status)131     inline void setRespondable(bool status) { respondable = status; }
setSelected(bool value)132     inline void setSelected(bool value) { selected = value; }
setSelectedByOtherPlayer(bool value)133     inline void setSelectedByOtherPlayer(bool value) { selectedByOtherPlayer = value; }
setDestination(const Coord & location)134     inline void setDestination(const Coord& location) { setDestination(location.x, location.y); }
setLocation(const Coord & location)135     inline void setLocation(const Coord& location) { setLocation(location.x, location.y); }
canAttack()136     inline bool canAttack() const { return canAttackStuff; }
hasATarget()137     inline bool hasATarget() const { return (target); }
hasObjectID(Uint32 id)138     inline bool hasObjectID(Uint32 id) const { return (objectID == id); }
isActive()139     inline bool isActive() const { return active; }
isAFlyingUnit()140     inline bool isAFlyingUnit() const { return aFlyingUnit; }
isAGroundUnit()141     inline bool isAGroundUnit() const { return aGroundUnit; }
isAStructure()142     inline bool isAStructure() const { return aStructure; }
isABuilder()143     inline bool isABuilder() const { return aBuilder; }
isInfantry()144     inline bool isInfantry() const { return infantry; }
isAUnit()145     inline bool isAUnit() const { return aUnit; }
isRespondable()146     inline bool isRespondable() const { return respondable; }
isSelected()147     inline bool isSelected() const { return selected; }
isSelectedByOtherPlayer()148     inline bool isSelectedByOtherPlayer() const { return selectedByOtherPlayer; }
isBadlyDamaged()149     inline bool isBadlyDamaged() const { return badlyDamaged; };
wasForced()150     inline bool wasForced() const { return forced; }
getItemID()151     inline int getItemID() const { return itemID; }
getX()152     inline int getX() const { return location.x; }
getY()153     inline int getY() const { return location.y; }
154 
getHealth()155     inline FixPoint getHealth() const { return health; }
156     int getMaxHealth() const;
getObjectID()157     inline Uint32 getObjectID() const { return objectID; }
158 
159 
160     int getViewRange() const;
161     int getAreaGuardRange() const;
162     int getWeaponRange() const;
163     int getWeaponReloadTime() const;
164     int getInfSpawnProp() const;
165 
getRealX()166     inline FixPoint getRealX() const { return realX; }
getRealY()167     inline FixPoint getRealY() const { return realY; }
getLocation()168     inline const Coord& getLocation() const { return location; }
getDestination()169     inline const Coord& getDestination() const { return destination; }
getTarget()170     inline ObjectBase* getTarget() { return target.getObjPointer(); }
getTarget()171     inline const ObjectBase* getTarget() const { return target.getObjPointer(); }
172 
getOriginalHouseID()173     inline int getOriginalHouseID() const { return originalHouseID; }
setOriginalHouseID(int i)174     virtual void setOriginalHouseID(int i) { originalHouseID = i; }
getOwner()175     inline House* getOwner() { return owner; }
getOwner()176     inline const House* getOwner() const { return owner; }
177 
setOwner(House * no)178     inline void setOwner(House* no) { owner = no; }
179 
180     static ObjectBase* createObject(int itemID,House* Owner, Uint32 objectID = NONE_ID);
181     static ObjectBase* loadObject(InputStream& stream, int itemID, Uint32 objectID);
182 
183 protected:
184     bool targetInWeaponRange() const;
185 
186     // constant for all objects of the same type
187     Uint32   itemID;                 ///< The ItemID of this object.
188     int      radius;                 ///< The radius of this object
189 
190     bool     aStructure;             ///< Is this a structure?
191     bool     aBuilder;               ///< Is this a builder?
192 
193     bool     aUnit;                  ///< Is this a unit?
194     bool     aFlyingUnit;            ///< Is this a flying unit?
195     bool     aGroundUnit;            ///< Is this a ground unit?
196     bool     infantry;               ///< Is this an infantry unit?
197 
198     bool     canAttackStuff;         ///< Can this unit/structure attack?
199 
200     // object state/properties
201     Uint32   objectID;               ///< The unique object ID of this object
202     int      originalHouseID;        ///< for takeover/deviation, we still want to keep track of what the original house was
203     House    *owner;                 ///< The owner of this object
204 
205     Coord    location;               ///< The current position of this object in tile coordinates
206     Coord    oldLocation;            ///< The previous position of this object in tile coordinates (used when moving from one tile to the next tile)
207     Coord    destination;            ///< The destination tile
208     FixPoint realX;                  ///< The x-coordinate of this object in world coordinates
209     FixPoint realY;                  ///< The y-coordinate of this object in world coordinates
210 
211     FixPoint angle;                  ///< The current angle of this unit/structure
212     Sint8    drawnAngle;             ///< The angle this unit/structure is drawn with. (e.g. 0 to 7)
213 
214     bool     active;                 ///< Is this unit/structure active?
215     bool     respondable;            ///< Is this unit/structure respondable to commands?
216     bool     selected;               ///< Is this object currently selected?
217     bool     selectedByOtherPlayer;  ///< This is only used in multiplayer games where two players control one house
218 
219     bool          forced;            ///< Is this unit/structure forced to do what it currently does or did the micro-AI decide to do that?
220     bool          targetFriendly;    ///< Is the current target a friendly unit/structure to follow/move to instead to attack?
221     ObjectPointer target;            ///< The target to attack or move to
222     ATTACKMODE    attackMode;        ///< The attack mode of this unit/structure
223 
224     bool     visible[NUM_TEAMS];     ///< To which teams is this unit visible?
225 
226     // drawing information
227     bool     badlyDamaged;           ///< Is the health below 50%?
228 
229     SDL_Texture** graphic;           ///< The graphic for this object
230     int         graphicID;           ///< The id of the graphic (needed if we want to reload the graphic, e.g. when a unit is deviated)
231     int         numImagesX;          ///< The number of images in x direction
232     int         numImagesY;          ///< The number of images in y direction
233 
234 private:
235     FixPoint health;                 ///< The health of this object
236 };
237 
238 
239 
240 #endif // OBJECTBASE_H
241