Browse Source

More town hall code, started making building requirements.

Michał W. Urbańczyk 17 years ago
parent
commit
b3c69fe838

+ 24 - 0
AdventureMapButton.h

@@ -6,6 +6,30 @@
 #include "hch\CPreGameTextHandler.h"
 #include "hch/CTownHandler.h"
 #include "CLua.h"
+#include "CPlayerInterface.h"
+template <typename T=CAdvMapInt>
+class AdventureMapButton 
+	: public ClickableL, public ClickableR, public Hoverable, public KeyInterested, public CButtonBase
+{
+public:
+	std::string name; //for status bar 
+	std::string helpBox; //for right-click help
+	char key; //key shortcut
+	T* owner;
+	void (T::*function)(); //function in CAdvMapInt called when this button is pressed, different for each button
+	bool colorChange;
+
+	void clickRight (tribool down);
+	void clickLeft (tribool down);
+	virtual void hover (bool on);
+	void keyPressed (SDL_KeyboardEvent & key);
+	void activate(); // makes button active
+	void deactivate(); // makes button inactive (but doesn't delete)
+
+	AdventureMapButton(); //c-tor
+	AdventureMapButton( std::string Name, std::string HelpBox, void(T::*Function)(), int x, int y, std::string defName, T* Owner, bool activ=false,  std::vector<std::string> * add = NULL, bool playerColoredButton = true );//c-tor
+};
+
 template <typename T>
 AdventureMapButton<T>::AdventureMapButton ()
 {

+ 1 - 22
CAdvmapInterface.h

@@ -5,6 +5,7 @@
 #include "SDL.h"
 #include "CPlayerInterface.h"
 #include <map>
+#include "AdventureMapButton.h"
 class CDefHandler;
 class CCallback;
 class CPath; 
@@ -12,28 +13,6 @@ class CAdvMapInt;
 class CGHeroInstance;
 class CGTownInstance;
 class CHeroWindow;
-template <typename T=CAdvMapInt>
-class AdventureMapButton 
-	: public ClickableL, public ClickableR, public Hoverable, public KeyInterested, public CButtonBase
-{
-public:
-	std::string name; //for status bar 
-	std::string helpBox; //for right-click help
-	char key; //key shortcut
-	T* owner;
-	void (T::*function)(); //function in CAdvMapInt called when this button is pressed, different for each button
-	bool colorChange;
-
-	void clickRight (tribool down);
-	void clickLeft (tribool down);
-	void hover (bool on);
-	void keyPressed (SDL_KeyboardEvent & key);
-	void activate(); // makes button active
-	void deactivate(); // makes button inactive (but doesn't delete)
-
-	AdventureMapButton(); //c-tor
-	AdventureMapButton( std::string Name, std::string HelpBox, void(T::*Function)(), int x, int y, std::string defName, T* Owner, bool activ=false,  std::vector<std::string> * add = NULL, bool playerColoredButton = true );//c-tor
-};
 /*****************************/
 class CMinimap
 	: public ClickableL, public ClickableR, public Hoverable, public MotionInterested, public virtual CIntObject

+ 87 - 38
CCastleInterface.cpp

@@ -444,17 +444,6 @@ void CCastleInterface::showAll(SDL_Surface * to)
 	if(town->getOwner()<PLAYER_LIMIT)
 		blitAt(flag->ourImages[town->getOwner()].bitmap,241,387,to);
 
-	//print garrison
-	//for(
-	//	std::map<int,std::pair<CCreature*,int> >::const_iterator i=town->garrison.slots.begin();
-	//	i!=town->garrison.slots.end();
-	//	i++
-	//		)
-	//{
-	//	blitAt(CGI->creh->bigImgs[i->second.first->idNumber],305+(62*(i->first)),387,to);
-	//	itoa(i->second.second,temp,10);
-	//	CSDL_Ext::printTo(temp,305+(62*(i->first))+57,387+61,GEOR13,zwykly,to);
-	//}
 	show();
 }
 void CCastleInterface::townChange()
@@ -550,7 +539,7 @@ void CHallInterface::CResDataBar::show(SDL_Surface * to)
 CHallInterface::CResDataBar::CResDataBar()
 {
 	bg = CGI->bitmaph->loadBitmap("Z2ESBAR.bmp");
-	CSDL_Ext::blueToPlayers(bg,LOCPLINT->playerID);
+	CSDL_Ext::blueToPlayersAdv(bg,LOCPLINT->playerID);
 	pos.x = 7;
 	pos.y = 575;
 	pos.w = bg->w;
@@ -563,6 +552,16 @@ CHallInterface::CResDataBar::~CResDataBar()
 
 void CHallInterface::CBuildingBox::hover(bool on)
 {
+	Hoverable::hover(on);
+	if(on)
+	{
+		std::string toPrint = CGI->townh->hcommands[state];
+		std::vector<std::string> name;
+		name.push_back(CGI->buildh->buildings[LOCPLINT->castleInt->town->subID][ID]->name);
+		LOCPLINT->statusbar->print(CSDL_Ext::processStr(toPrint,name));
+	}
+	else
+		LOCPLINT->statusbar->clear();
 }
 void CHallInterface::CBuildingBox::clickLeft (tribool down)
 {
@@ -573,29 +572,44 @@ void CHallInterface::CBuildingBox::clickRight (tribool down)
 void CHallInterface::CBuildingBox::show(SDL_Surface * to)
 {
 	blitAt(LOCPLINT->castleInt->bicons->ourImages[ID].bitmap,pos.x,pos.y);
-	int pom;
+	int pom, pom2=-1;
 	switch (state)
 	{
-	case 3: 
+	case 4: 
 		pom = 0;
+		pom2 = 0;
 		break;
-	case 0:
+	case 7:
 		pom = 1;
 		break;
-	case 1: case 2:
+	case 6:
+		pom2 = 2;
 		pom = 2;
 		break;
-	default:
+	case 0: case 5: 
+		pom2 = 1;
+		pom = 2;
+		break;
+	case 2: case 1: default:
 		pom = 3;
+		break;
 	}
 	blitAt(LOCPLINT->castleInt->hallInt->bars->ourImages[pom].bitmap,pos.x-1,pos.y+71);
+	if(pom2>=0)
+		blitAt(LOCPLINT->castleInt->hallInt->status->ourImages[pom2].bitmap,pos.x+135, pos.y+54);
 	CSDL_Ext::printAtMiddle(CGI->buildh->buildings[LOCPLINT->castleInt->town->subID][ID]->name,pos.x-1+LOCPLINT->castleInt->hallInt->bars->ourImages[0].bitmap->w/2,pos.y+71+LOCPLINT->castleInt->hallInt->bars->ourImages[0].bitmap->h/2, GEOR13,zwykly);
 }
 void CHallInterface::CBuildingBox::activate()
 {
+	Hoverable::activate();
+	ClickableL::activate();
+	ClickableR::activate();
 }
 void CHallInterface::CBuildingBox::deactivate()
 {
+	Hoverable::deactivate();
+	ClickableL::deactivate();
+	ClickableR::deactivate();
 }
 CHallInterface::CBuildingBox::~CBuildingBox()
 {
@@ -611,17 +625,20 @@ CHallInterface::CBuildingBox::CBuildingBox(int id, int x, int y)
 {
 	pos.x = x;
 	pos.y = y;
+	pos.w = 150;
+	pos.h = 70;
 }
 
 
 CHallInterface::CHallInterface(CCastleInterface * owner)
 {
 	bg = CGI->bitmaph->loadBitmap(CGI->buildh->hall[owner->town->subID].first);
-	CSDL_Ext::blueToPlayers(bg,LOCPLINT->playerID);
+	CSDL_Ext::blueToPlayersAdv(bg,LOCPLINT->playerID);
 	bars = CGI->spriteh->giveDefEss("TPTHBAR.DEF");
 	status = CGI->spriteh->giveDefEss("TPTHCHK.DEF");
 	exit = new AdventureMapButton<CHallInterface>
 		(CGI->townh->tcommands[8],"",&CHallInterface::close,748,556,"TPMAGE1.DEF",this,false,NULL,false);
+	boxes.resize(5);
 	for(int i=0;i<5;i++) //for each row
 	{
 		for(int j=0; j<CGI->buildh->hall[owner->town->subID].second[i].size();j++) //for each box
@@ -635,36 +652,42 @@ CHallInterface::CHallInterface(CCastleInterface * owner)
 					(owner->town->builtBuildings.end())						)
 				{
 					int x = 34 + 194*j,
-						y = 37 + 104*i;
-					if(CGI->buildh->hall[owner->town->subID].second[i].size() == 2)
+						y = 37 + 104*i,
+						ID = CGI->buildh->hall[owner->town->subID].second[i][j][k];
+					if(CGI->buildh->hall[owner->town->subID].second[i].size() == 2) //only two boxes in this row
 						x+=194;
-					else if(CGI->buildh->hall[owner->town->subID].second[i].size() == 3)
+					else if(CGI->buildh->hall[owner->town->subID].second[i].size() == 3) //only three boxes in this row
 						x+=97;
 					boxes[i].push_back(new CBuildingBox(CGI->buildh->hall[owner->town->subID].second[i][j][k],x,y));
-	
+
+					boxes[i][boxes[i].size()-1]->state = 7; //allowed by default
+
 					//can we build it?
-					if(owner->town->possibleBuildings.find(CGI->buildh->hall[owner->town->subID].second[i][j][k])==owner->town->possibleBuildings.end())
-						boxes[i][boxes[i].size()-1]->state = -1; //forbidden
-					else if(owner->town->builded >= MAX_BUILDING_PER_TURN)
+					if(owner->town->forbiddenBuildings.find(CGI->buildh->hall[owner->town->subID].second[i][j][k])!=owner->town->forbiddenBuildings.end())
 						boxes[i][boxes[i].size()-1]->state = 2; //forbidden
+					else if(owner->town->builded >= MAX_BUILDING_PER_TURN)
+						boxes[i][boxes[i].size()-1]->state = 4; //already built
 
-					//TODO: check requirements
-					//else if(owner->town->builded >= MAX_BUILDING_PER_TURN)
-					//	boxes[i][boxes[i].size()-1]->state = 2; //forbidden
-					
-					else
+					for( std::set<int>::iterator ri  =  CGI->townh->requirements[owner->town->subID][ID].begin();
+						 ri != CGI->townh->requirements[owner->town->subID][ID].end();
+						 ri++ )
 					{
-						CBuilding * pom = CGI->buildh->buildings[owner->town->subID][CGI->buildh->hall[owner->town->subID].second[i][j][k]];
+						if(owner->town->builtBuildings.find(*ri)==owner->town->builtBuildings.end())
+							boxes[i][boxes[i].size()-1]->state = 5; //lack of requirements - cannot build
+					}
 
-						boxes[i][boxes[i].size()-1]->state = 0; //allowed
+					//TODO: check if capital is already built, check if there is water for shipyard
+					
 
-						for(int res=0;res<7;res++) //TODO: support custom amount of resources
-						{
-							if(pom->resources[res]>LOCPLINT->cb->getResourceAmount(res))
-								boxes[i][boxes[i].size()-1]->state = 1; //lack of res
-						}
+					CBuilding * pom = CGI->buildh->buildings[owner->town->subID][CGI->buildh->hall[owner->town->subID].second[i][j][k]];
+
+					for(int res=0;res<7;res++) //TODO: support custom amount of resources
+					{
+						if(pom->resources[res]>LOCPLINT->cb->getResourceAmount(res))
+							boxes[i][boxes[i].size()-1]->state = 6; //lack of res
 					}
 
+
 					break;
 				}
 			}
@@ -677,13 +700,20 @@ CHallInterface::CHallInterface(CCastleInterface * owner)
 				else if(CGI->buildh->hall[owner->town->subID].second[i].size() == 3)
 					x+=97;
 				boxes[i].push_back(new CBuildingBox(CGI->buildh->hall[owner->town->subID].second[i][j][k-1],x,y));
-				boxes[i][boxes[i].size()-1]->state = 3; //already exists
+				boxes[i][boxes[i].size()-1]->state = 4; //already exists
 			}
 		}
 	}
 }
 CHallInterface::~CHallInterface()
 {
+	delete bars;
+	delete status;
+	SDL_FreeSurface(bg);
+	for(int i=0;i<boxes.size();i++)
+		for(int j=0;j<boxes[i].size();j++)
+			delete boxes[i][j];
+	delete exit;
 }
 void CHallInterface::close()
 {
@@ -720,4 +750,23 @@ void CHallInterface::deactivate()
 		}
 	}
 	exit->deactivate();
+}
+
+void CHallInterface::CBuildWindow::activate()
+{
+}
+void CHallInterface::CBuildWindow::deactivate()
+{
+}
+void CHallInterface::CBuildWindow::show(SDL_Surface * to)
+{
+}
+CHallInterface::CBuildWindow::CBuildWindow(int Tid, int Bid, int State, bool Mode)
+:tid(Tid),bid(Bid),mode(Mode), state(State)
+{
+	bitmap = CGI->bitmaph->loadBitmap("TPUBUILD.bmp");
+	CSDL_Ext::blueToPlayersAdv(bitmap,LOCPLINT->playerID);
+}
+CHallInterface::CBuildWindow::~CBuildWindow()
+{
 }

+ 17 - 2
CCastleInterface.h

@@ -76,7 +76,8 @@ public:
 	{
 	public:
 		int ID;
-		int state;//(-1) - forbidden in this town, 0 - possible, 1 - lack of res, 2 - requirements/buildings per turn limit, (3) - already exists
+		int state;// 0 - no more than one capitol, 1 - lack of water, 2 - forbidden, 3 - Add another level to Mage Guild, 4 - already built, 5 - cannot build, 6 - cannot afford, 7 - build
+		//(-1) - forbidden in this town, 0 - possible, 1 - lack of res, 2 - requirements/buildings per turn limit, (3) - already exists
 		void hover(bool on);
 		void clickLeft (tribool down);
 		void clickRight (tribool down);
@@ -88,9 +89,23 @@ public:
 		~CBuildingBox();
 	};
 
+	class CBuildWindow: public IShowable, public CIntObject
+	{
+	public: 
+		int tid, bid, state; //town id, building id, state
+		bool mode; // 0 - normal (with buttons), 1 - r-click popup
+		SDL_Surface * bitmap; //main window bitmap, with blitted res/text, without buttons/subtitle in "statusbar"
+
+		void activate();
+		void deactivate();
+		void show(SDL_Surface * to=NULL);
+		CBuildWindow(int Tid, int Bid, int State, bool Mode);
+		~CBuildWindow();
+	};
+
 	CDefEssential *bars, //0 - yellow, 1 - green, 2 - red, 3 - gray
 		*status; //0 - already, 1 - can't, 2 - lack of resources
-	std::vector<CBuildingBox*> boxes[5];
+	std::vector< std::vector<CBuildingBox*> >boxes;
 
 	AdventureMapButton<CHallInterface> * exit;
 

+ 0 - 1
CHeroWindow.h

@@ -1,6 +1,5 @@
 #pragma once
 #include "CPlayerInterface.h"
-#include "CAdvmapInterface.h"
 
 template <typename T> class AdventureMapButton;
 struct SDL_Surface;

+ 1 - 1
CPlayerInterface.cpp

@@ -1,6 +1,6 @@
 #include "stdafx.h"
 #include "CPlayerInterface.h"
-#include "CAdvMapInterface.h"
+#include "CAdvmapInterface.h"
 #include "CMessage.h"
 #include "mapHandler.h"
 #include "SDL_Extensions.h"

+ 6 - 0
CPlayerInterface.h

@@ -74,6 +74,7 @@ class ClickableL : public virtual CIntObject  //for left-clicks
 public:
 	bool pressedL;
 	ClickableL();
+	virtual ~ClickableL(){};
 	virtual void clickLeft (tribool down)=0;
 	virtual void activate()=0;
 	virtual void deactivate()=0;
@@ -83,6 +84,7 @@ class ClickableR : public virtual CIntObject //for right-clicks
 public:
 	bool pressedR;
 	ClickableR();
+	virtual ~ClickableR(){};
 	virtual void clickRight (tribool down)=0;
 	virtual void activate()=0;
 	virtual void deactivate()=0;
@@ -91,6 +93,7 @@ class Hoverable  : public virtual CIntObject
 {
 public:
 	Hoverable(){hovered=false;}
+	virtual ~Hoverable(){};
 	bool hovered;
 	virtual void hover (bool on)=0;
 	virtual void activate()=0;
@@ -99,6 +102,7 @@ public:
 class KeyInterested : public virtual CIntObject
 {
 public:
+	virtual ~KeyInterested(){};
 	virtual void keyPressed (SDL_KeyboardEvent & key)=0;
 	virtual void activate()=0;
 	virtual void deactivate()=0;
@@ -106,6 +110,7 @@ public:
 class MotionInterested: public virtual CIntObject
 {
 public:
+	virtual ~MotionInterested(){};
 	virtual void mouseMoved (SDL_MouseMotionEvent & sEvent)=0;
 	virtual void activate()=0;
 	virtual void deactivate()=0;
@@ -113,6 +118,7 @@ public:
 class TimeInterested: public virtual CIntObject
 {
 public:
+	virtual ~TimeInterested(){};
 	int toNextTick;
 	virtual void tick()=0;
 	virtual void activate();

+ 1 - 1
config/hall.txt

@@ -3,7 +3,7 @@
 TPTHBKCS.BMP
 10 11 12 13 | 7 8 9 | 5 22 | 16
 14 15 | 0 1 2 3 | 6
-21 | 24 25
+21 | 18 19
 30 37 | 31  38 | 32 39 | 33 40
 34 41 | 35 42 | 36 43
 1

+ 28 - 0
config/requirements.txt

@@ -0,0 +1,28 @@
+1
+0
+1 0
+2 1
+3 2
+4 3
+11 5
+12 11 0 14 16
+13 12 7 8 9
+22 5
+21 7 16 30 33
+18 7 16 30 32 33
+19 7 16 30 39 33
+30 7
+31 7 30
+32 7 16 30 33
+33 7 16 30
+34 0 7 16 30 33
+35 7 16 21 30 33
+36 0 7 16 30 33 34
+37 30
+38 31
+39 32
+40 33
+41 34
+42 35
+43 36
+-1

+ 11 - 0
hch/CAmbarCendamo.cpp

@@ -1951,7 +1951,18 @@ void CAmbarCendamo::deh3m()
 							}
 						}
 					}
+					for(int byte=6;byte<12;byte++)
+					{
+						for(int bit=0;bit<8;bit++)
+						{
+							if(spec->buildingSettings[byte] & (1<<bit))
+							{
+								nt->forbiddenBuildings.insert(byte*8+bit);
+							}
+						}
+					}
 					nt->builtBuildings = convertBuildings(nt->h3mbuildings,nt->subID);
+					nt->forbiddenBuildings = convertBuildings(nt->forbiddenBuildings,nt->subID);
 				}
 				else
 				{

+ 1 - 1
hch/CObjectHandler.h

@@ -390,7 +390,7 @@ public:
 	int income;
 	
 	//TODO:
-	std::set<int> possibleBuildings, builtBuildings, h3mbuildings;
+	std::set<int> forbiddenBuildings, builtBuildings, h3mbuildings;
 	std::vector<int> creatureIncome; //vector by level - that valueis addedto thebasic growth
 	std::vector<int> creaturesLeft; //that can be recruited
 

+ 28 - 1
hch/CTownHandler.cpp

@@ -19,7 +19,7 @@ void CTownHandler::loadNames()
 	ins.str(CGI->bitmaph->getTextFile("TOWNTYPE.TXT"));
 	names.str(CGI->bitmaph->getTextFile("TOWNNAME.TXT"));
 	int si=0;
-	char bufname[50];
+	char bufname[75];
 	while (!ins.eof())
 	{
 		CTown town;
@@ -224,6 +224,33 @@ void CTownHandler::loadNames()
 		}
 		of.close();
 		of.clear();
+
+		
+		of.open("config/requirements.txt");
+		while(!of.eof())
+		{
+			int ile, town, build, pom;
+			of >> ile;
+			for(int i=0;i<ile;i++)
+			{
+				of >> town;
+				while(true)
+				{
+					of.getline(bufname,75);
+					std::istringstream ifs(bufname);
+					ifs >> build;
+					if(build<0)
+						break;
+					while(!ifs.eof())
+					{
+						ifs >> pom;
+						requirements[town][build].insert(pom);
+					}
+				}
+			}
+		}
+		of.close();
+		of.clear();
 	}
 }
 SDL_Surface * CTownHandler::getPic(int ID, bool fort, bool builded)

+ 2 - 2
hch/CTownHandler.h

@@ -7,7 +7,7 @@
 #include "../int3.h"
 #include <string>
 #include <vector>
-
+#include <set>
 class CBuilding;
 class CSpell;
 class CHero;
@@ -50,7 +50,7 @@ public:
 	static int getTypeByDefName(std::string name);
 
 	std::map<int,std::map<int, Structure*> > structures; // <town ID, <structure ID, structure>>
-
+	std::map<int, std::map<int,std::set<int> > > requirements; //requirements[town_id][structure_id] -> set of required buildings
 
 	std::vector<CGTownInstance *> townInstances;