瀏覽代碼

- added new files to build system
- minor gcc fixes
- updated castle interface code, added missing parts including #380
- buildings enum in global.h

Ivan Savenko 14 年之前
父節點
當前提交
0f605256e9

+ 8 - 1
client/CAdvmapInterface.cpp

@@ -894,7 +894,7 @@ CResDataBar::CResDataBar(const std::string &defname, int x, int y, int offx, int
 	bg = BitmapHandler::loadBitmap(defname);
 	SDL_SetColorKey(bg,SDL_SRCCOLORKEY,SDL_MapRGB(bg->format,0,255,255));
 	graphics->blueToPlayersAdv(bg,LOCPLINT->playerID);
-	pos = genRect(bg->h,bg->w,x,y);
+	pos = genRect(bg->h, bg->w, pos.x+x, pos.y+y);
 
 	txtpos.resize(8);
 	for (int i = 0; i < 8 ; i++)
@@ -951,6 +951,13 @@ void CResDataBar::show( SDL_Surface * to )
 {
 
 }
+
+void CResDataBar::showAll( SDL_Surface * to )
+{
+	draw(to);
+}
+
+
 CInfoBar::CInfoBar()
 {
 	toNextTick = mode = pom = -1;

+ 1 - 0
client/CAdvmapInterface.h

@@ -115,6 +115,7 @@ public:
 
 	void draw(SDL_Surface * to);
 	void show(SDL_Surface * to);
+	void showAll(SDL_Surface * to);
 };
 
 /// Info box which shows next week/day information, hold the current date

+ 18 - 7
client/CAnimation.cpp

@@ -1161,9 +1161,11 @@ void CAnimImage::init()
 		anim->load(0,group);
 	
 	IImage *img = anim->getImage(frame, group);
-	pos.w = img->width();
-	pos.h = img->height();
-	
+	if (img)
+	{
+		pos.w = img->width();
+		pos.h = img->height();
+	}
 }
 
 CAnimImage::~CAnimImage()
@@ -1176,7 +1178,9 @@ CAnimImage::~CAnimImage()
 
 void CAnimImage::showAll(SDL_Surface *to)
 {
-	anim->getImage(frame, group)->draw(to, pos.x, pos.y);
+	IImage *img = anim->getImage(frame, group);
+	if (img)
+		img->draw(to, pos.x, pos.y);
 }
 
 void CAnimImage::setFrame(size_t Frame, size_t Group)
@@ -1189,8 +1193,14 @@ void CAnimImage::setFrame(size_t Frame, size_t Group)
 		anim->unload(frame, group);
 		frame = Frame;
 		group = Group;
-		if (flags & CShowableAnim::PLAYER_COLORED)
-			anim->getImage(frame, group)->playerColored(player);
+		IImage *img = anim->getImage(frame, group);
+		if (img)
+		{
+			if (flags & CShowableAnim::PLAYER_COLORED)
+				img->playerColored(player);
+			pos.w = img->width();
+			pos.h = img->height();
+		}
 	}
 }
 
@@ -1311,7 +1321,8 @@ void CShowableAnim::blitImage(size_t frame, size_t group, SDL_Surface *to)
 	assert(to);
 	Rect src( xOffset, yOffset, pos.w, pos.h);
 	IImage * img = anim.getImage(frame, group);
-	img->draw(to, pos.x-xOffset, pos.y-yOffset, &src, alpha);
+	if (img)
+		img->draw(to, pos.x-xOffset, pos.y-yOffset, &src, alpha);
 }
 
 void CShowableAnim::rotate(bool on, bool vertical)

文件差異過大導致無法顯示
+ 340 - 530
client/CCastleInterface.cpp


+ 187 - 123
client/CCastleInterface.h

@@ -5,21 +5,21 @@
 #include "CAnimation.h"
 #include "GUIBase.h"
 
-class CGTownInstance;
-class CTownHandler;
-class CHallInterface;
-struct Structure;
-class CSpell;
 class AdventureMapButton;
+class CBuilding;
+class CCastleBuildings;
+class CCreaturePic;
+class CGStatusBar;
+class CGTownInstance;
+class CLabel;
+class CMinorResDataBar;
+class CPicture;
 class CResDataBar;
+class CSpell;
 class CStatusBar;
+class CTextBox;
 class CTownList;
-class CRecruitmentWindow;
-class CTransformerWindow;
-class CPicture;
-class CCreaturePic;
-class CMinorResDataBar;
-class CCastleBuildings;
+struct Structure;
 
 /*
  * CCastleInterface.h, part of VCMI engine
@@ -36,13 +36,14 @@ class CBuildingRect : public CShowableAnim
 {
 public:
 	CCastleBuildings * parent;
+	const CGTownInstance * town;
 	const Structure* str;
 	SDL_Surface* border;
 	SDL_Surface* area;
 	
 	unsigned int stateCounter;//For building construction - current stage in animation
 	
-	CBuildingRect(CCastleBuildings * Par, const Structure *Str); //c-tor
+	CBuildingRect(CCastleBuildings * Par, const CGTownInstance *Town, const Structure *Str); //c-tor
 	~CBuildingRect(); //d-tor
 	bool operator<(const CBuildingRect & p2) const;
 	void hover(bool on);
@@ -53,6 +54,22 @@ public:
 	void showAll(SDL_Surface *to);
 };
 
+/// Dwelling info box - right-click screen for dwellings
+class CDwellingInfoBox : public CIntObject
+{
+	CPicture *background;
+	CLabel *title;
+	CCreaturePic *animation;
+	CLabel *available;
+	CLabel *costPerTroop;
+	
+	std::vector<CPicture *> resPicture;
+	std::vector<CLabel *> resAmount;
+public:
+	CDwellingInfoBox(int centerX, int centerY, const CGTownInstance *Town, int level);
+	void clickRight(tribool down, bool previousState);
+};
+
 /// Hero army slot
 class CHeroGSlot : public CIntObject
 {
@@ -67,7 +84,7 @@ public:
 	void hover (bool on);
 	void clickLeft(tribool down, bool previousState);
 	void deactivate();
-	void show(SDL_Surface * to);
+	void showAll(SDL_Surface * to);
 	CHeroGSlot(int x, int y, int updown, const CGHeroInstance *h,CCastleInterface * Owner); //c-tor
 	~CHeroGSlot(); //d-tor
 };
@@ -120,68 +137,77 @@ public:
 	void showAll(SDL_Surface *to);
 };
 
-/// Huge class which manages the castle window
-class CCastleInterface : public CWindowWithGarrison
+/// Creature info window
+class CCreaInfo : public CIntObject
 {
-	/// Creature info window
-	class CCreaInfo : public CIntObject
-	{
-	public:
-		int crid,level;
-		CCreaInfo(int CRID, int LVL); //c-tor
-		~CCreaInfo();//d-tor
-		int AddToString(std::string from, std::string & to, int numb);
-		void hover(bool on);
-		void clickLeft(tribool down, bool previousState);
-		void clickRight(tribool down, bool previousState);
-		void show(SDL_Surface * to);
-	};
-	/// Icons from town screen with castle\town hall images
-	class CTownInfo : public CIntObject
-	{
-	public:
-		int bid;//typeID
-		CDefHandler * pic;
-		CTownInfo(int BID); //c-tor
-		~CTownInfo();//d-tor
-		void hover(bool on);
-		void clickLeft(tribool down, bool previousState);
-		void clickRight(tribool down, bool previousState);
-		void show(SDL_Surface * to);
-	};
+	const CGTownInstance * town;
+	const CCreature *creature;
+	int level;
+	
+	CAnimImage *picture;
+	CLabel * label;
 
+	int AddToString(std::string from, std::string & to, int numb);
+	
 public:
-	CCastleBuildings *builds;
-	SDL_Surface * townInt;
-	const CGTownInstance * town;
-	CStatusBar * statusbar;
+	CCreaInfo(int posX, int posY, const CGTownInstance *Town, int Level);
+	
+	void hover(bool on);
+	void clickLeft(tribool down, bool previousState);
+	void clickRight(tribool down, bool previousState);
+};
+
+/// Town hall and fort icons for town screen
+class CTownInfo : public CIntObject
+{
+	const CGTownInstance *town;
+	const CBuilding *building;
+	CAnimImage *picture;
+public:
+	//if (townHall) hall-capital else fort - castle
+	CTownInfo(int posX, int posY, const CGTownInstance* town, bool townHall);
+	
+	void hover(bool on);
+	void clickRight(tribool down, bool previousState);
+};
+
+/// Class which manages the castle window
+class CCastleInterface : public CWindowWithGarrison
+{
+	CLabel *title;
+	CLabel *income;
+	CAnimImage *icon;
+
+	CPicture * panel;
 	CResDataBar *resdatabar;
-	int winMode;//0=right-click popup, 1 = normal, 2 = town hall only, 3 = fort only;
+	CGStatusBar * statusbar;
 
-	CDefEssential *bars, //0 - yellow, 1 - green, 2 - red, 3 - gray
-		*status; //0 - already, 1 - can't, 2 - lack of resources
-	CTownInfo *hall,*fort,*market;
-	CDefEssential* bicons; //150x70 buildings imgs
+	CTownInfo *hall, *fort;
 	CTownList * townlist;
 
-	CHeroGSlot hslotup, hslotdown;
 	AdventureMapButton *exit;
 	AdventureMapButton *split;
 
 	std::vector<CCreaInfo*> creainfo;//small icons of creatures (bottom-left corner);
 
+public:
+	//TODO: remove - currently used only in dialog messages
+	CDefEssential* bicons; //150x70 buildings imgs
+
+	//TODO: move to private
+	const CGTownInstance * town;
+	CHeroGSlot *heroSlotUp, *heroSlotDown;
+	CCastleBuildings *builds;
+
 	CCastleInterface(const CGTownInstance * Town, int listPos = 1); //c-tor
-	~CCastleInterface(); //d-tor
+	~CCastleInterface();
 
 	void castleTeleport(int where);
 	void townChange();
 	void keyPressed(const SDL_KeyboardEvent & key);
-	void show(SDL_Surface * to);
-	void showAll(SDL_Surface * to);
 	void splitClicked(); //for hero meeting (splitting stacks is handled by garrison int)
+	void showAll(SDL_Surface *to);
 	void close();
-	void activate();
-	void deactivate();
 	void addBuilding(int bid);
 	void removeBuilding(int bid);
 	void recreateIcons();
@@ -190,131 +216,169 @@ public:
 /// Hall window where you can build things
 class CHallInterface : public CIntObject
 {
-public:
-	CMinorResDataBar * resdatabar;
-
 	/// Building box from town hall (building icon + subtitle)
 	class CBuildingBox : public CIntObject
 	{
+		const CGTownInstance * town;
+		const CBuilding * building;
+
+		unsigned int state;//Buildings::EBuildStructure enum
+
+		CAnimImage * picture;
+		CAnimImage * panel;
+		CAnimImage * icon;
+		CLabel * label;
+
 	public:
-		int BID;
-		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 - already builded today, 6 - cannot afford, 7 - build, 8 - lack of requirements
-		//(-1) - forbidden in this town, 0 - possible, 1 - lack of res, 2 - requirements/buildings per turn limit, (3) - already exists
+		CBuildingBox(int x, int y, const CGTownInstance * Town, const CBuilding * Building);
 		void hover(bool on);
 		void clickLeft(tribool down, bool previousState);
 		void clickRight(tribool down, bool previousState);
-		void show(SDL_Surface * to);
-		CBuildingBox(int id); //c-tor
-		CBuildingBox(int id, int x, int y); //c-tor
-		~CBuildingBox(); //d-tor
 	};
+	const CGTownInstance * town;
+	
+	std::vector< std::vector<CBuildingBox*> >boxes;
+	CPicture *background;
+	CLabel *title;
+	CGStatusBar *statusBar;
+	CMinorResDataBar * resdatabar;
+	AdventureMapButton *exit;
 
-	///  Window where you can decide to buy a building or not
-	class CBuildWindow: 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"
-		AdventureMapButton *buy, *cancel;
-
-		void activate();
-		void deactivate();
-		std::string getTextForState(int state);
-		void clickRight(tribool down, bool previousState);
-		void show(SDL_Surface * to);
-		void Buy();
-		void close();
-		CBuildWindow(int Tid, int Bid, int State, bool Mode); //c-tor
-		~CBuildWindow(); //d-tor
-	};
+public:
+	CHallInterface(const CGTownInstance * Town); //c-tor
+	void close();
+};
 
-	std::vector< std::vector<CBuildingBox*> >boxes;
+///  Window where you can decide to buy a building or not
+class CBuildWindow: public CIntObject
+{
+	const CGTownInstance *town;
+	const CBuilding *building;
+	int state; //state - same as CHallInterface::CBuildingBox::state
+	bool mode; // 0 - normal (with buttons), 1 - r-click popup
 
-	AdventureMapButton *exit;
+	CPicture *background;
+	CAnimImage *buildingPic;
+	AdventureMapButton *buy;
+	AdventureMapButton *cancel;
+
+	CLabel * title;
+	CTextBox * buildingDescr;
+	CTextBox * buildingState;
+	CGStatusBar *statusBar;
 
-	SDL_Surface * bg; //background
-	int bid;//building ID
+	std::vector<CPicture *> resPicture;
+	std::vector<CLabel *> resAmount;
 
-	CHallInterface(CCastleInterface * owner); //c-tor
-	~CHallInterface(); //d-tor
+	std::string getTextForState(int state);
+	void buyFunc();
 	void close();
-	void showAll(SDL_Surface * to);
-	void activate();
-	void deactivate();
+
+public:
+	void clickRight(tribool down, bool previousState);
+	CBuildWindow(const CGTownInstance *Town, const CBuilding * building, int State, bool Mode); //c-tor
+	~CBuildWindow(); //d-tor
+};
+
+//Small class to display 
+class LabeledValue : public CIntObject
+{
+	std::string hoverText;
+	CLabel *name;
+	CLabel *value;
+	void init(std::string name, std::string descr, int min, int max);
+
+public:
+	LabeledValue(Rect size, std::string name, std::string descr, int min, int max);
+	LabeledValue(Rect size, std::string name, std::string descr, int val);
+	void hover(bool on);
 };
 
 /// The fort screen where you can afford units
 class CFortScreen : public CIntObject
 {
-	class RecArea : public CIntObject
+	class RecruitArea : public CIntObject
 	{
-	public:
+		const CGTownInstance *town;
 		int level;
-		RecArea(int LEVEL):level(LEVEL){used = LCLICK | RCLICK;}; //c-tor
+
+		std::string hoverText;
+		CLabel * creatureName;
+		CLabel * dwellingName;
+		CLabel * availableCount;
+
+		std::vector<LabeledValue*> values;
+		CPicture *icons;
+		CAnimImage * buildingPic;
+		CCreaturePic *creatureAnim;
+
+	public:
+		RecruitArea(int posX, int posY, const CGTownInstance *town, int buildingID, int level);
+		
+		void creaturesChanged();
+		void hover(bool on);
 		void clickLeft(tribool down, bool previousState);
 		void clickRight(tribool down, bool previousState);
 	};
-public:
+	
+	CPicture *background;
+	CLabel *title;
+	std::vector<RecruitArea*> recAreas;
 	CMinorResDataBar * resdatabar;
-	int fortSize;
+	CGStatusBar *statusBar;
 	AdventureMapButton *exit;
-	SDL_Surface * bg;
-	std::vector<Rect> positions;
-	std::vector<RecArea*> recAreas;
-	std::vector<CCreaturePic*> crePics;
 
-	CFortScreen(CCastleInterface * owner); //c-tor
+public:
+	CFortScreen(const CGTownInstance * town); //c-tor
 
-	void draw( CCastleInterface * owner, bool first);
-	~CFortScreen(); //d-tor
+	void creaturesChanged();
 	void close();
-	void show(SDL_Surface * to);
-	void showAll(SDL_Surface * to);
-	void activate();
-	void deactivate();
 };
 
 /// The mage guild screen where you can see which spells you have
 class CMageGuildScreen : public CIntObject
 {
-public:
 	class Scroll : public CIntObject
 	{
-	public:
 		const CSpell *spell;
+		CAnimImage *image;
 
-		Scroll(const CSpell *Spell);
+	public:
+		Scroll(Point position, const CSpell *Spell);
 		void clickLeft(tribool down, bool previousState);
 		void clickRight(tribool down, bool previousState);
 		void hover(bool on);
 	};
-	std::vector<std::vector<SDL_Rect> > positions;
-
-	CPicture *bg;
+	CPicture *background;
+	CPicture *window;
 	AdventureMapButton *exit;
 	std::vector<Scroll *> spells;
 	CMinorResDataBar * resdatabar;
+	CGStatusBar *statusBar;
 
-
-	CMageGuildScreen(CCastleInterface * owner); //c-tor
-	~CMageGuildScreen(); //d-tor
 	void close();
 
+public:
+	CMageGuildScreen(CCastleInterface * owner);
 };
 
 /// The blacksmith window where you can buy available in town war machine
 class CBlacksmithDialog : public CIntObject
 {
-public:
 	AdventureMapButton *buy, *cancel;
-	CPicture *bmp; //background
+	CPicture *background;
 	CPicture *animBG;
 	CCreatureAnim * anim;
+	CPicture * gold;
+	CLabel * title;
+	CLabel * costText;
+	CLabel * costValue;
+	CGStatusBar *statusBar;
 
-	CBlacksmithDialog(bool possible, int creMachineID, int aid, int hid); //c-tor
-	~CBlacksmithDialog(); //d-tor
 	void close();
+
+public:
+	CBlacksmithDialog(bool possible, int creMachineID, int aid, int hid);
 };
 
 #endif // __CCASTLEINTERFACE_H__

+ 3 - 3
client/CPlayerInterface.cpp

@@ -474,8 +474,8 @@ void CPlayerInterface::heroInGarrisonChange(const CGTownInstance *town)
 	if(CCastleInterface *c = castleInt)
 	{
 		c->garr->highlighted = NULL;
-		c->hslotup.hero = town->garrisonHero;
-		c->hslotdown.hero = town->visitingHero;
+		c->heroSlotUp->hero = town->garrisonHero;
+		c->heroSlotDown->hero = town->visitingHero;
 
 		c->garr->setArmy(town->getUpperArmy(), 0);
 		c->garr->setArmy(town->visitingHero, 1);
@@ -998,7 +998,7 @@ void CPlayerInterface::availableCreaturesChanged( const CGDwelling *town )
 	{
 		CFortScreen *fs = dynamic_cast<CFortScreen*>(GH.topInt());
 		if(fs)
-			fs->draw(castleInt,false);
+			fs->creaturesChanged();
 	}
 	else if(GH.listInt.size() && (town->ID == 17  ||  town->ID == 20  ||  town->ID == 106)) //external dwelling
 	{

+ 2 - 2
client/CVideoHandler.cpp

@@ -3,8 +3,8 @@
 #include "CSndHandler.h"
 #include "CVideoHandler.h"
 #include <SDL.h>
-#include "../client/SDL_Extensions.h"
-#include "../client/CPlayerInterface.h"
+#include "SDL_Extensions.h"
+#include "CPlayerInterface.h"
 #include "boost/filesystem.hpp"
 
 extern SystemOptions GDefaultOptions; 

+ 8 - 3
client/GUIBase.cpp

@@ -115,8 +115,9 @@ void CGuiHandler::internalTotalRedraw()
 
 	blitAt(screen2,0,0,screen);
 
-	if(objsToBlit.size())
-		objsToBlit.back()->showAll(screen);
+	//Any reason to blit last object second time?
+	//if(objsToBlit.size())
+	//	objsToBlit.back()->showAll(screen);
 
 	this->invalidateTotalRedraw = false;
 	this->invalidateSimpleRedraw = false;
@@ -359,7 +360,8 @@ void CGuiHandler::run()
 	setThreadName(-1, "CGuiHandler::run");
 	try
 	{
-		CCS->curh->centerCursor();
+		//CCS->curh->centerCursor();//Is this essential? random crashes on Linux
+
 		mainFPSmng->init(); // resets internal clock, needed for FPS manager
 		while(!terminate)
 		{
@@ -373,6 +375,7 @@ void CGuiHandler::run()
 			// Redraws the GUI only once during rendering
 			if (this->invalidateTotalRedraw == true)
 				internalTotalRedraw();
+
 			if (this->invalidateSimpleRedraw == true)
 				internalSimpleRedraw();
 
@@ -890,6 +893,8 @@ CPicture::CPicture(SDL_Surface *BG, const Rect &SrcRect, int x /*= 0*/, int y /*
 	srcRect = new Rect(SrcRect);
 	pos.x += x;
 	pos.y += y;
+	pos.w = srcRect->w;
+	pos.h = srcRect->h;
 	bg = BG;
 	freeSurf = free;
 }

+ 18 - 9
client/GUIClasses.cpp

@@ -1418,6 +1418,11 @@ void CHeroList::show( SDL_Surface * to )
 
 }
 
+void CHeroList::showAll( SDL_Surface * to )
+{
+	draw(to);
+}
+
 int CHeroList::size()
 {
 	return LOCPLINT->wanderingHeroes.size();
@@ -1434,17 +1439,17 @@ CTownList::CTownList(int Size, int x, int y, std::string arrupg, std::string arr
 {
 	arrup = CDefHandler::giveDef(arrupg);
 	arrdo = CDefHandler::giveDef(arrdog);
-	pos.x = x;
-	pos.y = y;
+	pos.x += x;
+	pos.y += y;
 	pos.w = std::max(arrdo->width, arrup->width);
 	pos.h = arrdo->height + arrup->height + Size*32;
 
-	arrupp.x=x;
-	arrupp.y=y;
+	arrupp.x=pos.x;
+	arrupp.y=pos.y;
 	arrupp.w=arrup->width;
 	arrupp.h=arrup->height;
-	arrdop.x=x;
-	arrdop.y=y+arrup->height+32*SIZE;
+	arrdop.x=pos.x;
+	arrdop.y=pos.y+arrup->height+32*SIZE;
 	arrdop.w=arrdo->width;
 	arrdop.h=arrdo->height;
 	posporx = arrdop.x;
@@ -1654,6 +1659,11 @@ void CTownList::show( SDL_Surface * to )
 
 }
 
+void CTownList::showAll( SDL_Surface * to )
+{
+	draw(to);
+}
+
 int CTownList::size()
 {
 	return LOCPLINT->towns.size();
@@ -4919,7 +4929,6 @@ void LRClickableAreaOpenTown::clickLeft(tribool down, bool previousState)
 	if((!down) && previousState && town)
 		{
 		LOCPLINT->openTownWindow(town);
-		LOCPLINT->castleInt->winMode = type;
 		if ( type == 2 )
 			LOCPLINT->castleInt->builds->buildingClicked(10);
 		else if ( type == 3 && town->fortLevel() )
@@ -5724,8 +5733,8 @@ void CShipyardWindow::deactivate()
 void CShipyardWindow::show( SDL_Surface * to )
 {
 	blitAt(bg,pos,to);
-	//FIXME: change to blit by CAnimation
-	//CSDL_Ext::blit8bppAlphaTo24bpp(graphics->boatAnims[boat]->ourImages[21 + frame++/8%8].bitmap, NULL, to, &genRect(64, 96, pos.x+110, pos.y+85));
+	Rect clipRect = genRect(64, 96, pos.x+110, pos.y+85);
+	CSDL_Ext::blit8bppAlphaTo24bpp(graphics->boatAnims[boat]->ourImages[21 + frame++/8%8].bitmap, NULL, to, &clipRect);
 	build->showAll(to);
 	quit->showAll(to);
 }

+ 2 - 0
client/GUIClasses.h

@@ -436,6 +436,7 @@ public:
 	void updateMove(const CGHeroInstance* which); //draws move points bar
 	void draw(SDL_Surface * to);
 	void show(SDL_Surface * to);
+	void showAll(SDL_Surface * to);
 	void init();
 	int size(); //how many elements do we have
 };
@@ -459,6 +460,7 @@ public:
 	void keyPressed (const SDL_KeyboardEvent & key);  //call-in
 	void draw(SDL_Surface * to);
 	void show(SDL_Surface * to);
+	void showAll(SDL_Surface * to);
 	int size(); //how many elements do we have
 };
 

+ 22 - 0
global.h

@@ -2,6 +2,7 @@
 #ifndef __GLOBAL_H__
 #define __GLOBAL_H__
 #include <iostream>
+#include <sstream>
 #include <algorithm> //std::find
 #include <string> //std::find
 #include <boost/logic/tribool.hpp>
@@ -322,6 +323,27 @@ namespace SpellCasting
 	enum ECastingMode {HERO_CASTING, AFTER_ATTACK_CASTING};
 }
 
+namespace Buildings
+{
+	enum EBuildStructure
+	{
+		HAVE_CAPITAL, NO_WATER, FORBIDDEN, ADD_MAGES_GUILD, ALREADY_PRESENT, CANT_BUILD_TODAY,
+		NO_RESOURCES, ALLOWED, PREREQUIRES, ERROR
+	};
+
+	//Quite useful as long as most of building mechanics hardcoded
+	enum EBuilding
+	{
+		MAGES_GUILD_1,  MAGES_GUILD_2, MAGES_GUILD_3,     MAGES_GUILD_4,   MAGES_GUILD_5, 
+		TAVERN,         SHIPYARD,      FORT,              CITADEL,         CASTLE,
+		VILLAGE_HALL,   TOWN_HALL,     CITY_HALL,         CAPITOL,         MARKETPLACE,
+		RESOURCE_SILO,  BLACKSMITH,    SPECIAL_1,         HORDE_1,         HORDE_1_UPGR,
+		SHIP,           SPECIAL_2,     SPECIAL_3,         SPECIAL_4,       HORDE_2,
+		HORDE_2_UPGR,   GRAIL,         EXTRA_CITY_HALL,   EXTRA_TOWN_HALL, EXTRA_CAPITOL,
+		DWELL_FIRST=30, DWELL_LAST=36, DWELL_UP_FIRST=37, DWELL_UP_LAST=43
+	};
+}
+
 namespace Res
 {
 	enum ERes 

+ 13 - 18
lib/CGameState.cpp

@@ -1850,24 +1850,21 @@ std::set<int> CGameState::getBuildingRequiments(const CGTownInstance *t, int ID)
 
 int CGameState::canBuildStructure( const CGTownInstance *t, int ID )
 {
-	int ret = 7; //allowed by default
+	int ret = Buildings::ALLOWED;
 
 	if(t->builded >= MAX_BUILDING_PER_TURN)
-		ret = 5; //building limit
+		ret = Buildings::CANT_BUILD_TODAY; //building limit
 
-	//checking resources
 	CBuilding * pom = VLC->buildh->buildings[t->subID][ID];
 	
 	if(!pom)
-		return 8;
+		return Buildings::ERROR;
 
-// 	if(pom->Name().size()==0||pom->resources.size()==0)
-// 		return 2;//TODO: why does this happen?
-
-	for(int res=0;res<pom->resources.size();res++) //TODO: support custom amount of resources
+	//checking resources
+	for(int res=0; res<RESOURCE_QUANTITY; res++)
 	{
 		if(pom->resources[res] > getPlayer(t->tempOwner)->resources[res])
-			ret = 6; //lack of res
+			ret = Buildings::NO_RESOURCES; //lack of res
 	}
 
 	//checking for requirements
@@ -1876,12 +1873,12 @@ int CGameState::canBuildStructure( const CGTownInstance *t, int ID )
 	for( std::set<int>::iterator ri  =  reqs.begin(); ri != reqs.end(); ri++ )
 	{
 		if(t->builtBuildings.find(*ri)==t->builtBuildings.end())
-			ret = 8; //lack of requirements - cannot build
+			ret = Buildings::PREREQUIRES; //lack of requirements - cannot build
 	}
 
 	//can we build it?
 	if(t->forbiddenBuildings.find(ID)!=t->forbiddenBuildings.end())
-		ret = 2; //forbidden
+		ret = Buildings::FORBIDDEN; //forbidden
 
 	if(ID == 13) //capitol
 	{
@@ -1889,22 +1886,20 @@ int CGameState::canBuildStructure( const CGTownInstance *t, int ID )
 		{
 			if(map->towns[in]->tempOwner==t->tempOwner  &&  vstd::contains(map->towns[in]->builtBuildings,13))
 			{
-				ret = 0; //no more than one capitol
+				ret = Buildings::HAVE_CAPITAL; //no more than one capitol
 				break;
 			}
 		}
 	}
 	else if(ID == 6) //shipyard
 	{
-		int3 t1(t->pos + int3(-1,3,0)),
-			t2(t->pos + int3(-3,3,0));
-		if(map->isInTheMap(t1) && map->getTile(t1).tertype != TerrainTile::water  
-			&&  (map->isInTheMap(t2) && map->getTile(t2).tertype != TerrainTile::water))
-			ret = 1; //lack of water
+		int3 tile = t->bestLocation();
+		if( !map->isInTheMap(tile) || map->getTile(tile).tertype != TerrainTile::water )
+			ret = Buildings::NO_WATER; //lack of water
 	}
 
 	if(t->builtBuildings.find(ID)!=t->builtBuildings.end())	//already built
-		ret = 4;
+		ret = Buildings::ALREADY_PRESENT;
 	return ret;
 }
 

+ 2 - 0
lib/CObjectHandler.cpp

@@ -1867,6 +1867,8 @@ int CGTownInstance::creatureGrowth(const int & level) const
 {
 	if (level<0 || level >=CREATURES_PER_TOWN)
 		return 0;
+	if (!vstd::contains(builtBuildings, Buildings::DWELL_FIRST+level))
+		return 0; //no dwelling
 	TCreature creid = town->basicCreatures[level];
 		
 	int ret = VLC->creh->creatures[creid]->growth;

+ 1 - 1
lib/ERMParser.cpp

@@ -45,7 +45,7 @@ namespace phoenix = boost::phoenix;
 
 #define DO_TYPE_CASE(LinePrinterVisitor, VAR) } ___UN; boost::apply_visitor(___UN, VAR);
 
-CERMPreprocessor::CERMPreprocessor(const std::string &Fname) : fname(Fname), file(Fname), lineNo(0), version(INVALID)
+CERMPreprocessor::CERMPreprocessor(const std::string &Fname) : fname(Fname), file(Fname.c_str()), lineNo(0), version(INVALID)
 {
 	if(!file.is_open())
 	{

+ 2 - 0
lib/Makefile.am

@@ -38,6 +38,8 @@ libvcmi_la_SOURCES = \
 	CSpellHandler.h \
 	CTownHandler.cpp \
 	CTownHandler.h \
+	ERMInterpreter.cpp \
+	ERMInterpreter.h \
 	ERMParser.cpp \
 	ERMParser.h \
 	HeroBonus.cpp \

+ 15 - 4
lib/Makefile.in

@@ -87,10 +87,10 @@ am_libvcmi_la_OBJECTS = libvcmi_la-BattleAction.lo \
 	libvcmi_la-CLodHandler.lo libvcmi_la-CMapInfo.lo \
 	libvcmi_la-CObjectHandler.lo libvcmi_la-Connection.lo \
 	libvcmi_la-CSpellHandler.lo libvcmi_la-CTownHandler.lo \
-	libvcmi_la-ERMParser.lo libvcmi_la-HeroBonus.lo \
-	libvcmi_la-IGameCallback.lo libvcmi_la-map.lo \
-	libvcmi_la-NetPacksLib.lo libvcmi_la-RegisterTypes.lo \
-	libvcmi_la-VCMI_Lib.lo
+	libvcmi_la-ERMInterpreter.lo libvcmi_la-ERMParser.lo \
+	libvcmi_la-HeroBonus.lo libvcmi_la-IGameCallback.lo \
+	libvcmi_la-map.lo libvcmi_la-NetPacksLib.lo \
+	libvcmi_la-RegisterTypes.lo libvcmi_la-VCMI_Lib.lo
 libvcmi_la_OBJECTS = $(am_libvcmi_la_OBJECTS)
 AM_V_lt = $(am__v_lt_$(V))
 am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
@@ -314,6 +314,8 @@ libvcmi_la_SOURCES = \
 	CSpellHandler.h \
 	CTownHandler.cpp \
 	CTownHandler.h \
+	ERMInterpreter.cpp \
+	ERMInterpreter.h \
 	ERMParser.cpp \
 	ERMParser.h \
 	HeroBonus.cpp \
@@ -421,6 +423,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvcmi_la-CSpellHandler.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvcmi_la-CTownHandler.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvcmi_la-Connection.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvcmi_la-ERMInterpreter.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvcmi_la-ERMParser.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvcmi_la-HeroBonus.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvcmi_la-IGameCallback.Plo@am__quote@
@@ -589,6 +592,14 @@ libvcmi_la-CTownHandler.lo: CTownHandler.cpp
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libvcmi_la_CXXFLAGS) $(CXXFLAGS) -c -o libvcmi_la-CTownHandler.lo `test -f 'CTownHandler.cpp' || echo '$(srcdir)/'`CTownHandler.cpp
 
+libvcmi_la-ERMInterpreter.lo: ERMInterpreter.cpp
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libvcmi_la_CXXFLAGS) $(CXXFLAGS) -MT libvcmi_la-ERMInterpreter.lo -MD -MP -MF $(DEPDIR)/libvcmi_la-ERMInterpreter.Tpo -c -o libvcmi_la-ERMInterpreter.lo `test -f 'ERMInterpreter.cpp' || echo '$(srcdir)/'`ERMInterpreter.cpp
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libvcmi_la-ERMInterpreter.Tpo $(DEPDIR)/libvcmi_la-ERMInterpreter.Plo
+@am__fastdepCXX_FALSE@	$(AM_V_CXX) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='ERMInterpreter.cpp' object='libvcmi_la-ERMInterpreter.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libvcmi_la_CXXFLAGS) $(CXXFLAGS) -c -o libvcmi_la-ERMInterpreter.lo `test -f 'ERMInterpreter.cpp' || echo '$(srcdir)/'`ERMInterpreter.cpp
+
 libvcmi_la-ERMParser.lo: ERMParser.cpp
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libvcmi_la_CXXFLAGS) $(CXXFLAGS) -MT libvcmi_la-ERMParser.lo -MD -MP -MF $(DEPDIR)/libvcmi_la-ERMParser.Tpo -c -o libvcmi_la-ERMParser.lo `test -f 'ERMParser.cpp' || echo '$(srcdir)/'`ERMParser.cpp
 @am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libvcmi_la-ERMParser.Tpo $(DEPDIR)/libvcmi_la-ERMParser.Plo

部分文件因文件數量過多而無法顯示