|
@@ -17,6 +17,8 @@
|
|
|
#include "InfoWindows.h"
|
|
|
|
|
|
#include "../CGameInfo.h"
|
|
|
+#include "../CServerHandler.h"
|
|
|
+#include "../Client.h"
|
|
|
#include "../CMusicHandler.h"
|
|
|
#include "../CPlayerInterface.h"
|
|
|
#include "../CVideoHandler.h"
|
|
@@ -48,6 +50,7 @@
|
|
|
#include "../lib/mapObjects/ObjectTemplate.h"
|
|
|
#include "../lib/gameState/CGameState.h"
|
|
|
#include "../lib/gameState/SThievesGuildInfo.h"
|
|
|
+#include "../lib/gameState/TavernHeroesPool.h"
|
|
|
#include "../lib/CGeneralTextHandler.h"
|
|
|
#include "../lib/CHeroHandler.h"
|
|
|
#include "../lib/GameSettings.h"
|
|
@@ -443,7 +446,8 @@ CLevelWindow::~CLevelWindow()
|
|
|
CTavernWindow::CTavernWindow(const CGObjectInstance * TavernObj, const std::function<void()> & onWindowClosed)
|
|
|
: CStatusbarWindow(PLAYER_COLORED, ImagePath::builtin("TPTAVERN")),
|
|
|
onWindowClosed(onWindowClosed),
|
|
|
- tavernObj(TavernObj)
|
|
|
+ tavernObj(TavernObj),
|
|
|
+ heroToInvite(nullptr)
|
|
|
{
|
|
|
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
|
|
|
|
|
@@ -459,8 +463,8 @@ CTavernWindow::CTavernWindow(const CGObjectInstance * TavernObj, const std::func
|
|
|
|
|
|
oldSelected = -1;
|
|
|
|
|
|
- h1 = std::make_shared<HeroPortrait>(selected, 0, 72, 299, h[0]);
|
|
|
- h2 = std::make_shared<HeroPortrait>(selected, 1, 162, 299, h[1]);
|
|
|
+ h1 = std::make_shared<HeroPortrait>(selected, 0, 72, 299, h[0], [this]() { if(!recruit->isBlocked()) recruitb(); });
|
|
|
+ h2 = std::make_shared<HeroPortrait>(selected, 1, 162, 299, h[1], [this]() { if(!recruit->isBlocked()) recruitb(); });
|
|
|
|
|
|
title = std::make_shared<CLabel>(197, 32, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->jktexts[37]);
|
|
|
cost = std::make_shared<CLabel>(320, 328, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, std::to_string(GameConstants::HERO_GOLD_COST));
|
|
@@ -507,6 +511,34 @@ CTavernWindow::CTavernWindow(const CGObjectInstance * TavernObj, const std::func
|
|
|
CCS->videoh->open(townObj->town->clientInfo.tavernVideo);
|
|
|
else
|
|
|
CCS->videoh->open(VideoPath::builtin("TAVERN.BIK"));
|
|
|
+
|
|
|
+ addInvite();
|
|
|
+}
|
|
|
+
|
|
|
+void CTavernWindow::addInvite()
|
|
|
+{
|
|
|
+ OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
|
|
|
+
|
|
|
+ if(!VLC->settings()->getBoolean(EGameSettings::HEROES_TAVERN_INVITE))
|
|
|
+ return;
|
|
|
+
|
|
|
+ const auto & heroesPool = CSH->client->gameState()->heroesPool;
|
|
|
+ for(auto & elem : heroesPool->unusedHeroesFromPool())
|
|
|
+ {
|
|
|
+ bool heroAvailable = heroesPool->isHeroAvailableFor(elem.first, tavernObj->getOwner());
|
|
|
+ if(heroAvailable)
|
|
|
+ inviteableHeroes[elem.first] = elem.second;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(!inviteableHeroes.empty())
|
|
|
+ {
|
|
|
+ if(!heroToInvite)
|
|
|
+ heroToInvite = (*RandomGeneratorUtil::nextItem(inviteableHeroes, CRandomGenerator::getDefault())).second;
|
|
|
+
|
|
|
+ inviteHero = std::make_shared<CLabel>(170, 444, EFonts::FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->translate("vcmi.tavernWindow.inviteHero"));
|
|
|
+ inviteHeroImage = std::make_shared<CAnimImage>(AnimationPath::builtin("PortraitsSmall"), (*CGI->heroh)[heroToInvite->getHeroType()]->imageIndex, 0, 245, 428);
|
|
|
+ inviteHeroImageArea = std::make_shared<LRClickableArea>(Rect(245, 428, 48, 32), [this](){ GH.windows().createAndPushWindow<HeroSelector>(inviteableHeroes, [this](CGHeroInstance* h){ heroToInvite = h; addInvite(); }); }, [this](){ GH.windows().createAndPushWindow<CRClickPopupInt>(std::make_shared<CHeroWindow>(heroToInvite)); });
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
void CTavernWindow::recruitb()
|
|
@@ -514,7 +546,7 @@ void CTavernWindow::recruitb()
|
|
|
const CGHeroInstance *toBuy = (selected ? h2 : h1)->h;
|
|
|
const CGObjectInstance *obj = tavernObj;
|
|
|
|
|
|
- LOCPLINT->cb->recruitHero(obj, toBuy);
|
|
|
+ LOCPLINT->cb->recruitHero(obj, toBuy, heroToInvite ? heroToInvite->getHeroType() : HeroTypeID::NONE);
|
|
|
close();
|
|
|
}
|
|
|
|
|
@@ -569,15 +601,23 @@ void CTavernWindow::HeroPortrait::clickPressed(const Point & cursorPosition)
|
|
|
*_sel = _id;
|
|
|
}
|
|
|
|
|
|
+void CTavernWindow::HeroPortrait::clickDouble(const Point & cursorPosition)
|
|
|
+{
|
|
|
+ clickPressed(cursorPosition);
|
|
|
+
|
|
|
+ if(onChoose)
|
|
|
+ onChoose();
|
|
|
+}
|
|
|
+
|
|
|
void CTavernWindow::HeroPortrait::showPopupWindow(const Point & cursorPosition)
|
|
|
{
|
|
|
if(h)
|
|
|
GH.windows().createAndPushWindow<CRClickPopupInt>(std::make_shared<CHeroWindow>(h));
|
|
|
}
|
|
|
|
|
|
-CTavernWindow::HeroPortrait::HeroPortrait(int & sel, int id, int x, int y, const CGHeroInstance * H)
|
|
|
- : CIntObject(LCLICK | SHOW_POPUP | HOVER),
|
|
|
- h(H), _sel(&sel), _id(id)
|
|
|
+CTavernWindow::HeroPortrait::HeroPortrait(int & sel, int id, int x, int y, const CGHeroInstance * H, std::function<void()> OnChoose)
|
|
|
+ : CIntObject(LCLICK | DOUBLECLICK | SHOW_POPUP | HOVER),
|
|
|
+ h(H), _sel(&sel), _id(id), onChoose(OnChoose)
|
|
|
{
|
|
|
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
|
|
|
h = H;
|
|
@@ -615,6 +655,33 @@ void CTavernWindow::HeroPortrait::hover(bool on)
|
|
|
GH.statusbar()->clear();
|
|
|
}
|
|
|
|
|
|
+CTavernWindow::HeroSelector::HeroSelector(std::map<HeroTypeID, CGHeroInstance*> InviteableHeroes, std::function<void(CGHeroInstance*)> OnChoose)
|
|
|
+ : CWindowObject(BORDERED), inviteableHeroes(InviteableHeroes), onChoose(OnChoose)
|
|
|
+{
|
|
|
+ OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE;
|
|
|
+
|
|
|
+ pos = Rect(0, 0, 16 * 48, (inviteableHeroes.size() / 16 + (inviteableHeroes.size() % 16 != 0)) * 32);
|
|
|
+ background = std::make_shared<CFilledTexture>(ImagePath::builtin("DIBOXBCK"), Rect(0, 0, pos.w, pos.h));
|
|
|
+
|
|
|
+ int x = 0;
|
|
|
+ int y = 0;
|
|
|
+ for(auto & h : inviteableHeroes)
|
|
|
+ {
|
|
|
+ portraits.push_back(std::make_shared<CAnimImage>(AnimationPath::builtin("PortraitsSmall"), (*CGI->heroh)[h.first]->imageIndex, 0, x * 48, y * 32));
|
|
|
+ portraitAreas.push_back(std::make_shared<LRClickableArea>(Rect(x * 48, y * 32, 48, 32), [this, h](){ close(); onChoose(inviteableHeroes[h.first]); }, [this, h](){ GH.windows().createAndPushWindow<CRClickPopupInt>(std::make_shared<CHeroWindow>(inviteableHeroes[h.first])); }));
|
|
|
+
|
|
|
+ if(x > 0 && x % 15 == 0)
|
|
|
+ {
|
|
|
+ x = 0;
|
|
|
+ y++;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ x++;
|
|
|
+ }
|
|
|
+
|
|
|
+ center();
|
|
|
+}
|
|
|
+
|
|
|
static const std::string QUICK_EXCHANGE_MOD_PREFIX = "quick-exchange";
|
|
|
static const std::string QUICK_EXCHANGE_BG = QUICK_EXCHANGE_MOD_PREFIX + "/TRADEQE";
|
|
|
|