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_UNIT_H
20 #define OPENXCOM_UNIT_H
21 
22 #include <string>
23 #include <yaml-cpp/yaml.h>
24 
25 namespace OpenXcom
26 {
27 
28 enum SpecialAbility { SPECAB_NONE = 0, SPECAB_EXPLODEONDEATH, SPECAB_BURNFLOOR, SPECAB_RESPAWN };
29 /**
30  * This struct holds some plain unit attribute data together.
31  */
32 struct UnitStats
33 {
34 	int tu, stamina, health, bravery, reactions, firing, throwing, strength, psiStrength, psiSkill, melee;
35 public:
UnitStatsUnitStats36 	UnitStats() : tu(0), stamina(0), health(0), bravery(0), reactions(0), firing(0), throwing(0), strength(0), psiStrength(0), psiSkill(0), melee(0) {};
UnitStatsUnitStats37 	UnitStats(int tu_, int stamina_, int health_, int bravery_, int reactions_, int firing_, int throwing_, int strength_, int psiStrength_, int psiSkill_, int melee_) : tu(tu_), stamina(stamina_), health(health_), bravery(bravery_), reactions(reactions_), firing(firing_), throwing(throwing_), strength(strength_), psiStrength(psiStrength_), psiSkill(psiSkill_), melee(melee_) {};
38 	UnitStats& operator+=(const UnitStats& stats) { tu += stats.tu; stamina += stats.stamina; health += stats.health; bravery += stats.bravery; reactions += stats.reactions; firing += stats.firing; throwing += stats.throwing; strength += stats.strength; psiStrength += stats.psiStrength; psiSkill += stats.psiSkill; melee += stats.melee; return *this; }
39 	UnitStats operator+(const UnitStats& stats) const { return UnitStats(tu + stats.tu, stamina + stats.stamina, health + stats.health, bravery + stats.bravery, reactions + stats.reactions, firing + stats.firing, throwing + stats.throwing, strength + stats.strength, psiStrength + stats.psiStrength, psiSkill + stats.psiSkill, melee + stats.melee); }
40 	UnitStats& operator-=(const UnitStats& stats) { tu -= stats.tu; stamina -= stats.stamina; health -= stats.health; bravery -= stats.bravery; reactions -= stats.reactions; firing -= stats.firing; throwing -= stats.throwing; strength -= stats.strength; psiStrength -= stats.psiStrength; psiSkill -= stats.psiSkill; melee -= stats.melee; return *this; }
41 	UnitStats operator-(const UnitStats& stats) const { return UnitStats(tu - stats.tu, stamina - stats.stamina, health - stats.health, bravery - stats.bravery, reactions - stats.reactions, firing - stats.firing, throwing - stats.throwing, strength - stats.strength, psiStrength - stats.psiStrength, psiSkill - stats.psiSkill, melee - stats.melee); }
42 	UnitStats operator-() const { return UnitStats(-tu, -stamina, -health, -bravery, -reactions, -firing, -throwing, -strength, -psiStrength, -psiSkill, -melee); }
mergeUnitStats43 	void merge(const UnitStats& stats) { tu = (stats.tu ? stats.tu : tu); stamina = (stats.stamina ? stats.stamina : stamina); health = (stats.health ? stats.health : health); bravery = (stats.bravery ? stats.bravery : bravery); reactions = (stats.reactions ? stats.reactions : reactions); firing = (stats.firing ? stats.firing : firing); throwing = (stats.throwing ? stats.throwing : throwing); strength = (stats.strength ? stats.strength : strength); psiStrength = (stats.psiStrength ? stats.psiStrength : psiStrength); psiSkill = (stats.psiSkill ? stats.psiSkill : psiSkill); melee = (stats.melee ? stats.melee : melee); };
44 };
45 
46 /**
47  * Represents the static data for a unit that is generated on the battlescape, this includes: HWPs, aliens and civilians.
48  * @sa Soldier BattleUnit
49  */
50 class Unit
51 {
52 private:
53 	std::string _type;
54 	std::string _race;
55 	std::string _rank;
56 	UnitStats _stats;
57 	std::string _armor;
58 	int _standHeight, _kneelHeight, _floatHeight;
59 	int _value, _deathSound, _aggroSound, _moveSound;
60 	int _intelligence, _aggression, _energyRecovery;
61 	SpecialAbility _specab;
62 	std::string _spawnUnit;
63 	bool _livingWeapon;
64 public:
65 	/// Creates a blank unit ruleset.
66 	Unit(const std::string &type);
67 	/// Cleans up the unit ruleset.
68 	~Unit();
69 	/// Loads the unit data from YAML.
70 	void load(const YAML::Node& node, int modIndex);
71 	/// Gets the unit's type.
72 	std::string getType() const;
73 	/// Gets the unit's stats.
74 	UnitStats *getStats();
75 	/// Gets the unit's height when standing.
76 	int getStandHeight() const;
77 	/// Gets the unit's height when kneeling.
78 	int getKneelHeight() const;
79 	/// Gets the unit's float elevation.
80 	int getFloatHeight() const;
81 	/// Gets the armor type.
82 	std::string getArmor() const;
83 	/// Gets the alien race type.
84 	std::string getRace() const;
85 	/// Gets the alien rank.
86 	std::string getRank() const;
87 	/// Gets the value - for score calculation.
88 	int getValue() const;
89 	/// Gets the death sound id.
90 	int getDeathSound() const;
91 	/// Gets the move sound id.
92 	int getMoveSound() const;
93 	/// Gets the intelligence. This is the number of turns AI remembers your troop positions.
94 	int getIntelligence() const;
95 	/// Gets the aggression. Determines the chance of revenge and taking cover.
96 	int getAggression() const;
97 	/// Gets the alien's special ability.
98 	int getSpecialAbility() const;
99 	/// Gets the unit's spawn unit.
100 	std::string getSpawnUnit() const;
101 	/// Gets the unit's war cry.
102 	int getAggroSound() const;
103 	/// Checks if this unit has a built in weapon.
104 	bool isLivingWeapon() const;
105 	int getEnergyRecovery() const;
106 };
107 
108 }
109 
110 namespace YAML
111 {
112 	template<>
113 	struct convert<OpenXcom::UnitStats>
114 	{
115 		static Node encode(const OpenXcom::UnitStats& rhs)
116 		{
117 			Node node;
118 			node["tu"] = rhs.tu;
119 			node["stamina"] = rhs.stamina;
120 			node["health"] = rhs.health;
121 			node["bravery"] = rhs.bravery;
122 			node["reactions"] = rhs.reactions;
123 			node["firing"] = rhs.firing;
124 			node["throwing"] = rhs.throwing;
125 			node["strength"] = rhs.strength;
126 			node["psiStrength"] = rhs.psiStrength;
127 			node["psiSkill"] = rhs.psiSkill;
128 			node["melee"] = rhs.melee;
129 			return node;
130 		}
131 
132 		static bool decode(const Node& node, OpenXcom::UnitStats& rhs)
133 		{
134 			if (!node.IsMap())
135 				return false;
136 
137 			rhs.tu = node["tu"].as<int>(rhs.tu);
138 			rhs.stamina = node["stamina"].as<int>(rhs.stamina);
139 			rhs.health = node["health"].as<int>(rhs.health);
140 			rhs.bravery = node["bravery"].as<int>(rhs.bravery);
141 			rhs.reactions = node["reactions"].as<int>(rhs.reactions);
142 			rhs.firing = node["firing"].as<int>(rhs.firing);
143 			rhs.throwing = node["throwing"].as<int>(rhs.throwing);
144 			rhs.strength = node["strength"].as<int>(rhs.strength);
145 			rhs.psiStrength = node["psiStrength"].as<int>(rhs.psiStrength);
146 			rhs.psiSkill = node["psiSkill"].as<int>(rhs.psiSkill);
147 			rhs.melee = node["melee"].as<int>(rhs.melee);
148 			return true;
149 		}
150 	};
151 }
152 
153 #endif
154