unit.cpp 7.7 KB

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