recruitmentscene.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449
  1. #include "ui/hotseat_recruitment/recruitmentscene.h"
  2. #include "ui/dialog_form/dialogform.h"
  3. #include "ui_recruitmentscene.h"
  4. #include "gui/guiscenemanager.h"
  5. #include "gui/scene.h"
  6. #include "player.h"
  7. #include "playermanager.h"
  8. #include "race.h"
  9. #include "racemanager.h"
  10. #include "soundengine.h"
  11. #include <QString>
  12. #include <QStringList>
  13. #include <QMovie>
  14. #include <QDebug>
  15. #include <QMouseEvent>
  16. #include <vector>
  17. RecruitmentScene::RecruitmentScene(QWidget *parent)
  18. : Scene(parent)
  19. , ui(new Ui::RecruitmentScene)
  20. {
  21. ui->setupUi(this);
  22. movie = new QMovie(":/assets/hotseat_recruit/image.gif");
  23. ui->image->setMovie(movie);
  24. movie->start();
  25. watcher = new ButtonEventListener(this);
  26. ui->complete_choice_button->installEventFilter(watcher);
  27. ui->back_button->installEventFilter(watcher);
  28. // Создаём обработчик событий нажатия иконок рас
  29. race_icon_watcher = new RaceIconEventListener(this, this);
  30. for (unsigned i = 0; i < RACES_NUMBER; i++) {
  31. QLabel* race_icon = findChild<QLabel*>("available_race_" + QString::number(i));
  32. if (race_icon)
  33. race_icon->installEventFilter(race_icon_watcher);
  34. }
  35. ui->chosen_race_image_->installEventFilter(race_icon_watcher);
  36. // Создаём обработчик событий нажатия иконок юнитов
  37. unit_icon_watcher = new UnitIconEventListener(this, this);
  38. for (unsigned i = 0; i < AVAILABLE_UNIT_NUMBER; i++) {
  39. QLabel* unit_icon = findChild<QLabel*>("available_unit_" + QString::number(i));
  40. if (unit_icon)
  41. unit_icon->installEventFilter(unit_icon_watcher);
  42. }
  43. for (unsigned i = 0; i < MAX_PARTY_SIZE; i++) {
  44. QLabel* unit_icon = findChild<QLabel*>("chosen_unit_" + QString::number(i));
  45. if (unit_icon)
  46. unit_icon->installEventFilter(unit_icon_watcher);
  47. }
  48. }
  49. RecruitmentScene::~RecruitmentScene()
  50. {
  51. }
  52. void RecruitmentScene::parseArgs(QString args) {
  53. QStringList list = args.split("|");
  54. if (list.size() < 2) {
  55. // TODO: ERROR MESSAGE - incorrect arguments number
  56. GuiSceneManager::getInstance().changeScene("main_menu");
  57. }
  58. current_player_id_ = list[0].toInt();
  59. current_player_ = PlayerManager::getInstance().getPlayer(current_player_id_);
  60. available_money_ = std::max(0, list[1].toInt());
  61. if (!current_player_) {
  62. // TODO: ERROR MESSAGE - incorrect argument - player_id;
  63. GuiSceneManager::getInstance().changeScene("main_menu");
  64. }
  65. }
  66. void RecruitmentScene::init() {
  67. current_money_ = available_money_;
  68. initAvailableRaces();
  69. initAvailableUnits();
  70. showChosenUnits();
  71. ui->title_->setText(
  72. "<p align=\"center\">Набор юнитов - " + current_player_->getPlayerName() + "</p>"
  73. );
  74. QString race_name = current_player_->getRace()->getRaceId();
  75. ui->chosen_race_image_->setText(
  76. "<img src=\":/assets/units/" + race_name + "/icon.png\" width=\"100\" height=\"100\"/>"
  77. );
  78. updateMoney();
  79. DialogForm* form = qobject_cast<DialogForm*>(GuiSceneManager::getInstance().getScene("dialog_form"));
  80. if (!form)
  81. return;
  82. form->setTitle("Найм юнитов для игрока: " + current_player_->getPlayerName());
  83. form->setShowCancel(false);
  84. form->setText("Игрок \"" + current_player_->getPlayerName() + "\", пришло время вам набрать свой отряд!");
  85. GuiSceneManager::getInstance().show("dialog_form");
  86. form->exec();
  87. GuiSceneManager::getInstance().hide("dialog_form");
  88. }
  89. Player *RecruitmentScene::getActivePlayer()
  90. {
  91. return current_player_;
  92. }
  93. bool RecruitmentScene::buyUnit(std::shared_ptr<Unit> unit)
  94. {
  95. if (!unit || unit->getCost() > current_money_ || current_player_->getUnits().size() >= MAX_PARTY_SIZE)
  96. return false;
  97. current_player_->addUnit(unit);
  98. current_money_ -= unit->getCost();
  99. updateMoney();
  100. showChosenUnits();
  101. return true;
  102. }
  103. bool RecruitmentScene::removeUnit(std::shared_ptr<Unit> unit) {
  104. current_money_ += unit->getCost();
  105. updateMoney();
  106. current_player_->deleteUnit(unit);
  107. showChosenUnits();
  108. return true;
  109. }
  110. void RecruitmentScene::initAvailableRaces() {
  111. auto races = RaceManager::getInstance().getAvailableRacesList();
  112. races_list.clear();
  113. for (unsigned i = 0; i < std::min(RACES_NUMBER, races.size()); i++) {
  114. QString race_name = races[i];
  115. races_list.push_back(RaceManager::getInstance().getRace(race_name));
  116. QLabel* race_icon = findChild<QLabel*>("available_race_" + QString::number(i));
  117. if (race_icon)
  118. race_icon->setText("<img src=\":/assets/units/" + race_name + "/icon.png\" width=\"66\" height=\"66\"/>");
  119. }
  120. }
  121. void RecruitmentScene::initAvailableUnits() {
  122. auto units_list = current_player_->getRace()->getAllUnitsList();
  123. available_units_list.clear();
  124. for (unsigned i = 0; i < std::min(AVAILABLE_UNIT_NUMBER, units_list.size()); i++) {
  125. QString race_name = current_player_->getRace()->getRaceId();
  126. QString unit_name = units_list[i]->getUnitId();
  127. available_units_list.push_back(units_list[i]);
  128. QLabel* unit_icon = findChild<QLabel*>("available_unit_" + QString::number(i));
  129. qDebug() << "<img src=\":/assets/units/" + race_name + "/" + unit_name + "/icon.png\" width=\"58\" height=\"58\"/>";
  130. if (unit_icon)
  131. unit_icon->setText("<img src=\":/assets/units/" + race_name + "/" + unit_name + "/icon.png\" width=\"58\" height=\"58\"/>");
  132. }
  133. }
  134. void RecruitmentScene::showChosenUnits() {
  135. unsigned counter = 0;
  136. chosen_units_list.clear();
  137. for (auto unit : current_player_->getUnits()) {
  138. if (counter >= MAX_PARTY_SIZE)
  139. break;
  140. QString unit_name = unit->getUnitId();
  141. chosen_units_list.push_back(unit);
  142. QString race_name = current_player_->getRace()->getRaceId();
  143. QLabel* unit_icon = findChild<QLabel*>("chosen_unit_" + QString::number(counter));
  144. if (unit_icon) {
  145. unit_icon->setText("<img src=\":/assets/units/" + race_name + "/" + unit_name + "/icon.png\" width=\"58\" height=\"58\"/>");
  146. unit_icon->setStyleSheet("border-image: url(:/assets/hotseat_recruit/unit_icon_default.png);\nbackground-color: rgb(253, 234, 168);");
  147. }
  148. counter++;
  149. }
  150. for (unsigned i = counter; i < MAX_PARTY_SIZE; i++) {
  151. QLabel* unit_icon = findChild<QLabel*>("chosen_unit_" + QString::number(i));
  152. if (unit_icon) {
  153. unit_icon->setText("");
  154. unit_icon->setStyleSheet("border-image: url(:/assets/hotseat_recruit/unit_icon_default.png);\nbackground-color: rgb(253, 234, 168);");
  155. }
  156. }
  157. }
  158. void RecruitmentScene::changeRace(std::shared_ptr<Race> race) {
  159. current_player_->clearUnits();
  160. current_player_->setRace(race);
  161. init();
  162. }
  163. void RecruitmentScene::updateMoney() {
  164. ui->available_money_text_->setText("Монеты: " + QString::number(current_money_));
  165. }
  166. void RecruitmentScene::on_back_button_clicked() {
  167. GuiSceneManager::getInstance().changeScene("pvp_intro");
  168. }
  169. void RecruitmentScene::on_complete_choice_button_clicked()
  170. {
  171. qDebug() << "Exiting recruit army scene with player_id =" << current_player_id_;
  172. if (current_player_id_ == 0) {
  173. qDebug() << "Changing to 1";
  174. GuiSceneManager::getInstance().changeScene("recruit_army", "1|" + QString::number(available_money_));
  175. } else {
  176. GuiSceneManager::getInstance().changeScene("prebattle");
  177. }
  178. }
  179. RaceIconEventListener::RaceIconEventListener(QObject *parent, RecruitmentScene* scene)
  180. : QObject(parent)
  181. , scene_(scene) {
  182. }
  183. bool RaceIconEventListener::eventFilter(QObject *watched, QEvent *event) {
  184. QLabel* icon = qobject_cast<QLabel*>(watched);
  185. if (!icon) {
  186. return false;
  187. }
  188. if (event->type() == QEvent::Enter) {
  189. if (icon->objectName() != "chosen_race_image_") {
  190. icon->setStyleSheet("border-image: url(:/assets/hotseat_recruit/unit_icon_hover.png);\nbackground-color: rgb(253, 234, 168);");
  191. SoundEngine::getInstance().playAsync("qrc:/assets/common/buttons/button_hover.mp3");
  192. unsigned race_id_number = icon->objectName().mid(icon->objectName().lastIndexOf('_') + 1).toInt();
  193. IconHint *hint = new IconHint(scene_);
  194. hint->setHintText("ЛКМ - сменить расу<br>ПКМ - открыть окно информации");
  195. hint->setHintTitle("Раса \"" + scene_->races_list[race_id_number]->getRaceName() + "\"");
  196. hint->move(icon->mapToGlobal(QPoint(0,0)).x() + icon->width() / 2 - hint->width() / 2, icon->mapToGlobal(QPoint(0,0)).y() + icon->height() + 2);
  197. } else {
  198. QString race_name = scene_->getActivePlayer()->getRace()->getRaceName();
  199. IconHint *hint = new IconHint(scene_);
  200. hint->setHintTitle("Раса \"" + race_name + "\"");
  201. hint->setHintText("ПКМ - открыть окно информации");
  202. hint->move(icon->mapToGlobal(QPoint(0,0)).x() + icon->width() / 2 - hint->width() / 2, icon->mapToGlobal(QPoint(0,0)).y() + icon->height() + 2);
  203. }
  204. return false;
  205. }
  206. if (event->type() == QEvent::Leave) {
  207. if (icon->objectName() != "chosen_race_image_") {
  208. icon->setStyleSheet("border-image: url(:/assets/hotseat_recruit/unit_icon_default.png);\nbackground-color: rgb(253, 234, 168);");
  209. SoundEngine::getInstance().playAsync("qrc:/assets/common/buttons/button_hover.mp3");
  210. if (!scene_)
  211. return false;
  212. }
  213. QList<IconHint*> hints = scene_->findChildren<IconHint*>("hint");
  214. for (auto &hint : hints) {
  215. hint->hide();
  216. hint->deleteLater();
  217. }
  218. return false;
  219. }
  220. if (event->type() == QEvent::MouseButtonPress) {
  221. if (icon->objectName() != "chosen_race_image_")
  222. icon->setStyleSheet("border-image: url(:/assets/hotseat_recruit/unit_icon_active.png);\nbackground-color: rgb(253, 234, 168);");
  223. SoundEngine::getInstance().playAsync("qrc:/assets/common/buttons/button_click.mp3");
  224. }
  225. if (event->type() == QEvent::MouseButtonRelease) {
  226. if (icon->objectName() != "chosen_race_image_")
  227. icon->setStyleSheet("border-image: url(:/assets/hotseat_recruit/unit_icon_hover.png);\nbackground-color: rgb(253, 234, 168);");
  228. QMouseEvent *evt = dynamic_cast<QMouseEvent*>(event);
  229. if (evt->button() == Qt::LeftButton) {
  230. if (icon->objectName() == "chosen_race_image_")
  231. return false;
  232. GuiSceneManager::getInstance().show("dialog_form");
  233. DialogForm* form = qobject_cast<DialogForm*>(GuiSceneManager::getInstance().getScene("dialog_form"));
  234. if (!form)
  235. return false;
  236. form->setTitle("Смена расы");
  237. form->setShowCancel(true);
  238. form->setText("Вы уверены, что хотите сменить расу? В этом случае все нанятые и улучшенные юниты исчезнут, а число монет будет восстановлено");
  239. form->exec();
  240. if (form->isOk()) {
  241. unsigned race_id_number = icon->objectName().mid(icon->objectName().lastIndexOf('_') + 1).toInt();
  242. scene_->changeRace(scene_->races_list[race_id_number]);
  243. }
  244. GuiSceneManager::getInstance().hide("dialog_form");
  245. }
  246. if (evt->button() == Qt::RightButton) {
  247. DialogForm* form = qobject_cast<DialogForm*>(GuiSceneManager::getInstance().getScene("dialog_form"));
  248. if (!form)
  249. return false;
  250. form->setTitle("Окно информации о расе");
  251. form->setShowCancel(false);
  252. form->setText("Окно информации о расе пока недоступно, извините");
  253. GuiSceneManager::getInstance().show("dialog_form");
  254. form->exec();
  255. GuiSceneManager::getInstance().hide("dialog_form");
  256. return false;
  257. }
  258. }
  259. return false;
  260. }
  261. UnitIconEventListener::UnitIconEventListener(QObject *parent, RecruitmentScene *scene)
  262. : QObject(parent)
  263. , scene_(scene) {
  264. }
  265. bool UnitIconEventListener::eventFilter(QObject *watched, QEvent *event) {
  266. QLabel* icon = qobject_cast<QLabel*>(watched);
  267. if (!icon) {
  268. qDebug() << __FILE__ << " " << __LINE__ << " cannot cast to icon!";
  269. return false;
  270. }
  271. unsigned unit_id_number = icon->objectName().mid(icon->objectName().lastIndexOf('_') + 1).toInt();
  272. QString icon_name = icon->objectName();
  273. if (icon_name.contains("available_unit") && unit_id_number >= scene_->available_units_list.size()) {
  274. return false;
  275. }
  276. if (icon_name.contains("chosen_unit") && unit_id_number >= scene_->chosen_units_list.size()) {
  277. return false;
  278. }
  279. std::shared_ptr<Unit> unit;
  280. if (icon_name.contains("available_unit"))
  281. unit = scene_->available_units_list[unit_id_number];
  282. else
  283. unit = scene_->chosen_units_list[unit_id_number];
  284. if (event->type() == QEvent::Enter) {
  285. icon->setStyleSheet("border-image: url(:/assets/hotseat_recruit/unit_icon_hover.png);\nbackground-color: rgb(253, 234, 168);");
  286. SoundEngine::getInstance().playAsync("qrc:/assets/common/buttons/button_hover.mp3");
  287. IconHint *hint = new IconHint(scene_);
  288. hint->resize(300, 300);
  289. hint->setHintTitle(unit->getUnitName());
  290. QString buttons_hint;
  291. if (icon_name.contains("available_unit"))
  292. buttons_hint = "<br>ЛКМ - нанять юнита<br>ПКМ - информация и улучшения";
  293. if (icon_name.contains("chosen_unit"))
  294. buttons_hint = "<br>ЛКМ - информация и улучшения<br>ПКМ - вернуть юнита";
  295. hint->setHintText("Стоимость: " + QString::number(unit->getCost()) + buttons_hint);
  296. hint->move(icon->mapToGlobal(QPoint(0,0)).x() + icon->width() / 2 - hint->width() / 2, icon->mapToGlobal(QPoint(0,0)).y() + icon->height() + 2);
  297. }
  298. if (event->type() == QEvent::Leave) {
  299. icon->setStyleSheet("border-image: url(:/assets/hotseat_recruit/unit_icon_default.png);\nbackground-color: rgb(253, 234, 168);");
  300. SoundEngine::getInstance().playAsync("qrc:/assets/common/buttons/button_hover.mp3");
  301. QList<IconHint*> hints = scene_->findChildren<IconHint*>("hint");
  302. for (auto &hint : hints) {
  303. hint->hide();
  304. hint->deleteLater();
  305. }
  306. }
  307. if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonDblClick) {
  308. icon->setStyleSheet("border-image: url(:/assets/hotseat_recruit/unit_icon_active.png);\nbackground-color: rgb(253, 234, 168);");
  309. SoundEngine::getInstance().playAsync("qrc:/assets/common/buttons/button_click.mp3");
  310. }
  311. if (event->type() == QEvent::MouseButtonRelease) {
  312. icon->setStyleSheet("border-image: url(:/assets/hotseat_recruit/unit_icon_hover.png);\nbackground-color: rgb(253, 234, 168);");
  313. QMouseEvent *evt = dynamic_cast<QMouseEvent*>(event);
  314. if (evt->button() == Qt::LeftButton) {
  315. if (icon_name.contains("available_unit")) {
  316. if (scene_->buyUnit(unit))
  317. return false;
  318. DialogForm* form = qobject_cast<DialogForm*>(GuiSceneManager::getInstance().getScene("dialog_form"));
  319. if (!form)
  320. return false;
  321. form->setTitle("Набор юнита " + unit->getUnitName());
  322. form->setShowCancel(false);
  323. form->setText("Не могу нанять юнита. Проверьте, возможно он слишком дорогой или для него нет места в отряде?");
  324. GuiSceneManager::getInstance().show("dialog_form");
  325. form->exec();
  326. GuiSceneManager::getInstance().hide("dialog_form");
  327. return false;
  328. }
  329. if (icon_name.contains("chosen_unit")) {
  330. DialogForm* form = qobject_cast<DialogForm*>(GuiSceneManager::getInstance().getScene("dialog_form"));
  331. if (!form) {
  332. return false;
  333. }
  334. form->setTitle("Окно информации о юните " + unit->getUnitName());
  335. form->setShowCancel(false);
  336. form->setText("К сожалению, окно информации о юните и его улучшениях временно недоступно :( <br> В данной версии вы можете выбирать только из юнитов первого звена");
  337. GuiSceneManager::getInstance().show("dialog_form");
  338. form->exec();
  339. GuiSceneManager::getInstance().hide("dialog_form");
  340. return false;
  341. }
  342. }
  343. if (evt->button() == Qt::RightButton) {
  344. if (icon_name.contains("available_unit")) {
  345. DialogForm* form = qobject_cast<DialogForm*>(GuiSceneManager::getInstance().getScene("dialog_form"));
  346. if (!form) {
  347. return false;
  348. }
  349. form->setTitle("Окно информации о юните " + unit->getUnitName());
  350. form->setShowCancel(false);
  351. form->setText("К сожалению, окно информации о юните и его улучшениях временно недоступно :( <br> В данной версии вы можете выбирать только из юнитов первого звена");
  352. GuiSceneManager::getInstance().show("dialog_form");
  353. form->exec();
  354. GuiSceneManager::getInstance().hide("dialog_form");
  355. return false;
  356. }
  357. if (icon_name.contains("chosen_unit")) {
  358. scene_->removeUnit(unit);
  359. QList<IconHint*> hints = scene_->findChildren<IconHint*>("hint");
  360. for (auto &hint : hints) {
  361. hint->hide();
  362. hint->deleteLater();
  363. }
  364. if (scene_->childAt(QCursor::pos()) == icon) {
  365. QEvent *event = new QEvent(QEvent::Enter);
  366. QCoreApplication::postEvent(icon, event);
  367. }
  368. }
  369. }
  370. }
  371. return false;
  372. }