unit.cpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. #include "AbstractFactory.h"
  2. #include "units/Unit.h"
  3. #include "Cell.h"
  4. #include "effects/effect.h"
  5. #include <iostream>
  6. #include <algorithm>
  7. #include <cassert>
  8. #include <string>
  9. #include <QFile>
  10. #include <QString>
  11. #include <QTextStream>
  12. Unit::Unit(QString parameters) {
  13. QStringList params = parameters.split("|");
  14. assert(params.size() >= 2);
  15. race_id_ = params[0];
  16. unit_id_ = params[1];
  17. QString unit_folder = ":/assets/units/" + race_id_ + "/" + unit_id_ + "/";
  18. loadUnitName(unit_folder);
  19. loadUnitDescr(unit_folder);
  20. loadUnitBaseClass(unit_folder);
  21. loadUnitTraits(unit_folder);
  22. loadUnitIcon(unit_folder);
  23. loadUnitPrevSpecs(unit_folder);
  24. loadUnitUpgradeSpecs(unit_folder);
  25. }
  26. void Unit::loadUnitName(QString unit_folder) {
  27. QFile file(unit_folder + "unitname.txt");
  28. file.open(QIODevice::ReadOnly);
  29. QTextStream in(&file);
  30. in.setCodec("UTF-8");
  31. unit_name_ = in.readLine();
  32. }
  33. void Unit::loadUnitDescr(QString unit_folder) {
  34. QFile file(unit_folder + "descr.txt");
  35. file.open(QIODevice::ReadOnly);
  36. QTextStream in(&file);
  37. in.setCodec("UTF-8");
  38. unit_descr_ = in.readAll();
  39. }
  40. void Unit::loadUnitBaseClass(QString unit_folder) {
  41. QFile file(unit_folder + "baseclass.txt");
  42. file.open(QIODevice::ReadOnly);
  43. QTextStream in(&file);
  44. in.setCodec("UTF-8");
  45. base_class_id_ = in.readLine();
  46. }
  47. void Unit::loadUnitTraits(QString unit_folder) {
  48. // TO BE DONE!!!
  49. health_points_ = rand();
  50. activity_points_ = rand();
  51. attack_cost_ = rand();
  52. attack_range_ = rand();
  53. }
  54. void Unit::loadUnitIcon(QString unit_folder) {
  55. unit_icon_.load(unit_folder + "icon.png");
  56. }
  57. void Unit::loadUnitPrevSpecs(QString unit_folder) {
  58. QFile file(unit_folder + "prevgrades.txt");
  59. file.open(QIODevice::ReadOnly);
  60. QTextStream in(&file);
  61. in.setCodec("UTF-8");
  62. QString line = in.readLine();
  63. while (!in.atEnd()) {
  64. parent_specs_.push_back(line);
  65. line = in.readLine();
  66. }
  67. parent_specs_.push_back(line);
  68. line = in.readLine();
  69. }
  70. void Unit::loadUnitUpgradeSpecs(QString unit_folder) {
  71. QFile file(unit_folder + "nextgrades.txt");
  72. file.open(QIODevice::ReadOnly);
  73. QTextStream in(&file);
  74. in.setCodec("UTF-8");
  75. QString line = in.readLine();
  76. while (!in.atEnd()) {
  77. upgrade_specs_.push_back(line);
  78. line = in.readLine();
  79. }
  80. upgrade_specs_.push_back(line);
  81. line = in.readLine();
  82. }
  83. int Unit::getCost(){
  84. return cost_;
  85. }
  86. std::vector<QString> Unit::getParentSpecs(){
  87. return parent_specs_;
  88. }
  89. std::vector<QString> Unit::getUpgradeSpecs(){
  90. return upgrade_specs_;
  91. }
  92. double Unit::getExperience() {
  93. return experience_;
  94. }
  95. int Unit::getLevel() {
  96. return level_;
  97. }
  98. int Unit::getHealthPoints() {
  99. return health_points_;
  100. }
  101. int Unit::getAttackRange() {
  102. return attack_range_;
  103. }
  104. int Unit::getActivityPoints(){
  105. return activity_points_;
  106. }
  107. int Unit::getStartingActivityPoints() {
  108. return starting_activity_points_;
  109. }
  110. Cell* Unit::getLocation() {
  111. return location_;
  112. }
  113. void Unit::setLocation(Cell* to) {
  114. location_ = to;
  115. }
  116. int Unit::getMovementSpeed() {
  117. return movement_speed_;
  118. }
  119. int Unit::getAttackCost(){
  120. return attack_cost_;
  121. }
  122. int Unit::getInitiative() {
  123. return initiative_;
  124. }
  125. int Unit::getIntelligence() {
  126. return intelligence_;
  127. }
  128. int Unit::getStrength() {
  129. return strength_;
  130. }
  131. int Unit::getAgility() {
  132. return agility_;
  133. }
  134. int Unit::getAttackPoints(){
  135. return attack_cost_;
  136. }
  137. int Unit::getMagicDefence() {
  138. return magic_defence_;
  139. }
  140. int Unit::getPhysicDefence() {
  141. return physic_defence_;
  142. }
  143. double Unit::getRealX() {
  144. return real_x_;
  145. }
  146. void Unit::setRealX(double x) {
  147. real_x_ = x;
  148. }
  149. double Unit::getRealY() {
  150. return real_y_;
  151. }
  152. void Unit::setRealY(double y) {
  153. real_y_ = y;
  154. }
  155. bool Unit::isCharacter(){
  156. return true;
  157. }
  158. int Unit::theSameNear(){
  159. short near_qnt = 0;
  160. if (this->location_->getleftUp()->getCharacter()->base_class_id_ == this->base_class_id_){
  161. near_qnt++;
  162. }
  163. if (this->location_->getleft()->getCharacter()->base_class_id_ == this->base_class_id_){
  164. near_qnt++;
  165. }
  166. if (this->location_->getleftDown()->getCharacter()->base_class_id_ == this->base_class_id_){
  167. near_qnt++;
  168. }
  169. if (this->location_->getrightUp()->getCharacter()->base_class_id_ == this->base_class_id_){
  170. near_qnt++;
  171. }
  172. if (this->location_->getright()->getCharacter()->base_class_id_ == this->base_class_id_){
  173. near_qnt++;
  174. }
  175. if (this->location_->getrightDown()->getCharacter()->base_class_id_ == this->base_class_id_){
  176. near_qnt++;
  177. }
  178. return near_qnt;
  179. }
  180. int Unit::reduceIncomingDamage(std::string damageType, int damage) { //returns damage after reducing by defence
  181. assert("Incorrect damage type in call reduceIncomingDamage(), expected" &&
  182. (damageType[0] == 'p' || damageType[0] == 'P' || damageType[0] == 'm' || damageType[0] == 'M'));
  183. assert("Magic defence of unit is incorrectly high (>40), but must be" && magic_defence_ <= 40);
  184. assert("Physic defence of unit is incorrectly high (>40), but must be" && physic_defence_ <= 40);
  185. if (damageType[0] == 'p' || damageType[0] == 'P') {
  186. return (damage - 2.5 * double(damage) * double(physic_defence_) / 100.0);
  187. }
  188. else if (damageType[0] == 'm' || damageType[0] == 'M') {
  189. return (damage - 2.5 * double(damage) * double(magic_defence_) / 100.0);
  190. }
  191. return damage;
  192. }
  193. int Unit::lenOfActualPath(Cell* destination) {
  194. return getLocation()->actualPath(destination).size() - 1;
  195. }
  196. bool Unit::canMoveForDistance(int distance) {
  197. return (activity_points_ * movement_speed_ >= distance);
  198. }
  199. bool Unit::canMoveToCell(Cell* destination) {
  200. return (destination->isEmpty() && lenOfActualPath(destination) > 0 && canMoveForDistance(lenOfActualPath(destination)));
  201. }
  202. void Unit::moveToCell(Cell* destination) {
  203. if (!canMoveToCell(destination))
  204. return; //here could be a gui-message about failed move (x-mark, for example)
  205. else {
  206. activity_points_ -= lenOfActualPath(destination)/movement_speed_;
  207. if (lenOfActualPath(destination) % movement_speed_)
  208. activity_points_ -= 1;
  209. setLocation(destination);
  210. }
  211. }
  212. QString Unit::getUnitId() const {
  213. return unit_id_;
  214. }
  215. QString Unit::getUnitName() const {
  216. return unit_name_;
  217. }
  218. QString Unit::getUnitDescr() const {
  219. return unit_descr_;
  220. }
  221. QString Unit::getUnitBaseClassId() const {
  222. return base_class_id_;
  223. }
  224. std::vector<QString> Unit::getUnitTraits() const {
  225. return {
  226. QString::number(health_points_),
  227. QString::number(attack_range_),
  228. QString::number(activity_points_),
  229. QString::number(initiative_)
  230. };
  231. }
  232. QImage Unit::getUnitIcon() const {
  233. return unit_icon_;
  234. }
  235. void Unit::operateEffectList(){
  236. for(std::vector<Effect*>::iterator it = beginIteratorEffectsList();
  237. it != endIteratorEffectsList(); ++it){
  238. (*it)->OperateOnUnit(this);
  239. }
  240. }
  241. void Unit::add(Effect* effect){
  242. if(effect == nullptr)
  243. throw new std::string("Try to add undefined effect to unit");
  244. effects_.push_back(effect);
  245. }
  246. void Unit::remove(std::vector<Effect*>::iterator it){
  247. if(beginIteratorEffectsList() <= it && it < endIteratorEffectsList()){
  248. effects_.erase(it);
  249. }
  250. }
  251. void Unit::remove(Effect* effect){
  252. for(std::vector<Effect*>::iterator it = beginIteratorEffectsList();
  253. it != endIteratorEffectsList(); ++it){
  254. if((*it) == effect){
  255. remove(it);
  256. return;
  257. }
  258. }
  259. }
  260. std::vector<Effect*>::iterator Unit::beginIteratorEffectsList(){
  261. return effects_.begin();
  262. }
  263. std::vector<Effect*>::iterator Unit::endIteratorEffectsList(){
  264. return effects_.end();
  265. }