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 UNITBASE_H 19 #define UNITBASE_H 20 21 #include <ObjectBase.h> 22 23 #include <House.h> 24 25 #include <list> 26 27 // forward declarations 28 class Tile; 29 30 class UnitBase : public ObjectBase 31 { 32 public: 33 explicit UnitBase(House* newOwner); 34 explicit UnitBase(InputStream& stream); 35 void init(); 36 virtual ~UnitBase(); 37 38 virtual void save(OutputStream& stream) const; 39 40 void blitToScreen(); 41 42 virtual ObjectInterface* getInterfaceContainer(); 43 44 virtual void checkPos() = 0; 45 virtual void deploy(const Coord& newLocation); 46 47 virtual void destroy(); 48 void deviate(House* newOwner); 49 50 virtual void drawSelectionBox(); 51 virtual void drawOtherPlayerSelectionBox(); 52 53 /** 54 This method is called when an unit is ordered by a right click 55 \param xPos the x position on the map 56 \param yPos the y position on the map 57 */ 58 virtual void handleActionClick(int xPos, int yPos); 59 60 /** 61 This method is called when an unit is ordered to attack 62 \param xPos the x position on the map 63 \param yPos the y position on the map 64 */ 65 virtual void handleAttackClick(int xPos, int yPos); 66 67 /** 68 This method is called when an unit is ordered to move 69 \param xPos the x position on the map 70 \param yPos the y position on the map 71 */ 72 virtual void handleMoveClick(int xPos, int yPos); 73 74 75 /** 76 This method is called when an unit is ordered to be in a new attack mode 77 \param newAttackMode the new attack mode the unit is put in. 78 */ 79 virtual void handleSetAttackModeClick(ATTACKMODE newAttackMode); 80 81 82 /** 83 This method is called when an unit is ordered to request a carryall drop 84 \param xPos the x position on the map 85 \param yPos the y position on the map 86 */ 87 virtual void handleRequestCarryallDropClick(int xPos, int yPos); 88 89 /** 90 This method is called when an unit should move to (xPos,yPos) 91 \param xPos the x position on the map 92 \param yPos the y position on the map 93 \param bForced true, if the unit should ignore everything else 94 */ 95 virtual void doMove2Pos(int xPos, int yPos, bool bForced); 96 97 /** 98 This method is called when an unit should move to coord 99 \param coord the position on the map 100 \param bForced true, if the unit should ignore everything else 101 */ 102 virtual void doMove2Pos(const Coord& coord, bool bForced); 103 104 /** 105 This method is called when an unit should move to another unit/structure 106 \param TargetObjectID the ID of the other unit/structure 107 */ 108 virtual void doMove2Object(Uint32 TargetObjectID); 109 110 /** 111 This method is called when an unit should move to another unit/structure 112 \param pTargetObject the other unit/structure 113 */ 114 virtual void doMove2Object(const ObjectBase* pTargetObject); 115 116 /** 117 This method is called when an unit should attack a position 118 \param xPos the x position on the map 119 \param yPos the y position on the map 120 \param bForced true, if the unit should ignore everything else 121 */ 122 virtual void doAttackPos(int xPos, int yPos, bool bForced); 123 124 /** 125 This method is called when an unit should attack to another unit/structure 126 \param pTargetObject the target unit/structure 127 \param bForced true, if the unit should ignore everything else 128 */ 129 virtual void doAttackObject(const ObjectBase* pTargetObject, bool bForced); 130 131 /** 132 This method is called when an unit should attack to another unit/structure 133 \param TargetObjectID the ID of the other unit/structure 134 \param bForced true, if the unit should ignore everything else 135 */ 136 virtual void doAttackObject(Uint32 TargetObjectID, bool bForced); 137 138 /** 139 This method is called when an unit should change it's current attack mode 140 \param newAttackMode the new attack mode 141 */ 142 void doSetAttackMode(ATTACKMODE newAttackMode); 143 144 virtual void handleDamage(int damage, Uint32 damagerID, House* damagerOwner); 145 doRepair()146 virtual void doRepair() { }; 147 148 /** 149 Is this object in a range we are guarding. If yes we shall react. 150 \param object the object to check 151 */ 152 bool isInGuardRange(const ObjectBase* object) const; 153 154 /** 155 Is this object in a range we want to attack. If no, we should stop following it. 156 \param object the object to check 157 */ 158 bool isInAttackRange(const ObjectBase* object) const; 159 160 /** 161 Is this object in a range we can attack. 162 \param object the object to check 163 */ 164 bool isInWeaponRange(const ObjectBase* object) const; 165 166 void setAngle(int newAngle); 167 168 virtual void setTarget(const ObjectBase* newTarget); 169 170 void setGettingRepaired(); 171 setGuardPoint(const Coord & newGuardPoint)172 inline void setGuardPoint(const Coord& newGuardPoint) { setGuardPoint(newGuardPoint.x, newGuardPoint.y); } 173 174 void setGuardPoint(int newX, int newY); 175 176 void setLocation(int xPos, int yPos); 177 setLocation(const Coord & location)178 inline void setLocation(const Coord& location) { setLocation(location.x, location.y); } 179 setDestination(int newX,int newY)180 inline void setDestination(int newX, int newY) { 181 if((destination.x != newX) || (destination.y != newY)) { 182 ObjectBase::setDestination(newX, newY); 183 clearPath(); 184 } 185 } 186 setDestination(const Coord & location)187 inline void setDestination(const Coord& location) { setDestination(location.x, location.y); } 188 189 virtual void setPickedUp(UnitBase* newCarrier); 190 191 /** 192 Updates this unit. 193 \return true if this unit still exists, false if it was destroyed 194 */ 195 virtual bool update(); 196 197 virtual bool canPass(int xPos, int yPos) const; 198 hasBumpyMovementOnRock()199 virtual bool hasBumpyMovementOnRock() const { return false; } 200 201 /** 202 Returns how fast a unit can move over the specified terrain type. 203 \param terrainType the type to consider 204 \return Returns a speed factor. Higher values mean slower. 205 */ getTerrainDifficulty(TERRAINTYPE terrainType)206 virtual FixPoint getTerrainDifficulty(TERRAINTYPE terrainType) const { return 1; } 207 208 virtual int getCurrentAttackAngle() const; 209 210 virtual FixPoint getMaxSpeed() const; 211 clearPath()212 inline void clearPath() { 213 pathList.clear(); 214 nextSpotFound = false; 215 recalculatePathTimer = 0; 216 nextSpotAngle = INVALID; 217 noCloserPointCount = 0; 218 } 219 isTracked()220 inline bool isTracked() const { return tracked; } 221 isTurreted()222 inline bool isTurreted() const { return turreted; } 223 isMoving()224 inline bool isMoving() const { return moving; } 225 wasDeviated()226 inline bool wasDeviated() const { return (owner->getHouseID() != originalHouseID); } 227 getAngle()228 inline int getAngle() const { return drawnAngle; } 229 getAttackMode()230 inline ATTACKMODE getAttackMode() const { return attackMode; } 231 getGuardPoint()232 inline const Coord& getGuardPoint() const { return guardPoint; } 233 234 virtual void playAttackSound(); 235 236 protected: 237 238 virtual void attack(); 239 240 virtual void releaseTarget(); 241 virtual void engageTarget(); 242 virtual void move(); 243 244 virtual void bumpyMovementOnRock(FixPoint fromDistanceX, FixPoint fromDistanceY, FixPoint toDistanceX, FixPoint toDistanceY); 245 246 virtual void navigate(); 247 248 /** 249 When the unit is currently idling this method is called about every 5 seconds. 250 */ 251 virtual void idleAction(); 252 253 virtual void setSpeeds(); 254 255 virtual void targeting(); 256 257 virtual void turn(); 258 void turnLeft(); 259 void turnRight(); 260 261 void quitDeviation(); 262 263 bool SearchPathWithAStar(); 264 265 void drawSmoke(int x, int y); 266 267 // constant for all units of the same type 268 bool tracked; ///< Does this unit have tracks? 269 bool turreted; ///< Does this unit have a turret? 270 int numWeapons; ///< How many weapons do we have? 271 int bulletType; ///< Type of bullet to shot with 272 273 // unit state/properties 274 Coord guardPoint; ///< The guard point where to return to after the micro-AI hunted some nearby enemy unit 275 Coord attackPos; ///< The position to attack 276 bool goingToRepairYard; ///< Are we currently going to a repair yard? 277 bool pickedUp; ///< Were we picked up by a carryall? 278 bool bFollow; ///< Do we currently follow some other unit (specified by target)? 279 280 281 bool moving; ///< Are we currently moving? 282 bool turning; ///< Are we currently turning? 283 bool justStoppedMoving; ///< Do we have just stopped moving? 284 FixPoint xSpeed; ///< Speed in x direction 285 FixPoint ySpeed; ///< Speed in y direction 286 FixPoint bumpyOffsetX; ///< The bumpy offset in x direction which is already included in realX 287 FixPoint bumpyOffsetY; ///< The bumpy offset in y direction which is already included in realY 288 289 FixPoint targetDistance; ///< Distance to the destination 290 Sint8 targetAngle; ///< Angle to the destination 291 292 // path finding 293 Uint8 noCloserPointCount; ///< How often have we tried to dinf a path? 294 bool nextSpotFound; ///< Is the next spot to move to already found? 295 Sint8 nextSpotAngle; ///< The angle to get to the next spot 296 Sint32 recalculatePathTimer; ///< This timer is for recalculating the best path after x ticks 297 Coord nextSpot; ///< The next spot to move to 298 std::list<Coord> pathList; ///< The path to the destination found so far 299 300 Sint32 findTargetTimer; ///< When to look for the next target? 301 Sint32 primaryWeaponTimer; ///< When can the primary weapon shot again? 302 Sint32 secondaryWeaponTimer; ///< When can the secondary weapon shot again? 303 304 // deviation 305 Sint32 deviationTimer; ///< When to revert back to the original owner? 306 307 // drawing information 308 int drawnFrame; ///< Which row in the picture should be drawn 309 }; 310 311 #endif //UNITBASE_H 312