unit.cpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  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. void Unit::setHealthPoints(int health){
  109. health_points_ = std::min(40, health);
  110. }
  111. int Unit::getStartingActivityPoints() {
  112. return starting_activity_points_;
  113. }
  114. Cell* Unit::getLocation() {
  115. return location_;
  116. }
  117. void Unit::setLocation(Cell* to) {
  118. location_ = to;
  119. }
  120. int Unit::getMovementSpeed() {
  121. return movement_speed_;
  122. }
  123. int Unit::getAttackCost(){
  124. return attack_cost_;
  125. }
  126. int Unit::getInitiative() {
  127. return initiative_;
  128. }
  129. int Unit::getIntelligence() {
  130. return intelligence_;
  131. }
  132. int Unit::getStrength() {
  133. return strength_;
  134. }
  135. int Unit::getAgility() {
  136. return agility_;
  137. }
  138. int Unit::getAttackPoints(){
  139. return attack_cost_;
  140. }
  141. int Unit::getMagicDefence() {
  142. return magic_defence_;
  143. }
  144. int Unit::getPhysicDefence() {
  145. return physic_defence_;
  146. }
  147. double Unit::getRealX() {
  148. return real_x_;
  149. }
  150. void Unit::setRealX(double x) {
  151. real_x_ = x;
  152. }
  153. double Unit::getRealY() {
  154. return real_y_;
  155. }
  156. void Unit::setRealY(double y) {
  157. real_y_ = y;
  158. }
  159. bool Unit::isCharacter(){
  160. return true;
  161. }
  162. int Unit::theSameNear(){
  163. short near_qnt = 0;
  164. if (this->location_->getleftUp()->getCharacter()->base_class_id_ == this->base_class_id_){
  165. near_qnt++;
  166. }
  167. if (this->location_->getleft()->getCharacter()->base_class_id_ == this->base_class_id_){
  168. near_qnt++;
  169. }
  170. if (this->location_->getleftDown()->getCharacter()->base_class_id_ == this->base_class_id_){
  171. near_qnt++;
  172. }
  173. if (this->location_->getrightUp()->getCharacter()->base_class_id_ == this->base_class_id_){
  174. near_qnt++;
  175. }
  176. if (this->location_->getright()->getCharacter()->base_class_id_ == this->base_class_id_){
  177. near_qnt++;
  178. }
  179. if (this->location_->getrightDown()->getCharacter()->base_class_id_ == this->base_class_id_){
  180. near_qnt++;
  181. }
  182. return near_qnt;
  183. }
  184. int Unit::reduceIncomingDamage(std::string damageType, int damage) { //returns damage after reducing by defence
  185. assert("Incorrect damage type in call reduceIncomingDamage(), expected" &&
  186. (damageType[0] == 'p' || damageType[0] == 'P' || damageType[0] == 'm' || damageType[0] == 'M'));
  187. assert("Magic defence of unit is incorrectly high (>40), but must be" && magic_defence_ <= 40);
  188. assert("Physic defence of unit is incorrectly high (>40), but must be" && physic_defence_ <= 40);
  189. if (damageType[0] == 'p' || damageType[0] == 'P') {
  190. return (damage - 2.5 * double(damage) * double(physic_defence_) / 100.0);
  191. }
  192. else if (damageType[0] == 'm' || damageType[0] == 'M') {
  193. return (damage - 2.5 * double(damage) * double(magic_defence_) / 100.0);
  194. }
  195. return damage;
  196. }
  197. int Unit::lenOfActualPath(Cell* destination) {
  198. return getLocation()->actualPath(destination).size() - 1;
  199. }
  200. bool Unit::canMoveForDistance(int distance) {
  201. return (activity_points_ * movement_speed_ >= distance);
  202. }
  203. bool Unit::canMoveToCell(Cell* destination) {
  204. return (destination->isEmpty() && lenOfActualPath(destination) > 0 && canMoveForDistance(lenOfActualPath(destination)));
  205. }
  206. void Unit::moveToCell(Cell* destination) {
  207. if (!canMoveToCell(destination))
  208. return; //here could be a gui-message about failed move (x-mark, for example)
  209. else {
  210. activity_points_ -= lenOfActualPath(destination)/movement_speed_;
  211. if (lenOfActualPath(destination) % movement_speed_)
  212. activity_points_ -= 1;
  213. setLocation(destination);
  214. }
  215. }
  216. QString Unit::getUnitId() const {
  217. return unit_id_;
  218. }
  219. QString Unit::getUnitName() const {
  220. return unit_name_;
  221. }
  222. QString Unit::getUnitDescr() const {
  223. return unit_descr_;
  224. }
  225. QString Unit::getUnitBaseClassId() const {
  226. return base_class_id_;
  227. }
  228. std::vector<QString> Unit::getUnitTraits() const {
  229. return {
  230. QString::number(health_points_),
  231. QString::number(attack_range_),
  232. QString::number(activity_points_),
  233. QString::number(initiative_)
  234. };
  235. }
  236. QImage Unit::getUnitIcon() const {
  237. return unit_icon_;
  238. }
  239. void Unit::operateEffectList(){
  240. for(std::vector<Effect*>::iterator it = beginIteratorEffectsList();
  241. it != endIteratorEffectsList(); ++it){
  242. (*it)->OperateOnUnit(this);
  243. }
  244. }
  245. void Unit::add(Effect* effect){
  246. if(effect == nullptr)
  247. throw new std::string("Try to add undefined effect to unit");
  248. effects_.push_back(effect);
  249. }
  250. void Unit::remove(std::vector<Effect*>::iterator it){
  251. if(beginIteratorEffectsList() <= it && it < endIteratorEffectsList()){
  252. effects_.erase(it);
  253. }
  254. }
  255. void Unit::remove(Effect* effect){
  256. for(std::vector<Effect*>::iterator it = beginIteratorEffectsList();
  257. it != endIteratorEffectsList(); ++it){
  258. if((*it) == effect){
  259. remove(it);
  260. return;
  261. }
  262. }
  263. }
  264. std::vector<Effect*>::iterator Unit::beginIteratorEffectsList(){
  265. return effects_.begin();
  266. }
  267. std::vector<Effect*>::iterator Unit::endIteratorEffectsList(){
  268. return effects_.end();
  269. }