Sfoglia il codice sorgente

Improve neutral creature adventure map popup

Dydzio 2 anni fa
parent
commit
ed12f20609

+ 23 - 0
client/widgets/MiscWidgets.cpp

@@ -17,6 +17,7 @@
 
 #include "../CPlayerInterface.h"
 #include "../CGameInfo.h"
+#include "../PlayerLocalState.h"
 #include "../widgets/TextControls.h"
 #include "../widgets/CGarrisonInt.h"
 #include "../windows/CCastleInterface.h"
@@ -31,6 +32,7 @@
 #include "../../lib/CModHandler.h"
 #include "../../lib/GameSettings.h"
 #include "../../lib/TextOperations.h"
+#include "../../lib/mapObjects/CGCreature.h"
 #include "../../lib/mapObjects/CGHeroInstance.h"
 #include "../../lib/mapObjects/CGTownInstance.h"
 
@@ -436,6 +438,27 @@ void CInteractableTownTooltip::init(const InfoAboutTown & town)
 	}
 }
 
+CreatureTooltip::CreatureTooltip(Point pos, const CGCreature * creature)
+{
+	OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE;
+
+	auto creatureData = (*CGI->creh)[creature->stacks.begin()->second->getCreatureID()].get();
+	creatureImage = std::make_shared<CAnimImage>(graphics->getAnimation("TWCRPORT"), creatureData->getIconIndex());
+	creatureImage->center(Point(parent->pos.x + parent->pos.w / 2, parent->pos.y + creatureImage->pos.h / 2 + 11));
+
+	bool isHeroSelected = LOCPLINT->localState->getCurrentHero() != nullptr;
+	std::string textContent = isHeroSelected
+			? creature->getHoverText(LOCPLINT->localState->getCurrentHero())
+			: creature->getHoverText(LOCPLINT->playerID);
+
+	//TODO: window is bigger than OH3
+	//TODO: vertical alignment does not match H3. Commented below example that matches H3 for creatures count but supports only 1 line:
+	/*std::shared_ptr<CLabel> = std::make_shared<CLabel>(parent->pos.w / 2, 103,
+			FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, creature->getHoverText(LOCPLINT->playerID));*/
+
+	tooltipTextbox = std::make_shared<CTextBox>(textContent, Rect(15, 95, 230, 150), 0, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE);
+}
+
 void MoraleLuckBox::set(const AFactionMember * node)
 {
 	OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);

+ 11 - 0
client/widgets/MiscWidgets.h

@@ -14,6 +14,7 @@
 VCMI_LIB_NAMESPACE_BEGIN
 
 class CGGarrison;
+class CGCreature;
 struct InfoAboutArmy;
 class CArmedInstance;
 class AFactionMember;
@@ -21,6 +22,7 @@ class AFactionMember;
 VCMI_LIB_NAMESPACE_END
 
 class CLabel;
+class CTextBox;
 class CGarrisonInt;
 class CCreatureAnim;
 class CComponent;
@@ -147,6 +149,15 @@ public:
 	void setAmount(int newAmount);
 };
 
+class CreatureTooltip : public CIntObject
+{
+	std::shared_ptr<CAnimImage> creatureImage;
+	std::shared_ptr<CTextBox> tooltipTextbox;
+
+public:
+	CreatureTooltip(Point pos, const CGCreature * creature);
+};
+
 /// Resource bar like that at the bottom of the adventure map screen
 class CMinorResDataBar : public CIntObject
 {

+ 13 - 3
client/windows/InfoWindows.cpp

@@ -35,6 +35,7 @@
 #include "../../lib/CConfigHandler.h"
 #include "../../lib/CondSh.h"
 #include "../../lib/CGeneralTextHandler.h" //for Unicode related stuff
+#include "../../lib/mapObjects/CGCreature.h"
 #include "../../lib/mapObjects/CGHeroInstance.h"
 #include "../../lib/mapObjects/CGTownInstance.h"
 #include "../../lib/mapObjects/MiscObjects.h"
@@ -333,7 +334,7 @@ void CRClickPopup::createAndPush(const std::string & txt, std::shared_ptr<CCompo
 
 void CRClickPopup::createAndPush(const CGObjectInstance * obj, const Point & p, ETextAlignment alignment)
 {
-	auto iWin = createInfoWin(p, obj); //try get custom infowindow for this obj
+	auto iWin = createCustomInfoWindow(p, obj); //try get custom infowindow for this obj
 	if(iWin)
 	{
 		GH.windows().pushWindow(iWin);
@@ -401,14 +402,21 @@ CInfoBoxPopup::CInfoBoxPopup(Point position, const CGGarrison * garr)
 	tooltip = std::make_shared<CArmyTooltip>(Point(9, 10), iah);
 }
 
-std::shared_ptr<WindowBase> CRClickPopup::createInfoWin(Point position, const CGObjectInstance * specific) //specific=0 => draws info about selected town/hero
+CInfoBoxPopup::CInfoBoxPopup(Point position, const CGCreature * creature)
+		: CWindowObject(RCLICK_POPUP | BORDERED, "DIBOXBCK", toScreen(position))
+{
+	OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
+	tooltip = std::make_shared<CreatureTooltip>(Point(9, 10), creature);
+}
+
+std::shared_ptr<WindowBase> CRClickPopup::createCustomInfoWindow(Point position, const CGObjectInstance * specific) //specific=0 => draws info about selected town/hero
 {
 	if(nullptr == specific)
 		specific = LOCPLINT->localState->getCurrentArmy();
 
 	if(nullptr == specific)
 	{
-		logGlobal->error("createInfoWin: no object to describe");
+		logGlobal->error("createCustomInfoWindow: no object to describe");
 		return nullptr;
 	}
 
@@ -418,6 +426,8 @@ std::shared_ptr<WindowBase> CRClickPopup::createInfoWin(Point position, const CG
 		return std::make_shared<CInfoBoxPopup>(position, dynamic_cast<const CGHeroInstance *>(specific));
 	case Obj::TOWN:
 		return std::make_shared<CInfoBoxPopup>(position, dynamic_cast<const CGTownInstance *>(specific));
+	case Obj::MONSTER:
+		return std::make_shared<CInfoBoxPopup>(position, dynamic_cast<const CGCreature *>(specific));
 	case Obj::GARRISON:
 	case Obj::GARRISON2:
 		return std::make_shared<CInfoBoxPopup>(position, dynamic_cast<const CGGarrison *>(specific));

+ 5 - 3
client/windows/InfoWindows.h

@@ -16,6 +16,7 @@
 VCMI_LIB_NAMESPACE_BEGIN
 
 class CGGarrison;
+class CGCreature;
 class Rect;
 
 VCMI_LIB_NAMESPACE_END
@@ -78,7 +79,7 @@ public:
 	virtual void close();
 	bool isPopupWindow() const override;
 
-	static std::shared_ptr<WindowBase> createInfoWin(Point position, const CGObjectInstance * specific);
+	static std::shared_ptr<WindowBase> createCustomInfoWindow(Point position, const CGObjectInstance * specific);
 	static void createAndPush(const std::string & txt, const CInfoWindow::TCompsInfo &comps = CInfoWindow::TCompsInfo());
 	static void createAndPush(const std::string & txt, std::shared_ptr<CComponent> component);
 	static void createAndPush(const CGObjectInstance * obj, const Point & p, ETextAlignment alignment = ETextAlignment::BOTTOMRIGHT);
@@ -108,15 +109,16 @@ public:
 	~CInfoPopup();
 };
 
-/// popup on adventure map for town\hero objects
+/// popup on adventure map for town\hero and other objects with customized popup content
 class CInfoBoxPopup : public CWindowObject
 {
-	std::shared_ptr<CArmyTooltip> tooltip;
+	std::shared_ptr<CIntObject> tooltip;
 	Point toScreen(Point pos);
 public:
 	CInfoBoxPopup(Point position, const CGTownInstance * town);
 	CInfoBoxPopup(Point position, const CGHeroInstance * hero);
 	CInfoBoxPopup(Point position, const CGGarrison * garr);
+	CInfoBoxPopup(Point position, const CGCreature * creature);
 };
 
 /// component selection window

+ 1 - 1
lib/mapObjects/CGCreature.cpp

@@ -53,7 +53,7 @@ std::string CGCreature::getHoverText(const CGHeroInstance * hero) const
 		ms.appendRawString(" ");
 		ms.appendLocalString(EMetaText::CRE_PL_NAMES,subID);
 
-		ms.appendRawString("\n");
+		ms.appendRawString("\n\n");
 
 		int decision = takenAction(hero, true);