unit.cpp 7.5 KB

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