Переглянути джерело

Finished drawing selection window for treasure chest.

(trzeba dorobic jego zamykanie, zwrocenie infa, zwrot pamieci)
Michał W. Urbańczyk 18 роки тому
батько
коміт
d3f5a1c1e7
11 змінених файлів з 198 додано та 28 видалено
  1. 1 1
      AI/EmptyAI/CEmptyAI.h
  2. 1 0
      CAdvmapInterface.cpp
  3. 1 1
      CCallback.cpp
  4. 2 1
      CCallback.h
  5. 2 2
      CGameInterface.h
  6. 9 9
      CLua.cpp
  7. 2 1
      CLua.h
  8. 131 6
      CMessage.cpp
  9. 7 0
      CMessage.h
  10. 36 5
      CPlayerInterface.cpp
  11. 6 2
      CPlayerInterface.h

+ 1 - 1
AI/EmptyAI/CEmptyAI.h

@@ -10,7 +10,7 @@ public:
 	void heroCreated(const CHeroInstance *);
 	void heroMoved(const HeroMoveDetails &);
 	void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, int val) {};
-	void showSelDialog(std::string text, std::vector<SComponent*> & components, int askID){};
+	void showSelDialog(std::string text, std::vector<CSelectableComponent*> & components, int askID){};
 	void tileRevealed(int3 pos){};
 	void tileHidden(int3 pos){};
 };

+ 1 - 0
CAdvmapInterface.cpp

@@ -1550,6 +1550,7 @@ void CAdvMapInt::handleRightClick(std::string text, tribool down, CIntObject * c
 			if (pom->owner==client)
 			{
 				LOCPLINT->objsToBlit.erase(LOCPLINT->objsToBlit.begin()+(i));
+				delete pom;
 			}
 		}
 	}

+ 1 - 1
CCallback.cpp

@@ -428,7 +428,7 @@ void CScriptCallback::showInfoDialog(int player, std::string text, std::vector<S
 	}
 }
 
-void CScriptCallback::showSelDialog(int player, std::string text, std::vector<SComponent*>*components, IChosen * asker)
+void CScriptCallback::showSelDialog(int player, std::string text, std::vector<CSelectableComponent*>*components, IChosen * asker)
 {
 	CGameInterface * temp = CGI->playerint[CGI->state->players[player].serial];
 	if (temp->human)

+ 2 - 1
CCallback.h

@@ -10,6 +10,7 @@ class CPath;
 class CGObjectInstance;
 class SComponent;
 class IChosen;
+class CSelectableComponent;
 typedef struct lua_State lua_State;
 
 class ICallback
@@ -95,7 +96,7 @@ public:
 	//do sth
 	static void changePrimSkill(int ID, int which, int val);
 	void showInfoDialog(int player, std::string text, std::vector<SComponent*> * components);
-	void showSelDialog(int player, std::string text, std::vector<SComponent*>*components, IChosen * asker);
+	void showSelDialog(int player, std::string text, std::vector<CSelectableComponent*>*components, IChosen * asker);
 	void giveResource(int player, int which, int val);
 	void showCompInfo(int player, SComponent * comp);
 

+ 2 - 2
CGameInterface.h

@@ -8,7 +8,7 @@ using namespace boost::logic;
 class CCallback;
 class CGlobalAI;
 class CGHeroInstance;
-
+class CSelectableComponent;
 class CGameInterface
 {
 public:
@@ -24,7 +24,7 @@ public:
 	virtual void tileRevealed(int3 pos)=0{};
 	virtual void tileHidden(int3 pos)=0{};
 	virtual void receivedResource(int type, int val){};
-	virtual void showSelDialog(std::string text, std::vector<SComponent*> & components, int askID)=0{};
+	virtual void showSelDialog(std::string text, std::vector<CSelectableComponent*> & components, int askID)=0{};
 };
 class CAIHandler
 {

+ 9 - 9
CLua.cpp

@@ -505,25 +505,25 @@ void CPickable::onHeroVisit(CGObjectInstance *os, int heroID)
 			int wyn = rand()%100;
 			if (wyn<32)
 			{
-				tempStore.push_back(new SComponent(SComponent::resource,6,1000));
-				tempStore.push_back(new SComponent(SComponent::experience,0,500));
+				tempStore.push_back(new CSelectableComponent(SComponent::resource,6,1000));
+				tempStore.push_back(new CSelectableComponent(SComponent::experience,0,500));
 			}//1k/0.5k
 			else if(wyn<64)
 			{
-				tempStore.push_back(new SComponent(SComponent::resource,6,1500));
-				tempStore.push_back(new SComponent(SComponent::experience,0,1000));
+				tempStore.push_back(new CSelectableComponent(SComponent::resource,6,1500));
+				tempStore.push_back(new CSelectableComponent(SComponent::experience,0,1000));
 			}//1.5k/1k
 			else if(wyn<95)
 			{
-				tempStore.push_back(new SComponent(SComponent::resource,6,2000));
-				tempStore.push_back(new SComponent(SComponent::experience,0,1500));
+				tempStore.push_back(new CSelectableComponent(SComponent::resource,6,2000));
+				tempStore.push_back(new CSelectableComponent(SComponent::experience,0,1500));
 			}//2k/1.5k
 			else
 			{
 				if (1/*TODO: backpack is full*/)
 				{
-					tempStore.push_back(new SComponent(SComponent::resource,6,1000));
-					tempStore.push_back(new SComponent(SComponent::experience,0,500));
+					tempStore.push_back(new CSelectableComponent(SComponent::resource,6,1000));
+					tempStore.push_back(new CSelectableComponent(SComponent::experience,0,500));
 				}
 				else
 				{
@@ -532,7 +532,7 @@ void CPickable::onHeroVisit(CGObjectInstance *os, int heroID)
 				}
 			}//random treasure artifact, or (if backapack is full) 1k/0.5k
 			player = cb->getHeroOwner(heroID);
-			cb->showSelDialog(player,"Wybierz prosze co chcesz dostac :)",&tempStore,this);
+			cb->showSelDialog(player,CGI->objh->advobtxt[146],&tempStore,this);
 			break;
 		}
 	}

+ 2 - 1
CLua.h

@@ -9,6 +9,7 @@ class CGameInfo;
 class CGHeroInstance;
 class CScriptCallback;
 class SComponent;
+class CSelectableComponent;
 enum ESLan{UNDEF=-1,CPP,ERM,LUA};
 class CObjectScript
 {
@@ -137,7 +138,7 @@ class CMines : public CCPPObjectScript  //flaggable, and giving resource at each
 
 class CPickable : public CCPPObjectScript, public IChosen  //pickable - resources, artifacts, etc
 {
-	std::vector<SComponent*> tempStore;
+	std::vector<CSelectableComponent*> tempStore;
 	int player;
 
 	CPickable(CScriptCallback * CB):CCPPObjectScript(CB){};

+ 131 - 6
CMessage.cpp

@@ -15,6 +15,7 @@
 #include "SDL_Extensions.h"
 #include <sstream>
 #include "CLua.h"
+#include "hch/CGeneralTextHandler.h"
 SDL_Color tytulowy, tlo, zwykly ;
 SDL_Rect genRect(int hh, int ww, int xx, int yy);
 
@@ -25,7 +26,13 @@ SDL_Color genRGB(int r, int g, int b, int a=0);
 bool isItIn(const SDL_Rect * rect, int x, int y);
 
 using namespace NMessage;
-
+template <typename T, typename U> std::pair<T,U> max(const std::pair<T,U> &x, const std::pair<T,U> &y)
+{
+	std::pair<T,U> ret;
+	ret.first = std::max(x.first,y.first);
+	ret.second = std::max(x.second,y.second);
+	return ret;
+}
 
 namespace NMessage
 {
@@ -182,6 +189,27 @@ std::vector<std::string> * CMessage::breakText(std::string text, int line, bool
 	}
 	return ret;
 }
+std::pair<int, int> CMessage::getMaxSizes(std::vector< std::vector<CSelectableComponent*> > * komp)
+{
+	std::pair<int,int> ret;
+	for (int i=0;i<komp->size();i++)
+	{
+		int sumaw=0;
+		int maxh=0;
+		for(int j=0;j<(*komp)[i].size();j++)
+		{
+			sumaw += (*komp)[i][j]->getImg()->w;
+			if (maxh < (*komp)[i][j]->getImg()->h)
+				maxh = (*komp)[i][j]->getImg()->h;
+		}
+		if(sumaw>ret.first)
+			ret.first = sumaw;
+		ret.second+=maxh;
+	}
+
+	return ret;
+}
+
 std::pair<int,int> CMessage::getMaxSizes(std::vector<std::vector<SDL_Surface*> > * txtg)
 {
 	std::pair<int,int> ret;		
@@ -218,6 +246,7 @@ SDL_Surface * CMessage::blitTextOnSur(std::vector<std::vector<SDL_Surface*> > *
 			SDL_FreeSurface((*txtg)[i][j]);
 		}
 	}
+	curh+=txtg->size()*19;
 	return ret;
 }
 SDL_Surface * CMessage::blitCompsOnSur(std::vector<SComponent*> & comps, int maxw, int inter, int & curh, SDL_Surface * ret)
@@ -241,6 +270,39 @@ SDL_Surface * CMessage::blitCompsOnSur(std::vector<SComponent*> & comps, int max
 	}
 	return ret;
 }
+SDL_Surface* CMessage::blitCompsOnSur(SDL_Surface * or, std::vector< std::vector<CSelectableComponent*> > *  komp, int inter, int &curh, SDL_Surface *ret)
+{
+	for (int i=0;i<komp->size();i++)
+	{
+		int totalw=0, maxh=0;
+		for(int j=0;j<(*komp)[i].size();j++)
+		{
+			totalw+=(*komp)[i][j]->getImg()->w;
+			if(maxh<(*komp)[i][j]->getImg()->h)
+				maxh=(*komp)[i][j]->getImg()->h;
+		}
+		totalw += (inter*2+or->w) * ((*komp)[i].size() - 1);
+		curh+=maxh/2;
+		int curw = (ret->w/2)-(totalw/2);
+		for(int j=0;j<(*komp)[i].size();j++)
+		{
+			blitAt((*komp)[i][j]->getImg(),curw,curh-((*komp)[i][j]->getImg()->h/2),ret);
+			(*komp)[i][j]->pos.x = curw;
+			(*komp)[i][j]->pos.y = curh-((*komp)[i][j]->getImg()->h/2);
+			CSDL_Ext::printAtMiddle((*komp)[i][j]->subtitle,curw+(*komp)[i][j]->getImg()->w/2,curh+((*komp)[i][j]->getImg()->h/2)+10,GEOR13,zwykly,ret);
+			curw += (*komp)[i][j]->getImg()->w;
+			if(j<((*komp)[i].size()-1))
+			{
+				curw+=inter;
+				blitAt(or,curw,curh-(or->h/2),ret);
+				curw+=or->w;
+				curw+=inter;
+			}
+		}
+		curh+=maxh/2;
+	}
+	return ret;
+}
 std::vector<std::vector<SDL_Surface*> > * CMessage::drawText(std::vector<std::string> * brtext)
 {
 	std::vector<std::vector<SDL_Surface*> > * txtg = new std::vector<std::vector<SDL_Surface*> >();
@@ -332,22 +394,85 @@ CInfoWindow * CMessage::genIWindow(std::string text, int player, int charperline
 	ret->bitmap = drawBox1(txts.first+70,txts.second+70,0); 
 	ret->pos.h=ret->bitmap->h;
 	ret->pos.w=ret->bitmap->w;
-
 	int curh = 30; //gorny margines
 	blitTextOnSur(txtg,curh,ret->bitmap);
-	curh += (19 * txtg->size()); //wys. tekstu
-
 	if (comps.size())
 	{
 		blitCompsOnSur(comps,200,0,curh,ret->bitmap);
 	}
 	curh += 20; //to buttton
-
 	ret->okb.posr.x = (ret->bitmap->w/2) - (ret->okb.imgs[0][0]->w/2);
 	ret->okb.posr.y = curh;
 	ret->okb.show();
 	curh+=ret->okb.imgs[0][0]->h;
-
+	return ret;
+}
+std::vector< std::vector<CSelectableComponent*> > * CMessage::breakComps(std::vector<CSelectableComponent*> & comps,int maxw, SDL_Surface* or)
+{
+	std::vector< std::vector<CSelectableComponent*> > * ret = new std::vector< std::vector<CSelectableComponent*> >();
+	ret->resize(1);
+	bool wywalicOr=false;
+	if (!or)
+	{
+		or = TTF_RenderText_Blended(GEOR13,CGI->generaltexth->allTexts[4].c_str(),zwykly);
+		wywalicOr=true;
+	}
+	int rvi = 0;
+	int curw = 0;
+	for(int i=0;i<comps.size();i++)
+	{
+		curw += (comps[i]->getImg()->w + 12 + or->w);
+		if (curw > maxw)
+		{
+			curw = 0;
+			rvi++;
+			ret->resize(rvi+1);
+		}
+		(*ret)[rvi].push_back(comps[i]);
+	}
+	if (wywalicOr)
+	{
+		SDL_FreeSurface(or);
+	}
+	return ret;
+}
+CSelWindow * CMessage::genSelWindow(std::string text, int player, int charperline, std::vector<CSelectableComponent*> & comps, int owner)
+{
+	CSelWindow * ret = new CSelWindow();
+	for(int i=0;i<comps.size();i++)
+	{
+		ret->components.push_back(comps[i]);
+		comps[i]->owner = ret;
+	}
+	std::vector<std::string> * tekst = breakText(text,charperline);
+	std::vector<std::vector<SDL_Surface*> > * txtg = drawText(tekst);
+	std::pair<int,int> txts = getMaxSizes(txtg);
+	txts.first+=45; //side margins
+	int curh = 50; //top margin
+	SDL_Surface * or = TTF_RenderText_Blended(GEOR13,CGI->generaltexth->allTexts[4].c_str(),zwykly);
+	std::vector< std::vector<CSelectableComponent*> > * komp = breakComps(comps,500,or);
+	std::pair<int,int> txts2 = getMaxSizes(komp);
+	ret->pos.h = txts.second //wys. tekstu
+		+ txts2.second //wys komponentow
+		+ 20 //podpis pod komponentami
+		+ 55 //gorny margines
+		+ 60 //text <=> comps
+		+ 20 //comps <=> button
+		+ ok->ourImages[0].bitmap->h //button
+		+ 30; //bottom margin
+	ret->pos.w = std::max(txts.first,txts.second);
+	ret->bitmap = drawBox1(ret->pos.w,ret->pos.h,player);
+	blitTextOnSur(txtg,curh,ret->bitmap);
+	curh += 50;
+	blitCompsOnSur(or,komp,10,curh,ret->bitmap);
+	curh += 30; //to buttton
+	ret->okb.posr.x = (ret->bitmap->w/2) - (ret->okb.imgs[0][0]->w/2);
+	ret->okb.posr.y = curh;
+	ret->okb.show();
+	curh+=ret->okb.imgs[0][0]->h;
+	SDL_FreeSurface(or);
+	delete komp;
+	delete tekst;
 	return ret;
 }
 

+ 7 - 0
CMessage.h

@@ -11,6 +11,8 @@ class CSimpleWindow;
 class CInfoWindow;
 class CDefHandler;
 class SComponent;
+class CSelWindow;
+class CSelectableComponent;
 namespace NMessage
 {
 	extern CDefHandler * ok, *cancel;
@@ -23,10 +25,14 @@ class CMessage
 public:
 	
 	static std::pair<int,int> getMaxSizes(std::vector<std::vector<SDL_Surface*> > * txtg);
+	static std::pair<int, int> getMaxSizes(std::vector< std::vector<CSelectableComponent*> > * komp);
 	static std::vector<std::vector<SDL_Surface*> > * drawText(std::vector<std::string> * brtext);
 	static SDL_Surface * blitTextOnSur(std::vector<std::vector<SDL_Surface*> > * txtg, int & curh, SDL_Surface * ret);
 	static SDL_Surface * blitCompsOnSur(std::vector<SComponent*> & comps, int maxw, int inter, int & curh, SDL_Surface * ret);
+	static SDL_Surface* blitCompsOnSur(SDL_Surface * or, std::vector< std::vector<CSelectableComponent*> > *  komp, int inter, int &curh, SDL_Surface *ret);
 	static CInfoWindow * genIWindow(std::string text, int player, int charperline, std::vector<SComponent*> & comps);
+	static std::vector< std::vector<CSelectableComponent*> > * breakComps(std::vector<CSelectableComponent*> & comps,int maxw, SDL_Surface* or=NULL);
+	static CSelWindow * genSelWindow(std::string text, int player, int charperline, std::vector<CSelectableComponent*> & comps, int owner);
 	static CSimpleWindow * genWindow(std::string text, int player, int Lmar=35, int Rmar=35, int Tmar=35, int Bmar=35);//supports h3 text formatting; player sets color of window, Lmar/Rmar/Tmar/Bmar are Left/Right/Top/Bottom margins
 	static SDL_Surface * genMessage(std::string title, std::string text, EWindowType type=infoOnly, 
 								std::vector<CDefHandler*> *addPics=NULL, void * cb=NULL);
@@ -38,4 +44,5 @@ public:
 };
 //
 
+
 #endif //CMESSAGE_H

+ 36 - 5
CPlayerInterface.cpp

@@ -126,14 +126,19 @@ void CSelectableComponent::clickLeft(tribool down)
 CSelectableComponent::CSelectableComponent(Etype Type, int Sub, int Val, CSelWindow * Owner, SDL_Surface * Border)
 :SComponent(Type,Sub,Val),owner(Owner)
 {
+	SDL_Surface * symb = SComponent::getImg();
+	myBitmap = CSDL_Ext::newSurface(symb->w+2,symb->h+2,ekran);
+	SDL_SetColorKey(myBitmap,SDL_SRCCOLORKEY,SDL_MapRGB(myBitmap->format,0,255,255));	
+	blitAt(symb,1,1,myBitmap);
 	if (Border) //use custom border
 	{
 		border = Border;
+		customB = true;
 	}
 	else //we need to draw border
 	{
-		SDL_Surface * symb = SComponent::getImg();
-		border = CSDL_Ext::newSurface(symb->w+2,symb->h+2,symb);
+		customB = false;
+		border = CSDL_Ext::newSurface(symb->w+2,symb->h+2,ekran);
 		SDL_FillRect(border,NULL,0x00FFFF);
 		for (int i=0;i<border->w;i++)
 		{
@@ -149,6 +154,12 @@ CSelectableComponent::CSelectableComponent(Etype Type, int Sub, int Val, CSelWin
 	}
 	selected = false;
 }
+CSelectableComponent::~CSelectableComponent()
+{
+	SDL_FreeSurface(myBitmap);
+	if (!customB)
+		SDL_FreeSurface(border);
+}
 void CSelectableComponent::activate()
 {
 	SComponent::activate();
@@ -167,6 +178,7 @@ void CSelectableComponent::select(bool on)
 {
 	if(on != selected)
 	{
+		SDL_FillRect(myBitmap,NULL,0x000000);
 		blitAt(SComponent::getImg(),1,1,myBitmap);
 		if (on)
 		{
@@ -198,14 +210,18 @@ CSimpleWindow::~CSimpleWindow()
 
 void CSelWindow::selectionChange(SComponent * to)
 {
+	blitAt(to->getImg(),to->pos.x-pos.x,to->pos.y-pos.y,bitmap);
 	for (int i=0;i<components.size();i++)
 	{
 		if(components[i]==to)
+		{
 			continue;
+		}
 		CSelectableComponent * pom = dynamic_cast<CSelectableComponent*>(components[i]);
 		if (!pom)
 			continue;
 		pom->select(false);
+		blitAt(pom->getImg(),pom->pos.x-pos.x,pom->pos.y-pos.y,bitmap);
 	}
 }
 void CSelWindow::okClicked(tribool down)
@@ -1149,7 +1165,7 @@ SDL_Surface * CPlayerInterface::drawPrimarySkill(const CGHeroInstance *curh, SDL
 		itoa(curh->primSkills[i],buf,10);
 		printAtMiddle(buf,84+28*i,68,GEOR13,zwykly,ret);
 	}
-	delete buf;
+	delete[] buf;
 	return ret;
 }
 SDL_Surface * CPlayerInterface::drawHeroInfoWin(const CGHeroInstance * curh)
@@ -1169,7 +1185,7 @@ SDL_Surface * CPlayerInterface::drawHeroInfoWin(const CGHeroInstance * curh)
 	blitAt(curh->type->portraitLarge,11,12,ret);
 	itoa(curh->mana,buf,10);
 	printAtMiddle(buf,166,109,GEORM,zwykly,ret); //mana points
-	delete buf;
+	delete[] buf;
 	blitAt(morale22->ourImages[curh->getCurrentMorale()+3].bitmap,14,84,ret);
 	blitAt(luck22->ourImages[curh->getCurrentLuck()+3].bitmap,14,101,ret);
 	//SDL_SaveBMP(ret,"inf1.bmp");
@@ -1455,8 +1471,23 @@ void CPlayerInterface::receivedResource(int type, int val)
 	adventureInt->resdatabar.draw();
 }
 
-void CPlayerInterface::showSelDialog(std::string text, std::vector<SComponent*> & components, int askID)
+void CPlayerInterface::showSelDialog(std::string text, std::vector<CSelectableComponent*> & components, int askID)
 {
+	adventureInt->hide(); //dezaktywacja starego interfejsu
+	CSelWindow * temp = CMessage::genSelWindow(text,LOCPLINT->playerID,35,components,playerID);
+	LOCPLINT->objsToBlit.push_back(temp);
+	temp->pos.x=300-(temp->pos.w/2);
+	temp->pos.y=300-(temp->pos.h/2);
+	temp->okb.pos.x = temp->okb.posr.x + temp->pos.x;
+	temp->okb.pos.y = temp->okb.posr.y + temp->pos.y;
+	temp->okb.activate();
+	for (int i=0;i<temp->components.size();i++)
+	{
+		temp->components[i]->activate();
+		temp->components[i]->pos.x += temp->pos.x;
+		temp->components[i]->pos.y += temp->pos.y;
+	}
+
 }
 
 void CPlayerInterface::showComp(SComponent comp)

+ 6 - 2
CPlayerInterface.h

@@ -127,7 +127,7 @@ public:
 	virtual void okClicked(tribool down);
 	virtual void close();
 	CInfoWindow();
-	~CInfoWindow();
+	virtual ~CInfoWindow();
 };
 class CSelWindow : public CInfoWindow //component selection window
 {
@@ -135,6 +135,7 @@ public:
 	void selectionChange(SComponent * to);
 	void okClicked(tribool down);
 	void close();
+	CSelWindow(){};
 };
 class SComponent : public ClickableR
 {
@@ -162,12 +163,15 @@ class CSelectableComponent : public SComponent, public ClickableL
 {
 public:
 	bool selected;
+
+	bool customB;
 	SDL_Surface * border, *myBitmap;
 	CSelWindow * owner;
 
 
 	void clickLeft(tribool down);
 	CSelectableComponent(Etype Type, int Sub, int Val, CSelWindow * Owner=NULL, SDL_Surface * Border=NULL);
+	~CSelectableComponent();
 	void activate();
 	void deactivate();
 	void select(bool on);
@@ -209,7 +213,7 @@ public:
 	void heroCreated(const CGHeroInstance* hero);
 	void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, int val);
 	void receivedResource(int type, int val);
-	void showSelDialog(std::string text, std::vector<SComponent*> & components, int askID);
+	void showSelDialog(std::string text, std::vector<CSelectableComponent*> & components, int askID);
 
 	void showComp(SComponent comp);