Kaynağa Gözat

Gui for hero invite

Laserlicht 1 yıl önce
ebeveyn
işleme
a0098eb065

+ 2 - 0
Mods/vcmi/config/vcmi/english.json

@@ -232,6 +232,8 @@
 	"vcmi.heroWindow.openBackpack.hover" : "Open artifact backpack window",
 	"vcmi.heroWindow.openBackpack.help"  : "Opens window that allows easier artifact backpack management.",
 
+	"vcmi.tavernWindow.inviteHero"  : "Invite hero",
+
 	"vcmi.commanderWindow.artifactMessage" : "Do you want to return this artifact to the hero?",
 
 	"vcmi.creatureWindow.showBonuses.hover"    : "Switch to bonuses view",

+ 2 - 0
Mods/vcmi/config/vcmi/german.json

@@ -232,6 +232,8 @@
 	"vcmi.heroWindow.openBackpack.hover" : "Artefakt-Rucksack-Fenster öffnen",
 	"vcmi.heroWindow.openBackpack.help"  : "Öffnet ein Fenster, das die Verwaltung des Artefakt-Rucksacks erleichtert",
 
+	"vcmi.tavernWindow.inviteHero"  : "Helden einladen",
+
 	"vcmi.commanderWindow.artifactMessage" : "Möchtet Ihr diesen Artefakt dem Helden zurückgeben?",
 
 	"vcmi.creatureWindow.showBonuses.hover"    : "Wechsle zur Bonus-Ansicht",

+ 57 - 12
client/windows/GUIClasses.cpp

@@ -446,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);
 
@@ -510,24 +511,42 @@ 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::recruitb()
+void CTavernWindow::addInvite()
 {
-	const CGHeroInstance *toBuy = (selected ? h2 : h1)->h;
-	const CGObjectInstance *obj = tavernObj;
-
-	const auto & heroesPool = CSH->client->gameState()->heroesPool;
-	HeroTypeID nextHero = HeroTypeID::NONE;
+	OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
 
-	for(auto & elem : heroesPool->unusedHeroesFromPool())
+	if(CSH->client->getStartInfo()->extraOptionsInfo.inviteHero)
 	{
-		bool heroAvailable = heroesPool->isHeroAvailableFor(elem.first, tavernObj->getOwner());
-		if(heroAvailable && elem.second->getNameTranslated() == "Sir Mullich")
-			nextHero = elem.first;
+		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.size() > 0)
+		{
+			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), [&](){ GH.windows().createAndPushWindow<HeroSelector>(inviteableHeroes, [&](CGHeroInstance* h){ heroToInvite = h; addInvite(); }); }, [&](){ GH.windows().createAndPushWindow<CRClickPopupInt>(std::make_shared<CHeroWindow>(heroToInvite)); });
+		}
 	}
+}
+
+void CTavernWindow::recruitb()
+{
+	const CGHeroInstance *toBuy = (selected ? h2 : h1)->h;
+	const CGObjectInstance *obj = tavernObj;
 
-	LOCPLINT->cb->recruitHero(obj, toBuy, nextHero);
+	LOCPLINT->cb->recruitHero(obj, toBuy, heroToInvite ? heroToInvite->getHeroType() : HeroTypeID::NONE);
 	close();
 }
 
@@ -636,6 +655,32 @@ 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, 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), [&](){ close(); onChoose(inviteableHeroes[h.first]); }, [&](){ 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";
 

+ 24 - 0
client/windows/GUIClasses.h

@@ -36,6 +36,8 @@ class CTextBox;
 class CGarrisonInt;
 class CGarrisonSlot;
 class CHeroArea;
+class CAnimImage;
+class CFilledTexture;
 
 enum class EUserEvent;
 
@@ -221,6 +223,21 @@ public:
 		std::shared_ptr<CAnimImage> portrait;
 	};
 
+	class HeroSelector : public CWindowObject
+	{
+	public:
+		std::shared_ptr<CFilledTexture> background;
+
+		HeroSelector(std::map<HeroTypeID, CGHeroInstance*> InviteableHeroes, std::function<void(CGHeroInstance*)> OnChoose);
+
+	private:
+		std::map<HeroTypeID, CGHeroInstance*> inviteableHeroes;
+		std::function<void(CGHeroInstance*)> onChoose;
+
+		std::vector<std::shared_ptr<CAnimImage>> portraits;
+		std::vector<std::shared_ptr<LRClickableArea>> portraitAreas;
+	};
+
 	//recruitable heroes
 	std::shared_ptr<HeroPortrait> h1;
 	std::shared_ptr<HeroPortrait> h2; //recruitable heroes
@@ -240,6 +257,13 @@ public:
 	std::shared_ptr<CTextBox> heroDescription;
 
 	std::shared_ptr<CTextBox> rumor;
+	
+	std::shared_ptr<CLabel> inviteHero;
+	std::shared_ptr<CAnimImage> inviteHeroImage;
+	std::shared_ptr<LRClickableArea> inviteHeroImageArea;
+	std::map<HeroTypeID, CGHeroInstance*> inviteableHeroes;
+	CGHeroInstance* heroToInvite;
+	void addInvite();
 
 	CTavernWindow(const CGObjectInstance * TavernObj, const std::function<void()> & onWindowClosed);
 	~CTavernWindow();