浏览代码

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);