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