2
0
Эх сурвалжийг харах

Reworked CHillFortWindow
* fixed displaying free upgrades
* do not try to print 3rd or more resource in slot cost (in theory possible with mods)
** we need dynamic gui for that
* CDefEssential--

AlexVinS 9 жил өмнө
parent
commit
5506ae036a

+ 0 - 5
client/gui/CIntObject.h

@@ -90,11 +90,6 @@ public:
  */
 	std::vector<CIntObject *> children;
 
-	//FIXME: workaround
-	void deactivateKeyboard()
-	{
-		deactivate(KEYBOARD);
-	}
 
 /*
  * Public interface

+ 6 - 2
client/widgets/Images.cpp

@@ -144,12 +144,12 @@ void CPicture::convertToScreenBPP()
 {
 	SDL_Surface *hlp = bg;
 	bg = SDL_ConvertSurface(hlp,screen->format,0);
-	CSDL_Ext::setDefaultColorKey(bg);	
+	CSDL_Ext::setDefaultColorKey(bg);
 	SDL_FreeSurface(hlp);
 }
 
 void CPicture::setAlpha(int value)
-{	
+{
 	CSDL_Ext::setAlpha (bg, value);
 }
 
@@ -241,6 +241,7 @@ size_t CAnimImage::size()
 
 void CAnimImage::init()
 {
+	visible = true;
 	anim->load(frame, group);
 	if (flags & CShowableAnim::BASE)
 		anim->load(0,group);
@@ -263,6 +264,9 @@ CAnimImage::~CAnimImage()
 
 void CAnimImage::showAll(SDL_Surface * to)
 {
+	if(!visible)
+		return;
+
 	IImage *img;
 
 	if ( flags & CShowableAnim::BASE && frame != 0)

+ 2 - 0
client/widgets/Images.h

@@ -80,6 +80,8 @@ private:
 	void init();
 
 public:
+	bool visible;
+
 	CAnimImage(std::string name, size_t Frame, size_t Group=0, int x=0, int y=0, ui8 Flags=0);
 	CAnimImage(CAnimation* anim, size_t Frame, size_t Group=0, int x=0, int y=0, ui8 Flags=0);
 	~CAnimImage();//d-tor

+ 85 - 63
client/windows/GUIClasses.cpp

@@ -8,7 +8,6 @@
 #include "CSpellWindow.h"
 
 #include "../CBitmapHandler.h"
-#include "../CDefHandler.h"
 #include "../CGameInfo.h"
 #include "../CMessage.h"
 #include "../CMusicHandler.h"
@@ -1371,26 +1370,29 @@ CHillFortWindow::CHillFortWindow(const CGHeroInstance *visitor, const CGObjectIn
 {
 	OBJ_CONSTRUCTION_CAPTURING_ALL;
 
-	slotsCount=7;
-	resources =  CDefHandler::giveDefEss("SMALRES.DEF");
-
 	new CLabel(325, 32, FONT_BIG, CENTER, Colors::YELLOW, fort->getObjectName());//Hill Fort
 
 	heroPic = new CHeroArea(30, 60, hero);
 
-	currState.resize(slotsCount+1);
-	costs.resize(slotsCount);
-	totalSumm.resize(GameConstants::RESOURCE_QUANTITY);
+	for (int i=0; i<resCount; i++)
+	{
+		totalIcons[i] = new CAnimImage("SMALRES", i, 0, 104 + 76 * i, 237);
+		totalLabels[i] = new CLabel(166 + 76 * i, 253, FONT_SMALL, BOTTOMRIGHT);
+	}
 
 	for (int i = 0; i < slotsCount; i++)
 	{
-		currState[i] = getState(SlotID(i));
 		upgrade[i] = new CButton(Point(107 + i * 76, 171), "", CButton::tooltip(getTextForSlot(SlotID(i))), [=]{ makeDeal(SlotID(i)); }, SDLK_1 + i);
 		for (auto image : { "APHLF1R.DEF", "APHLF1Y.DEF", "APHLF1G.DEF" })
 			upgrade[i]->addImage(image);
+
+		for(int j : {0,1})
+		{
+			slotIcons[i][j] = new CAnimImage("SMALRES", 0, 0, 104 + 76 * i, 128 + 20 * j);
+			slotLabels[i][j] = new CLabel(168 + 76 * i, 144 + 20 * j, FONT_SMALL, BOTTOMRIGHT);
+		}
 	}
 
-	currState[slotsCount] = getState(SlotID(slotsCount));
 	upgradeAll = new CButton(Point(30, 231), "", CButton::tooltip(CGI->generaltexth->allTexts[432]), [&]{ makeDeal(SlotID(slotsCount));}, SDLK_0);
 	for (auto image : { "APHLF4R.DEF", "APHLF4Y.DEF", "APHLF4G.DEF" })
 		upgradeAll->addImage(image);
@@ -1404,6 +1406,11 @@ CHillFortWindow::CHillFortWindow(const CGHeroInstance *visitor, const CGObjectIn
 
 void CHillFortWindow::updateGarrisons()
 {
+	std::array<TResources, slotsCount> costs;// costs [slot ID] [resource ID] = resource count for upgrade
+
+	TResources totalSumm; // totalSum[resource ID] = value
+	totalSumm.resize(GameConstants::RESOURCE_QUANTITY);
+
 	for (int i=0; i<GameConstants::RESOURCE_QUANTITY; i++)
 		totalSumm[i]=0;
 
@@ -1428,10 +1435,77 @@ void CHillFortWindow::updateGarrisons()
 		upgrade[i]->addHoverText(CButton::NORMAL, getTextForSlot(SlotID(i)));
 	}
 
-	int newState = getState(SlotID(slotsCount));
+	//"Upgrade all" slot
+	int newState = 2;
+	{
+		TResources myRes = LOCPLINT->cb->getResourceAmount();
+
+		bool allUpgraded = true;//All creatures are upgraded?
+		for (int i=0; i<slotsCount; i++)
+			allUpgraded &=  currState[i] == 1 || currState[i] == -1;
+
+		if (allUpgraded)
+			newState = 1;
+
+		if(!totalSumm.canBeAfforded(myRes))
+			newState = 0;
+	}
+
 	currState[slotsCount] = newState;
 	upgradeAll->setIndex(newState);
-	garr->recreateSlots();
+
+	CWindowWithGarrison::updateGarrisons();
+
+	for (int i = 0; i < slotsCount; i++)
+	{
+		//hide all first
+		for(int j : {0,1})
+		{
+			slotIcons[i][j]->visible = false;
+			slotLabels[i][j]->setText("");
+		}
+		//if can upgrade or can not afford, draw cost
+		if (currState[i] == 0 || currState[i] == 2)
+		{
+			if (costs[i].nonZero())
+			{
+				//reverse iterator is used to display gold as first element
+				int j = 0;
+				for(int res = costs[i].size()-1; (res >= 0) && (j < 2); res--)
+				{
+					int val = costs[i][res];
+					if(!val)
+						continue;
+
+					slotIcons[i][j]->visible = true;
+					slotIcons[i][j]->setFrame(res);
+
+					slotLabels[i][j]->setText(boost::lexical_cast<std::string>(val));
+					j++;
+				}
+			}
+			else//free upgrade - print gold image and "Free" text
+			{
+				slotIcons[i][0]->visible = true;
+				slotIcons[i][0]->setFrame(Res::GOLD);
+				slotLabels[i][0]->setText(CGI->generaltexth->allTexts[344]);
+			}
+		}
+	}
+
+	for (int i = 0; i < resCount; i++)
+	{
+		if(totalSumm[i] == 0)
+		{
+			totalIcons[i]->visible = false;
+			totalLabels[i]->setText("");
+		}
+		else
+		{
+			totalIcons[i]->visible = true;
+			totalLabels[i]->setText(boost::lexical_cast<std::string>(totalSumm[i]));
+		}
+	}
 }
 
 void CHillFortWindow::makeDeal(SlotID slot)
@@ -1461,44 +1535,6 @@ void CHillFortWindow::makeDeal(SlotID slot)
 	}
 }
 
-void CHillFortWindow::showAll (SDL_Surface *to)
-{
-	CWindowObject::showAll(to);
-
-	for ( int i=0; i<slotsCount; i++)
-	{
-		if ( currState[i] == 0 || currState[i] == 2 )
-		{
-			if ( costs[i].size() )//we have several elements
-			{
-				int curY = 128;//reverse iterator is used to display gold as first element
-				for(int j = costs[i].size()-1; j >= 0; j--)
-				{
-					int val = costs[i][j];
-					if(!val) continue;
-
-					blitAtLoc(resources->ourImages[j].bitmap, 104+76*i, curY, to);
-					printToLoc(boost::lexical_cast<std::string>(val), 168+76*i, curY+16, FONT_SMALL, Colors::WHITE, to);
-					curY += 20;
-				}
-			}
-			else//free upgrade - print gold image and "Free" text
-			{
-				blitAtLoc(resources->ourImages[6].bitmap, 104+76*i, 128, to);
-				printToLoc(CGI->generaltexth->allTexts[344], 168+76*i, 144, FONT_SMALL, Colors::WHITE, to);
-			}
-		}
-	}
-	for (int i=0; i<GameConstants::RESOURCE_QUANTITY; i++)
-	{
-		if (totalSumm[i])//this resource is used - display it
-		{
-			blitAtLoc(resources->ourImages[i].bitmap, 104+76*i, 237, to);
-			printToLoc(boost::lexical_cast<std::string>(totalSumm[i]), 166+76*i, 253, FONT_SMALL, Colors::WHITE, to);
-		}
-	}
-}
-
 std::string CHillFortWindow::getTextForSlot(SlotID slot)
 {
 	if ( !hero->getCreature(slot) )//we don`t have creature here
@@ -1517,20 +1553,6 @@ std::string CHillFortWindow::getTextForSlot(SlotID slot)
 int CHillFortWindow::getState(SlotID slot)
 {
 	TResources myRes = LOCPLINT->cb->getResourceAmount();
-	if ( slot.getNum() == slotsCount )//"Upgrade all" slot
-	{
-		bool allUpgraded = true;//All creatures are upgraded?
-		for (int i=0; i<slotsCount; i++)
-			allUpgraded &=  currState[i] == 1 || currState[i] == -1;
-
-		if (allUpgraded)
-			return 1;
-
-		if(!totalSumm.canBeAfforded(myRes))
-			return 0;
-
-		return 2;
-	}
 
 	if (hero->slotEmpty(slot))//no creature here
 		return -1;

+ 20 - 14
client/windows/GUIClasses.h

@@ -401,29 +401,35 @@ public:
 /// Hill fort is the building where you can upgrade units
 class CHillFortWindow : public CWindowObject, public CWindowWithGarrison
 {
-public:
-
-	int slotsCount;//=7;
-	CGStatusBar * bar;
-	CDefEssential *resources;
-	CHeroArea *heroPic;//clickable hero image
-	CButton *quit,//closes window
-	                   *upgradeAll,//upgrade all creatures
-	                   *upgrade[7];//upgrade single creature
+private:
+	static const int slotsCount = 7;
+	//todo: mithril support
+	static const int resCount = 7;
 
 	const CGObjectInstance * fort;
 	const CGHeroInstance * hero;
-	std::vector<int> currState;//current state of slot - to avoid calls to getState or updating buttons
-	std::vector<TResources> costs;// costs [slot ID] [resource ID] = resource count for upgrade
-	TResources totalSumm; // totalSum[resource ID] = value
 
-	CHillFortWindow(const CGHeroInstance *visitor, const CGObjectInstance *object); //c-tor
+	CGStatusBar * bar;
+	CHeroArea * heroPic;//clickable hero image
+	CButton * quit;//closes window
+	CButton * upgradeAll;//upgrade all creatures
+
+	std::array<CButton *, slotsCount> upgrade;//upgrade single creature
+	std::array<int, slotsCount + 1> currState;//current state of slot - to avoid calls to getState or updating buttons
+
+	//there is a place for only 2 resources per slot
+	std::array< std::array<CAnimImage *, 2>, slotsCount> slotIcons;
+	std::array< std::array<CLabel *, 2>, slotsCount> slotLabels;
+
+	std::array<CAnimImage *, resCount> totalIcons;
+	std::array<CLabel *, resCount> totalLabels;
 
-	void showAll (SDL_Surface *to) override;
 	std::string getDefForSlot(SlotID slot);//return def name for this slot
 	std::string getTextForSlot(SlotID slot);//return hover text for this slot
 	void makeDeal(SlotID slot);//-1 for upgrading all creatures
 	int getState(SlotID slot); //-1 = no creature 0=can't upgrade, 1=upgraded, 2=can upgrade
+public:
+	CHillFortWindow(const CGHeroInstance * visitor, const CGObjectInstance * object); //c-tor
 	void updateGarrisons() override;//update buttons after garrison changes
 };