recruitmentscene.cpp 18 KB

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