1 /* 2 * Copyright 2010-2014 OpenXcom Developers. 3 * 4 * This file is part of OpenXcom. 5 * 6 * OpenXcom is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * 11 * OpenXcom is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with OpenXcom. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 #ifndef OPENXCOM_BATTLEUNIT_H 20 #define OPENXCOM_BATTLEUNIT_H 21 22 #include <vector> 23 #include <string> 24 #include "../Battlescape/Position.h" 25 #include "../Battlescape/BattlescapeGame.h" 26 #include "../Ruleset/RuleItem.h" 27 #include "../Ruleset/Unit.h" 28 #include "../Ruleset/MapData.h" 29 #include "Soldier.h" 30 31 namespace OpenXcom 32 { 33 34 class Tile; 35 class BattleItem; 36 class Unit; 37 class BattleAIState; 38 class Node; 39 class Surface; 40 class RuleInventory; 41 class Soldier; 42 class Armor; 43 class SavedGame; 44 class Language; 45 class AlienBAIState; 46 class CivilianBAIState; 47 48 enum UnitStatus {STATUS_STANDING, STATUS_WALKING, STATUS_FLYING, STATUS_TURNING, STATUS_AIMING, STATUS_COLLAPSING, STATUS_DEAD, STATUS_UNCONSCIOUS, STATUS_PANICKING, STATUS_BERSERK}; 49 enum UnitFaction {FACTION_PLAYER, FACTION_HOSTILE, FACTION_NEUTRAL}; 50 enum UnitSide {SIDE_FRONT, SIDE_LEFT, SIDE_RIGHT, SIDE_REAR, SIDE_UNDER}; 51 enum UnitBodyPart {BODYPART_HEAD, BODYPART_TORSO, BODYPART_RIGHTARM, BODYPART_LEFTARM, BODYPART_RIGHTLEG, BODYPART_LEFTLEG}; 52 53 54 /** 55 * Represents a moving unit in the battlescape, player controlled or AI controlled 56 * it holds info about it's position, items carrying, stats, etc 57 */ 58 class BattleUnit 59 { 60 private: 61 UnitFaction _faction, _originalFaction; 62 UnitFaction _killedBy; 63 int _id; 64 Position _pos; 65 Tile *_tile; 66 Position _lastPos; 67 int _direction, _toDirection; 68 int _directionTurret, _toDirectionTurret; 69 int _verticalDirection; 70 Position _destination; 71 UnitStatus _status; 72 int _walkPhase, _fallPhase; 73 std::vector<BattleUnit *> _visibleUnits, _unitsSpottedThisTurn; 74 std::vector<Tile *> _visibleTiles; 75 int _tu, _energy, _health, _morale, _stunlevel; 76 bool _kneeled, _floating, _dontReselect; 77 int _currentArmor[5]; 78 int _fatalWounds[6]; 79 int _fire; 80 std::vector<BattleItem*> _inventory; 81 BattleAIState *_currentAIState; 82 bool _visible; 83 Surface *_cache[5]; 84 bool _cacheInvalid; 85 int _expBravery, _expReactions, _expFiring, _expThrowing, _expPsiSkill, _expMelee; 86 int improveStat(int exp); 87 int _motionPoints; 88 int _kills; 89 int _faceDirection; // used only during strafeing moves 90 bool _hitByFire; 91 int _moraleRestored; 92 int _coverReserve; 93 BattleUnit *_charging; 94 int _turnsSinceSpotted; 95 std::string _spawnUnit; 96 std::string _activeHand; 97 98 // static data 99 std::string _type; 100 std::string _rank; 101 std::string _race; 102 std::wstring _name; 103 UnitStats _stats; 104 int _standHeight, _kneelHeight, _floatHeight; 105 int _value, _deathSound, _aggroSound, _moveSound; 106 int _intelligence, _aggression; 107 SpecialAbility _specab; 108 Armor *_armor; 109 SoldierGender _gender; 110 Soldier *_geoscapeSoldier; 111 std::vector<int> _loftempsSet; 112 Unit *_unitRules; 113 int _rankInt; 114 int _turretType; 115 public: 116 static const int MAX_SOLDIER_ID = 1000000; 117 /// Creates a BattleUnit. 118 BattleUnit(Soldier *soldier, UnitFaction faction); 119 BattleUnit(Unit *unit, UnitFaction faction, int id, Armor *armor, int diff); 120 /// Cleans up the BattleUnit. 121 ~BattleUnit(); 122 /// Loads the unit from YAML. 123 void load(const YAML::Node& node); 124 /// Saves the unit to YAML. 125 YAML::Node save() const; 126 /// Gets the BattleUnit's ID. 127 int getId() const; 128 /// Sets the unit's position 129 void setPosition(const Position& pos, bool updateLastPos = true); 130 /// Gets the unit's position. 131 const Position& getPosition() const; 132 /// Gets the unit's position. 133 const Position& getLastPosition() const; 134 /// Sets the unit's direction 0-7. 135 void setDirection(int direction); 136 /// Sets the unit's face direction (only used by strafing moves) 137 void setFaceDirection(int direction); 138 /// Gets the unit's direction. 139 int getDirection() const; 140 /// Gets the unit's face direction (only used by strafing moves) 141 int getFaceDirection() const; 142 /// Gets the unit's turret direction. 143 int getTurretDirection() const; 144 /// Gets the unit's turret To direction. 145 int getTurretToDirection() const; 146 /// Gets the unit's vertical direction. 147 int getVerticalDirection() const; 148 /// Gets the unit's status. 149 UnitStatus getStatus() const; 150 /// Start the walkingPhase 151 void startWalking(int direction, const Position &destination, Tile *tileBelowMe, bool cache); 152 /// Increase the walkingPhase 153 void keepWalking(Tile *tileBelowMe, bool cache); 154 /// Gets the walking phase for animation and sound 155 int getWalkingPhase() const; 156 /// Gets the walking phase for diagonal walking 157 int getDiagonalWalkingPhase() const; 158 /// Gets the unit's destination when walking 159 const Position &getDestination() const; 160 /// Look at a certain point. 161 void lookAt(const Position &point, bool turret = false); 162 /// Look at a certain direction. 163 void lookAt(int direction, bool force = false); 164 /// Turn to the destination direction. 165 void turn(bool turret = false); 166 /// Abort turning. 167 void abortTurn(); 168 /// Gets the soldier's gender. 169 SoldierGender getGender() const; 170 /// Gets the unit's faction. 171 UnitFaction getFaction() const; 172 /// Set the cached flag. 173 void setCache(Surface *cache, int part = 0); 174 /// If this unit is cached on the battlescape. 175 Surface *getCache(bool *invalid, int part = 0) const; 176 /// Kneel down. 177 void kneel(bool kneeled); 178 /// Is kneeled? 179 bool isKneeled() const; 180 /// Is floating? 181 bool isFloating() const; 182 /// Aim. 183 void aim(bool aiming); 184 /// Get direction to a certain point 185 int directionTo(const Position &point) const; 186 /// Gets the unit's time units. 187 int getTimeUnits() const; 188 /// Gets the unit's stamina. 189 int getEnergy() const; 190 /// Gets the unit's health. 191 int getHealth() const; 192 /// Gets the unit's bravery. 193 int getMorale() const; 194 /// Do damage to the unit. 195 int damage(const Position &relative, int power, ItemDamageType type, bool ignoreArmor = false); 196 /// Heal stun level of the unit. 197 void healStun(int power); 198 /// Gets the unit's stun level. 199 int getStunlevel() const; 200 /// Knocks the unit out instantly. 201 void knockOut(BattlescapeGame *battle); 202 /// Start falling sequence. 203 void startFalling(); 204 /// Increment the falling sequence. 205 void keepFalling(); 206 /// Get falling sequence. 207 int getFallingPhase() const; 208 /// The unit is out - either dead or unconscious. 209 bool isOut() const; 210 /// Get the number of time units a certain action takes. 211 int getActionTUs(BattleActionType actionType, BattleItem *item); 212 /// Spend time units if it can. 213 bool spendTimeUnits(int tu); 214 /// Spend energy if it can. 215 bool spendEnergy(int tu); 216 /// Set time units. 217 void setTimeUnits(int tu); 218 /// Add unit to visible units. 219 bool addToVisibleUnits(BattleUnit *unit); 220 /// Get the list of visible units. 221 std::vector<BattleUnit*> *getVisibleUnits(); 222 /// Clear visible units. 223 void clearVisibleUnits(); 224 /// Add unit to visible tiles. 225 bool addToVisibleTiles(Tile *tile); 226 /// Get the list of visible tiles. 227 std::vector<Tile*> *getVisibleTiles(); 228 /// Clear visible tiles. 229 void clearVisibleTiles(); 230 /// Calculate firing accuracy. 231 int getFiringAccuracy(BattleActionType actionType, BattleItem *item); 232 /// Calculate accuracy modifier. 233 int getAccuracyModifier(BattleItem *item = 0); 234 /// Calculate throwing accuracy. 235 double getThrowingAccuracy(); 236 /// Set armor value. 237 void setArmor(int armor, UnitSide side); 238 /// Get armor value. 239 int getArmor(UnitSide side) const; 240 /// Get total number of fatal wounds. 241 int getFatalWounds() const; 242 /// Get the current reaction score. 243 double getReactionScore(); 244 /// Prepare for a new turn. 245 void prepareNewTurn(); 246 /// Morale change 247 void moraleChange(int change); 248 /// Don't reselect this unit 249 void dontReselect(); 250 /// Reselect this unit 251 void allowReselect(); 252 /// Check whether reselecting this unit is allowed. 253 bool reselectAllowed() const; 254 /// Set fire. 255 void setFire(int fire); 256 /// Get fire. 257 int getFire() const; 258 /// Get the list of items in the inventory. 259 std::vector<BattleItem*> *getInventory(); 260 /// Let AI do their thing. 261 void think(BattleAction *action); 262 /// Get current AI state. 263 BattleAIState *getCurrentAIState() const; 264 /// Set next AI State 265 void setAIState(BattleAIState *aiState); 266 /// Set whether this unit is visible 267 void setVisible(bool flag); 268 /// Get whether this unit is visible 269 bool getVisible() const; 270 /// Sets the unit's tile it's standing on 271 void setTile(Tile *tile, Tile *tileBelow = 0); 272 /// Gets the unit's tile. 273 Tile *getTile() const; 274 /// Gets the item in the specified slot. 275 BattleItem *getItem(RuleInventory *slot, int x = 0, int y = 0) const; 276 /// Gets the item in the specified slot. 277 BattleItem *getItem(const std::string &slot, int x = 0, int y = 0) const; 278 /// Gets the item in the main hand. 279 BattleItem *getMainHandWeapon(bool quickest = true) const; 280 /// Gets a grenade from the belt, if any. 281 BattleItem *getGrenadeFromBelt() const; 282 /// Reloads righthand weapon if needed. 283 bool checkAmmo(); 284 /// Check if this unit is in the exit area 285 bool isInExitArea(SpecialTileType stt = START_POINT) const; 286 /// Gets the unit height taking into account kneeling/standing. 287 int getHeight() const; 288 /// Gets the unit floating elevation. 289 int getFloatHeight() const; 290 /// Adds one to the reaction exp counter. 291 void addReactionExp(); 292 /// Adds one to the firing exp counter. 293 void addFiringExp(); 294 /// Adds one to the throwing exp counter. 295 void addThrowingExp(); 296 /// Adds one to the psi exp counter. 297 void addPsiExp(); 298 /// Adds one to the melee exp counter. 299 void addMeleeExp(); 300 /// Updates the stats of a Geoscape soldier. 301 void updateGeoscapeStats(Soldier *soldier); 302 /// Check if unit eligible for squaddie promotion. 303 bool postMissionProcedures(SavedGame *geoscape); 304 /// Get the sprite index for the minimap 305 int getMiniMapSpriteIndex () const; 306 /// Set the turret type. -1 is no turret. 307 void setTurretType(int turretType); 308 /// Get the turret type. -1 is no turret. 309 int getTurretType() const; 310 /// Get fatal wound amount of a body part 311 int getFatalWound(int part) const; 312 /// Heal one fatal wound 313 void heal(int part, int woundAmount, int healthAmount); 314 /// Give pain killers to this unit 315 void painKillers (); 316 /// Give stimulant to this unit 317 void stimulant (int energy, int stun); 318 /// Get motion points for the motion scanner. 319 int getMotionPoints() const; 320 /// Gets the unit's armor. 321 Armor *getArmor() const; 322 /// Gets the unit's name. 323 std::wstring getName(Language *lang, bool debugAppendId = false) const; 324 /// Gets the unit's stats. 325 UnitStats *getStats(); 326 /// Get the unit's stand height. 327 int getStandHeight() const; 328 /// Get the unit's kneel height. 329 int getKneelHeight() const; 330 /// Get the unit's loft ID. 331 int getLoftemps(int entry = 0) const; 332 /// Get the unit's value. 333 int getValue() const; 334 /// Get the unit's death sound. 335 int getDeathSound() const; 336 /// Get the unit's move sound. 337 int getMoveSound() const; 338 /// Get whether the unit is affected by fatal wounds. 339 bool isWoundable() const; 340 /// Get whether the unit is affected by fear. 341 bool isFearable() const; 342 /// Get the unit's intelligence. 343 int getIntelligence() const; 344 /// Get the unit's aggression. 345 int getAggression() const; 346 /// Get the units's special ability. 347 int getSpecialAbility() const; 348 /// Set the units's special ability. 349 void setSpecialAbility(SpecialAbility specab); 350 /// Get the units's rank string. 351 std::string getRankString() const; 352 /// Get the geoscape-soldier object. 353 Soldier *getGeoscapeSoldier() const; 354 /// Add a kill to the counter. 355 void addKillCount(); 356 /// Get unit type. 357 std::string getType() const; 358 /// Set the hand this unit is using; 359 void setActiveHand(const std::string &slot); 360 /// Get unit's active hand. 361 std::string getActiveHand() const; 362 /// Convert's unit to a faction 363 void convertToFaction(UnitFaction f); 364 /// Set health to 0 and set status dead 365 void instaKill(); 366 /// Gets the unit's spawn unit. 367 std::string getSpawnUnit() const; 368 /// Sets the unit's spawn unit. 369 void setSpawnUnit(std::string spawnUnit); 370 /// Gets the unit's aggro sound. 371 int getAggroSound() const; 372 /// Sets the unit's energy level. 373 void setEnergy(int energy); 374 /// Halve the unit's armor values. 375 void halveArmor(); 376 /// Get the faction that killed this unit. 377 UnitFaction killedBy() const; 378 /// Set the faction that killed this unit. 379 void killedBy(UnitFaction f); 380 /// Set the units we are charging towards. 381 void setCharging(BattleUnit *chargeTarget); 382 /// Get the units we are charging towards. 383 BattleUnit *getCharging(); 384 /// Get the carried weight in strength units. 385 int getCarriedWeight(BattleItem *draggingItem = 0) const; 386 /// Set how many turns this unit will be exposed for. 387 void setTurnsSinceSpotted (int turns); 388 /// Set how many turns this unit will be exposed for. 389 int getTurnsSinceSpotted () const; 390 /// Get this unit's original faction 391 UnitFaction getOriginalFaction() const; 392 /// call this after the default copy constructor deletes the cache? 393 void invalidateCache(); 394 getUnitRules()395 Unit *getUnitRules() const { return _unitRules; } 396 397 /// scratch value for AI's left hand to tell its right hand what's up... 398 bool _hidingForTurn; // don't zone out and start patrolling again 399 Position lastCover; 400 /// get the vector of units we've seen this turn. 401 std::vector<BattleUnit *> &getUnitsSpottedThisTurn(); 402 /// set the rank integer 403 void setRankInt(int rank); 404 /// get the rank integer 405 int getRankInt() const; 406 /// derive a rank integer based on rank string (for xcom soldiers ONLY) 407 void deriveRank(); 408 /// this function checks if a tile is visible, using maths. 409 bool checkViewSector(Position pos) const; 410 /// adjust this unit's stats according to difficulty. 411 void adjustStats(const int diff); 412 /// did this unit already take fire damage this turn? (used to avoid damaging large units multiple times.) 413 bool tookFireDamage() const; 414 /// switch the state of the fire damage tracker. 415 void toggleFireDamage(); 416 void setCoverReserve(int reserve); 417 int getCoverReserve() const; 418 /// Is this unit selectable? 419 bool isSelectable(UnitFaction faction, bool checkReselect, bool checkInventory) const; 420 /// Does this unit have an inventory? 421 bool hasInventory() const; 422 }; 423 424 } 425 426 #endif 427