2
0

CHeroOverview.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. /*
  2. * CHeroOverview.cpp, part of VCMI engine
  3. *
  4. * Authors: listed in file AUTHORS in main folder
  5. *
  6. * License: GNU General Public License v2.0 or later
  7. * Full text of license available in license.txt file, in main folder
  8. *
  9. */
  10. #include "StdInc.h"
  11. #include "CHeroOverview.h"
  12. #include "../CGameInfo.h"
  13. #include "../gui/CGuiHandler.h"
  14. #include "../render/Canvas.h"
  15. #include "../render/Colors.h"
  16. #include "../render/Graphics.h"
  17. #include "../render/IImage.h"
  18. #include "../renderSDL/RenderHandler.h"
  19. #include "../widgets/CComponent.h"
  20. #include "../widgets/Images.h"
  21. #include "../widgets/TextControls.h"
  22. #include "../widgets/MiscWidgets.h"
  23. #include "../../lib/CGeneralTextHandler.h"
  24. #include "../../lib/CCreatureHandler.h"
  25. #include "../../lib/CHeroHandler.h"
  26. #include "../../lib/CSkillHandler.h"
  27. #include "../../lib/spells/CSpellHandler.h"
  28. CHeroOverview::CHeroOverview(const HeroTypeID & h)
  29. : CWindowObject(BORDERED | RCLICK_POPUP), hero { h }
  30. {
  31. OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE;
  32. heroIndex = hero.getNum();
  33. pos = Rect(0, 0, 600, 485);
  34. genBackground();
  35. genControls();
  36. center();
  37. }
  38. void CHeroOverview::genBackground()
  39. {
  40. backgroundTexture = std::make_shared<CFilledTexture>(ImagePath::builtin("DIBOXBCK"), pos);
  41. updateShadow();
  42. Canvas canvas = Canvas(Point(pos.w, pos.h));
  43. // hero image
  44. canvas.drawBorder(Rect(borderOffset - 1, borderOffset + yOffset - 1, 58 + 2, 64 + 2), borderColor);
  45. // hero name
  46. canvas.drawColorBlended(Rect(64 + borderOffset, borderOffset + yOffset, 220, 64), ColorRGBA(0, 0, 0, alpha));
  47. canvas.drawBorder(Rect(64 + borderOffset - 1, borderOffset + yOffset - 1, 220 + 2, 64 + 2), borderColor);
  48. // vertical line
  49. canvas.drawLine(Point(295, borderOffset + yOffset - 1), Point(295, borderOffset + yOffset - 2 + 439), borderColor, borderColor);
  50. // skill header
  51. canvas.drawColorBlended(Rect(borderOffset, 2 * borderOffset + yOffset + 64, 284, 20), ColorRGBA(0, 0, 0, alpha));
  52. canvas.drawBorder(Rect(borderOffset - 1, 2 * borderOffset + yOffset + 64 - 1, 284 + 2, 20 + 2), borderColor);
  53. // skill
  54. for(int i = 0; i < 4; i++)
  55. canvas.drawBorder(Rect((284 / 4) * i + 21 - 1, 3 * borderOffset + yOffset + 64 + 20 + 1 - 1, 42 + 2, 42 + 2), borderColor);
  56. // skill footer
  57. canvas.drawColorBlended(Rect(borderOffset, 4 * borderOffset + yOffset + 128, 284, 20), ColorRGBA(0, 0, 0, alpha));
  58. canvas.drawBorder(Rect(borderOffset - 1, 4 * borderOffset + yOffset + 128 - 1, 284 + 2, 20 + 2), borderColor);
  59. // hero biography
  60. canvas.drawColorBlended(Rect(borderOffset, 5 * borderOffset + yOffset + 148, 284, 130), ColorRGBA(0, 0, 0, alpha));
  61. canvas.drawBorder(Rect(borderOffset - 1, 5 * borderOffset + yOffset + 148 - 1, 284 + 2, 130 + 2), borderColor);
  62. // speciality name
  63. canvas.drawColorBlended(Rect(2 * borderOffset + 44, 6 * borderOffset + yOffset + 278, 235, 44), ColorRGBA(0, 0, 0, alpha));
  64. canvas.drawBorder(Rect(2 * borderOffset + 44 - 1, 6 * borderOffset + yOffset + 278 - 1, 235 + 2, 44 + 2), borderColor);
  65. // speciality image
  66. canvas.drawBorder(Rect(borderOffset - 1, 6 * borderOffset + yOffset + 278 - 1, 44 + 2, 44 + 2), borderColor);
  67. // speciality description
  68. canvas.drawColorBlended(Rect(borderOffset, 7 * borderOffset + yOffset + 322, 284, 85), ColorRGBA(0, 0, 0, alpha));
  69. canvas.drawBorder(Rect(borderOffset - 1, 7 * borderOffset + yOffset + 322 - 1, 284 + 2, 85 + 2), borderColor);
  70. // army title
  71. canvas.drawColorBlended(Rect(302, borderOffset + yOffset, 292, 30), ColorRGBA(0, 0, 0, alpha));
  72. canvas.drawBorder(Rect(302 - 1, borderOffset + yOffset - 1, 292 + 2, 30 + 2), borderColor);
  73. // army
  74. for(int i = 0; i < 6; i++)
  75. {
  76. int space = (260 - 6 * 32) / 5;
  77. canvas.drawColorBlended(Rect(318 + i * (32 + space), 2 * borderOffset + yOffset + 30, 32, 32), ColorRGBA(0, 0, 0, alpha));
  78. canvas.drawBorder(Rect(318 + i * (32 + space) - 1, 2 * borderOffset + yOffset + 30 - 1, 32 + 2, 32 + 2), borderColor);
  79. }
  80. // army footer
  81. canvas.drawColorBlended(Rect(302, 3 * borderOffset + yOffset + 62, 292, 20), ColorRGBA(0, 0, 0, alpha));
  82. canvas.drawBorder(Rect(302 - 1, 3 * borderOffset + yOffset + 62 - 1, 292 + 2, 20 + 2), borderColor);
  83. // warmachine title
  84. canvas.drawColorBlended(Rect(302, 4 * borderOffset + yOffset + 82, 292, 30), ColorRGBA(0, 0, 0, alpha));
  85. canvas.drawBorder(Rect(302 - 1, 4 * borderOffset + yOffset + 82 - 1, 292 + 2, 30 + 2), borderColor);
  86. // warmachine
  87. for(int i = 0; i < 6; i++)
  88. {
  89. int space = (292 - 32 - 6 * 32) / 5;
  90. canvas.drawColorBlended(Rect(318 + i * (32 + space), 5 * borderOffset + yOffset + 112, 32, 32), ColorRGBA(0, 0, 0, alpha));
  91. canvas.drawBorder(Rect(318 + i * (32 + space) - 1, 5 * borderOffset + yOffset + 112 - 1, 32 + 2, 32 + 2), borderColor);
  92. }
  93. // secskill title
  94. canvas.drawColorBlended(Rect(302, 6 * borderOffset + yOffset + 144, (292 / 2) - 2 * borderOffset, 30), ColorRGBA(0, 0, 0, alpha));
  95. canvas.drawBorder(Rect(302 - 1, 6 * borderOffset + yOffset + 144 - 1, (292 / 2) - 2 * borderOffset + 2, 30 + 2), borderColor);
  96. // vertical line
  97. canvas.drawLine(Point(302 + (292 / 2), 6 * borderOffset + yOffset + 144 - 1), Point(302 + (292 / 2), 6 * borderOffset + yOffset + 144 - 2 + 254), borderColor, borderColor);
  98. // spell title
  99. canvas.drawColorBlended(Rect(302 + (292 / 2) + 2 * borderOffset, 6 * borderOffset + yOffset + 144, (292 / 2) - 2 * borderOffset, 30), ColorRGBA(0, 0, 0, alpha));
  100. canvas.drawBorder(Rect(302 + (292 / 2) + 2 * borderOffset - 1, 6 * borderOffset + yOffset + 144 - 1, (292 / 2) - 2 * borderOffset + 2, 30 + 2), borderColor);
  101. // secskill
  102. for(int i = 0; i < 6; i++)
  103. {
  104. canvas.drawColorBlended(Rect(302, 7 * borderOffset + yOffset + 174 + i * (32 + borderOffset), 32, 32), ColorRGBA(0, 0, 0, alpha));
  105. canvas.drawBorder(Rect(302 - 1, 7 * borderOffset + yOffset + 174 + i * (32 + borderOffset) - 1, 32 + 2, 32 + 2), borderColor);
  106. canvas.drawColorBlended(Rect(302 + 32 + borderOffset, 7 * borderOffset + yOffset + 174 + i * (32 + borderOffset), (292 / 2) - 32 - 3 * borderOffset, 32), ColorRGBA(0, 0, 0, alpha));
  107. canvas.drawBorder(Rect(302 + 32 + borderOffset - 1, 7 * borderOffset + yOffset + 174 + i * (32 + borderOffset) - 1, (292 / 2) - 32 - 3 * borderOffset + 2, 32 + 2), borderColor);
  108. }
  109. // spell
  110. for(int i = 0; i < 6; i++)
  111. {
  112. canvas.drawColorBlended(Rect(302 + (292 / 2) + 2 * borderOffset, 7 * borderOffset + yOffset + 174 + i * (32 + borderOffset), 32, 32), ColorRGBA(0, 0, 0, alpha));
  113. canvas.drawBorder(Rect(302 + (292 / 2) + 2 * borderOffset - 1, 7 * borderOffset + yOffset + 174 + i * (32 + borderOffset) - 1, 32 + 2, 32 + 2), borderColor);
  114. canvas.drawColorBlended(Rect(302 + (292 / 2) + 2 * borderOffset + 32 + borderOffset, 7 * borderOffset + yOffset + 174 + i * (32 + borderOffset), (292 / 2) - 32 - 3 * borderOffset, 32), ColorRGBA(0, 0, 0, alpha));
  115. canvas.drawBorder(Rect(302 + (292 / 2) + 2 * borderOffset + 32 + borderOffset - 1, 7 * borderOffset + yOffset + 174 + i * (32 + borderOffset) - 1, (292 / 2) - 32 - 3 * borderOffset + 2, 32 + 2), borderColor);
  116. }
  117. std::shared_ptr<IImage> backgroundShapesImg = GH.renderHandler().createImage(canvas.getInternalSurface());
  118. backgroundShapes = std::make_shared<CPicture>(backgroundShapesImg, pos);
  119. }
  120. void CHeroOverview::genControls()
  121. {
  122. labelTitle = std::make_shared<CLabel>(pos.w / 2 + 8, 21, FONT_MEDIUM, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[77]);
  123. // hero image
  124. imageHero = std::make_shared<CAnimImage>(AnimationPath::builtin("PortraitsLarge"), (*CGI->heroh)[heroIndex]->imageIndex, 0, borderOffset, borderOffset + yOffset);
  125. // hero name
  126. labelHeroName = std::make_shared<CLabel>(borderOffset + 174, borderOffset + yOffset + 20, FONT_MEDIUM, ETextAlignment::CENTER, Colors::YELLOW, (*CGI->heroh)[heroIndex]->getNameTranslated());
  127. labelHeroClass = std::make_shared<CLabel>(borderOffset + 174, borderOffset + yOffset + 45, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, (*CGI->heroh)[heroIndex]->heroClass->getNameTranslated());
  128. // skills header
  129. for(int i = 0; i < 4; i++)
  130. labelSkillHeader.push_back(std::make_shared<CLabel>((284 / 4) * i + 42, 2 * borderOffset + yOffset + 74, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->jktexts[1 + i]));
  131. // skill
  132. const int tmp[] = {0, 1, 2, 5};
  133. for(int i = 0; i < 4; i++)
  134. imageSkill.push_back(std::make_shared<CAnimImage>(AnimationPath::builtin("PSKIL42"), tmp[i], 0, (284 / 4) * i + 21, 3 * borderOffset + yOffset + 64 + 20 + 1));
  135. // skills footer
  136. for(int i = 0; i < 4; i++)
  137. labelSkillFooter.push_back(std::make_shared<CLabel>((284 / 4) * i + 42, 4 * borderOffset + yOffset + 138, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, std::to_string((*CGI->heroh)[heroIndex]->heroClass->primarySkillInitial[i])));
  138. // hero biography
  139. labelHeroBiography = std::make_shared<CMultiLineLabel>(Rect(2 * borderOffset, 5 * borderOffset + borderOffset + yOffset + 148, 284 - 2 * borderOffset, 130 - 2 * borderOffset), FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, (*CGI->heroh)[heroIndex]->getBiographyTranslated());
  140. // speciality name
  141. labelHeroSpeciality = std::make_shared<CLabel>(3 * borderOffset + 44, 7 * borderOffset + yOffset + 278, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::YELLOW, CGI->generaltexth->allTexts[78]);
  142. labelSpecialityName = std::make_shared<CLabel>(3 * borderOffset + 44, 7 * borderOffset + yOffset + 298, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, (*CGI->heroh)[heroIndex]->getSpecialtyNameTranslated());
  143. // speciality image
  144. imageSpeciality = std::make_shared<CAnimImage>(AnimationPath::builtin("UN44"), (*CGI->heroh)[heroIndex]->imageIndex, 0, borderOffset, 6 * borderOffset + yOffset + 278);
  145. // speciality description
  146. labelSpecialityDescription = std::make_shared<CMultiLineLabel>(Rect(2 * borderOffset, 8 * borderOffset + yOffset + 321, 284 - borderOffset, 85 - borderOffset), FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, (*CGI->heroh)[heroIndex]->getSpecialtyDescriptionTranslated());
  147. // army title
  148. labelArmyTitle = std::make_shared<CLabel>(302 + borderOffset, 2 * borderOffset + yOffset + 2, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::YELLOW, CGI->generaltexth->translate("vcmi.heroOverview.startingArmy"));
  149. // army
  150. int i = 0;
  151. for(auto & army : (*CGI->heroh)[heroIndex]->initialArmy)
  152. {
  153. if((*CGI->creh)[army.creature]->warMachine == ArtifactID::NONE)
  154. {
  155. int space = (292 - 32 - 6 * 32) / 5;
  156. imageArmy.push_back(std::make_shared<CAnimImage>(AnimationPath::builtin("CPRSMALL"), (*CGI->creh)[army.creature]->getIconIndex(), 0, 302 + i * (32 + space) + 16, 2 * borderOffset + yOffset + 30));
  157. labelArmyCount.push_back(std::make_shared<CLabel>(302 + i * (32 + space) + 32, 3 * borderOffset + yOffset + 72, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, (army.minAmount == army.maxAmount) ? std::to_string(army.minAmount) : std::to_string(army.minAmount) + "-" + std::to_string(army.maxAmount)));
  158. i++;
  159. }
  160. }
  161. // war machine title
  162. labelWarMachineTitle = std::make_shared<CLabel>(302 + borderOffset, 4 * borderOffset + yOffset + 89, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::YELLOW, CGI->generaltexth->translate("vcmi.heroOverview.warMachine"));
  163. // war machine
  164. i = 0;
  165. for(auto & army : (*CGI->heroh)[heroIndex]->initialArmy)
  166. {
  167. int space = (292 - 32 - 6 * 32) / 5;
  168. if(i == 0)
  169. {
  170. imageWarMachine.push_back(std::make_shared<CAnimImage>(AnimationPath::builtin("CPRSMALL"), (*CGI->creh)[army.creature.CATAPULT]->getIconIndex(), 0, 302 + i * (32 + space) + 16, 5 * borderOffset + yOffset + 112));
  171. i++;
  172. }
  173. if((*CGI->creh)[army.creature]->warMachine != ArtifactID::NONE)
  174. {
  175. imageWarMachine.push_back(std::make_shared<CAnimImage>(AnimationPath::builtin("CPRSMALL"), (*CGI->creh)[army.creature]->getIconIndex(), 0, 302 + i * (32 + space) + 16, 5 * borderOffset + yOffset + 112));
  176. i++;
  177. }
  178. }
  179. // secskill title
  180. labelSecSkillTitle = std::make_shared<CLabel>(302 + borderOffset, 6 * borderOffset + yOffset + 152, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::YELLOW, CGI->generaltexth->translate("vcmi.heroOverview.secondarySkills"));
  181. // spell title
  182. labelSpellTitle = std::make_shared<CLabel>(302 + (292 / 2) + 3 * borderOffset, 6 * borderOffset + yOffset + 152, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::YELLOW, CGI->generaltexth->translate("vcmi.heroOverview.spells"));
  183. // secskill
  184. i = 0;
  185. for(auto & skill : (*CGI->heroh)[heroIndex]->secSkillsInit)
  186. {
  187. imageSecSkills.push_back(std::make_shared<CAnimImage>(AnimationPath::builtin("SECSK32"), (*CGI->skillh)[skill.first]->getIconIndex() * 3 + skill.second + 2, 0, 302, 7 * borderOffset + yOffset + 174 + i * (32 + borderOffset)));
  188. labelSecSkillsNames.push_back(std::make_shared<CLabel>(334 + 2 * borderOffset, 8 * borderOffset + yOffset + 174 + i * (32 + borderOffset) - 5, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->levels[skill.second - 1]));
  189. labelSecSkillsNames.push_back(std::make_shared<CLabel>(334 + 2 * borderOffset, 8 * borderOffset + yOffset + 174 + i * (32 + borderOffset) + 10, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, (*CGI->skillh)[skill.first]->getNameTranslated()));
  190. i++;
  191. }
  192. // spell
  193. i = 0;
  194. for(auto & spell : (*CGI->heroh)[heroIndex]->spells)
  195. {
  196. if(i == 0)
  197. {
  198. if((*CGI->heroh)[heroIndex]->haveSpellBook)
  199. {
  200. imageSpells.push_back(std::make_shared<CAnimImage>(GH.renderHandler().loadAnimation(AnimationPath::builtin("ARTIFACT")), 0, Rect(302 + (292 / 2) + 2 * borderOffset, 7 * borderOffset + yOffset + 174 + i * (32 + borderOffset), 32, 32), 0));
  201. }
  202. i++;
  203. }
  204. imageSpells.push_back(std::make_shared<CAnimImage>(GH.renderHandler().loadAnimation(AnimationPath::builtin("SPELLBON")), (*CGI->spellh)[spell]->getIconIndex(), Rect(302 + (292 / 2) + 2 * borderOffset, 7 * borderOffset + yOffset + 174 + i * (32 + borderOffset), 32, 32), 0));
  205. labelSpellsNames.push_back(std::make_shared<CLabel>(302 + (292 / 2) + 3 * borderOffset + 32 + borderOffset, 8 * borderOffset + yOffset + 174 + i * (32 + borderOffset) + 3, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, (*CGI->spellh)[spell]->getNameTranslated()));
  206. i++;
  207. }
  208. }