Browse Source

* heroList
* functions for getting info about heroes in CCallback
* function for initializing GameState
* improvements in CHeroInstance
* added codename
* minor stuff

Michał W. Urbańczyk 18 years ago
parent
commit
16a1861fc4

+ 211 - 18
CAdvmapInterface.cpp

@@ -2,10 +2,13 @@
 #include "CAdvmapInterface.h"
 #include "hch\CLodHandler.h"
 #include "hch\CPreGameTextHandler.h"
-
+#include "hch\CGeneralTextHandler.h"
+#include "CCallback.h"
+#include <boost/assign/std/vector.hpp>
 extern TTF_Font * TNRB16, *TNR, *GEOR13, *GEORXX; //fonts
 
 using namespace boost::logic;
+using namespace boost::assign;
 using namespace CSDL_Ext;
 CAdvMapInt::~CAdvMapInt()
 {
@@ -115,6 +118,7 @@ void CList::activate()
 	ClickableR::activate();
 	Hoverable::activate();
 	KeyInterested::activate();
+	MotionInterested::activate();
 }; 
 void CList::deactivate()
 {
@@ -122,6 +126,7 @@ void CList::deactivate()
 	ClickableR::deactivate();
 	Hoverable::deactivate();
 	KeyInterested::deactivate();
+	MotionInterested::deactivate();
 }; 
 void CList::clickLeft(tribool down)
 {
@@ -129,17 +134,139 @@ void CList::clickLeft(tribool down)
 CHeroList::CHeroList()
 {
 	pos = genRect(192,64,609,196);
-
+	
+	arrupp = genRect(16,64,609,196);
+	arrdop = genRect(16,64,609,372);
+ //32px per hero
+	posmobx = 610;
+	posmoby = 213;
+	posporx = 617;
+	pospory = 212;
+	posmanx = 666;
+	posmany = 213;
+	
 	arrup = CGI->spriteh->giveDef("IAM012.DEF");
 	arrdo = CGI->spriteh->giveDef("IAM013.DEF");
 	mobile = CGI->spriteh->giveDef("IMOBIL.DEF");
 	mana = CGI->spriteh->giveDef("IMANA.DEF");
+	empty = CGI->bitmaph->loadBitmap("HPSXXX.bmp");
+	selection = CGI->bitmaph->loadBitmap("HPSYYY.bmp");
+	SDL_SetColorKey(selection,SDL_SRCCOLORKEY,SDL_MapRGB(selection->format,0,255,255));
+	from = 0;
+	pressed = indeterminate;
+}
+
+void CHeroList::init()
+{
+	bg = SDL_CreateRGBSurface(ekran->flags,68,193,ekran->format->BitsPerPixel,ekran->format->Rmask,ekran->format->Gmask,ekran->format->Bmask,ekran->format->Amask);
+	SDL_BlitSurface(LOCPLINT->adventureInt->bg,&genRect(193,68,607,196),bg,&genRect(193,68,0,0));
+}
+void CHeroList::genList()
+{
+	int howMany = LOCPLINT->cb->howManyHeroes(LOCPLINT->playerID);
+	for (int i=0;i<howMany;i++)
+	{
+		items.push_back(LOCPLINT->cb->getHeroInfo(LOCPLINT->playerID,i,0));
+	}
 }
 void CHeroList::select(int which)
 {
+	selected = which;
+	if (which>=items.size()) 
+		which=items.size();
+	draw();
+	LOCPLINT->adventureInt->centerOn(items[which]->pos);
+	LOCPLINT->adventureInt->selection.type = &HEROI_TYPE;
+	LOCPLINT->adventureInt->selection.selected = items[which];
 }
 void CHeroList::clickLeft(tribool down)
 {
+	if (down)
+	{
+		/***************************ARROWS*****************************************/
+		if(isItIn(&arrupp,LOCPLINT->current->motion.x,LOCPLINT->current->motion.y) && from>0)
+		{
+			blitAtWR(arrup->ourImages[1].bitmap,arrupp.x,arrupp.y);
+			pressed = true;
+			return;
+		}
+		else if(isItIn(&arrdop,LOCPLINT->current->motion.x,LOCPLINT->current->motion.y) && (items.size()-from>5))
+		{
+			blitAtWR(arrdo->ourImages[1].bitmap,arrdop.x,arrdop.y);
+			pressed = false;
+			return;
+		}
+		/***************************HEROES*****************************************/
+		int hx = LOCPLINT->current->motion.x, hy = LOCPLINT->current->motion.y;
+		hx-=pos.x;
+		hy-=pos.y; hy-=arrup->ourImages[0].bitmap->h;
+		float ny = (float)hy/(float)32;
+		if (ny>5 || ny<0)
+			return;
+		select(ny+from);
+	}
+	else
+	{
+		if (indeterminate(pressed))
+			return;
+		if (pressed) //up
+		{
+			blitAtWR(arrup->ourImages[0].bitmap,arrupp.x,arrupp.y);
+			pressed = indeterminate;
+			if (!down)
+			{
+				from--;
+				if (from<0)
+					from=0;
+				draw();
+			}
+		}
+		else if (!pressed) //down
+		{
+			blitAtWR(arrdo->ourImages[0].bitmap,arrdop.x,arrdop.y);
+			pressed = indeterminate;
+			if (!down)
+			{
+				from++;
+				if (from<items.size()-5)
+					from=items.size()-5;
+				draw();
+			}
+		}
+		else
+			throw 0;
+
+	}
+}
+void CHeroList::mouseMoved (SDL_MouseMotionEvent & sEvent)
+{
+	if(isItIn(&arrupp,LOCPLINT->current->motion.x,LOCPLINT->current->motion.y))
+	{
+		if (from>0)
+			LOCPLINT->adventureInt->statusbar.print(CGI->preth->advHListUp.first);
+		else
+			LOCPLINT->adventureInt->statusbar.clear();
+		return;
+	}
+	else if(isItIn(&arrdop,LOCPLINT->current->motion.x,LOCPLINT->current->motion.y))
+	{
+		if ((items.size()-from)  >  5)
+			LOCPLINT->adventureInt->statusbar.print(CGI->preth->advHListDown.first);
+		else
+			LOCPLINT->adventureInt->statusbar.clear();
+		return;
+	}
+	//if not buttons then heroes
+	int hx = LOCPLINT->current->motion.x, hy = LOCPLINT->current->motion.y;
+	hx-=pos.x;
+	hy-=pos.y; hy-=arrup->ourImages[0].bitmap->h;
+	float ny = (float)hy/(float)32;
+	if (ny>5 || ny<0)
+		return;
+	std::vector<std::string> temp;
+	temp+=(items[from+ny]->name),(items[from+ny]->type->heroClass->name);
+	LOCPLINT->adventureInt->statusbar.print( processStr(CGI->generaltexth->allTexts[15],temp) );
+	//select(ny+from);
 }
 void CHeroList::clickRight(tribool down)
 {
@@ -150,15 +277,58 @@ void CHeroList::hover (bool on)
 void CHeroList::keyPressed (SDL_KeyboardEvent & key)
 {
 }
+void CHeroList::draw()
+{	for (int iT=0+from;iT<5+from;iT++)
+	{
+		int i = iT-from;
+		if (iT>=items.size())
+		{
+			blitAtWR(mobile->ourImages[0].bitmap,posmobx,posmoby+i*32);
+			blitAtWR(mana->ourImages[0].bitmap,posmanx,posmany+i*32);
+			blitAtWR(empty,posporx,pospory+i*32);
+			continue;
+		}
+		int pom = (LOCPLINT->cb->getHeroInfo(LOCPLINT->playerID,iT,0)->movement)/100;
+		if (pom>25) pom=25;
+		if (pom<0) pom=0;
+		blitAtWR(mobile->ourImages[pom].bitmap,posmobx,posmoby+i*32); //move point
+		pom = (LOCPLINT->cb->getHeroInfo(LOCPLINT->playerID,iT,0)->mana)/10;
+		if (pom>25) pom=25;
+		if (pom<0) pom=0;
+		blitAtWR(mana->ourImages[pom].bitmap,posmanx,posmany+i*32); //mana
+		SDL_Surface * temp = LOCPLINT->cb->getHeroInfo(LOCPLINT->playerID,iT,0)->type->portraitSmall;
+		blitAtWR(temp,posporx,pospory+i*32);
+		if (selected == iT)
+		{
+			blitAtWR(selection,posporx,pospory+i*32);
+		}
+		//TODO: support for custom portraits
+	}
+	if (from>0)
+		blitAtWR(arrup->ourImages[0].bitmap,arrupp.x,arrupp.y);
+	else
+		blitAtWR(arrup->ourImages[2].bitmap,arrupp.x,arrupp.y);
+
+	if (items.size()-from>5)
+		blitAtWR(arrdo->ourImages[0].bitmap,arrdop.x,arrdop.y);
+	else
+		blitAtWR(arrdo->ourImages[2].bitmap,arrdop.x,arrdop.y);
+}
 CTownList::CTownList()
 {
 	pos = genRect(192,48,747,196);
 	arrup = CGI->spriteh->giveDef("IAM014.DEF");
 	arrdo = CGI->spriteh->giveDef("IAM015.DEF");
 }
+void CTownList::genList()
+{
+}
 void CTownList::select(int which)
 {
 }
+void CTownList::mouseMoved (SDL_MouseMotionEvent & sEvent)
+{
+}
 void CTownList::clickLeft(tribool down)
 {
 }
@@ -171,6 +341,9 @@ void CTownList::hover (bool on)
 void CTownList::keyPressed (SDL_KeyboardEvent & key)
 {
 }
+void CTownList::draw()
+{
+}
 CStatusBar::CStatusBar(int x, int y)
 {
 	bg=CGI->bitmaph->loadBitmap("ADROLLVR.bmp");
@@ -283,22 +456,11 @@ void CMinimap::clickLeft (tribool down)
 	float dx=((float)(LOCPLINT->current->motion.x-pos.x))/((float)pos.w),
 		dy=((float)(LOCPLINT->current->motion.y-pos.y))/((float)pos.h);
 
-	int dxa = (CGI->mh->sizes.x*dx)-(LOCPLINT->adventureInt->terrain.tilesw/2);
-	int dya = (CGI->mh->sizes.y*dy)-(LOCPLINT->adventureInt->terrain.tilesh/2);
-
-	if (dxa<0)
-		dxa=-(Woff/2);
-	else if((dxa+LOCPLINT->adventureInt->terrain.tilesw)  >  (CGI->mh->sizes.x))
-		dxa=CGI->mh->sizes.x-LOCPLINT->adventureInt->terrain.tilesw+(Woff/2);
-
-	if (dya<0)
-		dya = -(Hoff/2);
-	else if((dya+LOCPLINT->adventureInt->terrain.tilesh)  >  (CGI->mh->sizes.y))
-		dya = CGI->mh->sizes.y-LOCPLINT->adventureInt->terrain.tilesh+(Hoff/2);
-
-	LOCPLINT->adventureInt->position.x=dxa;
-	LOCPLINT->adventureInt->position.y=dya;
-	LOCPLINT->adventureInt->updateScreen=true;
+	int3 newCPos;
+	newCPos.x = (CGI->mh->sizes.x*dx);
+	newCPos.y = (CGI->mh->sizes.y*dy);
+	newCPos.z = LOCPLINT->adventureInt->position.z;
+	LOCPLINT->adventureInt->centerOn(newCPos);
 }
 void CMinimap::hover (bool on)
 {
@@ -602,6 +764,7 @@ nextHero(CGI->preth->advNextHero.first,CGI->preth->advNextHero.second,
 endTurn(CGI->preth->advEndTurn.first,CGI->preth->advEndTurn.second,
 		  &CAdvMapInt::fendTurn, 679, 356, "IAM001.DEF")
 {
+	LOCPLINT->adventureInt=this;
 	bg = CGI->bitmaph->loadBitmap("ADVMAP.bmp");
 	blueToPlayersAdv(bg,player);
 	scrollingLeft = false;
@@ -611,6 +774,9 @@ endTurn(CGI->preth->advEndTurn.first,CGI->preth->advEndTurn.second,
 	updateScreen  = false;
 	anim=0;
 	animValHitCount=0; //animation frame
+
+	heroList.init();
+	heroList.genList();
 	
 	gems.push_back(CGI->spriteh->giveDef("agemLL.def"));
 	gems.push_back(CGI->spriteh->giveDef("agemLR.def"));
@@ -692,6 +858,8 @@ void CAdvMapInt::show()
 
 	minimap.activate();
 	minimap.draw();
+	heroList.activate();
+	heroList.draw();
 
 	statusbar.show();
 
@@ -705,4 +873,29 @@ void CAdvMapInt::update()
 	blitAt(gems[1]->ourImages[LOCPLINT->playerID].bitmap,556,508);
 	blitAt(gems[3]->ourImages[LOCPLINT->playerID].bitmap,556,6);
 	updateRect(&genRect(550,600,6,6));
+}
+
+void CAdvMapInt::centerOn(int3 on)
+{
+	on.x -= (LOCPLINT->adventureInt->terrain.tilesw/2);
+	on.y -= (LOCPLINT->adventureInt->terrain.tilesh/2);
+
+	if (on.x<0)
+		on.x=-(Woff/2);
+	else if((on.x+LOCPLINT->adventureInt->terrain.tilesw)  >  (CGI->mh->sizes.x))
+		on.x=CGI->mh->sizes.x-LOCPLINT->adventureInt->terrain.tilesw+(Woff/2);
+
+	if (on.y<0)
+		on.y = -(Hoff/2);
+	else if((on.y+LOCPLINT->adventureInt->terrain.tilesh)  >  (CGI->mh->sizes.y))
+		on.y = CGI->mh->sizes.y-LOCPLINT->adventureInt->terrain.tilesh+(Hoff/2);
+
+	LOCPLINT->adventureInt->position.x=on.x;
+	LOCPLINT->adventureInt->position.y=on.y;
+	LOCPLINT->adventureInt->updateScreen=true;
+}
+CAdvMapInt::CurrentSelection::CurrentSelection()
+{
+	type=NULL;
+	selected=NULL;
 }

+ 31 - 3
CAdvmapInterface.h

@@ -1,6 +1,6 @@
 #ifndef CADVENTUREMAPINTERFACE_H
 #define CADVENTUREMAPINTERFACE_H
-
+#include <typeinfo>
 #include "SDL.h"
 #include "hch\CDefHandler.h"
 #include "SDL_Extensions.h"
@@ -12,6 +12,8 @@
 #include "CPathfinder.h"
 #include "mapHandler.h"
 
+class CCallback;
+
 class AdventureMapButton 
 	: public ClickableL, public ClickableR, public Hoverable, public KeyInterested, public CButtonBase
 {
@@ -34,31 +36,46 @@ public:
 };
 /*****************************/
 class CList 
-	: public ClickableL, public ClickableR, public Hoverable, public KeyInterested, public virtual CIntObject
+	: public ClickableL, public ClickableR, public Hoverable, public KeyInterested, public virtual CIntObject, public MotionInterested
 {
 public:
 	SDL_Surface * bg;
 	CDefHandler *arrup, *arrdo;
-	SDL_Rect arrupp, arrdop;
+	SDL_Surface *empty, *selection; 
+	SDL_Rect arrupp, arrdop; //positions of arrows
 	int posw, posh; //position width/height
+	int selected, //id of selected position, <0 if none
+		from; 
+	tribool pressed; //true=up; false=down; indeterminate=none
 
 	void clickLeft(tribool down);
 	void activate(); 
 	void deactivate();
+	virtual void mouseMoved (SDL_MouseMotionEvent & sEvent)=0;
+	virtual void genList()=0;
 	virtual void select(int which)=0;
+	virtual void draw()=0;
 };
 class CHeroList 
 	: public CList
 {
 public:
 	CDefHandler *mobile, *mana;
+	std::vector<const CHeroInstance*> items;
+	int posmobx, posporx, posmanx, posmoby, pospory, posmany;
 
 	CHeroList();
+	void genList();
 	void select(int which);
+	void mouseMoved (SDL_MouseMotionEvent & sEvent);
 	void clickLeft(tribool down);
 	void clickRight(tribool down);
 	void hover (bool on);
 	void keyPressed (SDL_KeyboardEvent & key);
+	void updateHList();
+	void redrawAllOne(int which);
+	void draw();
+	void init();
 };
 class CTownList 
 	: public CList
@@ -66,11 +83,14 @@ class CTownList
 public: 
 
 	CTownList();
+	void genList();
 	void select(int which);
+	void mouseMoved (SDL_MouseMotionEvent & sEvent);
 	void clickLeft(tribool down);
 	void clickRight(tribool down);
 	void hover (bool on);
 	void keyPressed (SDL_KeyboardEvent & key);
+	void draw();
 };
 class CResourceBar
 	:public ClickableR, public CIntObject
@@ -197,6 +217,14 @@ public:
 	void show(); //shows and activates adv. map interface
 	void update(); //redraws terrain
 
+	void centerOn(int3 on);
+
+	struct CurrentSelection
+	{
+		const type_info* type;
+		const void* selected;
+		CurrentSelection(); //ctor
+	} selection;
 
 };
 #endif //CADVENTUREMAPINTERFACE_H

+ 24 - 0
CCallback.cpp

@@ -46,3 +46,27 @@ bool CCallback::moveHero(int ID, int3 destPoint)
 	}
 	return true;
 }
+
+
+int CCallback::howManyHeroes(int player)
+{
+	if (gs->currentPlayer!=player) //TODO: checking if we are allowed to give that info
+		return -1;
+	return gs->players[player].heroes.size();
+}
+const CHeroInstance * CCallback::getHeroInfo(int player, int val, bool mode) //mode = 0 -> val = serial; mode = 1 -> val = ID
+{
+	if (gs->currentPlayer!=player) //TODO: checking if we are allowed to give that info
+		return NULL;
+	if (!mode)
+		return gs->players[player].heroes[val];
+	else 
+	{
+		for (int i=0; i<gs->players[player].heroes.size();i++)
+		{
+			if (gs->players[player].heroes[i]->type->ID==val)
+				return gs->players[player].heroes[i];
+		}
+	}
+	return NULL;
+}

+ 8 - 0
CCallback.h

@@ -1,6 +1,7 @@
 #ifndef CCALLBACK_H
 #define CCALLBACK_H
 class CGameState;
+class CHeroInstance;
 struct HeroMoveDetails
 {
 	int3 src, dst; //source and destination points
@@ -9,11 +10,18 @@ struct HeroMoveDetails
 };
 class CCallback 
 {
+private:
+	void newTurn();
+
 protected:
 	CGameState * gs;
 
 public:
+	CCallback(CGameState * GS):gs(GS){};
 	bool moveHero(int ID, int3 destPoint);
+
+	int howManyHeroes(int player);
+	const CHeroInstance * getHeroInfo(int player, int val, bool mode); //mode = 0 -> val = serial; mode = 1 -> val = ID
 };
 
 #endif //CCALLBACK_H

+ 9 - 2
CGameInterface.cpp

@@ -100,8 +100,9 @@ CPlayerInterface::CPlayerInterface(int Player, int serial)
 	CGI->localPlayer = playerID;
 	human=true;
 }
-void CPlayerInterface::init()
+void CPlayerInterface::init(CCallback * CB)
 {
+	cb = CB;
 	CGI->localPlayer = serialID;
 	adventureInt = new CAdvMapInt(playerID);
 }
@@ -233,6 +234,12 @@ void CPlayerInterface::heroMoved(const HeroMoveDetails & details)
 		}
 	}
 }
+void CPlayerInterface::heroKilled(const CHeroInstance * hero)
+{
+}
+void CPlayerInterface::heroCreated(const CHeroInstance * hero)
+{
+}
 
 void CPlayerInterface::handleEvent(SDL_Event *sEvent)
 {
@@ -363,7 +370,7 @@ void CPlayerInterface::handleEvent(SDL_Event *sEvent)
 		{
 			LOCPLINT->adventureInt->scrollingDown = false;
 		}
-	}
+	} //mousemotion end
 
 	else if ((sEvent->type==SDL_MOUSEBUTTONDOWN) && (sEvent->button.button == SDL_BUTTON_LEFT))
 	{

+ 13 - 2
CGameInterface.h

@@ -9,7 +9,8 @@
 BOOST_TRIBOOL_THIRD_STATE(outOfRange)
 using namespace boost::logic;
 class CAdvMapInt;
-
+class CCallback;
+class CHeroInstance;
 struct HeroMoveDetails;
 class CIntObject //interface object
 {
@@ -80,6 +81,8 @@ public:
 	int playerID, serialID;
 
 	virtual void yourTurn()=0{};
+	virtual void heroKilled(const CHeroInstance * hero)=0{};
+	virtual void heroCreated(const CHeroInstance * hero)=0{};
 
 	virtual void heroMoved(const HeroMoveDetails & details)=0;
 };
@@ -87,6 +90,8 @@ class CGlobalAI : public CGameInterface // AI class (to derivate)
 {
 public:
 	virtual void yourTurn(){};
+	virtual void heroKilled(const CHeroInstance * hero){};
+	virtual void heroCreated(const CHeroInstance * hero){};
 };
 class CPlayerInterface : public CGameInterface
 {
@@ -96,6 +101,8 @@ public:
 	FPSmanager * mainFPSmng;
 	//TODO: town interace, battle interface, other interfaces
 
+	CCallback * cb;
+
 	std::vector<ClickableL*> lclickable;
 	std::vector<ClickableR*> rclickable;
 	std::vector<Hoverable*> hoverable;
@@ -104,8 +111,12 @@ public:
 
 	void yourTurn();
 	void heroMoved(const HeroMoveDetails & details);
+	void heroKilled(const CHeroInstance * hero);
+	void heroCreated(const CHeroInstance * hero);
+
+
 	void handleEvent(SDL_Event * sEvent);
-	void init();
+	void init(CCallback * CB);
 
 	CPlayerInterface(int Player, int serial);
 };

+ 2 - 1
CGameState.h

@@ -22,8 +22,9 @@ class CGameState
 public:
 	friend CCallback;
 	friend int _tmain(int argc, _TCHAR* argv[]);
+	friend void initGameState(CGameInfo * cgi);
 	friend void CAmbarCendamo::deh3m();
 	CCallback * cb; //for communication between PlayerInterface/AI and GameState
 };
 
-#endif //CGAMESTATE_H
+#endif //CGAMESTATE_H

+ 102 - 56
CMT.cpp

@@ -42,6 +42,7 @@
 #include "CScreenHandler.h"
 #include "CPathfinder.h"
 #include "CGameState.h"
+#include "CCallback.h"
 
 #if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
 #  include <fcntl.h>
@@ -52,7 +53,7 @@
 #endif
 
 #define CHUNK 16384
-const char * NAME = "VCMI 0.3";
+const char * NAME = "VCMI 0.3 \"Tol Galen\"";
 
 /* Compress from file source to file dest until EOF on source.
    def() returns Z_OK on success, Z_MEM_ERROR if memory could not be
@@ -82,37 +83,101 @@ TTF_Font * TNRB16, *TNR, *GEOR13, *GEORXX, *GEORM;
 //	std::cout<<"powitanie2zc++. Liczba dnia to " << i;
 //}
 
+void initGameState(CGameInfo * cgi)
+{
+	/*************************FOG**OF**WAR******************************************/		
+	for(int k=0; k<CGI->state->players.size(); ++k)
+	{
+		cgi->state->players[k].fogOfWarMap.resize(cgi->ac->map.width);
+		for(int g=0; g<cgi->ac->map.width; ++g)
+			cgi->state->players[k].fogOfWarMap[g].resize(cgi->ac->map.height);
+
+		for(int g=0; g<cgi->ac->map.width; ++g)
+			for(int h=0; h<cgi->ac->map.height; ++h)
+				cgi->state->players[k].fogOfWarMap[g][h].resize(cgi->ac->map.twoLevel+1);
+
+		for(int g=0; g<cgi->ac->map.width; ++g)
+			for(int h=0; h<cgi->ac->map.height; ++h)
+				for(int v=0; v<cgi->ac->map.twoLevel+1; ++v)
+					cgi->state->players[k].fogOfWarMap[g][h][v] = 1;
+	}
+	/*************************HEROES************************************************/
+	for (int i=0; i<cgi->heroh->heroInstances.size();i++) //heroes instances
+	{
+		if (!cgi->heroh->heroInstances[i]->type || cgi->heroh->heroInstances[i]->owner<0)
+			continue;
+		CHeroInstance * vhi = new CHeroInstance();
+		*vhi=*(cgi->heroh->heroInstances[i]);
+		if (!vhi->level)
+		{
+			vhi->exp=40+rand()%50;
+			vhi->level = 1;
+		}
+		if (vhi->level>1) ;//TODO dodac um dr, ale potrzebne los
+		if ((!vhi->primSkills.size()) || (vhi->primSkills[0]<0))
+		{
+			if (vhi->primSkills.size()<PRIMARY_SKILLS)
+				vhi->primSkills.resize(PRIMARY_SKILLS);
+			vhi->primSkills[0] = vhi->type->heroClass->initialAttack;
+			vhi->primSkills[1] = vhi->type->heroClass->initialDefence;
+			vhi->primSkills[2] = vhi->type->heroClass->initialPower;
+			vhi->primSkills[3] = vhi->type->heroClass->initialKnowledge;
+			vhi->mana = vhi->primSkills[3]*10;
+		}
+		if (!vhi->name.length())
+		{
+			vhi->name = vhi->type->name;
+		}
+		if (!vhi->biography.length())
+		{
+			vhi->biography = vhi->type->biography;
+		}
+		if (vhi->portrait < 0)
+			vhi->portrait = vhi->type->ID;
+
+		cgi->state->players[vhi->owner].heroes.push_back(vhi);
+
+	}
+	/****************************TOWNS************************************************/
+
+}
+
 int _tmain(int argc, _TCHAR* argv[])
 { 
 
-//int iErr = 0;
-//lua_State *lua = lua_open ();  // Open Lua
-//	LUA_OPEN_LIB(lua, luaopen_base);
-//	LUA_OPEN_LIB(lua, luaopen_io);
-//
-//if ((iErr = luaL_loadfile (lua, "test.lua")) == 0)
-//{
-//	
-//
-//   // Call main...
-//   if ((iErr = lua_pcall (lua, 0, LUA_MULTRET, 0)) == 0)
-//   {    luabind::open(lua);
-//   luabind::module(lua)
-//	[
-//		luabind::def("powitanie",&piszpowitanie2)
-//
-//	];
-//
-//   int ret = luabind::call_function<int>(lua, "helloWorld2");
-//      // Push the function name onto the stack
-//      lua_pushstring (lua, "helloWorld");
-//      // Function is located in the Global Table
-//      lua_gettable (lua, LUA_GLOBALSINDEX);  
-//      lua_pcall (lua, 0, 0, 0);
-//   }
-//
-//}
-//lua_close (lua);
+	//int iErr = 0;
+	//lua_State *lua = lua_open ();  // Open Lua
+	//	LUA_OPEN_LIB(lua, luaopen_base);
+	//	LUA_OPEN_LIB(lua, luaopen_io);
+
+	//if ((iErr = luaL_loadfile (lua, "test.lua")) == 0)
+	//{
+	//	
+
+	//   // Call main...
+	//   if ((iErr = lua_pcall (lua, 0, LUA_MULTRET, 0)) == 0)
+	//   {    
+	//	   luabind::open(lua);
+	//	   luabind::module(lua)
+	//		[
+	//			luabind::def("powitanie",&piszpowitanie2)
+
+	//		];
+
+	//   //int ret = luabind::call_function<int>(lua, "helloWorld2");
+
+	//	  lua_pushstring (lua, "helloWorld2");
+	//	  lua_gettable (lua, LUA_GLOBALSINDEX);  
+	//	  lua_pcall (lua, 0, 0, 0);
+
+	//	  // Push the function name onto the stack
+	//	  lua_pushstring (lua, "helloWorld");
+	//	  lua_gettable (lua, LUA_GLOBALSINDEX);  
+	//	  lua_pcall (lua, 0, 0, 0);
+	//   }
+
+	//}
+	//lua_close (lua);
 
 
 		//CBIKHandler cb;
@@ -141,9 +206,9 @@ int _tmain(int argc, _TCHAR* argv[])
 		//initializing audio
 		CMusicHandler * mush = new CMusicHandler;
 		mush->initMusics();
-		//CSndHandler snd("Heroes3.snd");
+		//CSndHandler snd("Heroes3.snd"); 
 		//snd.extract("AELMMOVE.wav","snddd.wav");
-		//audio initialized
+		//audio initialized 
 
 		/*if(Mix_PlayMusic(mush->mainMenuWoG, -1)==-1) //uncomment this fragment to have music
 		{
@@ -238,6 +303,7 @@ int _tmain(int argc, _TCHAR* argv[])
 		cgi->dobjinfo = new CDefObjInfoHandler;
 		cgi->dobjinfo->load();
 		cgi->state = new CGameState();
+		cgi->state->cb = new CCallback(cgi->state);
 		cgi->pathf = new CPathfinder();
 		THC std::cout<<"Handlers initailization: "<<tmh.getDif()<<std::endl;
 
@@ -266,23 +332,6 @@ int _tmain(int argc, _TCHAR* argv[])
 		cgi->ac = ac;
 		THC std::cout<<"Reading file: "<<tmh.getDif()<<std::endl;
 		ac->deh3m();
-		//initializing gamestate
-		for(int k=0; k<CGI->state->players.size(); ++k)
-		{
-			CGI->state->players[k].fogOfWarMap.resize(ac->map.width);
-			for(int g=0; g<ac->map.width; ++g)
-				CGI->state->players[k].fogOfWarMap[g].resize(ac->map.height);
-
-			for(int g=0; g<ac->map.width; ++g)
-				for(int h=0; h<ac->map.height; ++h)
-					CGI->state->players[k].fogOfWarMap[g][h].resize(ac->map.twoLevel+1);
-
-			for(int g=0; g<ac->map.width; ++g)
-				for(int h=0; h<ac->map.height; ++h)
-					for(int v=0; v<ac->map.twoLevel+1; ++v)
-						CGI->state->players[k].fogOfWarMap[g][h][v] = 1;
-		}
-		//gamestate nitialized (at least partially)
 		THC std::cout<<"Detecting file (together): "<<tmh.getDif()<<std::endl;
 		ac->loadDefs();
 		THC std::cout<<"Reading terrain defs: "<<tmh.getDif()<<std::endl;
@@ -292,13 +341,9 @@ int _tmain(int argc, _TCHAR* argv[])
 		THC std::cout<<"Creating mapHandler: "<<tmh.getDif()<<std::endl;
 		mh->init();
 		THC std::cout<<"Initializing mapHandler: "<<tmh.getDif()<<std::endl;
-		//SDL_Rect * sr = new SDL_Rect(); sr->h=64;sr->w=64;sr->x=0;sr->y=0;
-		//SDL_Surface * teren = mh->terrainRect(xx,yy,25,19);
-		//THC std::cout<<"Preparing terrain to display: "<<tmh.getDif()<<std::endl;
-		//SDL_BlitSurface(teren,NULL,ekran,NULL);
-		//SDL_FreeSurface(teren);
-		//SDL_UpdateRect(ekran, 0, 0, ekran->w, ekran->h);
-		//THC std::cout<<"Displaying terrain: "<<tmh.getDif()<<std::endl;
+
+		initGameState(cgi);
+		THC std::cout<<"Initializing GameState: "<<tmh.getDif()<<std::endl;
 
 
 		for (int i=0; i<cgi->scenarioOps.playerInfos.size();i++) //initializing interfaces
@@ -310,8 +355,9 @@ int _tmain(int argc, _TCHAR* argv[])
 			//	cgi->playerint.push_back(new CGlobalAI());
 			//else 
 			{
+				cgi->state->currentPlayer=i;
 				cgi->playerint.push_back(new CPlayerInterface(cgi->scenarioOps.playerInfos[i].color,i));
-				((CPlayerInterface*)(cgi->playerint[i]))->init();
+				((CPlayerInterface*)(cgi->playerint[i]))->init(cgi->state->cb);
 			}
 		}
 

+ 9 - 0
SDL_Extensions.cpp

@@ -6,6 +6,7 @@
 #include <utility>
 #include <algorithm>
 #include "CMessage.h"
+#include <boost/algorithm/string.hpp>
 
 bool isItIn(const SDL_Rect * rect, int x, int y)
 {
@@ -670,3 +671,11 @@ void CSDL_Ext::fullAlphaTransform(SDL_Surface *& src)
 	src = hlp2;
 }
 
+std::string CSDL_Ext::processStr(std::string str, std::vector<std::string> & tor)
+{
+	for (int i=0;(i<tor.size())&&(boost::find_first(str,"%s"));i++)
+	{
+		boost::replace_first(str,"%s",tor[i]);
+	}
+	return str;
+}

+ 1 - 0
SDL_Extensions.h

@@ -32,6 +32,7 @@ namespace CSDL_Ext
 	void blueToPlayers(SDL_Surface * sur, int player); //simple color substitution
 	void blueToPlayersAdv(SDL_Surface * sur, int player); //substitute blue color by another one, makes it nicer keeping nuances
 	void setPlayerColor(SDL_Surface * sur, int player); //sets correct color of flags; -1 for neutral
+	std::string processStr(std::string str, std::vector<std::string> & tor); //replaces %s in string
 };
 
 #endif // SDL_EXTENSIONS_H

+ 4 - 0
global.h

@@ -27,6 +27,9 @@ enum EHeroClasses {HERO_KNIGHT, HERO_CLERIC, HERO_RANGER, HERO_DRUID, HERO_ALCHE
 //CURPLINT gives pointer to the interface of human player which is currently making turn, 
 //LOCPLINT gives pointer to the interface which is currently showed (on this machine)
 
+#define HEROI_TYPE (typeid(CHeroInstance*))
+#define TOWNI_TYPE (typeid(CTownInstance*))
+
 
 const int F_NUMBER = 9; //factions (town types) quantity
 const int PLAYER_LIMIT = 8; //player limit per map
@@ -35,6 +38,7 @@ const int SKILL_QUANTITY=28;
 const int ARTIFACTS_QUANTITY=171;
 const int HEROES_QUANTITY=156;
 const int TERRAIN_TYPES=10;
+const int PRIMARY_SKILLS=4;
 
 #define MARK_BLOCKED_POSITIONS false
 #define MARK_VISITABLE_POSITIONS false

+ 15 - 1
hch/CAmbarCendamo.cpp

@@ -8,7 +8,7 @@
 #include "CDefObjInfoHandler.h"
 #include "../SDL_Extensions.h"
 #include "boost\filesystem.hpp"
-#include "CGameState.h"
+#include "../CGameState.h"
 #include "CLodHandler.h"
 #include <set>
 #include <iomanip>
@@ -869,6 +869,14 @@ void CAmbarCendamo::deh3m()
 						spec->power = bufor[i]; ++i;
 						spec->knowledge = bufor[i]; ++i;
 					}
+					else
+					{
+						spec->attack = -1;
+						spec->defence = -1;
+						spec->power = -1;
+						spec->knowledge = -1;
+					}
+
 				}
 				i+=16;
 				nobj->info = spec;
@@ -876,6 +884,11 @@ void CAmbarCendamo::deh3m()
 				CHeroInstance * nhi = new CHeroInstance;
 				nhi->exp = spec->experience;
 				nhi->level = CGI->heroh->level(nhi->exp);
+				nhi->primSkills.resize(PRIMARY_SKILLS);
+				nhi->primSkills[0] = spec->attack;
+				nhi->primSkills[1] = spec->defence;
+				nhi->primSkills[2] = spec->power;
+				nhi->primSkills[3] = spec->knowledge;
 				nhi->mana = spec->knowledge * 10;
 				nhi->movement = -1;
 				nhi->name = spec->name;
@@ -883,6 +896,7 @@ void CAmbarCendamo::deh3m()
 				nhi->pos = nobj->pos;
 				nhi->type = spec->type;
 				nhi->army = spec->garrison;
+				nhi->portrait = -1; // TODO: przypisywac portret
 				nhi->ourObject = nobj;
 				CGI->heroh->heroInstances.push_back(nhi);
 				break;

+ 29 - 1
hch/CHeroHandler.cpp

@@ -6,6 +6,7 @@
 #include "CGeneralTextHandler.h"
 #include "CLodHandler.h"
 #include "CAbilityHandler.h"
+#include <cmath>
 
 CHeroHandler::~CHeroHandler()
 {
@@ -342,7 +343,34 @@ unsigned int CHeroInstance::getTileCost(EterrainType & ttype, Eroad & rdtype, Er
 
 unsigned int CHeroHandler::level(unsigned int experience)
 {
-	return 0; //TODO: finish it
+	if (experience==0)
+		return 0; 
+	else if (experience<14700) //level < 10
+	{
+		return (-500+20*sqrt((float)experience+1025))/(200);
+	}
+	else if (experience<24320) //10 - 12
+	{
+		if (experience>20600)
+			return 12;
+		else if (experience>17500)
+			return 11;
+		else return 10;
+	}
+	else //>12
+	{
+		int lvl=12;
+		int xp = 24320; //xp needed for 13 lvl
+		int td = 4464; //diff 14-13
+		float mp = 1.2;
+		while (experience>xp)
+		{
+			xp+=td;
+			td*=mp;
+			lvl++;
+		}
+		return lvl;
+	}
 }
 
 unsigned int CHeroInstance::getLowestCreatureSpeed()

+ 6 - 1
hch/CHeroHandler.h

@@ -56,12 +56,17 @@ public:
 	int3 pos; //position on adventure map
 	CCreatureSet army; //army
 	int mana; // remaining spell points
+	std::vector<int> primSkills; //0-attack, 1-defence, 2-spell power, 3-knowledge
+	std::vector<std::pair<int,int> > secSkills; //first - ID of skill, second - level of skill (0 - basic, 1 - adv., 2 - expert)
 	int movement; //remaining movement points
+	bool inTownGarrison; // if hero is in town garrison 
+
 	unsigned int getTileCost(EterrainType & ttype, Eroad & rdtype, Eriver & rvtype);
 	unsigned int getLowestCreatureSpeed();
 	unsigned int getAdditiveMoveBonus();
 	unsigned float getMultiplicativeMoveBonus();
-	//TODO: artifacts, primary and secondary skills, known spells, commander, blessings, curses, morale/luck special modifiers
+
+	//TODO: artifacts, known spells, commander, blessings, curses, morale/luck special modifiers
 };
 
 class CHeroHandler

+ 4 - 0
hch/CPreGameTextHandler.cpp

@@ -446,6 +446,10 @@ void CPreGameTextHandler::loadTexts()
 	loadToIt(advNextHero.second, buf, i, 2);
 	loadToIt(advEndTurn.first, buf, i, 4);
 	loadToIt(advEndTurn.second, buf, i, 2);
+	loadToIt(advHListUp.first, buf, i, 4);
+	loadToIt(advHListUp.second, buf, i, 2);
+	loadToIt(advHListDown.first, buf, i, 4);
+	loadToIt(advHListDown.second, buf, i, 2);
 
 	loadLossConditions();
 	loadVictoryConditions();

+ 1 - 1
hch/CPreGameTextHandler.h

@@ -39,7 +39,7 @@ public:
 	std::string getDescr(std::string text);
 
 	std::pair<std::string, std::string> //first is statusbar text, second right-click help; they're all for adventure map interface
-		advKingdomOverview, advSurfaceSwitch, advQuestlog, advSleepWake, advMoveHero, advCastSpell, advAdvOptions, advSystemOptions, advNextHero, advEndTurn, //buttons
+		advKingdomOverview, advSurfaceSwitch, advQuestlog, advSleepWake, advMoveHero, advCastSpell, advAdvOptions, advSystemOptions, advNextHero, advEndTurn, advHListUp, advHListDown, //buttons
 		advWorldMap, advStatusWindow1;
 
 	void loadTexts();