2
0
Эх сурвалжийг харах

* restored objects functionalities (hopefully working)
* new file in vcmi lib: IGameCallback.cpp

Michał W. Urbańczyk 17 жил өмнө
parent
commit
4a8ae4ed9a
19 өөрчлөгдсөн 2316 нэмэгдсэн , 2103 устгасан
  1. 176 177
      CAdvmapInterface.h
  2. 4 1
      CCallback.cpp
  3. 115 17
      CGameState.cpp
  4. 230 222
      CGameState.h
  5. 3 1
      CPlayerInterface.cpp
  6. 16 4
      ChangeLog
  7. 26 79
      client/Client.cpp
  8. 87 63
      client/Client.h
  9. 1 1
      config/settings.txt
  10. 388 32
      hch/CObjectHandler.cpp
  11. 453 439
      hch/CObjectHandler.h
  12. 36 0
      lib/IGameCallback.cpp
  13. 58 54
      lib/IGameCallback.h
  14. 13 1
      lib/NetPacks.h
  15. 4 0
      lib/VCMI_lib.vcproj
  16. 129 402
      map.cpp
  17. 392 390
      map.h
  18. 18 47
      server/CGameHandler.cpp
  19. 167 173
      server/CGameHandler.h

+ 176 - 177
CAdvmapInterface.h

@@ -1,177 +1,176 @@
-#ifndef __CADVMAPINTERFACE_H__
-#define __CADVMAPINTERFACE_H__
-#include <typeinfo>
-#include "global.h"
-#include "SDL.h"
-#include "CPlayerInterface.h"
-#include <map>
-#include "AdventureMapButton.h"
-class CDefHandler;
-class CCallback;
-struct CPath;
-class CAdvMapInt;
-class CGHeroInstance;
-class CGTownInstance;
-class CHeroWindow;
-/*****************************/
-class CMinimap
-	: public ClickableL, public ClickableR, public Hoverable, public MotionInterested, public virtual CIntObject
-{
-public:
-	SDL_Surface * radar;
-	SDL_Surface * temps;
-	std::map<int,SDL_Color> colors;
-	std::map<int,SDL_Color> colorsBlocked;
-	std::vector<SDL_Surface *> map, FoW; //one bitmap for each level (terrain, Fog of War)
-	//TODO flagged buildings
-	std::string statusbarTxt, rcText;
-
-	CMinimap(bool draw=true);
-	void draw();
-	void redraw(int level=-1);// (level==-1) => redraw all levels
-	void updateRadar();
-
-	void clickRight (tribool down);
-	void clickLeft (tribool down);
-	void hover (bool on);
-	void mouseMoved (const SDL_MouseMotionEvent & sEvent);
-	void activate(); // makes button active
-	void deactivate(); // makes button inactive (but don't deletes)
-	void hideTile(const int3 &pos); //puts FoW
-	void showTile(const int3 &pos); //removes FoW
-};
-class CTerrainRect
-	:  public ClickableL, public ClickableR, public Hoverable, public MotionInterested
-{
-public:
-	int tilesw, tilesh; //width and height of terrain to blit in tiles
-	int3 curHoveredTile;
-	int moveX, moveY; //shift between actual position of screen and the one we wil blit; ranges from -31 to 31 (in pixels)
-
-	CDefHandler * arrows;
-	CTerrainRect();
-	CPath * currentPath;
-	void activate();
-	void deactivate();
-	void clickLeft(tribool down);
-	void clickRight(tribool down);
-	void hover(bool on);
-	void mouseMoved (const SDL_MouseMotionEvent & sEvent);
-	void show();
-	void showPath();
-	int3 whichTileIsIt(const int & x, const int & y); //x,y are cursor position
-	int3 whichTileIsIt(); //uses current cursor pos
-};
-class CResDataBar
-	:public ClickableR, public virtual CIntObject
-{
-public:
-	SDL_Surface * bg;
-	std::vector<std::pair<int,int> > txtpos;
-	std::string datetext;
-
-	void clickRight (tribool down);
-	void activate();
-	void deactivate();
-	CResDataBar();
-	CResDataBar(const std::string &defname, int x, int y, int offx, int offy, int resdist, int datedist);
-	~CResDataBar();
-
-	void draw();
-};
-class CInfoBar
-	:public virtual CIntObject, public TimeInterested
-{
-public:
-	CDefHandler *day, *week1, *week2, *week3, *week4;
-	SComponent * current;
-	int mode;
-	int pom;
-
-	CInfoBar();
-	~CInfoBar();
-	void newDay(int Day);
-	void showComp(SComponent * comp, int time=5000);
-	void tick();
-	void draw(const CGObjectInstance * specific=NULL); // if specific==0 function draws info about selected hero/town
-	void blitAnim(int mode);//0 - day, 1 - week
-	CDefHandler * getAnim(int mode);
-};
-/*****************************/
-class CAdvMapInt : public CMainInterface, public KeyInterested //adventure map interface
-{
-public:
-	CAdvMapInt(int Player);
-	~CAdvMapInt();
-
-	int3 position; //top left corner of visible map part
-	int player;
-
-	std::vector<CDefHandler *> gems;
-
-	bool scrollingLeft ;
-	bool scrollingRight ;
-	bool scrollingUp ;
-	bool scrollingDown ;
-	bool updateScreen, updateMinimap ;
-	unsigned char anim, animValHitCount; //animation frame
-	unsigned char heroAnim, heroAnimValHitCount; //animation frame
-
-	CMinimap minimap;
-
-
-	SDL_Surface * bg;
-	AdventureMapButton kingOverview,//- kingdom overview
-		underground,//- underground switch
-		questlog,//- questlog
-		sleepWake, //- sleep/wake hero
-		moveHero, //- move hero
-		spellbook,//- spellbook
-		advOptions, //- adventure options
-		sysOptions,//- system options
-		nextHero, //- next hero
-		endTurn;//- end turn
-	//CHeroList herolist;
-
-	CTerrainRect terrain; //visible terrain
-
-	CStatusBar statusbar;
-	CResDataBar resdatabar;
-
-	CHeroList heroList;
-	CTownList townList;
-	CInfoBar infoBar;
-
-	CHeroWindow * heroWindow;
-
-	const CArmedInstance *selection;
-
-	//fuctions binded to buttons
-	void fshowOverview();
-	void fswitchLevel();
-	void fshowQuestlog();
-	void fsleepWake();
-	void fmoveHero();
-	void fshowSpellbok();
-	void fadventureOPtions();
-	void fsystemOptions();
-	void fnextHero();
-	void fendTurn();
-
-	void activate();
-	void deactivate();
-
-	void show(SDL_Surface * to=NULL); //shows and activates adv. map interface
-	void hide(); //deactivates advmap interface
-	void update(); //redraws terrain
-
-	void select(const CArmedInstance *sel);
-	void selectionChanged();
-	void centerOn(int3 on);
-	int3 verifyPos(int3 ver);
-	void handleRightClick(std::string text, tribool down, CIntObject * client);
-	void keyPressed(const SDL_KeyboardEvent & key);
-
-
-};
-#endif // __CADVMAPINTERFACE_H__
+#ifndef __CADVMAPINTERFACE_H__
+#define __CADVMAPINTERFACE_H__
+#include <typeinfo>
+#include "global.h"
+#include "SDL.h"
+#include "CPlayerInterface.h"
+#include <map>
+#include "AdventureMapButton.h"
+class CDefHandler;
+class CCallback;
+struct CPath;
+class CAdvMapInt;
+class CGHeroInstance;
+class CGTownInstance;
+class CHeroWindow;
+/*****************************/
+class CMinimap
+	: public ClickableL, public ClickableR, public Hoverable, public MotionInterested, public virtual CIntObject
+{
+public:
+	SDL_Surface * radar;
+	SDL_Surface * temps;
+	std::map<int,SDL_Color> colors;
+	std::map<int,SDL_Color> colorsBlocked;
+	std::vector<SDL_Surface *> map, FoW; //one bitmap for each level (terrain, Fog of War)
+	std::string statusbarTxt, rcText;
+
+	CMinimap(bool draw=true);
+	void draw();
+	void redraw(int level=-1);// (level==-1) => redraw all levels
+	void updateRadar();
+
+	void clickRight (tribool down);
+	void clickLeft (tribool down);
+	void hover (bool on);
+	void mouseMoved (const SDL_MouseMotionEvent & sEvent);
+	void activate(); // makes button active
+	void deactivate(); // makes button inactive (but don't deletes)
+	void hideTile(const int3 &pos); //puts FoW
+	void showTile(const int3 &pos); //removes FoW
+};
+class CTerrainRect
+	:  public ClickableL, public ClickableR, public Hoverable, public MotionInterested
+{
+public:
+	int tilesw, tilesh; //width and height of terrain to blit in tiles
+	int3 curHoveredTile;
+	int moveX, moveY; //shift between actual position of screen and the one we wil blit; ranges from -31 to 31 (in pixels)
+
+	CDefHandler * arrows;
+	CTerrainRect();
+	CPath * currentPath;
+	void activate();
+	void deactivate();
+	void clickLeft(tribool down);
+	void clickRight(tribool down);
+	void hover(bool on);
+	void mouseMoved (const SDL_MouseMotionEvent & sEvent);
+	void show();
+	void showPath();
+	int3 whichTileIsIt(const int & x, const int & y); //x,y are cursor position
+	int3 whichTileIsIt(); //uses current cursor pos
+};
+class CResDataBar
+	:public ClickableR, public virtual CIntObject
+{
+public:
+	SDL_Surface * bg;
+	std::vector<std::pair<int,int> > txtpos;
+	std::string datetext;
+
+	void clickRight (tribool down);
+	void activate();
+	void deactivate();
+	CResDataBar();
+	CResDataBar(const std::string &defname, int x, int y, int offx, int offy, int resdist, int datedist);
+	~CResDataBar();
+
+	void draw();
+};
+class CInfoBar
+	:public virtual CIntObject, public TimeInterested
+{
+public:
+	CDefHandler *day, *week1, *week2, *week3, *week4;
+	SComponent * current;
+	int mode;
+	int pom;
+
+	CInfoBar();
+	~CInfoBar();
+	void newDay(int Day);
+	void showComp(SComponent * comp, int time=5000);
+	void tick();
+	void draw(const CGObjectInstance * specific=NULL); // if specific==0 function draws info about selected hero/town
+	void blitAnim(int mode);//0 - day, 1 - week
+	CDefHandler * getAnim(int mode);
+};
+/*****************************/
+class CAdvMapInt : public CMainInterface, public KeyInterested //adventure map interface
+{
+public:
+	CAdvMapInt(int Player);
+	~CAdvMapInt();
+
+	int3 position; //top left corner of visible map part
+	int player;
+
+	std::vector<CDefHandler *> gems;
+
+	bool scrollingLeft ;
+	bool scrollingRight ;
+	bool scrollingUp ;
+	bool scrollingDown ;
+	bool updateScreen, updateMinimap ;
+	unsigned char anim, animValHitCount; //animation frame
+	unsigned char heroAnim, heroAnimValHitCount; //animation frame
+
+	CMinimap minimap;
+
+
+	SDL_Surface * bg;
+	AdventureMapButton kingOverview,//- kingdom overview
+		underground,//- underground switch
+		questlog,//- questlog
+		sleepWake, //- sleep/wake hero
+		moveHero, //- move hero
+		spellbook,//- spellbook
+		advOptions, //- adventure options
+		sysOptions,//- system options
+		nextHero, //- next hero
+		endTurn;//- end turn
+	//CHeroList herolist;
+
+	CTerrainRect terrain; //visible terrain
+
+	CStatusBar statusbar;
+	CResDataBar resdatabar;
+
+	CHeroList heroList;
+	CTownList townList;
+	CInfoBar infoBar;
+
+	CHeroWindow * heroWindow;
+
+	const CArmedInstance *selection;
+
+	//fuctions binded to buttons
+	void fshowOverview();
+	void fswitchLevel();
+	void fshowQuestlog();
+	void fsleepWake();
+	void fmoveHero();
+	void fshowSpellbok();
+	void fadventureOPtions();
+	void fsystemOptions();
+	void fnextHero();
+	void fendTurn();
+
+	void activate();
+	void deactivate();
+
+	void show(SDL_Surface * to=NULL); //shows and activates adv. map interface
+	void hide(); //deactivates advmap interface
+	void update(); //redraws terrain
+
+	void select(const CArmedInstance *sel);
+	void selectionChanged();
+	void centerOn(int3 on);
+	int3 verifyPos(int3 ver);
+	void handleRightClick(std::string text, tribool down, CIntObject * client);
+	void keyPressed(const SDL_KeyboardEvent & key);
+
+
+};
+#endif // __CADVMAPINTERFACE_H__

+ 4 - 1
CCallback.cpp

@@ -648,7 +648,10 @@ void CCallback::setFormation(const CGHeroInstance * hero, bool tight)
 
 void CCallback::setSelection(const CArmedInstance * obj)
 {
-	*cl->serv << ui16(514) << obj->id;
+	SetSelection ss;
+	ss.player = player;
+	ss.id = obj->id;
+	*cl->serv << ui16(514) << ss;
 }
 
 void CCallback::recruitHero(const CGTownInstance *town, const CGHeroInstance *hero)

+ 115 - 17
CGameState.cpp

@@ -6,6 +6,7 @@
 #include <boost/random/linear_congruential.hpp>
 #include "hch/CDefObjInfoHandler.h"
 #include "hch/CArtHandler.h"
+#include "hch/CGeneralTextHandler.h"
 #include "hch/CTownHandler.h"
 #include "hch/CSpellHandler.h"
 #include "hch/CHeroHandler.h"
@@ -28,6 +29,79 @@ boost::rand48 ran;
 #undef max
 #endif
 
+std::string DLL_EXPORT toString(MetaString &ms)
+{
+	std::string ret;
+	for(size_t i=0;i<ms.message.size();++i)
+	{
+		if(ms.message[i]>0)
+		{
+			ret += ms.strings[ms.message[i]-1];
+		}
+		else
+		{
+			std::vector<std::string> *vec;
+			int type = ms.texts[-ms.message[i]-1].first,
+				ser = ms.texts[-ms.message[i]-1].second;
+			if(type == 5)
+			{
+				ret += VLC->arth->artifacts[ser].Name();
+				continue;
+			}
+			else if(type == 7)
+			{
+				ret += VLC->creh->creatures[ser].namePl;
+				continue;
+			}
+			else if(type == 9)
+			{
+				ret += VLC->objh->mines[ser].first;
+				continue;
+			}
+			else if(type == 10)
+			{
+				ret += VLC->objh->mines[ser].second;
+				continue;
+			}
+			else
+			{
+				switch(type)
+				{
+				case 1:
+					vec = &VLC->generaltexth->allTexts;
+					break;
+				case 2:
+					vec = &VLC->objh->xtrainfo;
+					break;
+				case 3:
+					vec = &VLC->objh->names;
+					break;
+				case 4:
+					vec = &VLC->objh->restypes;
+					break;
+				case 6:
+					vec = &VLC->generaltexth->arraytxt;
+					break;
+				case 8:
+					vec = &VLC->objh->creGens;
+					break;
+				case 11:
+					vec = &VLC->objh->advobtxt;
+					break;
+				case 12:
+					vec = &VLC->generaltexth->artifEvents;
+					break;
+				}
+				ret += (*vec)[ser];
+			}
+		}
+	}
+	for(size_t i=0; i < ms.replacements.size(); ++i)
+	{
+		ret.replace(ret.find("%s"),2,ms.replacements[i]);
+	}
+	return ret;
+}
 
 CGObjectInstance * createObject(int id, int subid, int3 pos, int owner)
 {
@@ -624,6 +698,12 @@ void CGameState::applyNL(IPack * pack)
 			h->artifWorn = sha->artifWorn;
 			break;
 		}
+	case 514:
+		{
+			SetSelection *ss = static_cast<SetSelection*>(pack);
+			players[ss->player].currentSelection = ss->id;
+			break;
+		}
 	case 515:
 		{
 			HeroRecruited *sha = static_cast<HeroRecruited*>(pack);
@@ -652,23 +732,13 @@ void CGameState::applyNL(IPack * pack)
 	case 1001://set object property
 		{
 			SetObjectProperty *p = static_cast<SetObjectProperty*>(pack);
-			if(p->what == 3) //set creatures amount
-			{
-				tlog5 << "Setting creatures amount in " << p->id << std::endl;
-				static_cast<CGCreature*>(map->objects[p->id])->army.slots[0].second = p->val;
-				break;
-			}
-			ui8 CGObjectInstance::*point;
-			switch(p->what)
-			{
-			case 1:
-				point = &CGObjectInstance::tempOwner;
-				break;
-			case 2:
-				point = &CGObjectInstance::blockVisit;
-				break;
-			}
-			map->objects[p->id]->*point = p->val;
+			setObjProperty(p);
+			break;
+		}
+	case 1002:
+		{
+			SetHoverName *shn = static_cast<SetHoverName*>(pack);
+			map->objects[shn->id]->hoverName = toString(shn->name);
 			break;
 		}
 	case 2000:
@@ -1381,6 +1451,9 @@ void CGameState::init(StartInfo * si, Mapa * map, int Seed)
 			}
 		}
 	}
+
+	for(int i=0; i<map->objects.size(); i++)
+		map->objects[i]->initObj();
 }
 
 bool CGameState::battleShootCreatureStack(int ID, int dest)
@@ -1498,6 +1571,31 @@ void CGameState::loadTownDInfos()
 		capitols[i] = new CGDefInfo(*VLC->dobjinfo->castles[i]);
 	}
 }
+
+void CGameState::setObjProperty( SetObjectProperty * p )
+{
+	CGObjectInstance *obj = map->objects[p->id];
+
+	switch(p->what)
+	{
+	case 1:
+		obj->tempOwner = p->val;
+		break;
+	case 2:
+		obj->blockVisit = p->val;
+		break;
+	case 3:
+		static_cast<CArmedInstance*>(obj)->army.slots[0].second = p->val;
+		break;
+	case 4: 
+		static_cast<CGVisitableOPH*>(obj)->visitors.insert(p->val);
+		break;
+	case 5:
+		static_cast<CGVisitableOPW*>(obj)->visited = p->val;
+		break;
+	}
+}
+
 int BattleInfo::calculateDmg(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting)
 {
 	int attackerAttackBonus = attacker->creature->attack + (attackerHero ? attackerHero->getPrimSkillLevel(0) : 0);

+ 230 - 222
CGameState.h

@@ -1,222 +1,230 @@
-#ifndef __CGAMESTATE_H__
-#define __CGAMESTATE_H__
-#include "global.h"
-#ifndef _MSC_VER
-#include "hch/CCreatureHandler.h"
-#include "lib/VCMI_Lib.h"
-#endif
-#include <set>
-#include <vector>
-#ifdef _WIN32
-#include <tchar.h>
-#else
-#include "tchar_amigaos4.h"
-#endif
-
-class CTown;
-class CScriptCallback;
-class CCallback;
-class CLuaCallback;
-class CCPPObjectScript;
-class CCreatureSet;
-class CStack;
-class CGHeroInstance;
-class CGTownInstance;
-class CArmedInstance;
-class CGDefInfo;
-class CObjectScript;
-class CGObjectInstance;
-class CCreature;
-struct Mapa;
-struct StartInfo;
-struct SDL_Surface;
-class CMapHandler;
-class CPathfinder;
-struct IPack;
-
-namespace boost
-{
-	class shared_mutex;
-}
-
-struct DLL_EXPORT PlayerState
-{
-public:
-	ui8 color, serial;
-	ui32 currentSelection; //id of hero/town, 0xffffffff if none
-	std::vector<std::vector<std::vector<ui8> > >  fogOfWarMap; //true - visible, false - hidden
-	std::vector<si32> resources;
-	std::vector<CGHeroInstance *> heroes;
-	std::vector<CGTownInstance *> towns;
-	std::vector<CGHeroInstance *> availableHeroes; //heroes available in taverns
-	PlayerState():color(-1),currentSelection(0xffffffff){};
-	template <typename Handler> void serialize(Handler &h, const int version)
-	{
-		h & color & serial & currentSelection & fogOfWarMap & resources;
-		//TODO: vectors of heroes/towns
-	}
-};
-
-struct DLL_EXPORT BattleInfo
-{
-	ui8 side1, side2;
-	si32 round, activeStack;
-	ui8 siege; //    = 0 ordinary battle    = 1 a siege with a Fort    = 2 a siege with a Citadel    = 3 a siege with a Castle
-	int3 tile; //for background and bonuses
-	si32 hero1, hero2;
-	CCreatureSet army1, army2;
-	std::vector<CStack*> stacks;
-
-	template <typename Handler> void serialize(Handler &h, const int version)
-	{
-		h & side1 & side2 & round & activeStack & siege & tile & stacks & army1 & army2 & hero1 & hero2;
-	}
-	CStack * getNextStack(); //which stack will have turn after current one
-	std::vector<CStack> getStackQueue(); //returns stack in order of their movement action
-	CStack * getStack(int stackID);
-	CStack * getStackT(int tileID);
-	void getAccessibilityMap(bool *accessibility, int stackToOmmit=-1); //send pointer to at least 187 allocated bytes
-	void getAccessibilityMapForTwoHex(bool *accessibility, bool atackerSide, int stackToOmmit=-1); //send pointer to at least 187 allocated bytes
-	void makeBFS(int start, bool*accessibility, int *predecessor, int *dists); //*accessibility must be prepared bool[187] array; last two pointers must point to the at least 187-elements int arrays - there is written result
-	std::vector<int> getPath(int start, int dest, bool*accessibility);
-	std::vector<int> getAccessibility(int stackID); //returns vector of accessible tiles (taking into account the creature range)
-
-	bool isStackBlocked(int ID); //returns true if there is neighbouring enemy stack
-	static signed char mutualPosition(int hex1, int hex2); //returns info about mutual position of given hexes (-1 - they're distant, 0 - left top, 1 - right top, 2 - right, 3 - right bottom, 4 - left bottom, 5 - left)
-	static std::vector<int> neighbouringTiles(int hex);
-	static int calculateDmg(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting); //TODO: add additional conditions and require necessary data
-	void calculateCasualties(std::set<std::pair<ui32,si32> > *casualties);
-};
-
-class DLL_EXPORT CStack
-{ 
-public:
-	ui32 ID; //unique ID of stack
-	CCreature * creature;
-	ui32 amount, baseAmount;
-	ui32 firstHPleft; //HP of first creature in stack
-	ui8 owner, slot;  //owner - player colour (255 for neutrals), slot - position in garrison (may be 255 for neutrals/called creatures)
-	ui8 attackerOwned; //if true, this stack is owned by attakcer (this one from left hand side of battle)
-	ui16 position; //position on battlefield
-	ui8 counterAttacks; //how many counter attacks can be performed more in this turn (by default set at the beginning of the round to 1)
-	si16 shots; //how many shots left
-
-	std::set<EAbilities> abilities;
-	std::set<ECombatInfo> state;
-	struct StackEffect
-	{
-		ui16 id; //spell id
-		ui8 level; //skill level
-		ui16 turnsRemain; 
-		template <typename Handler> void serialize(Handler &h, const int version)
-		{
-			h & id & level & turnsRemain;
-		}
-	};
-	std::vector<StackEffect> effects;
-
-	CStack(CCreature * C, int A, int O, int I, bool AO, int S);
-	CStack() : creature(NULL),amount(-1),owner(255), position(-1), ID(-1), attackerOwned(true), firstHPleft(-1), slot(255), baseAmount(-1), counterAttacks(1), effects(), state(), abilities(){}
-	const StackEffect * getEffect(ui16 id) const; //effect id (SP)
-	ui32 speed() const;
-	template <typename Handler> void save(Handler &h, const int version)
-	{
-		h & creature->idNumber;
-	}
-	template <typename Handler> void load(Handler &h, const int version)
-	{
-		ui32 id;
-		h & id;
-		creature = &VLC->creh->creatures[id];
-		abilities = creature->abilities;
-	}
-	template <typename Handler> void serialize(Handler &h, const int version)
-	{
-		h & ID & amount & baseAmount & firstHPleft & owner & slot & attackerOwned & position & state & counterAttacks
-			& shots;
-		if(h.saving)
-			save(h,version);
-		else
-			load(h,version);
-	}
-	bool alive() const
-	{
-		return vstd::contains(state,ALIVE);
-	}
-};
-
-struct UpgradeInfo
-{
-	int oldID; //creature to be upgraded
-	std::vector<int> newID; //possible upgrades
-	std::vector<std::set<std::pair<int,int> > > cost; // cost[upgrade_serial] -> set of pairs<resource_ID,resource_amount>
-	UpgradeInfo(){oldID = -1;};
-};
-
-class DLL_EXPORT CGameState
-{
-private:
-	StartInfo* scenarioOps;
-	ui32 seed;
-	ui8 currentPlayer; //ID of player currently having turn
-	BattleInfo *curB; //current battle
-	ui32 day; //total number of days in game
-	Mapa * map;
-	std::map<ui8,PlayerState> players; //ID <-> player state
-	std::map<int, CGDefInfo*> villages, forts, capitols; //def-info for town graphics
-	std::vector<ui32> resVals;
-
-	struct DLL_EXPORT HeroesPool
-	{
-		std::map<ui32,CGHeroInstance *> heroesPool; //[subID] - heroes available to buy; NULL if not available
-		std::map<ui32,ui8> pavailable; // [subid] -> which players can recruit hero
-
-		CGHeroInstance * pickHeroFor(bool native, int player, const CTown *town, int notThatOne=-1);
-	} hpool; //we have here all heroes available on this map that are not hired
-
-	boost::shared_mutex *mx;
-
-	CGameState();
-	~CGameState();
-	void init(StartInfo * si, Mapa * map, int Seed);
-	void loadTownDInfos();
-	void applyNL(IPack * pack);
-	void apply(IPack * pack);
-	void randomizeObject(CGObjectInstance *cur);
-	std::pair<int,int> pickObject(CGObjectInstance *obj);
-	int pickHero(int owner);
-
-	CGHeroInstance *getHero(int objid);
-	CGTownInstance *getTown(int objid);
-
-	bool battleMoveCreatureStack(int ID, int dest);
-	bool battleAttackCreatureStack(int ID, int dest);
-	bool battleShootCreatureStack(int ID, int dest);
-	int battleGetStack(int pos); //returns ID of stack at given tile
-	UpgradeInfo getUpgradeInfo(CArmedInstance *obj, int stackPos);
-	float getMarketEfficiency(int player, int mode=0);
-	std::set<int3> tilesToReveal(int3 pos, int radious, int player) const; //if player==-1 => adds all tiles in radious
-public:
-	int getDate(int mode=0) const; //mode=0 - total days in game, mode=1 - day of week, mode=2 - current week, mode=3 - current month
-	template <typename Handler> void serialize(Handler &h, const int version)
-	{
-		h & scenarioOps & seed & currentPlayer & day & map & players & resVals;
-		if(!h.saving)
-		{
-			loadTownDInfos();
-		}
-		//TODO: hero pool
-	}
-
-	friend class CCallback;
-	friend class CPathfinder;;
-	friend class CLuaCallback;
-	friend class CClient;
-	friend void initGameState(Mapa * map, CGameInfo * cgi);
-	friend class CScriptCallback;
-	friend class CMapHandler;
-	friend class CGameHandler;
-};
-
-
-#endif // __CGAMESTATE_H__
+#ifndef __CGAMESTATE_H__
+#define __CGAMESTATE_H__
+#include "global.h"
+#ifndef _MSC_VER
+#include "hch/CCreatureHandler.h"
+#include "lib/VCMI_Lib.h"
+#endif
+#include <set>
+#include <vector>
+#ifdef _WIN32
+#include <tchar.h>
+#else
+#include "tchar_amigaos4.h"
+#endif
+
+class CTown;
+class CScriptCallback;
+class CCallback;
+class CLuaCallback;
+class CCPPObjectScript;
+class CCreatureSet;
+class CStack;
+class CGHeroInstance;
+class CGTownInstance;
+class CArmedInstance;
+class CGDefInfo;
+class CObjectScript;
+class CGObjectInstance;
+class CCreature;
+struct Mapa;
+struct StartInfo;
+struct SDL_Surface;
+class CMapHandler;
+class CPathfinder;
+struct IPack;
+struct SetObjectProperty;
+struct MetaString;
+
+
+std::string DLL_EXPORT toString(MetaString &ms);
+
+
+namespace boost
+{
+	class shared_mutex;
+}
+
+struct DLL_EXPORT PlayerState
+{
+public:
+	ui8 color, serial;
+	ui32 currentSelection; //id of hero/town, 0xffffffff if none
+	std::vector<std::vector<std::vector<ui8> > >  fogOfWarMap; //true - visible, false - hidden
+	std::vector<si32> resources;
+	std::vector<CGHeroInstance *> heroes;
+	std::vector<CGTownInstance *> towns;
+	std::vector<CGHeroInstance *> availableHeroes; //heroes available in taverns
+	PlayerState():color(-1),currentSelection(0xffffffff){};
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & color & serial & currentSelection & fogOfWarMap & resources;
+		//TODO: vectors of heroes/towns
+	}
+};
+
+struct DLL_EXPORT BattleInfo
+{
+	ui8 side1, side2;
+	si32 round, activeStack;
+	ui8 siege; //    = 0 ordinary battle    = 1 a siege with a Fort    = 2 a siege with a Citadel    = 3 a siege with a Castle
+	int3 tile; //for background and bonuses
+	si32 hero1, hero2;
+	CCreatureSet army1, army2;
+	std::vector<CStack*> stacks;
+
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & side1 & side2 & round & activeStack & siege & tile & stacks & army1 & army2 & hero1 & hero2;
+	}
+	CStack * getNextStack(); //which stack will have turn after current one
+	std::vector<CStack> getStackQueue(); //returns stack in order of their movement action
+	CStack * getStack(int stackID);
+	CStack * getStackT(int tileID);
+	void getAccessibilityMap(bool *accessibility, int stackToOmmit=-1); //send pointer to at least 187 allocated bytes
+	void getAccessibilityMapForTwoHex(bool *accessibility, bool atackerSide, int stackToOmmit=-1); //send pointer to at least 187 allocated bytes
+	void makeBFS(int start, bool*accessibility, int *predecessor, int *dists); //*accessibility must be prepared bool[187] array; last two pointers must point to the at least 187-elements int arrays - there is written result
+	std::vector<int> getPath(int start, int dest, bool*accessibility);
+	std::vector<int> getAccessibility(int stackID); //returns vector of accessible tiles (taking into account the creature range)
+
+	bool isStackBlocked(int ID); //returns true if there is neighbouring enemy stack
+	static signed char mutualPosition(int hex1, int hex2); //returns info about mutual position of given hexes (-1 - they're distant, 0 - left top, 1 - right top, 2 - right, 3 - right bottom, 4 - left bottom, 5 - left)
+	static std::vector<int> neighbouringTiles(int hex);
+	static int calculateDmg(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting); //TODO: add additional conditions and require necessary data
+	void calculateCasualties(std::set<std::pair<ui32,si32> > *casualties);
+};
+
+class DLL_EXPORT CStack
+{ 
+public:
+	ui32 ID; //unique ID of stack
+	CCreature * creature;
+	ui32 amount, baseAmount;
+	ui32 firstHPleft; //HP of first creature in stack
+	ui8 owner, slot;  //owner - player colour (255 for neutrals), slot - position in garrison (may be 255 for neutrals/called creatures)
+	ui8 attackerOwned; //if true, this stack is owned by attakcer (this one from left hand side of battle)
+	ui16 position; //position on battlefield
+	ui8 counterAttacks; //how many counter attacks can be performed more in this turn (by default set at the beginning of the round to 1)
+	si16 shots; //how many shots left
+
+	std::set<EAbilities> abilities;
+	std::set<ECombatInfo> state;
+	struct StackEffect
+	{
+		ui16 id; //spell id
+		ui8 level; //skill level
+		ui16 turnsRemain; 
+		template <typename Handler> void serialize(Handler &h, const int version)
+		{
+			h & id & level & turnsRemain;
+		}
+	};
+	std::vector<StackEffect> effects;
+
+	CStack(CCreature * C, int A, int O, int I, bool AO, int S);
+	CStack() : creature(NULL),amount(-1),owner(255), position(-1), ID(-1), attackerOwned(true), firstHPleft(-1), slot(255), baseAmount(-1), counterAttacks(1), effects(), state(), abilities(){}
+	const StackEffect * getEffect(ui16 id) const; //effect id (SP)
+	ui32 speed() const;
+	template <typename Handler> void save(Handler &h, const int version)
+	{
+		h & creature->idNumber;
+	}
+	template <typename Handler> void load(Handler &h, const int version)
+	{
+		ui32 id;
+		h & id;
+		creature = &VLC->creh->creatures[id];
+		abilities = creature->abilities;
+	}
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & ID & amount & baseAmount & firstHPleft & owner & slot & attackerOwned & position & state & counterAttacks
+			& shots;
+		if(h.saving)
+			save(h,version);
+		else
+			load(h,version);
+	}
+	bool alive() const
+	{
+		return vstd::contains(state,ALIVE);
+	}
+};
+
+struct UpgradeInfo
+{
+	int oldID; //creature to be upgraded
+	std::vector<int> newID; //possible upgrades
+	std::vector<std::set<std::pair<int,int> > > cost; // cost[upgrade_serial] -> set of pairs<resource_ID,resource_amount>
+	UpgradeInfo(){oldID = -1;};
+};
+
+class DLL_EXPORT CGameState
+{
+private:
+	StartInfo* scenarioOps;
+	ui32 seed;
+	ui8 currentPlayer; //ID of player currently having turn
+	BattleInfo *curB; //current battle
+	ui32 day; //total number of days in game
+	Mapa * map;
+	std::map<ui8,PlayerState> players; //ID <-> player state
+	std::map<int, CGDefInfo*> villages, forts, capitols; //def-info for town graphics
+	std::vector<ui32> resVals;
+
+	struct DLL_EXPORT HeroesPool
+	{
+		std::map<ui32,CGHeroInstance *> heroesPool; //[subID] - heroes available to buy; NULL if not available
+		std::map<ui32,ui8> pavailable; // [subid] -> which players can recruit hero
+
+		CGHeroInstance * pickHeroFor(bool native, int player, const CTown *town, int notThatOne=-1);
+	} hpool; //we have here all heroes available on this map that are not hired
+
+	boost::shared_mutex *mx;
+
+	CGameState();
+	~CGameState();
+	void init(StartInfo * si, Mapa * map, int Seed);
+	void loadTownDInfos();
+	void applyNL(IPack * pack);
+
+	void setObjProperty( SetObjectProperty * p );
+	void apply(IPack * pack);
+	void randomizeObject(CGObjectInstance *cur);
+	std::pair<int,int> pickObject(CGObjectInstance *obj);
+	int pickHero(int owner);
+
+	CGHeroInstance *getHero(int objid);
+	CGTownInstance *getTown(int objid);
+
+	bool battleMoveCreatureStack(int ID, int dest);
+	bool battleAttackCreatureStack(int ID, int dest);
+	bool battleShootCreatureStack(int ID, int dest);
+	int battleGetStack(int pos); //returns ID of stack at given tile
+	UpgradeInfo getUpgradeInfo(CArmedInstance *obj, int stackPos);
+	float getMarketEfficiency(int player, int mode=0);
+	std::set<int3> tilesToReveal(int3 pos, int radious, int player) const; //if player==-1 => adds all tiles in radious
+public:
+	int getDate(int mode=0) const; //mode=0 - total days in game, mode=1 - day of week, mode=2 - current week, mode=3 - current month
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & scenarioOps & seed & currentPlayer & day & map & players & resVals;
+		if(!h.saving)
+		{
+			loadTownDInfos();
+		}
+		//TODO: hero pool
+	}
+
+	friend class CCallback;
+	friend class CPathfinder;;
+	friend class CLuaCallback;
+	friend class CClient;
+	friend void initGameState(Mapa * map, CGameInfo * cgi);
+	friend class IGameCallback;
+	friend class CMapHandler;
+	friend class CGameHandler;
+};
+
+
+#endif // __CGAMESTATE_H__

+ 3 - 1
CPlayerInterface.cpp

@@ -1076,6 +1076,8 @@ void CPlayerInterface::yourTurn()
 
 	adventureInt->infoBar.newDay(cb->getDate(1));
 
+	//select first hero if available.
+	//TODO: check if hero is slept
 	if(adventureInt->heroList.items.size())
 		adventureInt->select(adventureInt->heroList.items[0].first);
 	else
@@ -1193,7 +1195,7 @@ void CPlayerInterface::heroMoved(const HeroMoveDetails & details)
 	if(adventureInt == curint)
 		adventureInt->minimap.draw();
 
-	if(details.style)
+	if(details.style>0)
 		return;
 
 	//initializing objects and performing first step of move

+ 16 - 4
ChangeLog

@@ -1,12 +1,14 @@
-0.64 -> 0.next (???)  [as for r651]
+0.64 -> 0.next (???)  [as for r672]
 GENERAL:
 * move some settings to the config/settings.txt file
 * partial support for new screen resolutions
 * /Data and /Sprites subfolders can be used for adding files not present in .lod archives 
 * fixed crashbug occuring when hero levelled above 15 level
+* support for non-standard screen resolutions
 
 ADVENTURE INTERFACE:
 * added water animation
+* speed of scrolling map and hero movement can be adjusted in the System Options Window
 
 TOWN INTERFACE:
 * the scroll tab won't remain hanged to our mouse position if we move the mouse away from the scroll bar
@@ -18,6 +20,9 @@ BATTLES
 * war machines support partially added
 * queue of stacks narrowed
 * spell effect animation displaying improvements
+* positive/negative spells cannot be cast on hostile/our stacks
+* showing spell effects affecting stack in creature info window
+* more appropriate coloring of stack amount box when stack is affected by a spell 
 * several reported bugs fixed
 * new spells supported:
 	a) Haste 
@@ -26,12 +31,19 @@ BATTLES
 	d) slow 
 	e) implosion
 	f) forgetfulness
+	g) shield
+	h) air shield
+	i) bless
+	j) curse
+	k) bloodlust
+	l) weakness
+	m) stone skin
+	n) prayer 	
+	o) frenzy	
 	
-AI:
+AI PLAYER:
 * Genius AI (first VCMI AI) will control computer creatures during the combat.
 
-GENERAL:
-* started making external settings file (will be used for support for non 800x600 screen resolutions) 
 And a lot of minor fixes
 
 0.63 -> 0.64 (Nov 01 2008)

+ 26 - 79
client/Client.cpp

@@ -18,82 +18,9 @@
 #include <boost/foreach.hpp>
 #include <boost/thread.hpp>
 #include <boost/thread/shared_mutex.hpp>
+#include <sstream>
 CSharedCond<std::set<IPack*> > mess(new std::set<IPack*>);
 
-std::string toString(MetaString &ms)
-{
-	std::string ret;
-	for(size_t i=0;i<ms.message.size();++i)
-	{
-		if(ms.message[i]>0)
-		{
-			ret += ms.strings[ms.message[i]-1];
-		}
-		else
-		{
-			std::vector<std::string> *vec;
-			int type = ms.texts[-ms.message[i]-1].first,
-				ser = ms.texts[-ms.message[i]-1].second;
-			if(type == 5)
-			{
-				ret += CGI->arth->artifacts[ser].Name();
-				continue;
-			}
-			else if(type == 7)
-			{
-				ret += CGI->creh->creatures[ser].namePl;
-				continue;
-			}
-			else if(type == 9)
-			{
-				ret += CGI->objh->mines[ser].first;
-				continue;
-			}
-			else if(type == 10)
-			{
-				ret += CGI->objh->mines[ser].second;
-				continue;
-			}
-			else
-			{
-				switch(type)
-				{
-				case 1:
-					vec = &CGI->generaltexth->allTexts;
-					break;
-				case 2:
-					vec = &CGI->objh->xtrainfo;
-					break;
-				case 3:
-					vec = &CGI->objh->names;
-					break;
-				case 4:
-					vec = &CGI->objh->restypes;
-					break;
-				case 6:
-					vec = &CGI->generaltexth->arraytxt;
-					break;
-				case 8:
-					vec = &CGI->objh->creGens;
-					break;
-				case 11:
-					vec = &CGI->objh->advobtxt;
-					break;
-				case 12:
-					vec = &CGI->generaltexth->artifEvents;
-					break;
-				}
-				ret += (*vec)[ser];
-			}
-		}
-	}
-	for(size_t i=0; i < ms.replacements.size(); ++i)
-	{
-		ret.replace(ret.find("%s"),2,ms.replacements[i]);
-	}
-	return ret;
-}
-
 CClient::CClient(void)
 {
 }
@@ -101,6 +28,7 @@ CClient::CClient(CConnection *con, StartInfo *si)
 	:serv(con)
 {		
 	timeHandler tmh;
+	IObjectInterface::cb = this;
 	CGI->state = new CGameState();
 	tlog0 <<"\tGamestate: "<<tmh.getDif()<<std::endl;
 	CConnection &c(*con);
@@ -449,6 +377,14 @@ void CClient::process(int what)
 			tlog4 << "Player "<<(int)color<<" sends a message: " << message << std::endl;
 			break;
 		}
+	case 514:
+		{
+			SetSelection ss;
+			*serv >> ss;
+			tlog5 << "Selection of player " << (int)ss.player << " set to " << ss.id << std::endl;
+			gs->apply(&ss);
+			break;
+		}
 	case 515:
 		{
 			HeroRecruited hr;
@@ -475,9 +411,7 @@ void CClient::process(int what)
 			SetHoverName shn;
 			*serv >> shn;
 			tlog5 << "Setting a name of " << shn.id <<" object to "<< toString(shn.name) <<std::endl;
-			gs->mx->lock();
-			//gs->map->objects[shn.id]->hoverName = toString(shn.name);
-			gs->mx->unlock();
+			gs->apply(&shn);
 			break;
 		}
 	case 2000:
@@ -668,8 +602,11 @@ void CClient::process(int what)
 	case 9999:
 		break;
 	default:
-		throw std::string("Not supported server message!");
-		break;
+		{
+			std::ostringstream ex;
+			ex << "Not supported server message (type=" << what <<")";
+			throw ex.str();
+		}
 	}
 }
 void CClient::waitForMoveAndSend(int color)
@@ -709,3 +646,13 @@ void CClient::save(const std::string & fname)
 {
 	*serv << ui16(98) << fname;
 }
+
+int CClient::getCurrentPlayer()
+{
+	return gs->currentPlayer;
+}
+
+int CClient::getSelectedHero()
+{
+	return IGameCallback::getSelectedHero(getCurrentPlayer())->id;
+}

+ 87 - 63
client/Client.h

@@ -1,63 +1,87 @@
-#ifndef __CLIENT_H__
-#define __CLIENT_H__
-
-
-#include "../global.h"
-#include <boost/thread.hpp>
-struct StartInfo;
-class CGameState;
-class CGameInterface;
-class CConnection;
-class CCallback;
-class CClient;
-void processCommand(const std::string &message, CClient *&client);
-namespace boost
-{
-	class mutex;
-	class condition_variable;
-}
-
-template <typename T>
-struct CSharedCond
-{
-	boost::mutex *mx;
-	boost::condition_variable *cv;
-	T *res;
-	CSharedCond(T*R)
-	{
-		res = R;
-		mx = new boost::mutex;
-		cv = new boost::condition_variable;
-	}
-	~CSharedCond()
-	{
-		delete res;
-		delete mx;
-		delete cv;
-	}
-};
-
-class CClient
-{
-	CCallback *cb;
-	CGameState *gs;
-	std::map<ui8,CGameInterface *> playerint;
-	CConnection *serv;
-
-	void waitForMoveAndSend(int color);
-public:
-	CClient(void);
-	CClient(CConnection *con, StartInfo *si);
-	~CClient(void);
-
-	void close();
-	void save(const std::string & fname);
-	void process(int what);
-	void run();
-
-	friend class CCallback; //handling players actions
-	friend class CScriptCallback; //for objects scripts
-	friend void processCommand(const std::string &message, CClient *&client); //handling console
-};
-
-#endif // __CLIENT_H__
+#ifndef __CLIENT_H__
+#define __CLIENT_H__
+
+
+#include "../global.h"
+#include <boost/thread.hpp>
+#include "../lib/IGameCallback.h"
+struct StartInfo;
+class CGameState;
+class CGameInterface;
+class CConnection;
+class CCallback;
+class CClient;
+void processCommand(const std::string &message, CClient *&client);
+namespace boost
+{
+	class mutex;
+	class condition_variable;
+}
+
+template <typename T>
+struct CSharedCond
+{
+	boost::mutex *mx;
+	boost::condition_variable *cv;
+	T *res;
+	CSharedCond(T*R)
+	{
+		res = R;
+		mx = new boost::mutex;
+		cv = new boost::condition_variable;
+	}
+	~CSharedCond()
+	{
+		delete res;
+		delete mx;
+		delete cv;
+	}
+};
+
+class CClient : public IGameCallback
+{
+	CCallback *cb;
+	std::map<ui8,CGameInterface *> playerint;
+	CConnection *serv;
+
+	void waitForMoveAndSend(int color);
+public:
+	CClient(void);
+	CClient(CConnection *con, StartInfo *si);
+	~CClient(void);
+
+	void close();
+	void save(const std::string & fname);
+	void process(int what);
+	void run();
+	//////////////////////////////////////////////////////////////////////////
+	//from IGameCallback
+	int getCurrentPlayer();
+	int getSelectedHero();
+
+	//not working yet, will be implement somewhen later with support for local-sim-based gameplay
+	void changeSpells(int hid, bool give, const std::set<ui32> &spells){};
+	void removeObject(int objid){};
+	void setBlockVis(int objid, bool bv){};
+	void setOwner(int objid, ui8 owner){};
+	void setHoverName(int objid, MetaString * name){};
+	void setObjProperty(int objid, int prop, int val){};
+	void changePrimSkill(int ID, int which, int val, bool abs=false){};
+	void showInfoDialog(InfoWindow *iw){};
+	void showYesNoDialog(YesNoDialog *iw, const CFunctionList<void(ui32)> &callback){};
+	void showSelectionDialog(SelectionDialog *iw, const CFunctionList<void(ui32)> &callback){}; //returns question id
+	void giveResource(int player, int which, int val){};
+	void showCompInfo(ShowInInfobox * comp){};
+	void heroVisitCastle(int obj, int heroID){};
+	void stopHeroVisitCastle(int obj, int heroID){};
+	void giveHeroArtifact(int artid, int hid, int position){}; //pos==-1 - first free slot in backpack=0; pos==-2 - default if available or backpack
+	void startBattleI(const CCreatureSet * army1, const CCreatureSet * army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, boost::function<void(BattleResult*)> cb){}; //use hero=NULL for no hero
+	void startBattleI(int heroID, CCreatureSet army, int3 tile, boost::function<void(BattleResult*)> cb){}; //for hero<=>neutral army
+	void setAmount(int objid, ui32 val){};
+	void moveHero(int hid, int3 pos, bool instant){};
+	//////////////////////////////////////////////////////////////////////////
+	friend class CCallback; //handling players actions
+	friend void processCommand(const std::string &message, CClient *&client); //handling console
+};
+
+#endif // __CLIENT_H__

+ 1 - 1
config/settings.txt

@@ -3,7 +3,7 @@
 clientSettings
 {
 	port=3030;
-	resolution=800x600; // format: WxH
+	resolution=1024x768; // format: WxH
 	bpp=24; // bpp!=24 => problems
 	fullscreen=0; //0 - windowed mode, 1 - fullscreen
 	server=127.0.0.1; //use 127.0.0.1 for localhost

+ 388 - 32
hch/CObjectHandler.cpp

@@ -17,19 +17,20 @@
 #include "../CGameState.h"
 #include "../lib/NetPacks.h"
 
+std::map<int,std::map<int, std::vector<int> > > CGTeleport::objs;
 IGameCallback * IObjectInterface::cb = NULL;
 DLL_EXPORT void loadToIt(std::string &dest, std::string &src, int &iter, int mode);
 extern CLodHandler * bitmaph;
 extern boost::rand48 ran;
 
 
-void IObjectInterface::onHeroVisit(const CGHeroInstance * h) 
+void IObjectInterface::onHeroVisit(const CGHeroInstance * h) const 
 {};
 
-void IObjectInterface::onHeroLeave(const CGHeroInstance * h) 
+void IObjectInterface::onHeroLeave(const CGHeroInstance * h) const 
 {};
 
-void IObjectInterface::newTurn () 
+void IObjectInterface::newTurn () const
 {};
 
 IObjectInterface::~IObjectInterface()
@@ -645,7 +646,7 @@ bool CGHeroInstance::needsLastStack() const
 {
 	return true;
 }
-void CGHeroInstance::onHeroVisit(const CGHeroInstance * h)
+void CGHeroInstance::onHeroVisit(const CGHeroInstance * h) const
 {
 	//TODO: check for allies
 	if(tempOwner == h->tempOwner) //our hero
@@ -673,7 +674,7 @@ const std::string & CGHeroInstance::getBiography() const
 }
 void CGHeroInstance::initObj()
 {
-	cb->setBlockVis(id,true);
+	blockVisit = true;
 }
 int CGTownInstance::getSightDistance() const //returns sight distance
 {
@@ -795,7 +796,7 @@ bool CGTownInstance::needsLastStack() const
 	else return false;
 }
 
-void CGTownInstance::onHeroVisit(const CGHeroInstance * h)
+void CGTownInstance::onHeroVisit(const CGHeroInstance * h) const
 {
 	if(getOwner() != h->getOwner())
 	{
@@ -804,7 +805,7 @@ void CGTownInstance::onHeroVisit(const CGHeroInstance * h)
 	cb->heroVisitCastle(id,h->id);
 }
 
-void CGTownInstance::onHeroLeave(const CGHeroInstance * h)
+void CGTownInstance::onHeroLeave(const CGHeroInstance * h) const
 {
 	cb->stopHeroVisitCastle(id,h->id);
 }
@@ -813,28 +814,16 @@ void CGTownInstance::initObj()
 {
 	MetaString ms;
 	ms << name << ", " << town->Name();
-	cb->setHoverName(id,&ms);
+	hoverName = toString(ms);
 }
 
-//std::vector<int> CVisitableOPH::yourObjects()
-//{
-//	std::vector<int> ret;
-//	ret.push_back(51);//camp 
-//	ret.push_back(23);//tower
-//	ret.push_back(61);//axis
-//	ret.push_back(32);//garden
-//	ret.push_back(100);//stone
-//	ret.push_back(102);//tree
-//	return ret;
-//}
-
-void CGVisitableOPH::onHeroVisit( const CGHeroInstance * h )
+void CGVisitableOPH::onHeroVisit( const CGHeroInstance * h ) const
 {
 	if(visitors.find(h->id)==visitors.end())
 	{
 		onNAHeroVisit(h->id, false);
 		if(ID != 102) //not tree
-			visitors.insert(h->id);
+			cb->setObjProperty(id,4,h->id); //add to the visitors
 	}
 	else
 	{
@@ -850,16 +839,16 @@ void CGVisitableOPH::initObj()
 		ttype = -1;
 }
 
-void CGVisitableOPH::treeSelected( int heroID, int resType, int resVal, int expVal, ui32 result )
+void CGVisitableOPH::treeSelected( int heroID, int resType, int resVal, int expVal, ui32 result ) const
 {
 	if(result==0) //player agreed to give res for exp
 	{
 		cb->giveResource(cb->getOwner(heroID),resType,-resVal); //take resource
 		cb->changePrimSkill(heroID,4,expVal); //give exp
-		visitors.insert(heroID); //set state to visited
+		cb->setObjProperty(id,4,heroID); //add to the visitors
 	}
 }
-void CGVisitableOPH::onNAHeroVisit(int heroID, bool alreadyVisited)
+void CGVisitableOPH::onNAHeroVisit(int heroID, bool alreadyVisited) const
 {
 	int id=0, subid=0, ot=0, val=1;
 	switch(ID)
@@ -925,7 +914,7 @@ void CGVisitableOPH::onNAHeroVisit(int heroID, bool alreadyVisited)
 				val = VLC->heroh->reqExp(h->level+val) - VLC->heroh->reqExp(h->level);
 				if(!ttype)
 				{
-					visitors.insert(heroID);
+					cb->setObjProperty(id,4,heroID); //add to the visitors
 					InfoWindow iw;
 					iw.components.push_back(Component(id,subid,1,0));
 					iw.player = cb->getOwner(heroID);
@@ -1010,9 +999,10 @@ const std::string & CGVisitableOPH::getHoverText() const
 	const CGHeroInstance *h = cb->getSelectedHero(cb->getCurrentPlayer());
 	if(h)
 	{
+		hoverName += ' ';
 		hoverName += (vstd::contains(visitors,h->id)) 
-						? (VLC->generaltexth->allTexts[353])  //not visited
-						: ( VLC->generaltexth->allTexts[352]); //visited
+							? (VLC->generaltexth->allTexts[352])  //visited
+							: ( VLC->generaltexth->allTexts[353]); //not visited
 	}
 	return hoverName;
 }
@@ -1022,13 +1012,12 @@ bool CArmedInstance::needsLastStack() const
 	return false;
 }
 
-void CGCreature::onHeroVisit( const CGHeroInstance * h )
+void CGCreature::onHeroVisit( const CGHeroInstance * h ) const
 {
-	army.slots[0].first = subID;
 	cb->startBattleI(h->id,army,pos,boost::bind(&CGCreature::endBattle,this,_1));
 }
 
-void CGCreature::endBattle( BattleResult *result )
+void CGCreature::endBattle( BattleResult *result ) const
 {
 	if(result->winner==0)
 	{
@@ -1040,12 +1029,19 @@ void CGCreature::endBattle( BattleResult *result )
 		for(std::set<std::pair<ui32,si32> >::iterator i=result->casualties[1].begin(); i!=result->casualties[1].end(); i++)
 			if(i->first == subID)
 				killedAmount += i->second;
-		cb->setAmount(id, army.slots[0].second - killedAmount);
+		cb->setAmount(id, army.slots.find(0)->second.second - killedAmount);	
+		
+		MetaString ms;
+		int pom = CCreature::getQuantityID(army.slots.find(0)->second.second);
+		pom = 174 + 3*pom + 1;
+		ms << std::pair<ui8,ui32>(6,pom) << " " << std::pair<ui8,ui32>(7,subID);
+		cb->setHoverName(id,&ms);
 	}
 }
 
 void CGCreature::initObj()
 {
+	army.slots[0].first = subID;
 	si32 &amount = army.slots[0].second;
 	CCreature &c = VLC->creh->creatures[subID];
 	if(!amount)
@@ -1053,4 +1049,364 @@ void CGCreature::initObj()
 			amount = c.ammMax;
 		else
 			amount = c.ammMin + (ran() % (c.ammMax - c.ammMin));
+
+	MetaString ms;
+	int pom = CCreature::getQuantityID(army.slots.find(0)->second.second);
+	pom = 174 + 3*pom + 1;
+	ms << std::pair<ui8,ui32>(6,pom) << " " << std::pair<ui8,ui32>(7,subID);
+	hoverName = toString(ms);
+}
+
+void CGMine::onHeroVisit( const CGHeroInstance * h ) const
+{
+	if(subID == 7) //TODO: support for abandoned mine
+		return;
+
+	if(h->tempOwner == tempOwner) //we're visiting our mine
+		return; //TODO: leaving garrison
+
+	//TODO: check if mine is guarded
+	cb->setOwner(id,h->tempOwner); //not ours? flag it!
+
+	MetaString ms;
+	ms << std::pair<ui8,ui32>(9,subID) << " (" << std::pair<ui8,ui32>(6,23+h->tempOwner) << ")";
+	cb->setHoverName(id,&ms);
+
+	int vv=1; //amount of resource per turn	
+	if (subID==0 || subID==2)
+		vv++;
+	else if (subID==6)
+		vv = 1000;
+
+	InfoWindow iw;
+	iw.text << std::pair<ui8,ui32>(10,subID);
+	iw.player = h->tempOwner;
+	iw.components.push_back(Component(2,subID,vv,-1));
+	cb->showInfoDialog(&iw);
+}
+
+void CGMine::newTurn() const
+{
+	if (tempOwner == NEUTRAL_PLAYER)
+		return;
+	int vv = 1;
+	if (subID==0 || subID==2)
+		vv++;
+	else if (subID==6)
+		vv = 1000;
+	cb->giveResource(tempOwner,subID,vv);
+}
+
+void CGMine::initObj()
+{
+	MetaString ms;
+	ms << std::pair<ui8,ui32>(9,subID);
+	if(tempOwner >= PLAYER_LIMIT)
+		tempOwner = NEUTRAL_PLAYER;	
+	else
+		ms << " (" << std::pair<ui8,ui32>(6,23+tempOwner) << ")";
+	hoverName = toString(ms);
+}
+
+void CGResource::initObj()
+{
+	blockVisit = true;
+	hoverName = VLC->objh->restypes[subID];
+
+	if(!amount)
+	{
+		switch(subID)
+		{
+		case 6:
+			amount = 500 + (rand()%6)*100;
+			break;
+		case 0: case 2:
+			amount = 6 + (rand()%5);
+			break;
+		default:
+			amount = 3 + (rand()%3);
+			break;
+		}
+	}
+}
+
+void CGResource::onHeroVisit( const CGHeroInstance * h ) const
+{
+	//TODO: handle guards (when battles are finished)
+	if(message.length())
+	{
+		InfoWindow iw;
+		iw.player = h->tempOwner;
+		iw.text << message;
+		cb->showInfoDialog(&iw);
+	}
+
+	cb->giveResource(h->tempOwner,subID,amount);
+
+	ShowInInfobox sii;
+	sii.player = h->tempOwner;
+	sii.c = Component(2,subID,amount,0);
+	sii.text << std::pair<ui8,ui32>(11,113);
+	sii.text.replacements.push_back(VLC->objh->restypes[subID]);
+	cb->showCompInfo(&sii);
+	cb->removeObject(id);
+}
+
+void CGVisitableOPW::newTurn() const
+{
+	if (cb->getDate(1)==1) //first day of week
+	{
+		cb->setObjProperty(id,5,false);
+		MetaString ms; //set text to "not visited"
+		ms << std::pair<ui8,ui32>(3,ID) << " " << std::pair<ui8,ui32>(1,353);
+		cb->setHoverName(id,&ms);
+	}
+}
+
+void CGVisitableOPW::onHeroVisit( const CGHeroInstance * h ) const
+{
+	int mid;
+	switch (ID)
+	{
+	case 55:
+		mid = 92;
+		break;
+	case 112:
+		mid = 170;
+		break;
+	case 109:
+		mid = 164;
+		break;
+	}
+	if (visited)
+	{
+		if (ID!=112)
+			mid++;
+		else 
+			mid--;
+
+		InfoWindow iw;
+		iw.player = h->tempOwner;
+		iw.text << std::pair<ui8,ui32>(11,mid);
+		cb->showInfoDialog(&iw);
+	}
+	else
+	{
+		int type, sub, val;
+		type = 2;
+		switch (ID)
+		{
+		case 55:
+			if (rand()%2)
+			{
+				sub = 5;
+				val = 5;
+			}
+			else
+			{
+				sub = 6;
+				val = 500;
+			}
+			break;
+		case 112:
+			mid = 170;
+			sub = (rand() % 5) + 1;
+			val = (rand() % 4) + 3;
+			break;
+		case 109:
+			mid = 164;
+			sub = 6;
+			if(cb->getDate(2)<2)
+				val = 500;
+			else
+				val = 1000;
+		}
+		cb->giveResource(h->tempOwner,sub,val);
+		InfoWindow iw;
+		iw.player = h->tempOwner;
+		iw.components.push_back(Component(type,sub,val,0));
+		iw.text << std::pair<ui8,ui32>(11,mid);
+		cb->showInfoDialog(&iw);
+		cb->setObjProperty(id,5,true);
+		MetaString ms; //set text to "visited"
+		ms << std::pair<ui8,ui32>(3,ID) << " " << std::pair<ui8,ui32>(1,352);
+		cb->setHoverName(id,&ms);
+	}
+}
+
+void CGTeleport::onHeroVisit( const CGHeroInstance * h ) const
+{
+	int destinationid=-1;
+	switch(ID)
+	{
+	case 43: //one way - find correspong exit monolith
+		if(vstd::contains(objs,44) && vstd::contains(objs[44],subID) && objs[44][subID].size())
+			destinationid = objs[44][subID][rand()%objs[44][subID].size()];
+		else
+			tlog2 << "Cannot find corresponding exit monolith for "<< id << std::endl;
+		break;
+	case 45: //two way monolith - pick any other one
+		if(vstd::contains(objs,45) && vstd::contains(objs[45],subID) && objs[45][subID].size()>1)
+			while ((destinationid = objs[45][subID][rand()%objs[45][subID].size()])==id);
+		else
+			tlog2 << "Cannot find corresponding exit monolith for "<< id << std::endl;
+		break;
+	case 103: //find nearest subterranean gate on the other level
+		{
+			std::pair<int,double> best(-1,150000); //pair<id,dist>
+			for(int i=0; i<objs[103][0].size(); i++)
+			{
+				if(cb->getObj(objs[103][0][i])->pos.z == pos.z) continue; //gates on our level are not interesting
+				double hlp = cb->getObj(objs[103][0][i])->pos.dist2d(pos);
+				if(hlp<best.second)
+				{
+					best.first = objs[103][0][i];
+					best.second = hlp;
+				}
+			}
+			if(best.first<0)
+				return;
+			else 
+				destinationid = best.first;
+			break;
+		}
+	}
+	if(destinationid < 0)
+	{
+		tlog2 << "Cannot find exit... :( \n";
+		return;
+	}
+	cb->moveHero(h->id,
+				(ID!=103)
+					? (CGHeroInstance::convertPosition(cb->getObj(destinationid)->pos,true))
+					: (cb->getObj(destinationid)->pos),
+				true);
+}
+
+void CGTeleport::initObj()
+{
+	objs[ID][subID].push_back(id);
+}
+
+void CGArtifact::initObj()
+{
+	blockVisit = true;
+	if(ID == 5)
+		hoverName = VLC->arth->artifacts[subID].Name();
+}
+
+void CGArtifact::onHeroVisit( const CGHeroInstance * h ) const
+{
+	cb->giveHeroArtifact(subID,h->id,-2);
+	InfoWindow iw;
+	iw.player = h->tempOwner;
+	iw.components.push_back(Component(4,subID,0,0));
+	iw.text << std::pair<ui8,ui32>(12,subID);
+	cb->showInfoDialog(&iw);
+}
+
+void CGPickable::initObj()
+{
+	blockVisit = true;
+	switch(ID)
+	{
+	case 12: //campfire
+		val2 = (ran()%3) + 4; //4 - 6
+		val1 = val2 * 100;
+		type = ran()%6; //given resource
+		break;
+	case 101: //treasure chest
+		{
+			int hlp = ran()%100;
+			if(hlp >= 95)
+			{
+				type = 1;
+				val1 = VLC->arth->treasures[ran()%VLC->arth->treasures.size()]->id;
+				return;
+			}
+			else if (hlp >= 65)
+			{
+				val1 = 2000;
+			}
+			else if(hlp >= 33)
+			{
+				val1 = 1500;
+			}
+			else
+			{
+				val1 = 1000;
+			}
+
+			val2 = val1 - 500;
+			type = 0;
+			break;
+		}
+	}
+}
+
+void CGPickable::onHeroVisit( const CGHeroInstance * h ) const
+{
+
+	switch(ID)
+	{
+	case 12: //campfire
+		{
+			cb->giveResource(h->tempOwner,type,val2); //non-gold resource
+			cb->giveResource(h->tempOwner,6,val1);//gold
+			InfoWindow iw;
+			iw.player = h->tempOwner;
+			iw.components.push_back(Component(2,6,val1,0));
+			iw.components.push_back(Component(2,type,val2,0));
+			iw.text << std::pair<ui8,ui32>(11,23);
+			cb->showInfoDialog(&iw);
+			break;
+		}
+	case 101: //treasure chest
+		{
+			if (subID) //not OH3 treasure chest
+			{
+				tlog2 << "Not supported WoG treasure chest!\n";
+				return; 
+			}
+
+			if(type) //there is an artifact
+			{
+				cb->giveHeroArtifact(val1,h->id,-2);
+				InfoWindow iw;
+				iw.player = h->tempOwner;
+				iw.components.push_back(Component(4,val1,1,0));
+				iw.text << std::pair<ui8,ui32>(11,145);
+				iw.text.replacements.push_back(VLC->arth->artifacts[val1].Name());
+				cb->showInfoDialog(&iw);
+				break;
+			}
+			else
+			{
+				SelectionDialog sd;
+				sd.player = h->tempOwner;
+				sd.text << std::pair<ui8,ui32>(11,146);
+				sd.components.push_back(Component(2,6,val1,0));
+				sd.components.push_back(Component(5,0,val2,0));
+				boost::function<void(ui32)> fun = boost::bind(&CGPickable::chosen,this,_1,h->id);
+				cb->showSelectionDialog(&sd,fun);
+				return;
+			}
+		}
+	}
+	cb->removeObject(id);
+}
+
+void CGPickable::chosen( int which, int heroID ) const
+{
+	switch(which)
+	{
+	case 0: //player pick gold
+		cb->giveResource(cb->getOwner(heroID),6,val1);
+		break;
+	case 1: //player pick exp
+		cb->changePrimSkill(heroID, 4, val2);
+		break;
+	default:
+		throw std::string("Unhandled treasure choice");
+	}
 }

+ 453 - 439
hch/CObjectHandler.h

@@ -1,439 +1,453 @@
-#ifndef __COBJECTHANDLER_H__
-#define __COBJECTHANDLER_H__
-#include "../global.h"
-#include <string>
-#include <vector>
-#include <set>
-#include <map>
-#include "CCreatureHandler.h"
-
-using boost::logic::tribool;
-class IGameCallback;
-struct BattleResult;
-class CCPPObjectScript;
-class CGObjectInstance;
-class CScript;
-class CObjectScript;
-class CGHeroInstance;
-class CTown;
-class CHero;
-class CBuilding;
-class CSpell;
-class CGTownInstance;
-class CArtifact;
-class CGDefInfo;
-class CSpecObjInfo;
-
-class DLL_EXPORT CCastleEvent
-{
-public:
-	std::string name, message;
-	int wood, mercury, ore, sulfur, crystal, gems, gold; //gain / loss of resources
-	unsigned char players; //players for whom this event can be applied
-	bool forHuman, forComputer;
-	int firstShow; //postpone of first encounter time in days
-	int forEvery; //every n days this event will occure
-
-	unsigned char bytes[6]; //build specific buildings (raw format, similar to town's)
-
-	int gen[7]; //additional creatures in i-th level dwelling
-
-	bool operator<(const CCastleEvent &drugie) const
-	{
-		return firstShow<drugie.firstShow;
-	}
-};
-
-class DLL_EXPORT IObjectInterface
-{
-public:
-	static IGameCallback *cb;
-
-	IObjectInterface();
-	virtual ~IObjectInterface();
-
-	virtual void onHeroVisit(const CGHeroInstance * h);
-	virtual void onHeroLeave(const CGHeroInstance * h);
-	virtual void newTurn();
-	virtual void initObj();
-};
-
-class DLL_EXPORT CGObjectInstance : protected IObjectInterface
-{
-protected:
-public:
-	mutable std::string hoverName;
-	int3 pos; //h3m pos
-	int ID, subID; //normal ID (this one from OH3 maps ;]) - eg. town=98; hero=34
-	si32 id;//number of object in CObjectHandler's vector		
-	CGDefInfo * defInfo;
-	CCPPObjectScript * state;
-	CSpecObjInfo * info;
-	unsigned char animPhaseShift;
-
-	ui8 tempOwner; //uzywane dla szybkosci, skrypt ma obowiazek aktualizowac te zmienna
-	ui8 blockVisit; //if non-zero then blocks the tile but is visitable from neighbouring tile
-
-	int getOwner() const;
-	void setOwner(int ow);
-	int getWidth() const; //returns width of object graphic in tiles
-	int getHeight() const; //returns height of object graphic in tiles
-	bool visitableAt(int x, int y) const; //returns true if object is visitable at location (x, y) form left top tile of image (x, y in tiles)
-	bool blockingAt(int x, int y) const; //returns true if object is blocking location (x, y) form left top tile of image (x, y in tiles)
-	bool operator<(const CGObjectInstance & cmp) const;  //screen printing priority comparing
-	CGObjectInstance();
-	virtual ~CGObjectInstance();
-	CGObjectInstance(const CGObjectInstance & right);
-	CGObjectInstance& operator=(const CGObjectInstance & right);
-	virtual const std::string & getHoverText() const;
-	//////////////////////////////////////////////////////////////////////////
-	void initObj();
-
-	friend class CGameHandler;
-};
-
-class  DLL_EXPORT CArmedInstance: public CGObjectInstance
-{
-public:
-	CCreatureSet army; //army
-	virtual bool needsLastStack() const; //true if last stack cannot be taken
-};
-
-class DLL_EXPORT CGHeroInstance : public CArmedInstance
-{
-public:
-	//////////////////////////////////////////////////////////////////////////
-
-	mutable int moveDir; //format:	123
-					//		8 4
-					//		765
-	mutable ui8 isStanding, tacticFormationEnabled;
-
-	//////////////////////////////////////////////////////////////////////////
-
-	CHero * type;
-	ui32 exp; //experience point
-	int level; //current level of hero
-	std::string name; //may be custom
-	std::string biography; //if custom
-	int portrait; //may be custom
-	int mana; // remaining spell points
-	std::vector<int> primSkills; //0-attack, 1-defence, 2-spell power, 3-knowledge
-	std::vector<std::pair<ui8,ui8> > secSkills; //first - ID of skill, second - level of skill (1 - basic, 2 - adv., 3 - expert); if hero has ability (-1, -1) it meansthat it should have default secondary abilities
-	int movement; //remaining movement points
-	int identifier; //from the map file
-	bool sex;
-	struct DLL_EXPORT Patrol
-	{
-		Patrol(){patrolling=false;patrolRadious=-1;};
-		bool patrolling;
-		int patrolRadious;
-	} patrol;
-	bool inTownGarrison; // if hero is in town garrison 
-	CGTownInstance * visitedTown; //set if hero is visiting town or in the town garrison
-	std::vector<ui32> artifacts; //hero's artifacts from bag
-	std::map<ui16,ui32> artifWorn; //map<position,artifact_id>; positions: 0 - head; 1 - shoulders; 2 - neck; 3 - right hand; 4 - left hand; 5 - torso; 6 - right ring; 7 - left ring; 8 - feet; 9 - misc1; 10 - misc2; 11 - misc3; 12 - misc4; 13 - mach1; 14 - mach2; 15 - mach3; 16 - mach4; 17 - spellbook; 18 - misc5
-	std::set<ui32> spells; //known spells (spell IDs)
-
-	//////////////////////////////////////////////////////////////////////////
-
-	const std::string &getBiography() const;
-	bool needsLastStack()const;
-	unsigned int getTileCost(const EterrainType & ttype, const Eroad & rdtype, const Eriver & rvtype) const;
-	unsigned int getLowestCreatureSpeed() const;
-	unsigned int getAdditiveMoveBonus() const;
-	float getMultiplicativeMoveBonus() const;
-	int3 getPosition(bool h3m) const; //h3m=true - returns position of hero object; h3m=false - returns position of hero 'manifestation'
-	int getSightDistance() const; //returns sight distance of this hero
-	int manaLimit() const; //maximum mana value for this hero (basically 10*knowledge)
-	bool canWalkOnSea() const;
-	int getCurrentLuck() const;
-	int getCurrentMorale() const;
-	int getPrimSkillLevel(int id) const;
-	int getSecSkillLevel(const int & ID) const; //0 - no skill
-	int maxMovePoints(bool onLand) const;
-	ui32 getArtAtPos(ui16 pos) const; //-1 - no artifact
-	void setArtAtPos(ui16 pos, int art);
-	const CArtifact * getArt(int pos) const;
-	int getSpellSecLevel(int spell) const; //returns level of secondary ability (fire, water, earth, air magic) known to this hero and applicable to given spell; -1 if error
-	static int3 convertPosition(int3 src, bool toh3m); //toh3m=true: manifest->h3m; toh3m=false: h3m->manifest
-
-	//////////////////////////////////////////////////////////////////////////
-
-	void initHero(); 
-	void initHero(int SUBID); 
-	CGHeroInstance();
-	virtual ~CGHeroInstance();
-
-	//////////////////////////////////////////////////////////////////////////
-	void initObj();
-	void onHeroVisit(const CGHeroInstance * h);
-};
-
-class DLL_EXPORT CGTownInstance : public CArmedInstance
-{
-public:
-	CTown * town;
-	std::string name; // name of town
-	int builded; //how many buildings has been built this turn
-	int destroyed; //how many buildings has been destroyed this turn
-	const CGHeroInstance * garrisonHero, *visitingHero;
-	int identifier; //special identifier from h3m (only > RoE maps)
-	int alignment;
-	std::set<si32> forbiddenBuildings, builtBuildings;
-	std::vector<int> possibleSpells, obligatorySpells;
-	std::vector<std::vector<ui32> > spells; //spells[level] -> vector of spells, first will be available in guild
-
-	struct StrInfo
-	{
-		std::map<si32,ui32> creatures; //level - available amount
-
-		template <typename Handler> void serialize(Handler &h, const int version)
-		{
-			h & creatures;
-		}
-	} strInfo;
-	std::set<CCastleEvent> events;
-
-
-	bool needsLastStack() const;
-	int getSightDistance() const; //returns sight distance
-	int fortLevel() const; //0 - none, 1 - fort, 2 - citadel, 3 - castle
-	int hallLevel() const; // -1 - none, 0 - village, 1 - town, 2 - city, 3 - capitol
-	int mageGuildLevel() const; // -1 - none, 0 - village, 1 - town, 2 - city, 3 - capitol
-	bool creatureDwelling(const int & level, bool upgraded=false) const;
-	int getHordeLevel(const int & HID) const; //HID - 0 or 1; returns creature level or -1 if that horde structure is not present
-	int creatureGrowth(const int & level) const;
-	bool hasFort() const;
-	bool hasCapitol() const;
-	int dailyIncome() const;
-	int spellsAtLevel(int level, bool checkGuild) const; //levels are counted from 1 (1 - 5)
-
-	CGTownInstance();
-	virtual ~CGTownInstance();
-
-	//////////////////////////////////////////////////////////////////////////
-
-
-	void onHeroVisit(const CGHeroInstance * h);
-	void onHeroLeave(const CGHeroInstance * h);
-	void initObj();
-};
-
-class DLL_EXPORT CGVisitableOPH : public CGObjectInstance //objects visitable only once per hero
-{
-public:
-	std::set<si32> visitors; //ids of heroes who have visited this obj
-	si8 ttype; //tree type - used only by trees of knowledge: 0 - give level for free; 1 - take 2000 gold; 2 - take 10 gems
-	const std::string & getHoverText() const;
-
-	void onHeroVisit(const CGHeroInstance * h);
-	void onNAHeroVisit(int heroID, bool alreadyVisited);
-	void initObj();
-	void treeSelected(int heroID, int resType, int resVal, int expVal, ui32 result); //handle player's anwer to the Tree of Knowledge dialog
-};
-
-class DLL_EXPORT CGEvent : public CGObjectInstance //event objects
-{
-public:
-	bool areGuarders; //true if there are
-	CCreatureSet guarders;
-	bool isMessage; //true if there is a message
-	std::string message;
-	unsigned int gainedExp;
-	int manaDiff; //amount of gained / lost mana
-	int moraleDiff; //morale modifier
-	int luckDiff; //luck modifier
-	int wood, mercury, ore, sulfur, crystal, gems, gold; //gained / lost resources
-	unsigned int attack; //added attack points
-	unsigned int defence; //added defence points
-	unsigned int power; //added power points
-	unsigned int knowledge; //added knowledge points
-	std::vector<int> abilities; //gained abilities
-	std::vector<int> abilityLevels; //levels of gained abilities
-	std::vector<int> artifacts; //gained artifacts
-	std::vector<int> spells; //gained spells
-	CCreatureSet creatures; //gained creatures
-	unsigned char availableFor; //players whom this event is available for
-	bool computerActivate; //true if computre player can activate this event
-	bool humanActivate; //true if human player can activate this event
-};
-
-class DLL_EXPORT CGCreature : public CArmedInstance //creatures on map
-{
-public:
-	ui32 identifier; //unique code for this monster (used in missions)
-	ui8 character; //chracter of this set of creatures (0 - the most friendly, 4 - the most hostile)
-	std::string message; //message printed for attacking hero
-	std::vector<ui32> resources; //[res_id], resources given to hero that has won with monsters
-	si32 gainedArtifact; //ID of artifact gained to hero, -1 if none
-	ui8 neverFlees; //if true, the troops will never flee
-	ui8 notGrowingTeam; //if true, number of units won't grow
-
-	void onHeroVisit(const CGHeroInstance * h);
-	void endBattle(BattleResult *result);
-	void initObj();
-}; 
-
-
-class DLL_EXPORT CGSignBottle : public CGObjectInstance //signs and ocean bottles
-{
-	//TODO: generate default message if sign is 'empty'
-public:
-	std::string message;
-};
-
-class DLL_EXPORT CGSeerHut : public CGObjectInstance
-{
-public:
-	unsigned char missionType; //type of mission: 0 - no mission; 1 - reach level; 2 - reach main statistics values; 3 - win with a certain hero; 4 - win with a certain creature; 5 - collect some atifacts; 6 - have certain troops in army; 7 - collect resources; 8 - be a certain hero; 9 - be a certain player
-	bool isDayLimit; //if true, there is a day limit
-	int lastDay; //after this day (first day is 0) mission cannot be completed
-	int m1level; //for mission 1	
-	int m2attack, m2defence, m2power, m2knowledge;//for mission 2
-	unsigned char m3bytes[4];//for mission 3
-	unsigned char m4bytes[4];//for mission 4
-	std::vector<int> m5arts;//for mission 5 - artifact ID
-	std::vector<CCreature *> m6cre;//for mission 6
-	std::vector<int> m6number;
-	int m7wood, m7mercury, m7ore, m7sulfur, m7crystal, m7gems, m7gold;	//for mission 7
-	int m8hero;//for mission 8 - hero ID
-	int m9player; //for mission 9 - number; from 0 to 7
-
-	std::string firstVisitText, nextVisitText, completedText;
-
-	char rewardType; //type of reward: 0 - no reward; 1 - experience; 2 - mana points; 3 - morale bonus; 4 - luck bonus; 5 - resources; 6 - main ability bonus (attak, defence etd.); 7 - secondary ability gain; 8 - artifact; 9 - spell; 10 - creature
-	//for reward 1
-	int r1exp;
-	//for reward 2
-	int r2mana;
-	//for reward 3
-	int r3morale;
-	//for reward 4
-	int r4luck;
-	//for reward 5
-	unsigned char r5type; //0 - wood, 1 - mercury, 2 - ore, 3 - sulfur, 4 - crystal, 5 - gems, 6 - gold
-	int r5amount;
-	//for reward 6
-	unsigned char r6type; //0 - attack, 1 - defence, 2 - power, 3 - knowledge
-	int r6amount;
-	//for reward 7
-	int r7ability; //ability id
-	unsigned char r7level; //1 - basic, 2 - advanced, 3 - expert
-	//for reward 8
-	int r8art;//artifact id
-	//for reward 9
-	int r9spell;//spell id
-	//for reward 10
-	int r10creature; //creature id
-	int r10amount;
-};
-
-class DLL_EXPORT CGWitchHut : public CGObjectInstance
-{
-public:
-	std::vector<int> allowedAbilities;
-};
-
-
-class DLL_EXPORT CGScholar : public CGObjectInstance
-{
-public:
-	ui8 bonusType; //255 - random, 0 - primary skill, 1 - secondary skill, 2 - spell
-
-	ui8 r0type;
-	ui32 r1; //Ability ID
-	ui32 r2; //Spell ID
-};
-
-class DLL_EXPORT CGGarrison : public CArmedInstance
-{
-public:
-	bool removableUnits;
-};
-
-class DLL_EXPORT CGArtifact : public CArmedInstance
-{
-public:
-	std::string message;
-	ui32 spell; //if it's spell scroll
-};
-
-class DLL_EXPORT CGResource : public CArmedInstance
-{
-public:
-	int amount; //0 if random
-	std::string message;
-};
-
-class DLL_EXPORT CGShrine : public CGObjectInstance
-{
-public:
-	unsigned char spell; //number of spell or 255 if random
-};
-
-class DLL_EXPORT CGPandoraBox : public CArmedInstance
-{
-public:
-	std::string message;
-
-	//gained things:
-	unsigned int gainedExp;
-	int manaDiff;
-	int moraleDiff;
-	int luckDiff;
-	int wood, mercury, ore, sulfur, crystal, gems, gold;
-	int attack, defence, power, knowledge;
-	std::vector<int> abilities;
-	std::vector<int> abilityLevels;
-	std::vector<int> artifacts;
-	std::vector<int> spells;
-	CCreatureSet creatures;
-};
-
-class DLL_EXPORT CGQuestGuard : public CArmedInstance
-{
-public:
-	char missionType; //type of mission: 0 - no mission; 1 - reach level; 2 - reach main statistics values; 3 - win with a certain hero; 4 - win with a certain creature; 5 - collect some atifacts; 6 - have certain troops in army; 7 - collect resources; 8 - be a certain hero; 9 - be a certain player
-	bool isDayLimit; //if true, there is a day limit
-	int lastDay; //after this day (first day is 0) mission cannot be completed
-	//for mission 1
-	int m1level;
-	//for mission 2
-	int m2attack, m2defence, m2power, m2knowledge;
-	//for mission 3
-	unsigned char m3bytes[4];
-	//for mission 4
-	unsigned char m4bytes[4];
-	//for mission 5
-	std::vector<int> m5arts; //artifacts id
-	//for mission 6
-	std::vector<CCreature *> m6cre;
-	std::vector<int> m6number;
-	//for mission 7
-	int m7wood, m7mercury, m7ore, m7sulfur, m7crystal, m7gems, m7gold;
-	//for mission 8
-	int m8hero; //hero id
-	//for mission 9
-	int m9player; //number; from 0 to 7
-
-	std::string firstVisitText, nextVisitText, completedText;
-};
-
-class DLL_EXPORT CObjectHandler
-{
-public:
-	std::vector<std::string> names; //vector of objects; i-th object in vector has subnumber i
-	std::vector<int> cregens; //type 17. dwelling subid -> creature ID
-	void loadObjects();
-
-	std::vector<std::string> creGens; //names of creatures' generators
-	std::vector<std::string> advobtxt;
-	std::vector<std::string> xtrainfo;
-	std::vector<std::string> restypes;
-	std::vector<std::pair<std::string,std::string> > mines; //first - name; second - event description
-};
-
-
-
-#endif // __COBJECTHANDLER_H__
+#ifndef __COBJECTHANDLER_H__
+#define __COBJECTHANDLER_H__
+#include "../global.h"
+#include <string>
+#include <vector>
+#include <set>
+#include <map>
+#include "CCreatureHandler.h"
+
+using boost::logic::tribool;
+class IGameCallback;
+struct BattleResult;
+class CCPPObjectScript;
+class CGObjectInstance;
+class CScript;
+class CObjectScript;
+class CGHeroInstance;
+class CTown;
+class CHero;
+class CBuilding;
+class CSpell;
+class CGTownInstance;
+class CArtifact;
+class CGDefInfo;
+class CSpecObjInfo;
+
+class DLL_EXPORT CCastleEvent
+{
+public:
+	std::string name, message;
+	int wood, mercury, ore, sulfur, crystal, gems, gold; //gain / loss of resources
+	unsigned char players; //players for whom this event can be applied
+	bool forHuman, forComputer;
+	int firstShow; //postpone of first encounter time in days
+	int forEvery; //every n days this event will occure
+
+	unsigned char bytes[6]; //build specific buildings (raw format, similar to town's)
+
+	int gen[7]; //additional creatures in i-th level dwelling
+
+	bool operator<(const CCastleEvent &drugie) const
+	{
+		return firstShow<drugie.firstShow;
+	}
+};
+
+class CQuest
+{
+public:
+	ui8 missionType; //type of mission: 0 - no mission; 1 - reach level; 2 - reach main statistics values; 3 - win with a certain hero; 4 - win with a certain creature; 5 - collect some atifacts; 6 - have certain troops in army; 7 - collect resources; 8 - be a certain hero; 9 - be a certain playe
+	si32 lastDay; //after this day (first day is 0) mission cannot be completed; if -1 - no limit
+
+	ui32 m13489val;
+	std::vector<ui32> m2stats;
+	std::vector<ui16> m5arts; //artifacts id
+	std::vector<std::pair<ui32, ui32> > m6creatures; //pair[cre id, cre count]
+	std::vector<ui32> m7resources;
+
+	std::string firstVisitText, nextVisitText, completedText;
+};
+
+class DLL_EXPORT IObjectInterface
+{
+public:
+	static IGameCallback *cb;
+
+	IObjectInterface();
+	virtual ~IObjectInterface();
+
+	virtual void onHeroVisit(const CGHeroInstance * h) const;
+	virtual void onHeroLeave(const CGHeroInstance * h) const;
+	virtual void newTurn() const;
+	virtual void initObj();
+};
+
+class DLL_EXPORT CGObjectInstance : protected IObjectInterface
+{
+protected:
+public:
+	mutable std::string hoverName;
+	int3 pos; //h3m pos
+	int ID, subID; //normal ID (this one from OH3 maps ;]) - eg. town=98; hero=34
+	si32 id;//number of object in CObjectHandler's vector		
+	CGDefInfo * defInfo;
+	CCPPObjectScript * state;
+	CSpecObjInfo * info;
+	unsigned char animPhaseShift;
+
+	ui8 tempOwner; //uzywane dla szybkosci, skrypt ma obowiazek aktualizowac te zmienna
+	ui8 blockVisit; //if non-zero then blocks the tile but is visitable from neighbouring tile
+
+	int getOwner() const;
+	void setOwner(int ow);
+	int getWidth() const; //returns width of object graphic in tiles
+	int getHeight() const; //returns height of object graphic in tiles
+	bool visitableAt(int x, int y) const; //returns true if object is visitable at location (x, y) form left top tile of image (x, y in tiles)
+	bool blockingAt(int x, int y) const; //returns true if object is blocking location (x, y) form left top tile of image (x, y in tiles)
+	bool operator<(const CGObjectInstance & cmp) const;  //screen printing priority comparing
+	CGObjectInstance();
+	virtual ~CGObjectInstance();
+	CGObjectInstance(const CGObjectInstance & right);
+	CGObjectInstance& operator=(const CGObjectInstance & right);
+	virtual const std::string & getHoverText() const;
+	//////////////////////////////////////////////////////////////////////////
+	void initObj();
+
+	friend class CGameHandler;
+};
+
+class  DLL_EXPORT CArmedInstance: public CGObjectInstance
+{
+public:
+	CCreatureSet army; //army
+	virtual bool needsLastStack() const; //true if last stack cannot be taken
+};
+
+class DLL_EXPORT CGHeroInstance : public CArmedInstance
+{
+public:
+	//////////////////////////////////////////////////////////////////////////
+
+	mutable int moveDir; //format:	123
+					//		8 4
+					//		765
+	mutable ui8 isStanding, tacticFormationEnabled;
+
+	//////////////////////////////////////////////////////////////////////////
+
+	CHero * type;
+	ui32 exp; //experience point
+	int level; //current level of hero
+	std::string name; //may be custom
+	std::string biography; //if custom
+	int portrait; //may be custom
+	int mana; // remaining spell points
+	std::vector<int> primSkills; //0-attack, 1-defence, 2-spell power, 3-knowledge
+	std::vector<std::pair<ui8,ui8> > secSkills; //first - ID of skill, second - level of skill (1 - basic, 2 - adv., 3 - expert); if hero has ability (-1, -1) it meansthat it should have default secondary abilities
+	int movement; //remaining movement points
+	int identifier; //from the map file
+	bool sex;
+	struct DLL_EXPORT Patrol
+	{
+		Patrol(){patrolling=false;patrolRadious=-1;};
+		bool patrolling;
+		int patrolRadious;
+	} patrol;
+	bool inTownGarrison; // if hero is in town garrison 
+	CGTownInstance * visitedTown; //set if hero is visiting town or in the town garrison
+	std::vector<ui32> artifacts; //hero's artifacts from bag
+	std::map<ui16,ui32> artifWorn; //map<position,artifact_id>; positions: 0 - head; 1 - shoulders; 2 - neck; 3 - right hand; 4 - left hand; 5 - torso; 6 - right ring; 7 - left ring; 8 - feet; 9 - misc1; 10 - misc2; 11 - misc3; 12 - misc4; 13 - mach1; 14 - mach2; 15 - mach3; 16 - mach4; 17 - spellbook; 18 - misc5
+	std::set<ui32> spells; //known spells (spell IDs)
+
+	//////////////////////////////////////////////////////////////////////////
+
+	const std::string &getBiography() const;
+	bool needsLastStack()const;
+	unsigned int getTileCost(const EterrainType & ttype, const Eroad & rdtype, const Eriver & rvtype) const;
+	unsigned int getLowestCreatureSpeed() const;
+	unsigned int getAdditiveMoveBonus() const;
+	float getMultiplicativeMoveBonus() const;
+	int3 getPosition(bool h3m) const; //h3m=true - returns position of hero object; h3m=false - returns position of hero 'manifestation'
+	int getSightDistance() const; //returns sight distance of this hero
+	int manaLimit() const; //maximum mana value for this hero (basically 10*knowledge)
+	bool canWalkOnSea() const;
+	int getCurrentLuck() const;
+	int getCurrentMorale() const;
+	int getPrimSkillLevel(int id) const;
+	int getSecSkillLevel(const int & ID) const; //0 - no skill
+	int maxMovePoints(bool onLand) const;
+	ui32 getArtAtPos(ui16 pos) const; //-1 - no artifact
+	void setArtAtPos(ui16 pos, int art);
+	const CArtifact * getArt(int pos) const;
+	int getSpellSecLevel(int spell) const; //returns level of secondary ability (fire, water, earth, air magic) known to this hero and applicable to given spell; -1 if error
+	static int3 convertPosition(int3 src, bool toh3m); //toh3m=true: manifest->h3m; toh3m=false: h3m->manifest
+
+	//////////////////////////////////////////////////////////////////////////
+
+	void initHero(); 
+	void initHero(int SUBID); 
+	CGHeroInstance();
+	virtual ~CGHeroInstance();
+
+	//////////////////////////////////////////////////////////////////////////
+	void initObj();
+	void onHeroVisit(const CGHeroInstance * h) const;
+};
+
+class DLL_EXPORT CGTownInstance : public CArmedInstance
+{
+public:
+	CTown * town;
+	std::string name; // name of town
+	int builded; //how many buildings has been built this turn
+	int destroyed; //how many buildings has been destroyed this turn
+	const CGHeroInstance * garrisonHero, *visitingHero;
+	int identifier; //special identifier from h3m (only > RoE maps)
+	int alignment;
+	std::set<si32> forbiddenBuildings, builtBuildings;
+	std::vector<int> possibleSpells, obligatorySpells;
+	std::vector<std::vector<ui32> > spells; //spells[level] -> vector of spells, first will be available in guild
+
+	struct StrInfo
+	{
+		std::map<si32,ui32> creatures; //level - available amount
+
+		template <typename Handler> void serialize(Handler &h, const int version)
+		{
+			h & creatures;
+		}
+	} strInfo;
+	std::set<CCastleEvent> events;
+
+
+	bool needsLastStack() const;
+	int getSightDistance() const; //returns sight distance
+	int fortLevel() const; //0 - none, 1 - fort, 2 - citadel, 3 - castle
+	int hallLevel() const; // -1 - none, 0 - village, 1 - town, 2 - city, 3 - capitol
+	int mageGuildLevel() const; // -1 - none, 0 - village, 1 - town, 2 - city, 3 - capitol
+	bool creatureDwelling(const int & level, bool upgraded=false) const;
+	int getHordeLevel(const int & HID) const; //HID - 0 or 1; returns creature level or -1 if that horde structure is not present
+	int creatureGrowth(const int & level) const;
+	bool hasFort() const;
+	bool hasCapitol() const;
+	int dailyIncome() const;
+	int spellsAtLevel(int level, bool checkGuild) const; //levels are counted from 1 (1 - 5)
+
+	CGTownInstance();
+	virtual ~CGTownInstance();
+
+	//////////////////////////////////////////////////////////////////////////
+
+
+	void onHeroVisit(const CGHeroInstance * h) const;
+	void onHeroLeave(const CGHeroInstance * h) const;
+	void initObj();
+};
+
+class DLL_EXPORT CGVisitableOPH : public CGObjectInstance //objects visitable only once per hero
+{
+public:
+	std::set<si32> visitors; //ids of heroes who have visited this obj
+	si8 ttype; //tree type - used only by trees of knowledge: 0 - give level for free; 1 - take 2000 gold; 2 - take 10 gems
+	const std::string & getHoverText() const;
+
+	void onHeroVisit(const CGHeroInstance * h) const;
+	void onNAHeroVisit(int heroID, bool alreadyVisited) const;
+	void initObj();
+	void treeSelected(int heroID, int resType, int resVal, int expVal, ui32 result) const; //handle player's anwer to the Tree of Knowledge dialog
+};
+
+class DLL_EXPORT CGEvent : public CGObjectInstance //event objects
+{
+public:
+	bool areGuarders; //true if there are
+	CCreatureSet guarders;
+	bool isMessage; //true if there is a message
+	std::string message;
+	unsigned int gainedExp;
+	int manaDiff; //amount of gained / lost mana
+	int moraleDiff; //morale modifier
+	int luckDiff; //luck modifier
+	int wood, mercury, ore, sulfur, crystal, gems, gold; //gained / lost resources
+	unsigned int attack; //added attack points
+	unsigned int defence; //added defence points
+	unsigned int power; //added power points
+	unsigned int knowledge; //added knowledge points
+	std::vector<int> abilities; //gained abilities
+	std::vector<int> abilityLevels; //levels of gained abilities
+	std::vector<int> artifacts; //gained artifacts
+	std::vector<int> spells; //gained spells
+	CCreatureSet creatures; //gained creatures
+	unsigned char availableFor; //players whom this event is available for
+	bool computerActivate; //true if computre player can activate this event
+	bool humanActivate; //true if human player can activate this event
+};
+
+class DLL_EXPORT CGCreature : public CArmedInstance //creatures on map
+{
+public:
+	ui32 identifier; //unique code for this monster (used in missions)
+	ui8 character; //chracter of this set of creatures (0 - the most friendly, 4 - the most hostile)
+	std::string message; //message printed for attacking hero
+	std::vector<ui32> resources; //[res_id], resources given to hero that has won with monsters
+	si32 gainedArtifact; //ID of artifact gained to hero, -1 if none
+	ui8 neverFlees; //if true, the troops will never flee
+	ui8 notGrowingTeam; //if true, number of units won't grow
+
+	void onHeroVisit(const CGHeroInstance * h) const;
+	void endBattle(BattleResult *result) const;
+	void initObj();
+}; 
+
+
+class DLL_EXPORT CGSignBottle : public CGObjectInstance //signs and ocean bottles
+{
+	//TODO: generate default message if sign is 'empty'
+public:
+	std::string message;
+};
+
+class DLL_EXPORT CGSeerHut : public CGObjectInstance, public CQuest
+{
+public:
+	char rewardType; //type of reward: 0 - no reward; 1 - experience; 2 - mana points; 3 - morale bonus; 4 - luck bonus; 5 - resources; 6 - main ability bonus (attak, defence etd.); 7 - secondary ability gain; 8 - artifact; 9 - spell; 10 - creature
+	//for reward 1
+	int r1exp;
+	//for reward 2
+	int r2mana;
+	//for reward 3
+	int r3morale;
+	//for reward 4
+	int r4luck;
+	//for reward 5
+	unsigned char r5type; //0 - wood, 1 - mercury, 2 - ore, 3 - sulfur, 4 - crystal, 5 - gems, 6 - gold
+	int r5amount;
+	//for reward 6
+	unsigned char r6type; //0 - attack, 1 - defence, 2 - power, 3 - knowledge
+	int r6amount;
+	//for reward 7
+	int r7ability; //ability id
+	unsigned char r7level; //1 - basic, 2 - advanced, 3 - expert
+	//for reward 8
+	int r8art;//artifact id
+	//for reward 9
+	int r9spell;//spell id
+	//for reward 10
+	int r10creature; //creature id
+	int r10amount;
+};
+
+class DLL_EXPORT CGWitchHut : public CGObjectInstance
+{
+public:
+	std::vector<int> allowedAbilities;
+};
+
+
+class DLL_EXPORT CGScholar : public CGObjectInstance
+{
+public:
+	ui8 bonusType; //255 - random, 0 - primary skill, 1 - secondary skill, 2 - spell
+
+	ui8 r0type;
+	ui32 r1; //Ability ID
+	ui32 r2; //Spell ID
+};
+
+class DLL_EXPORT CGGarrison : public CArmedInstance
+{
+public:
+	bool removableUnits;
+};
+
+class DLL_EXPORT CGArtifact : public CArmedInstance
+{
+public:
+	std::string message;
+	ui32 spell; //if it's spell scroll
+	void onHeroVisit(const CGHeroInstance * h) const;
+	void initObj();	
+};
+
+class DLL_EXPORT CGResource : public CArmedInstance
+{
+public:
+	int amount; //0 if random
+	std::string message;
+
+	void onHeroVisit(const CGHeroInstance * h) const;
+	void initObj();
+};
+
+class DLL_EXPORT CGPickable : public CGObjectInstance //campfire, treasure chest
+{
+	ui32 type, val1, val2;
+
+	void onHeroVisit(const CGHeroInstance * h) const;
+	void initObj();
+	void chosen(int which, int heroID) const;
+};
+
+class DLL_EXPORT CGShrine : public CGObjectInstance
+{
+public:
+	unsigned char spell; //number of spell or 255 if random
+};
+
+class DLL_EXPORT CGPandoraBox : public CArmedInstance
+{
+public:
+	std::string message;
+
+	//gained things:
+	unsigned int gainedExp;
+	int manaDiff;
+	int moraleDiff;
+	int luckDiff;
+	int wood, mercury, ore, sulfur, crystal, gems, gold;
+	int attack, defence, power, knowledge;
+	std::vector<int> abilities;
+	std::vector<int> abilityLevels;
+	std::vector<int> artifacts;
+	std::vector<int> spells;
+	CCreatureSet creatures;
+};
+
+class DLL_EXPORT CGQuestGuard : public CGObjectInstance, public CQuest
+{
+public:
+};
+
+class DLL_EXPORT CGMine : public CArmedInstance
+{
+public: 
+	void onHeroVisit(const CGHeroInstance * h) const;
+	void newTurn() const;
+	void initObj();	
+};
+
+class DLL_EXPORT CGVisitableOPW : public CGObjectInstance //objects visitable OPW
+{
+public:
+	ui8 visited; //true if object has been visited this week
+
+	void onHeroVisit(const CGHeroInstance * h) const;
+	void newTurn() const;
+};
+
+class DLL_EXPORT CGTeleport : public CGObjectInstance //teleports and subterranean gates
+{
+public:
+	static std::map<int,std::map<int, std::vector<int> > > objs; //map[ID][subID] => vector of ids
+	void onHeroVisit(const CGHeroInstance * h) const;
+	void initObj();	
+};
+
+class DLL_EXPORT CObjectHandler
+{
+public:
+	std::vector<std::string> names; //vector of objects; i-th object in vector has subnumber i
+	std::vector<int> cregens; //type 17. dwelling subid -> creature ID
+	void loadObjects();
+
+	std::vector<std::string> creGens; //names of creatures' generators
+	std::vector<std::string> advobtxt;
+	std::vector<std::string> xtrainfo;
+	std::vector<std::string> restypes;
+	std::vector<std::pair<std::string,std::string> > mines; //first - name; second - event description
+};
+
+
+
+#endif // __COBJECTHANDLER_H__

+ 36 - 0
lib/IGameCallback.cpp

@@ -0,0 +1,36 @@
+#define VCMI_DLL
+#include "IGameCallback.h"
+#include "../CGameState.h"
+#include "../map.h"
+#include "../hch/CObjectHandler.h"
+
+const CGObjectInstance* IGameCallback::getObj(int objid)
+{
+	return gs->map->objects[objid];
+}
+const CGHeroInstance* IGameCallback::getHero(int objid)
+{
+	return dynamic_cast<const CGHeroInstance*>(gs->map->objects[objid]);
+}
+const CGTownInstance* IGameCallback::getTown(int objid)
+{
+	return dynamic_cast<const CGTownInstance*>(gs->map->objects[objid]);
+}
+
+int IGameCallback::getOwner(int heroID)
+{
+	return gs->map->objects[heroID]->tempOwner;
+}
+int IGameCallback::getResource(int player, int which)
+{
+	return gs->players.find(player)->second.resources[which];
+}
+int IGameCallback::getDate(int mode)
+{
+	return gs->getDate(mode);
+}
+
+const CGHeroInstance* IGameCallback::getSelectedHero( int player )
+{
+	return getHero(gs->players.find(player)->second.currentSelection);
+}

+ 58 - 54
lib/IGameCallback.h

@@ -1,54 +1,58 @@
-#ifndef __IGAMECALLBACK_H__
-#define __IGAMECALLBACK_H__
-
-#include "../global.h"
-#include <vector>
-#include <set>
-#include "../client/FunctionList.h"
-
-class CGObjectInstance;
-class CGTownInstance;
-class CGHeroInstance;
-struct SelectionDialog;
-struct YesNoDialog;
-struct InfoWindow;
-struct MetaString;
-struct ShowInInfobox;
-struct BattleResult;
-
-class IGameCallback
-{
-public:
-	virtual ~IGameCallback(){};
-
-	virtual int getOwner(int heroID)=0;
-	virtual int getResource(int player, int which)=0;
-	virtual int getSelectedHero()=0;
-	virtual int getDate(int mode=0)=0;
-	virtual const CGObjectInstance* getObj(int objid)=0;
-	virtual const CGHeroInstance* getHero(int objid)=0;
-	virtual const CGTownInstance* getTown(int objid)=0;
-	virtual const CGHeroInstance* getSelectedHero(int player)=0; //NULL if no hero is selected
-	virtual int getCurrentPlayer()=0;
-
-	//do sth
-	virtual void changeSpells(int hid, bool give, const std::set<ui32> &spells)=0;
-	virtual void removeObject(int objid)=0;
-	virtual void setBlockVis(int objid, bool bv)=0;
-	virtual void setOwner(int objid, ui8 owner)=0;
-	virtual void setHoverName(int objid, MetaString * name)=0;
-	virtual void changePrimSkill(int ID, int which, int val, bool abs=false)=0;
-	virtual void showInfoDialog(InfoWindow *iw)=0;
-	virtual void showYesNoDialog(YesNoDialog *iw, const CFunctionList<void(ui32)> &callback)=0;
-	virtual void showSelectionDialog(SelectionDialog *iw, const CFunctionList<void(ui32)> &callback)=0; //returns question id
-	virtual void giveResource(int player, int which, int val)=0;
-	virtual void showCompInfo(ShowInInfobox * comp)=0;
-	virtual void heroVisitCastle(int obj, int heroID)=0;
-	virtual void stopHeroVisitCastle(int obj, int heroID)=0;
-	virtual void giveHeroArtifact(int artid, int hid, int position)=0; //pos==-1 - first free slot in backpack=0; pos==-2 - default if available or backpack
-	virtual void startBattleI(const CCreatureSet * army1, const CCreatureSet * army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, boost::function<void(BattleResult*)> cb)=0; //use hero=NULL for no hero
-	virtual void startBattleI(int heroID, CCreatureSet army, int3 tile, boost::function<void(BattleResult*)> cb)=0; //for hero<=>neutral army
-	virtual void setAmount(int objid, ui32 val)=0;
-	virtual void moveHero(int hid, int3 pos, bool instant)=0;
-};
-#endif // __IGAMECALLBACK_H__
+#ifndef __IGAMECALLBACK_H__
+#define __IGAMECALLBACK_H__
+
+#include "../global.h"
+#include <vector>
+#include <set>
+#include "../client/FunctionList.h"
+
+class CGObjectInstance;
+class CGTownInstance;
+class CGHeroInstance;
+struct SelectionDialog;
+struct YesNoDialog;
+struct InfoWindow;
+struct MetaString;
+struct ShowInInfobox;
+struct BattleResult;
+class CGameState;
+
+class DLL_EXPORT IGameCallback
+{
+protected:
+	CGameState *gs;
+public:
+	virtual ~IGameCallback(){};
+
+	virtual int getOwner(int heroID);
+	virtual int getResource(int player, int which);
+	virtual int getDate(int mode=0);
+	virtual const CGObjectInstance* getObj(int objid);
+	virtual const CGHeroInstance* getHero(int objid);
+	virtual const CGTownInstance* getTown(int objid);
+	virtual const CGHeroInstance* getSelectedHero(int player); //NULL if no hero is selected
+	virtual int getCurrentPlayer()=0;
+	virtual int getSelectedHero()=0;
+
+	//do sth
+	virtual void changeSpells(int hid, bool give, const std::set<ui32> &spells)=0;
+	virtual void removeObject(int objid)=0;
+	virtual void setBlockVis(int objid, bool bv)=0;
+	virtual void setOwner(int objid, ui8 owner)=0;
+	virtual void setHoverName(int objid, MetaString * name)=0;
+	virtual void setObjProperty(int objid, int prop, int val)=0;
+	virtual void changePrimSkill(int ID, int which, int val, bool abs=false)=0;
+	virtual void showInfoDialog(InfoWindow *iw)=0;
+	virtual void showYesNoDialog(YesNoDialog *iw, const CFunctionList<void(ui32)> &callback)=0;
+	virtual void showSelectionDialog(SelectionDialog *iw, const CFunctionList<void(ui32)> &callback)=0; //returns question id
+	virtual void giveResource(int player, int which, int val)=0;
+	virtual void showCompInfo(ShowInInfobox * comp)=0;
+	virtual void heroVisitCastle(int obj, int heroID)=0;
+	virtual void stopHeroVisitCastle(int obj, int heroID)=0;
+	virtual void giveHeroArtifact(int artid, int hid, int position)=0; //pos==-1 - first free slot in backpack=0; pos==-2 - default if available or backpack
+	virtual void startBattleI(const CCreatureSet * army1, const CCreatureSet * army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, boost::function<void(BattleResult*)> cb)=0; //use hero=NULL for no hero
+	virtual void startBattleI(int heroID, CCreatureSet army, int3 tile, boost::function<void(BattleResult*)> cb)=0; //for hero<=>neutral army
+	virtual void setAmount(int objid, ui32 val)=0;
+	virtual void moveHero(int hid, int3 pos, bool instant)=0;
+};
+#endif // __IGAMECALLBACK_H__

+ 13 - 1
lib/NetPacks.h

@@ -236,6 +236,18 @@ struct SetHeroArtifacts : public CPack<SetHeroArtifacts> //509
 	}
 };  
 
+struct SetSelection : public CPack<SetSelection> //514
+{
+	SetSelection(){type = 514;};
+	ui8 player;
+	ui32 id;
+
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & id & player;
+	}
+};  
+
 struct HeroRecruited : public CPack<HeroRecruited> //515
 {
 	HeroRecruited(){type = 515;};
@@ -346,7 +358,7 @@ struct InfoWindow : public CPack<InfoWindow> //103  - displays simple info windo
 struct SetObjectProperty : public CPack<SetObjectProperty>//1001
 {
 	ui32 id;
-	ui8 what; //1 - owner; 2 - blockvis; 3 - amount (works with creatures stacks)
+	ui8 what; //1 - owner; 2 - blockvis
 	ui32 val;
 	SetObjectProperty(){type = 1001;};
 	SetObjectProperty(ui32 ID, ui8 What, ui32 Val):id(ID),what(What),val(Val){type = 1001;};

+ 4 - 0
lib/VCMI_lib.vcproj

@@ -310,6 +310,10 @@
 				RelativePath="..\hch\CTownHandler.cpp"
 				>
 			</File>
+			<File
+				RelativePath=".\IGameCallback.cpp"
+				>
+			</File>
 			<File
 				RelativePath="..\map.cpp"
 				>

+ 129 - 402
map.cpp

@@ -577,203 +577,7 @@ int Mapa::loadSeerHut( unsigned char * bufor, int i, CGObjectInstance *& nobj )
 
 	if(version>RoE)
 	{
-		hut->missionType = bufor[i]; ++i;
-		switch(hut->missionType)
-		{
-		case 0:
-			i+=3;
-			return i;
-		case 1:
-			{
-				hut->m1level = readNormalNr(bufor,i); i+=4;
-				int limit = readNormalNr(bufor,i); i+=4;
-				if(limit == ((int)0xffffffff))
-				{
-					hut->isDayLimit = false;
-					hut->lastDay = -1;
-				}
-				else
-				{
-					hut->isDayLimit = true;
-					hut->lastDay = limit;
-				}
-				break;
-			}
-		case 2:
-			{
-				hut->m2attack = bufor[i]; ++i;
-				hut->m2defence = bufor[i]; ++i;
-				hut->m2power = bufor[i]; ++i;
-				hut->m2knowledge = bufor[i]; ++i;
-				int limit = readNormalNr(bufor,i); i+=4;
-				if(limit == ((int)0xffffffff))
-				{
-					hut->isDayLimit = false;
-					hut->lastDay = -1;
-				}
-				else
-				{
-					hut->isDayLimit = true;
-					hut->lastDay = limit;
-				}
-				break;
-			}
-		case 3:
-			{
-				hut->m3bytes[0] = bufor[i]; ++i;
-				hut->m3bytes[1] = bufor[i]; ++i;
-				hut->m3bytes[2] = bufor[i]; ++i;
-				hut->m3bytes[3] = bufor[i]; ++i;
-				int limit = readNormalNr(bufor,i); i+=4;
-				if(limit == ((int)0xffffffff))
-				{
-					hut->isDayLimit = false;
-					hut->lastDay = -1;
-				}
-				else
-				{
-					hut->isDayLimit = true;
-					hut->lastDay = limit;
-				}
-				break;
-			}
-		case 4:
-			{
-				hut->m4bytes[0] = bufor[i]; ++i;
-				hut->m4bytes[1] = bufor[i]; ++i;
-				hut->m4bytes[2] = bufor[i]; ++i;
-				hut->m4bytes[3] = bufor[i]; ++i;
-				int limit = readNormalNr(bufor,i); i+=4;
-				if(limit == ((int)0xffffffff))
-				{
-					hut->isDayLimit = false;
-					hut->lastDay = -1;
-				}
-				else
-				{
-					hut->isDayLimit = true;
-					hut->lastDay = limit;
-				}
-				break;
-			}
-		case 5:
-			{
-				int artNumber = bufor[i]; ++i;
-				for(int yy=0; yy<artNumber; ++yy)
-				{
-					int artid = readNormalNr(bufor,i, 2); i+=2;
-					hut->m5arts.push_back(artid);
-				}
-				int limit = readNormalNr(bufor,i); i+=4;
-				if(limit == ((int)0xffffffff))
-				{
-					hut->isDayLimit = false;
-					hut->lastDay = -1;
-				}
-				else
-				{
-					hut->isDayLimit = true;
-					hut->lastDay = limit;
-				}
-				break;
-			}
-		case 6:
-			{
-				int typeNumber = bufor[i]; ++i;
-				for(int hh=0; hh<typeNumber; ++hh)
-				{
-					int creType = readNormalNr(bufor,i, 2); i+=2;
-					int creNumb = readNormalNr(bufor,i, 2); i+=2;
-					hut->m6cre.push_back(&(VLC->creh->creatures[creType]));
-					hut->m6number.push_back(creNumb);
-				}
-				int limit = readNormalNr(bufor,i); i+=4;
-				if(limit == ((int)0xffffffff))
-				{
-					hut->isDayLimit = false;
-					hut->lastDay = -1;
-				}
-				else
-				{
-					hut->isDayLimit = true;
-					hut->lastDay = limit;
-				}
-				break;
-			}
-		case 7:
-			{
-				hut->m7wood = readNormalNr(bufor,i); i+=4;
-				hut->m7mercury = readNormalNr(bufor,i); i+=4;
-				hut->m7ore = readNormalNr(bufor,i); i+=4;
-				hut->m7sulfur = readNormalNr(bufor,i); i+=4;
-				hut->m7crystal = readNormalNr(bufor,i); i+=4;
-				hut->m7gems = readNormalNr(bufor,i); i+=4;
-				hut->m7gold = readNormalNr(bufor,i); i+=4;
-				int limit = readNormalNr(bufor,i); i+=4;
-				if(limit == ((int)0xffffffff))
-				{
-					hut->isDayLimit = false;
-					hut->lastDay = -1;
-				}
-				else
-				{
-					hut->isDayLimit = true;
-					hut->lastDay = limit;
-				}
-				break;
-			}
-		case 8:
-			{
-				int heroType = bufor[i]; ++i;
-				hut->m8hero = heroType;
-				int limit = readNormalNr(bufor,i); i+=4;
-				if(limit == ((int)0xffffffff))
-				{
-					hut->isDayLimit = false;
-					hut->lastDay = -1;
-				}
-				else
-				{
-					hut->isDayLimit = true;
-					hut->lastDay = limit;
-				}
-				break;
-			}
-		case 9:
-			{
-				hut->m9player = bufor[i]; ++i;
-				int limit = readNormalNr(bufor,i); i+=4;
-				if(limit == ((int)0xffffffff))
-				{
-					hut->isDayLimit = false;
-					hut->lastDay = -1;
-				}
-				else
-				{
-					hut->isDayLimit = true;
-					hut->lastDay = limit;
-				}
-				break;
-			}
-		}//internal switch end (seer huts)
-
-		int len1 = readNormalNr(bufor,i); i+=4;
-		for(int ee=0; ee<len1; ++ee)
-		{
-			hut->firstVisitText += bufor[i]; ++i;
-		}
-
-		int len2 = readNormalNr(bufor,i); i+=4;
-		for(int ee=0; ee<len2; ++ee)
-		{
-			hut->nextVisitText += bufor[i]; ++i;
-		}
-
-		int len3 = readNormalNr(bufor,i); i+=4;
-		for(int ee=0; ee<len3; ++ee)
-		{
-			hut->completedText += bufor[i]; ++i;
-		}
+		loadQuest(hut,bufor,i);
 	}
 	else //RoE
 	{
@@ -1848,7 +1652,40 @@ void Mapa::readObjects( unsigned char * bufor, int &i)
 				loadHero(nobj, bufor, i);
 				break;
 			}
-		case 54: case 71: case 72: case 73: case 74: case 75: case 162: case 163: case 164:
+		case 51: //Mercenary Camp
+		case 23: //Marletto Tower
+		case 61: // Star Axis
+		case 32: // Garden of Revelation
+		case 100: //Learning Stone
+		case 102: //Tree of Knowledge
+			{
+				nobj = new CGVisitableOPH();
+				break;
+			}
+		case 55: //mystical garden
+		case 112://windmill
+		case 109://water wheel
+			{
+				nobj = new CGVisitableOPW();
+				break;
+			}
+		case 43: //teleport
+		case 44: //teleport
+		case 45: //teleport
+		case 103://subterranean gate
+			{
+				nobj = new CGTeleport();
+				break;
+			}
+		case 12: //campfire
+		case 101: //treasure chest
+			{
+				nobj = new CGPickable();
+				break;
+			}
+		case 54:  //Monster 
+		case 71: case 72: case 73: case 74: case 75:	// Random Monster 1 - 4
+		case 162: case 163: case 164:					// Random Monster 5 - 7
 			{
 				CGCreature *cre = new CGCreature();
 				nobj = cre;
@@ -1971,7 +1808,8 @@ void Mapa::readObjects( unsigned char * bufor, int &i)
 				i+=8;
 				break;
 			}
-		case 5: case 65: case 66: case 67: case 68: case 69: //artifact	
+		case 5: //artifact	
+		case 65: case 66: case 67: case 68: case 69: //random artifact
 		case 93: //spell scroll
 			{
 				CGArtifact *art = new CGArtifact();
@@ -1991,7 +1829,7 @@ void Mapa::readObjects( unsigned char * bufor, int &i)
 				}
 				break;
 			}
-		case 76: case 79: //resource
+		case 76: case 79: //random resource; resource
 			{
 				CGResource *res = new CGResource();
 				nobj = res;
@@ -2011,12 +1849,22 @@ void Mapa::readObjects( unsigned char * bufor, int &i)
 
 				break;
 			}
-		case 77: case 98: //town
+		case 77: case 98: //random town; town
 			{
 				loadTown(nobj, bufor, i);
 				break;
 			}
-		case 53: case 17: case 18: case 19: case 20: case 42: case 87: case 220://cases 17 - 20 and 42 - tests
+		case 53: 
+			{
+				nobj = new CGMine();
+				nobj->setOwner(bufor[i++]);
+				i+=3;
+				break;
+			}
+		case 17: case 18: case 19: case 20: //dwellings
+		case 42: //lighthouse
+		case 87: //shipyard
+		case 220://mine (?)
 			{
 				nobj = new CGObjectInstance();
 				nobj->setOwner(bufor[i++]);
@@ -2157,206 +2005,7 @@ void Mapa::readObjects( unsigned char * bufor, int &i)
 			{
 				CGQuestGuard *guard = new CGQuestGuard();
 				nobj = guard;
-				guard->missionType = bufor[i]; ++i;
-				int len1, len2, len3;
-				switch(guard->missionType)
-				{
-				case 0:
-					{
-						goto borderguardend;
-						break;
-					}
-				case 1:
-					{
-						guard->m1level = readNormalNr(bufor,i); i+=4;
-						int limit = readNormalNr(bufor,i); i+=4;
-						if(limit == ((int)0xffffffff))
-						{
-							guard->isDayLimit = false;
-							guard->lastDay = -1;
-						}
-						else
-						{
-							guard->isDayLimit = true;
-							guard->lastDay = limit;
-						}
-						break;
-					}
-				case 2:
-					{
-						guard->m2attack = bufor[i]; ++i;
-						guard->m2defence = bufor[i]; ++i;
-						guard->m2power = bufor[i]; ++i;
-						guard->m2knowledge = bufor[i]; ++i;
-						int limit = readNormalNr(bufor,i); i+=4;
-						if(limit == ((int)0xffffffff))
-						{
-							guard->isDayLimit = false;
-							guard->lastDay = -1;
-						}
-						else
-						{
-							guard->isDayLimit = true;
-							guard->lastDay = limit;
-						}
-						break;
-					}
-				case 3:
-					{
-						guard->m3bytes[0] = bufor[i]; ++i;
-						guard->m3bytes[1] = bufor[i]; ++i;
-						guard->m3bytes[2] = bufor[i]; ++i;
-						guard->m3bytes[3] = bufor[i]; ++i;
-						int limit = readNormalNr(bufor,i); i+=4;
-						if(limit == ((int)0xffffffff))
-						{
-							guard->isDayLimit = false;
-							guard->lastDay = -1;
-						}
-						else
-						{
-							guard->isDayLimit = true;
-							guard->lastDay = limit;
-						}
-						break;
-					}
-				case 4:
-					{
-						guard->m4bytes[0] = bufor[i]; ++i;
-						guard->m4bytes[1] = bufor[i]; ++i;
-						guard->m4bytes[2] = bufor[i]; ++i;
-						guard->m4bytes[3] = bufor[i]; ++i;
-						int limit = readNormalNr(bufor,i); i+=4;
-						if(limit == ((int)0xffffffff))
-						{
-							guard->isDayLimit = false;
-							guard->lastDay = -1;
-						}
-						else
-						{
-							guard->isDayLimit = true;
-							guard->lastDay = limit;
-						}
-						break;
-					}
-				case 5:
-					{
-						int artNumber = bufor[i]; ++i;
-						for(int yy=0; yy<artNumber; ++yy)
-						{
-							guard->m5arts.push_back(readNormalNr(bufor,i, 2)); i+=2;
-						}
-						int limit = readNormalNr(bufor,i); i+=4;
-						if(limit == ((int)0xffffffff))
-						{
-							guard->isDayLimit = false;
-							guard->lastDay = -1;
-						}
-						else
-						{
-							guard->isDayLimit = true;
-							guard->lastDay = limit;
-						}
-						break;
-					}
-				case 6:
-					{
-						int typeNumber = bufor[i]; ++i;
-						for(int hh=0; hh<typeNumber; ++hh)
-						{
-							int creType = readNormalNr(bufor,i, 2); i+=2;
-							int creNumb = readNormalNr(bufor,i, 2); i+=2;
-							guard->m6cre.push_back(&(VLC->creh->creatures[creType]));
-							guard->m6number.push_back(creNumb);
-						}
-						int limit = readNormalNr(bufor,i); i+=4;
-						if(limit == ((int)0xffffffff))
-						{
-							guard->isDayLimit = false;
-							guard->lastDay = -1;
-						}
-						else
-						{
-							guard->isDayLimit = true;
-							guard->lastDay = limit;
-						}
-						break;
-					}
-				case 7:
-					{
-						guard->m7wood = readNormalNr(bufor,i); i+=4;
-						guard->m7mercury = readNormalNr(bufor,i); i+=4;
-						guard->m7ore = readNormalNr(bufor,i); i+=4;
-						guard->m7sulfur = readNormalNr(bufor,i); i+=4;
-						guard->m7crystal = readNormalNr(bufor,i); i+=4;
-						guard->m7gems = readNormalNr(bufor,i); i+=4;
-						guard->m7gold = readNormalNr(bufor,i); i+=4;
-						int limit = readNormalNr(bufor,i); i+=4;
-						if(limit == ((int)0xffffffff))
-						{
-							guard->isDayLimit = false;
-							guard->lastDay = -1;
-						}
-						else
-						{
-							guard->isDayLimit = true;
-							guard->lastDay = limit;
-						}
-						break;
-					}
-				case 8:
-					{
-						int heroType = bufor[i]; ++i;
-						guard->m8hero = heroType;
-						int limit = readNormalNr(bufor,i); i+=4;
-						if(limit == ((int)0xffffffff))
-						{
-							guard->isDayLimit = false;
-							guard->lastDay = -1;
-						}
-						else
-						{
-							guard->isDayLimit = true;
-							guard->lastDay = limit;
-						}
-						break;
-					}
-				case 9:
-					{
-						guard->m9player = bufor[i]; ++i;
-						int limit = readNormalNr(bufor,i); i+=4;
-						if(limit == ((int)0xffffffff))
-						{
-							guard->isDayLimit = false;
-							guard->lastDay = -1;
-						}
-						else
-						{
-							guard->isDayLimit = true;
-							guard->lastDay = limit;
-						}
-						break;
-					}
-				}//internal switch end (seer huts)
-
-				len1 = readNormalNr(bufor,i); i+=4;
-				for(int ee=0; ee<len1; ++ee)
-				{
-					guard->firstVisitText += bufor[i]; ++i;
-				}
-
-				len2 = readNormalNr(bufor,i); i+=4;
-				for(int ee=0; ee<len2; ++ee)
-				{
-					guard->nextVisitText += bufor[i]; ++i;
-				}
-
-				len3 = readNormalNr(bufor,i); i+=4;
-				for(int ee=0; ee<len3; ++ee)
-				{
-					guard->completedText += bufor[i]; ++i;
-				}
-borderguardend:
+				loadQuest(guard, bufor, i);
 				break;
 			}
 		case 214: //hero placeholder
@@ -2428,3 +2077,81 @@ bool Mapa::isInTheMap( int3 pos )
 		return false;
 	else return true;
 }
+
+void Mapa::loadQuest(CQuest * guard, unsigned char * bufor, int & i)
+{
+	guard->missionType = bufor[i]; ++i;
+	int len1, len2, len3;
+	switch(guard->missionType)
+	{
+	case 0:
+		return;
+	case 2:
+		{
+			guard->m2stats.resize(4);
+			for(int x=0; x<4; x++)
+			{
+				guard->m2stats[x] = bufor[i++];
+			}
+		}
+		break;
+	case 1:
+	case 3:
+	case 4:
+		{
+			guard->m13489val = readNormalNr(bufor,i); i+=4;
+			break;
+		}
+	case 5:
+		{
+			int artNumber = bufor[i]; ++i;
+			for(int yy=0; yy<artNumber; ++yy)
+			{
+				guard->m5arts.push_back(readNormalNr(bufor,i, 2)); i+=2;
+			}
+			break;
+		}
+	case 6:
+		{
+			int typeNumber = bufor[i]; ++i;
+			for(int hh=0; hh<typeNumber; ++hh)
+			{
+				ui32 creType = readNormalNr(bufor,i, 2); i+=2;
+				ui32 creNumb = readNormalNr(bufor,i, 2); i+=2;
+				guard->m6creatures.push_back(std::make_pair(creType,creNumb));
+			}
+			break;
+		}
+	case 7:
+		{
+			guard->m7resources.resize(7);
+			for(int x=0; x<7; x++)
+			{
+				guard->m7resources[x] = readNormalNr(bufor,i); 
+				i+=4;
+			}
+			break;
+		}
+	case 8:
+	case 9:
+		{
+			guard->m13489val = bufor[i]; ++i;
+			break;
+		}
+	}
+
+
+	int limit = readNormalNr(bufor,i); i+=4;
+	if(limit == ((int)0xffffffff))
+	{
+		guard->lastDay = -1;
+	}
+	else
+	{
+		guard->lastDay = limit;
+	}
+
+	guard->firstVisitText = readString(bufor,i);
+	guard->nextVisitText = readString(bufor,i);
+	guard->completedText = readString(bufor,i);
+}

+ 392 - 390
map.h

@@ -1,390 +1,392 @@
-#ifndef __MAP_H__
-#define __MAP_H__
-#ifdef _MSC_VER
-#pragma warning (disable : 4482)
-#endif
-#include <cstring>
-#include <vector>
-#include <map>
-#include <set>
-#include "global.h"
-class CGDefInfo;
-class CGObjectInstance;
-class CGHeroInstance;
-class CGTownInstance;
-enum ESortBy{_name, _playerAm, _size, _format, _viccon, _loscon};
-enum EDefType {TOWN_DEF, HERO_DEF, CREATURES_DEF, SEERHUT_DEF, RESOURCE_DEF, TERRAINOBJ_DEF, 
-	EVENTOBJ_DEF, SIGN_DEF, GARRISON_DEF, ARTIFACT_DEF, WITCHHUT_DEF, SCHOLAR_DEF, PLAYERONLY_DEF, 
-	SHRINE_DEF, SPELLSCROLL_DEF, PANDORA_DEF, GRAIL_DEF, CREGEN_DEF, CREGEN2_DEF, CREGEN3_DEF, 
-	BORDERGUARD_DEF, HEROPLACEHOLDER_DEF};
-
-class DLL_EXPORT CSpecObjInfo
-{
-public:
-	virtual ~CSpecObjInfo(){};
-};
-
-class DLL_EXPORT CCreGenObjInfo : public CSpecObjInfo
-{
-public:
-	unsigned char player; //owner
-	bool asCastle;
-	int identifier;
-	unsigned char castles[2]; //allowed castles
-};
-class DLL_EXPORT CCreGen2ObjInfo : public CSpecObjInfo
-{
-public:
-	unsigned char player; //owner
-	bool asCastle;
-	int identifier;
-	unsigned char castles[2]; //allowed castles
-	unsigned char minLevel, maxLevel; //minimal and maximal level of creature in dwelling: <0, 6>
-};
-class DLL_EXPORT CCreGen3ObjInfo : public CSpecObjInfo
-{
-public:
-	unsigned char player; //owner
-	unsigned char minLevel, maxLevel; //minimal and maximal level of creature in dwelling: <0, 6>
-};
-
-struct DLL_EXPORT Sresource
-{
-	std::string resName; //name of this resource
-	int amount; //it can be greater and lesser than 0
-};
-struct DLL_EXPORT TimeEvent
-{
-	std::string eventName;
-	std::string message;
-	std::vector<Sresource> decIncRes; //decreases / increases of resources
-	unsigned int whichPlayers; //which players are affected by this event (+1 - first, +2 - second, +4 - third, +8 - fourth etc.)
-	bool areHumansAffected;
-	bool areCompsAffected;
-	int firstAfterNDays; //how many days after appears this event
-	int nextAfterNDays; //how many days after the epperance before appaers this event
-};
-struct DLL_EXPORT TerrainTile
-{
-	EterrainType tertype; // type of terrain
-	unsigned char terview; // look of terrain
-	Eriver nuine; // type of Eriver (0 if there is no Eriver)
-	unsigned char rivDir; // direction of Eriver
-	Eroad malle; // type of Eroad (0 if there is no Eriver)
-	unsigned char roadDir; // direction of Eroad
-	unsigned char siodmyTajemniczyBajt; //bitfield, info whether this tile is coastal and how to rotate tile graphics
-
-	bool visitable; //false = not visitable; true = visitable
-	bool blocked; //false = free; true = blocked;
-
-	std::vector <CGObjectInstance*> visitableObjects; //pointers to objects hero can visit while being on this tile
-	std::vector <CGObjectInstance*> blockingObjects; //pointers to objects that are blocking this tile
-
-	template <typename Handler> void serialize(Handler &h, const int version)
-	{
-		h & tertype & terview & nuine & rivDir & malle &roadDir & siodmyTajemniczyBajt;
-	}
-};
-struct DLL_EXPORT SheroName //name of starting hero
-{
-	int heroID;
-	std::string heroName;
-
-	template <typename Handler> void serialize(Handler &h, const int version)
-	{
-		h & heroID & heroName;
-	}
-};
-struct DLL_EXPORT PlayerInfo
-{
-	si32 p7, p8, p9;
-	ui8 canHumanPlay;
-	ui8 canComputerPlay;
-	ui32 AITactic; //(00 - random, 01 -  warrior, 02 - builder, 03 - explorer)
-	ui32 allowedFactions; //(01 - castle; 02 - rampart; 04 - tower; 08 - inferno; 16 - necropolis; 32 - dungeon; 64 - stronghold; 128 - fortress; 256 - conflux);
-	ui8 isFactionRandom;
-	ui32 mainHeroPortrait; //it's ID of hero with choosen portrait; 255 if standard
-	std::string mainHeroName;
-	std::vector<SheroName> heroesNames;
-	ui8 hasMainTown;
-	ui8 generateHeroAtMainTown;
-	int3 posOfMainTown;
-	ui8 team;
-	ui8 generateHero;
-
-	template <typename Handler> void serialize(Handler &h, const int version)
-	{
-		h & p7 & p8 & p9 & canHumanPlay & canComputerPlay & AITactic & allowedFactions & isFactionRandom &
-			mainHeroPortrait & mainHeroName & heroesNames & hasMainTown & generateHeroAtMainTown &
-			posOfMainTown & team & generateHero;
-	}
-};
-struct DLL_EXPORT LossCondition
-{
-	ElossCon typeOfLossCon;
-	int3 castlePos;
-	int3 heroPos;
-	int timeLimit; // in days
-
-	template <typename Handler> void serialize(Handler &h, const int version)
-	{
-		h & typeOfLossCon & castlePos & heroPos & timeLimit;
-	}
-};
-struct DLL_EXPORT CspecificVictoryConidtions
-{
-	bool allowNormalVictory;
-	bool appliesToAI;
-};
-struct DLL_EXPORT VicCon0 : public CspecificVictoryConidtions //acquire artifact
-{
-	int ArtifactID;
-};
-struct DLL_EXPORT VicCon1 : public CspecificVictoryConidtions //accumulate creatures
-{
-	int monsterID;
-	int neededQuantity;
-};
-struct DLL_EXPORT VicCon2 : public CspecificVictoryConidtions // accumulate resources
-{
-	int resourceID;
-	int neededQuantity;
-};
-struct DLL_EXPORT VicCon3 : public CspecificVictoryConidtions // upgrade specific town
-{
-	int3 posOfCity;
-	int councilNeededLevel; //0 - town; 1 - city; 2 - capitol
-	int fortNeededLevel;// 0 - fort; 1 - citadel; 2 - castle
-};
-struct DLL_EXPORT VicCon4 : public CspecificVictoryConidtions // build grail structure
-{
-	bool anyLocation;
-	int3 whereBuildGrail;
-};
-struct DLL_EXPORT VicCon5 : public CspecificVictoryConidtions // defeat a specific hero
-{
-	int3 locationOfHero;
-};
-struct DLL_EXPORT VicCon6 : public CspecificVictoryConidtions // capture a specific town
-{
-	int3 locationOfTown;
-};
-struct DLL_EXPORT VicCon7 : public CspecificVictoryConidtions // defeat a specific monster
-{
-	int3 locationOfMonster;
-};
-struct DLL_EXPORT VicCona : public CspecificVictoryConidtions //transport specific artifact
-{
-	int artifactID;
-	int3 destinationPlace;
-};
-struct DLL_EXPORT Rumor
-{
-	std::string name, text;
-
-	template <typename Handler> void serialize(Handler &h, const int version)
-	{
-		h & name & text;
-	}
-};
-
-struct DLL_EXPORT DisposedHero
-{
-	ui32 ID;
-	ui16 portrait; //0xFF - default
-	std::string name;
-	ui8 players; //who can hire this hero (bitfield)
-
-	template <typename Handler> void serialize(Handler &h, const int version)
-	{
-		h & ID & portrait & name & players;
-	}
-};
-
-class DLL_EXPORT CMapEvent
-{
-public:
-	std::string name, message;
-	si32 wood, mercury, ore, sulfur, crystal, gems, gold; //gained / taken resources
-	ui8 players; //affected players
-	ui8 humanAffected;
-	ui8 computerAffected;
-	ui32 firstOccurence;
-	ui32 nextOccurence; //after nextOccurance day event will occure; if it it 0, event occures only one time;
-	template <typename Handler> void serialize(Handler &h, const int version)
-	{
-		h & name & message & wood & mercury & ore & sulfur & crystal & gems & gold
-			& players & humanAffected & computerAffected & firstOccurence & nextOccurence;
-	}
-};
-class DLL_EXPORT CMapHeader
-{
-public:
-	Eformat version; // version of map Eformat
-	bool areAnyPLayers; // if there are any playable players on map
-	int height, width;
-	bool twoLevel; // if map has underground level
-	std::string name;  //name of map
-	std::string description;  //and description
-	int difficulty; // 0 easy - 4 impossible
-	int levelLimit;
-	LossCondition lossCondition;
-	EvictoryConditions victoryCondition; //victory conditions
-	CspecificVictoryConidtions * vicConDetails; // used only if vistory conditions aren't standard
-	PlayerInfo players[8]; // info about players
-	std::vector<int> teams;  // teams[i] = team of player no i
-	int howManyTeams;
-	CMapHeader(unsigned char *map); //an argument is a reference to string described a map (unpacked)
-};
-class DLL_EXPORT CMapInfo : public CMapHeader
-{
-public:
-	std::string filename;
-	int playerAmnt, humenPlayers;
-	CMapInfo(std::string fname, unsigned char *map):CMapHeader(map),filename(fname)
-	{
-		playerAmnt=humenPlayers=0;
-		for (int i=0;i<PLAYER_LIMIT;i++)
-		{
-			if (players[i].canHumanPlay) {playerAmnt++;humenPlayers++;}
-			else if (players[i].canComputerPlay) {playerAmnt++;}
-		}
-	};
-};
-
-
-class DLL_EXPORT mapSorter
-{
-public:
-	ESortBy sortBy;
-	bool operator()(const CMapHeader & a, const CMapHeader& b)
-	{
-		switch (sortBy)
-		{
-		case _format:
-			return (a.version<b.version);
-			break;
-		case _loscon:
-			return (a.lossCondition.typeOfLossCon<b.lossCondition.typeOfLossCon);
-			break;
-		case _playerAm:
-			int playerAmntB,humenPlayersB,playerAmntA,humenPlayersA;
-			playerAmntB=humenPlayersB=playerAmntA=humenPlayersA=0;
-			for (int i=0;i<8;i++)
-			{
-				if (a.players[i].canHumanPlay) {playerAmntA++;humenPlayersA++;}
-				else if (a.players[i].canComputerPlay) {playerAmntA++;}
-				if (b.players[i].canHumanPlay) {playerAmntB++;humenPlayersB++;}
-				else if (b.players[i].canComputerPlay) {playerAmntB++;}
-			}
-			if (playerAmntB!=playerAmntA)
-				return (playerAmntA<playerAmntB);
-			else
-				return (humenPlayersA<humenPlayersB);
-			break;
-		case _size:
-			return (a.width<b.width);
-			break;
-		case _viccon:
-			return (a.victoryCondition<b.victoryCondition);
-			break;
-		case _name:
-			return (a.name<b.name);
-			break;
-		default:
-			return (a.name<b.name);
-			break;
-		}
-	};
-	mapSorter(ESortBy es):sortBy(es){};
-};
-struct DLL_EXPORT Mapa
-{
-	Eformat version; // version of map Eformat
-	ui32 checksum;
-	int twoLevel; // if map has underground level
-	int difficulty; // 0 easy - 4 impossible
-	int levelLimit;
-	bool areAnyPLayers; // if there are any playable players on map
-	std::string name;  //name of map
-	std::string description;  //and description
-	int height, width; 
-	TerrainTile*** terrain; 
-	std::vector<Rumor> rumors;
-	std::vector<DisposedHero> disposedHeroes;
-	std::vector<CGHeroInstance*> predefinedHeroes;
-	std::vector<CGDefInfo *> defy; // list of .def files with definitions from .h3m (may be custom)
-	std::set<CGDefInfo *> defs; // other defInfos - for randomized objects, objects added or modified by scripts
-	PlayerInfo players[8]; // info about players
-	std::vector<int> teams;  // teams[i] = team of player no i 
-	LossCondition lossCondition;
-	EvictoryConditions victoryCondition; //victory conditions
-	CspecificVictoryConidtions * vicConDetails; // used only if vistory conditions aren't standard
-	int howManyTeams;
-	std::vector<bool> allowedSpell; //allowedSpell[spell_ID] - if the spell is allowed
-	std::vector<bool> allowedArtifact; //allowedArtifact[artifact_ID] - if the artifact is allowed
-	std::vector<bool> allowedAbilities; //allowedAbilities[ability_ID] - if the ability is allowed
-	std::vector<bool> allowedHeroes; //allowedHeroes[hero_ID] - if the hero is allowed
-	std::vector<CMapEvent> events;
-
-	int3 grailPos;
-	int grailRadious;
-
-	std::vector<CGObjectInstance*> objects;
-	std::vector<CGHeroInstance*> heroes;
-	std::vector<CGTownInstance*> towns;
-
-	void initFromBytes(unsigned char * bufor); //creates map from decompressed .h3m data
-
-	void readEvents( unsigned char * bufor, int &i);
-	void readObjects( unsigned char * bufor, int &i);
-	void readDefInfo( unsigned char * bufor, int &i);
-	void readTerrain( unsigned char * bufor, int &i);
-	void readPredefinedHeroes( unsigned char * bufor, int &i);
-	void readHeader( unsigned char * bufor, int &i);
-	void readRumors( unsigned char * bufor, int &i);
-	void loadViCLossConditions( unsigned char * bufor, int &i);
-	void loadPlayerInfo( int &pom, unsigned char * bufor, int &i);
-	void loadHero( CGObjectInstance * &nobj, unsigned char * bufor, int &i);
-	void loadTown( CGObjectInstance * &nobj, unsigned char * bufor, int &i);
-	int loadSeerHut( unsigned char * bufor, int i, CGObjectInstance *& nobj);
-
-
-	void addBlockVisTiles(CGObjectInstance * obj);
-	void removeBlockVisTiles(CGObjectInstance * obj);
-	Mapa(std::string filename); //creates map structure from .h3m file
-	CGHeroInstance * getHero(int ID, int mode=0);
-	bool isInTheMap(int3 pos);
-	template <typename Handler> void serialize(Handler &h, const int version)
-	{
-		h & version & name & description & width & height & twoLevel & difficulty & levelLimit & rumors & defy & defs
-			& players & teams & lossCondition & victoryCondition & howManyTeams & allowedSpell & allowedAbilities
-			& allowedArtifact &allowedHeroes & events;
-		//TODO: viccondetails
-		if(h.saving)
-		{
-			//saving terrain
-			for (int i = 0; i < width ; i++)
-				for (int j = 0; j < height ; j++)
-					for (int k = 0; k <= twoLevel ; k++)
-						h & terrain[i][j][k];
-		}
-		else
-		{
-			//loading terrain
-			terrain = new TerrainTile**[width]; // allocate memory 
-			for (int ii=0;ii<width;ii++)
-			{
-				terrain[ii] = new TerrainTile*[height]; // allocate memory 
-				for(int jj=0;jj<height;jj++)
-					terrain[ii][jj] = new TerrainTile[twoLevel+1];
-			}
-			for (int i = 0; i < width ; i++)
-				for (int j = 0; j < height ; j++)
-					for (int k = 0; k <= twoLevel ; k++)
-						h & terrain[i][j][k];
-		}
-		//TODO: recreate blockvis maps
-	}
-};
-#endif // __MAP_H__
+#ifndef __MAP_H__
+#define __MAP_H__
+#ifdef _MSC_VER
+#pragma warning (disable : 4482)
+#endif
+#include <cstring>
+#include <vector>
+#include <map>
+#include <set>
+#include "global.h"
+class CGDefInfo;
+class CGObjectInstance;
+class CGHeroInstance;
+class CQuest;
+class CGTownInstance;
+enum ESortBy{_name, _playerAm, _size, _format, _viccon, _loscon};
+enum EDefType {TOWN_DEF, HERO_DEF, CREATURES_DEF, SEERHUT_DEF, RESOURCE_DEF, TERRAINOBJ_DEF, 
+	EVENTOBJ_DEF, SIGN_DEF, GARRISON_DEF, ARTIFACT_DEF, WITCHHUT_DEF, SCHOLAR_DEF, PLAYERONLY_DEF, 
+	SHRINE_DEF, SPELLSCROLL_DEF, PANDORA_DEF, GRAIL_DEF, CREGEN_DEF, CREGEN2_DEF, CREGEN3_DEF, 
+	BORDERGUARD_DEF, HEROPLACEHOLDER_DEF};
+
+class DLL_EXPORT CSpecObjInfo
+{
+public:
+	virtual ~CSpecObjInfo(){};
+};
+
+class DLL_EXPORT CCreGenObjInfo : public CSpecObjInfo
+{
+public:
+	unsigned char player; //owner
+	bool asCastle;
+	int identifier;
+	unsigned char castles[2]; //allowed castles
+};
+class DLL_EXPORT CCreGen2ObjInfo : public CSpecObjInfo
+{
+public:
+	unsigned char player; //owner
+	bool asCastle;
+	int identifier;
+	unsigned char castles[2]; //allowed castles
+	unsigned char minLevel, maxLevel; //minimal and maximal level of creature in dwelling: <0, 6>
+};
+class DLL_EXPORT CCreGen3ObjInfo : public CSpecObjInfo
+{
+public:
+	unsigned char player; //owner
+	unsigned char minLevel, maxLevel; //minimal and maximal level of creature in dwelling: <0, 6>
+};
+
+struct DLL_EXPORT Sresource
+{
+	std::string resName; //name of this resource
+	int amount; //it can be greater and lesser than 0
+};
+struct DLL_EXPORT TimeEvent
+{
+	std::string eventName;
+	std::string message;
+	std::vector<Sresource> decIncRes; //decreases / increases of resources
+	unsigned int whichPlayers; //which players are affected by this event (+1 - first, +2 - second, +4 - third, +8 - fourth etc.)
+	bool areHumansAffected;
+	bool areCompsAffected;
+	int firstAfterNDays; //how many days after appears this event
+	int nextAfterNDays; //how many days after the epperance before appaers this event
+};
+struct DLL_EXPORT TerrainTile
+{
+	EterrainType tertype; // type of terrain
+	unsigned char terview; // look of terrain
+	Eriver nuine; // type of Eriver (0 if there is no Eriver)
+	unsigned char rivDir; // direction of Eriver
+	Eroad malle; // type of Eroad (0 if there is no Eriver)
+	unsigned char roadDir; // direction of Eroad
+	unsigned char siodmyTajemniczyBajt; //bitfield, info whether this tile is coastal and how to rotate tile graphics
+
+	bool visitable; //false = not visitable; true = visitable
+	bool blocked; //false = free; true = blocked;
+
+	std::vector <CGObjectInstance*> visitableObjects; //pointers to objects hero can visit while being on this tile
+	std::vector <CGObjectInstance*> blockingObjects; //pointers to objects that are blocking this tile
+
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & tertype & terview & nuine & rivDir & malle &roadDir & siodmyTajemniczyBajt;
+	}
+};
+struct DLL_EXPORT SheroName //name of starting hero
+{
+	int heroID;
+	std::string heroName;
+
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & heroID & heroName;
+	}
+};
+struct DLL_EXPORT PlayerInfo
+{
+	si32 p7, p8, p9;
+	ui8 canHumanPlay;
+	ui8 canComputerPlay;
+	ui32 AITactic; //(00 - random, 01 -  warrior, 02 - builder, 03 - explorer)
+	ui32 allowedFactions; //(01 - castle; 02 - rampart; 04 - tower; 08 - inferno; 16 - necropolis; 32 - dungeon; 64 - stronghold; 128 - fortress; 256 - conflux);
+	ui8 isFactionRandom;
+	ui32 mainHeroPortrait; //it's ID of hero with choosen portrait; 255 if standard
+	std::string mainHeroName;
+	std::vector<SheroName> heroesNames;
+	ui8 hasMainTown;
+	ui8 generateHeroAtMainTown;
+	int3 posOfMainTown;
+	ui8 team;
+	ui8 generateHero;
+
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & p7 & p8 & p9 & canHumanPlay & canComputerPlay & AITactic & allowedFactions & isFactionRandom &
+			mainHeroPortrait & mainHeroName & heroesNames & hasMainTown & generateHeroAtMainTown &
+			posOfMainTown & team & generateHero;
+	}
+};
+struct DLL_EXPORT LossCondition
+{
+	ElossCon typeOfLossCon;
+	int3 castlePos;
+	int3 heroPos;
+	int timeLimit; // in days
+
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & typeOfLossCon & castlePos & heroPos & timeLimit;
+	}
+};
+struct DLL_EXPORT CspecificVictoryConidtions
+{
+	bool allowNormalVictory;
+	bool appliesToAI;
+};
+struct DLL_EXPORT VicCon0 : public CspecificVictoryConidtions //acquire artifact
+{
+	int ArtifactID;
+};
+struct DLL_EXPORT VicCon1 : public CspecificVictoryConidtions //accumulate creatures
+{
+	int monsterID;
+	int neededQuantity;
+};
+struct DLL_EXPORT VicCon2 : public CspecificVictoryConidtions // accumulate resources
+{
+	int resourceID;
+	int neededQuantity;
+};
+struct DLL_EXPORT VicCon3 : public CspecificVictoryConidtions // upgrade specific town
+{
+	int3 posOfCity;
+	int councilNeededLevel; //0 - town; 1 - city; 2 - capitol
+	int fortNeededLevel;// 0 - fort; 1 - citadel; 2 - castle
+};
+struct DLL_EXPORT VicCon4 : public CspecificVictoryConidtions // build grail structure
+{
+	bool anyLocation;
+	int3 whereBuildGrail;
+};
+struct DLL_EXPORT VicCon5 : public CspecificVictoryConidtions // defeat a specific hero
+{
+	int3 locationOfHero;
+};
+struct DLL_EXPORT VicCon6 : public CspecificVictoryConidtions // capture a specific town
+{
+	int3 locationOfTown;
+};
+struct DLL_EXPORT VicCon7 : public CspecificVictoryConidtions // defeat a specific monster
+{
+	int3 locationOfMonster;
+};
+struct DLL_EXPORT VicCona : public CspecificVictoryConidtions //transport specific artifact
+{
+	int artifactID;
+	int3 destinationPlace;
+};
+struct DLL_EXPORT Rumor
+{
+	std::string name, text;
+
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & name & text;
+	}
+};
+
+struct DLL_EXPORT DisposedHero
+{
+	ui32 ID;
+	ui16 portrait; //0xFF - default
+	std::string name;
+	ui8 players; //who can hire this hero (bitfield)
+
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & ID & portrait & name & players;
+	}
+};
+
+class DLL_EXPORT CMapEvent
+{
+public:
+	std::string name, message;
+	si32 wood, mercury, ore, sulfur, crystal, gems, gold; //gained / taken resources
+	ui8 players; //affected players
+	ui8 humanAffected;
+	ui8 computerAffected;
+	ui32 firstOccurence;
+	ui32 nextOccurence; //after nextOccurance day event will occure; if it it 0, event occures only one time;
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & name & message & wood & mercury & ore & sulfur & crystal & gems & gold
+			& players & humanAffected & computerAffected & firstOccurence & nextOccurence;
+	}
+};
+class DLL_EXPORT CMapHeader
+{
+public:
+	Eformat version; // version of map Eformat
+	bool areAnyPLayers; // if there are any playable players on map
+	int height, width;
+	bool twoLevel; // if map has underground level
+	std::string name;  //name of map
+	std::string description;  //and description
+	int difficulty; // 0 easy - 4 impossible
+	int levelLimit;
+	LossCondition lossCondition;
+	EvictoryConditions victoryCondition; //victory conditions
+	CspecificVictoryConidtions * vicConDetails; // used only if vistory conditions aren't standard
+	PlayerInfo players[8]; // info about players
+	std::vector<int> teams;  // teams[i] = team of player no i
+	int howManyTeams;
+	CMapHeader(unsigned char *map); //an argument is a reference to string described a map (unpacked)
+};
+class DLL_EXPORT CMapInfo : public CMapHeader
+{
+public:
+	std::string filename;
+	int playerAmnt, humenPlayers;
+	CMapInfo(std::string fname, unsigned char *map):CMapHeader(map),filename(fname)
+	{
+		playerAmnt=humenPlayers=0;
+		for (int i=0;i<PLAYER_LIMIT;i++)
+		{
+			if (players[i].canHumanPlay) {playerAmnt++;humenPlayers++;}
+			else if (players[i].canComputerPlay) {playerAmnt++;}
+		}
+	};
+};
+
+
+class DLL_EXPORT mapSorter
+{
+public:
+	ESortBy sortBy;
+	bool operator()(const CMapHeader & a, const CMapHeader& b)
+	{
+		switch (sortBy)
+		{
+		case _format:
+			return (a.version<b.version);
+			break;
+		case _loscon:
+			return (a.lossCondition.typeOfLossCon<b.lossCondition.typeOfLossCon);
+			break;
+		case _playerAm:
+			int playerAmntB,humenPlayersB,playerAmntA,humenPlayersA;
+			playerAmntB=humenPlayersB=playerAmntA=humenPlayersA=0;
+			for (int i=0;i<8;i++)
+			{
+				if (a.players[i].canHumanPlay) {playerAmntA++;humenPlayersA++;}
+				else if (a.players[i].canComputerPlay) {playerAmntA++;}
+				if (b.players[i].canHumanPlay) {playerAmntB++;humenPlayersB++;}
+				else if (b.players[i].canComputerPlay) {playerAmntB++;}
+			}
+			if (playerAmntB!=playerAmntA)
+				return (playerAmntA<playerAmntB);
+			else
+				return (humenPlayersA<humenPlayersB);
+			break;
+		case _size:
+			return (a.width<b.width);
+			break;
+		case _viccon:
+			return (a.victoryCondition<b.victoryCondition);
+			break;
+		case _name:
+			return (a.name<b.name);
+			break;
+		default:
+			return (a.name<b.name);
+			break;
+		}
+	};
+	mapSorter(ESortBy es):sortBy(es){};
+};
+struct DLL_EXPORT Mapa
+{
+	Eformat version; // version of map Eformat
+	ui32 checksum;
+	int twoLevel; // if map has underground level
+	int difficulty; // 0 easy - 4 impossible
+	int levelLimit;
+	bool areAnyPLayers; // if there are any playable players on map
+	std::string name;  //name of map
+	std::string description;  //and description
+	int height, width; 
+	TerrainTile*** terrain; 
+	std::vector<Rumor> rumors;
+	std::vector<DisposedHero> disposedHeroes;
+	std::vector<CGHeroInstance*> predefinedHeroes;
+	std::vector<CGDefInfo *> defy; // list of .def files with definitions from .h3m (may be custom)
+	std::set<CGDefInfo *> defs; // other defInfos - for randomized objects, objects added or modified by scripts
+	PlayerInfo players[8]; // info about players
+	std::vector<int> teams;  // teams[i] = team of player no i 
+	LossCondition lossCondition;
+	EvictoryConditions victoryCondition; //victory conditions
+	CspecificVictoryConidtions * vicConDetails; // used only if vistory conditions aren't standard
+	int howManyTeams;
+	std::vector<bool> allowedSpell; //allowedSpell[spell_ID] - if the spell is allowed
+	std::vector<bool> allowedArtifact; //allowedArtifact[artifact_ID] - if the artifact is allowed
+	std::vector<bool> allowedAbilities; //allowedAbilities[ability_ID] - if the ability is allowed
+	std::vector<bool> allowedHeroes; //allowedHeroes[hero_ID] - if the hero is allowed
+	std::vector<CMapEvent> events;
+
+	int3 grailPos;
+	int grailRadious;
+
+	std::vector<CGObjectInstance*> objects;
+	std::vector<CGHeroInstance*> heroes;
+	std::vector<CGTownInstance*> towns;
+
+	void initFromBytes(unsigned char * bufor); //creates map from decompressed .h3m data
+
+	void readEvents( unsigned char * bufor, int &i);
+	void readObjects( unsigned char * bufor, int &i);
+	void loadQuest( CQuest * guard, unsigned char * bufor, int & i);
+	void readDefInfo( unsigned char * bufor, int &i);
+	void readTerrain( unsigned char * bufor, int &i);
+	void readPredefinedHeroes( unsigned char * bufor, int &i);
+	void readHeader( unsigned char * bufor, int &i);
+	void readRumors( unsigned char * bufor, int &i);
+	void loadViCLossConditions( unsigned char * bufor, int &i);
+	void loadPlayerInfo( int &pom, unsigned char * bufor, int &i);
+	void loadHero( CGObjectInstance * &nobj, unsigned char * bufor, int &i);
+	void loadTown( CGObjectInstance * &nobj, unsigned char * bufor, int &i);
+	int loadSeerHut( unsigned char * bufor, int i, CGObjectInstance *& nobj);
+
+
+	void addBlockVisTiles(CGObjectInstance * obj);
+	void removeBlockVisTiles(CGObjectInstance * obj);
+	Mapa(std::string filename); //creates map structure from .h3m file
+	CGHeroInstance * getHero(int ID, int mode=0);
+	bool isInTheMap(int3 pos);
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & version & name & description & width & height & twoLevel & difficulty & levelLimit & rumors & defy & defs
+			& players & teams & lossCondition & victoryCondition & howManyTeams & allowedSpell & allowedAbilities
+			& allowedArtifact &allowedHeroes & events;
+		//TODO: viccondetails
+		if(h.saving)
+		{
+			//saving terrain
+			for (int i = 0; i < width ; i++)
+				for (int j = 0; j < height ; j++)
+					for (int k = 0; k <= twoLevel ; k++)
+						h & terrain[i][j][k];
+		}
+		else
+		{
+			//loading terrain
+			terrain = new TerrainTile**[width]; // allocate memory 
+			for (int ii=0;ii<width;ii++)
+			{
+				terrain[ii] = new TerrainTile*[height]; // allocate memory 
+				for(int jj=0;jj<height;jj++)
+					terrain[ii][jj] = new TerrainTile[twoLevel+1];
+			}
+			for (int i = 0; i < width ; i++)
+				for (int j = 0; j < height ; j++)
+					for (int k = 0; k <= twoLevel ; k++)
+						h & terrain[i][j][k];
+		}
+		//TODO: recreate blockvis maps
+	}
+};
+#endif // __MAP_H__

+ 18 - 47
server/CGameHandler.cpp

@@ -1027,9 +1027,9 @@ upgend:
 				}
 			case 514:
 				{
-					ui32 id;
-					c >> id;
-					gs->players[*players.begin()].currentSelection = id;
+					SetSelection ss;
+					c >> ss;
+					sendAndApply(&ss);
 					break;
 				}
 			case 515:
@@ -1517,9 +1517,6 @@ void CGameHandler::init(StartInfo *si, int Seed)
 	gs->init(si,map,Seed);	
 	tlog0 << "Gamestate initialized!" << std::endl;
 
-
-	for(int i=0; i<gs->map->objects.size(); i++)
-		gs->map->objects[i]->initObj();
 	/****************************LUA OBJECT SCRIPTS************************************************/
 	//std::vector<std::string> * lf = CLuaHandler::searchForScripts("scripts/lua/objects"); //files
 	//for (int i=0; i<lf->size(); i++)
@@ -1627,7 +1624,8 @@ void CGameHandler::newTurn()
 	sendAndApply(&n);
 	tlog5 << "Info about turn " << n.day << "has been sent!" << std::endl;
 	for(size_t i = 0; i<gs->map->objects.size(); i++)
-		gs->map->objects[i]->newTurn();
+		if(gs->map->objects[i])
+			gs->map->objects[i]->newTurn();
 }
 void CGameHandler::run()
 {	
@@ -1962,32 +1960,11 @@ void CGameHandler::setOwner(int objid, ui8 owner)
 	SetObjectProperty sop(objid,1,owner);
 	sendAndApply(&sop);
 }
-const CGObjectInstance* CGameHandler::getObj(int objid)
-{
-	return gs->map->objects[objid];
-}
-const CGHeroInstance* CGameHandler::getHero(int objid)
-{
-	return dynamic_cast<const CGHeroInstance*>(gs->map->objects[objid]);
-}
-const CGTownInstance* CGameHandler::getTown(int objid)
-{
-	return dynamic_cast<const CGTownInstance*>(gs->map->objects[objid]);
-}
 void CGameHandler::setHoverName(int objid, MetaString* name)
 {
 	SetHoverName shn(objid, *name);
 	sendAndApply(&shn);
 }
-
-int CGameHandler::getOwner(int heroID)
-{
-	return gs->map->objects[heroID]->tempOwner;
-}
-int CGameHandler::getResource(int player, int which)
-{
-	return gs->players.find(player)->second.resources[which];
-}
 void CGameHandler::showInfoDialog(InfoWindow *iw)
 {
 	sendToAllClients(iw);
@@ -2000,26 +1977,11 @@ void CGameHandler::showSelectionDialog(SelectionDialog *iw, const CFunctionList<
 {
 	ask(iw,iw->player,callback);
 }
-
-int CGameHandler::getSelectedHero()
-{	
-	//int ret;
-	//if (LOCPLINT->adventureInt->selection->ID == HEROI_TYPE)
-	//	ret = ((CGHeroInstance*)(LOCPLINT->adventureInt->selection))->subID;
-	//else 
-	//	ret = -1;;
-	return -1;
-}
-
-const CGHeroInstance* CGameHandler::getSelectedHero( int player )
+int CGameHandler::getCurrentPlayer()
 {
-	return getHero(gs->players.find(player)->second.currentSelection);
+	return gs->currentPlayer;
 }
 
-int CGameHandler::getDate(int mode)
-{
-	return getDate(mode);
-}
 void CGameHandler::giveResource(int player, int which, int val)
 {
 	SetResource sr;
@@ -2108,7 +2070,16 @@ void CGameHandler::changeSpells( int hid, bool give, const std::set<ui32> &spell
 	sendAndApply(&cs);
 }
 
-int CGameHandler::getCurrentPlayer()
+int CGameHandler::getSelectedHero() 
 {
-	return gs->currentPlayer;
+	return IGameCallback::getSelectedHero(getCurrentPlayer())->id;
+}
+
+void CGameHandler::setObjProperty( int objid, int prop, int val )
+{
+	SetObjectProperty sob;
+	sob.id = objid;
+	sob.what = prop;
+	sob.val = val;
+	sendAndApply(&sob);
 }

+ 167 - 173
server/CGameHandler.h

@@ -1,173 +1,167 @@
-#ifndef __CGAMEHANDLER_H__
-#define __CGAMEHANDLER_H__
-
-#include "../global.h"
-#include <set>
-#include "../client/FunctionList.h"
-#include "../CGameState.h"
-#include "../lib/Connection.h"
-#include "../lib/IGameCallback.h"
-#include <boost/function.hpp>
-#include <boost/thread.hpp>
-class CVCMIServer;
-class CGameState;
-struct StartInfo;
-class CCPPObjectScript;
-class CScriptCallback;
-struct BattleResult;
-struct BattleAttack;
-struct BattleStackAttacked;
-template <typename T> struct CPack;
-template <typename T> struct Query;
-class CGHeroInstance;
-extern std::map<ui32, CFunctionList<void(ui32)> > callbacks; //question id => callback functions - for selection dialogs
-extern boost::mutex gsm;
-
-struct PlayerStatus
-{
-	bool makingTurn, engagedIntoBattle;
-	std::set<ui32> queries;
-
-	PlayerStatus():makingTurn(false),engagedIntoBattle(false){};
-	template <typename Handler> void serialize(Handler &h, const int version)
-	{
-		h & makingTurn & engagedIntoBattle & queries;
-	}
-};
-class PlayerStatuses
-{
-public:
-	std::map<ui8,PlayerStatus> players;
-	boost::mutex mx;
-	boost::condition_variable cv; //notifies when any changes are made
-
-	void addPlayer(ui8 player);
-	PlayerStatus operator[](ui8 player);
-	bool hasQueries(ui8 player);
-	bool checkFlag(ui8 player, bool PlayerStatus::*flag);
-	void setFlag(ui8 player, bool PlayerStatus::*flag, bool val);
-	void addQuery(ui8 player, ui32 id);
-	void removeQuery(ui8 player, ui32 id);
-	template <typename Handler> void serialize(Handler &h, const int version)
-	{
-		h & players;
-	}
-};
-
-class CGameHandler : public IGameCallback
-{
-	static ui32 QID;
-	CGameState *gs;
-	//std::set<CCPPObjectScript *> cppscripts; //C++ scripts
-	//std::map<int, std::map<std::string, CObjectScript*> > objscr; //non-C++ scripts 
-
-	CVCMIServer *s;
-	std::map<int,CConnection*> connections; //player color -> connection to clinet with interface of that player
-	PlayerStatuses states; //player color -> player state
-	std::set<CConnection*> conns;
-
-	void changeSecSkill(int ID, ui16 which, int val, bool abs=false);
-	void giveSpells(const CGTownInstance *t, const CGHeroInstance *h);
-	void moveStack(int stack, int dest);
-	void startBattle(CCreatureSet army1, CCreatureSet army2, int3 tile, CGHeroInstance *hero1, CGHeroInstance *hero2, boost::function<void(BattleResult*)> cb); //use hero=NULL for no hero
-	void prepareAttack(BattleAttack &bat, CStack *att, CStack *def); //if last parameter is true, attack is by shooting, if false it's a melee attack
-	void prepareAttacked(BattleStackAttacked &bsa, CStack *def);
-	void checkForBattleEnd( std::vector<CStack*> &stacks );
-	void setupBattle( BattleInfo * curB, int3 tile, CCreatureSet &army1, CCreatureSet &army2, CGHeroInstance * hero1, CGHeroInstance * hero2 );
-
-public:
-	CGameHandler(void);
-	~CGameHandler(void);
-
-	//////////////////////////////////////////////////////////////////////////
-	//from IGameCallback
-	//get info
-	int getOwner(int heroID);
-	int getResource(int player, int which);
-	int getSelectedHero();
-	int getDate(int mode=0);
-	const CGObjectInstance* getObj(int objid);
-	const CGHeroInstance* getHero(int objid);
-	const CGTownInstance* getTown(int objid);
-	const CGHeroInstance* getSelectedHero(int player); //NULL if no hero is selected
-	int getCurrentPlayer();
-
-	//do sth
-	void changeSpells(int hid, bool give, const std::set<ui32> &spells);
-	void removeObject(int objid);
-	void setBlockVis(int objid, bool bv);
-	void setOwner(int objid, ui8 owner);
-	void setHoverName(int objid, MetaString * name);
-	void changePrimSkill(int ID, int which, int val, bool abs=false);
-	void showInfoDialog(InfoWindow *iw);
-	void showYesNoDialog(YesNoDialog *iw, const CFunctionList<void(ui32)> &callback);
-	void showSelectionDialog(SelectionDialog *iw, const CFunctionList<void(ui32)> &callback); //returns question id
-	void giveResource(int player, int which, int val);
-	void showCompInfo(ShowInInfobox * comp);
-	void heroVisitCastle(int obj, int heroID);
-	void stopHeroVisitCastle(int obj, int heroID);
-	void giveHeroArtifact(int artid, int hid, int position); //pos==-1 - first free slot in backpack; pos==-2 - default if available or backpack
-	void startBattleI(const CCreatureSet * army1, const CCreatureSet * army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, boost::function<void(BattleResult*)> cb); //use hero=NULL for no hero
-	void startBattleI(int heroID, CCreatureSet army, int3 tile, boost::function<void(BattleResult*)> cb); //for hero<=>neutral army
-	void setAmount(int objid, ui32 val);
-	void moveHero(int hid, int3 pos, bool instant);
-	//////////////////////////////////////////////////////////////////////////
-
-	void init(StartInfo *si, int Seed);
-	void handleConnection(std::set<int> players, CConnection &c);
-	template <typename Handler> void serialize(Handler &h, const int version)
-	{
-		h & QID & gs & states;
-	}
-	template <typename T> void applyAndAsk(Query<T> * sel, ui8 player, boost::function<void(ui32)> &callback)
-	{
-		gsm.lock();
-		sel->id = QID;
-		callbacks[QID] = callback;
-		states.addQuery(player,QID);
-		QID++; 
-		sendAndApply(sel);
-		gsm.unlock();
-	}
-	template <typename T> void ask(Query<T> * sel, ui8 player, const CFunctionList<void(ui32)> &callback)
-	{
-		gsm.lock();
-		sel->id = QID;
-		callbacks[QID] = callback;
-		states.addQuery(player,QID);
-		sendToAllClients(sel);
-		QID++; 
-		gsm.unlock();
-	}
-
-	template <typename T>void sendDataToClients(const T & data)
-	{
-		for(std::set<CConnection*>::iterator i=conns.begin(); i!=conns.end();i++)
-		{
-			(*i)->wmx->lock();
-			**i << data;
-			(*i)->wmx->unlock();
-		}
-	}
-	template <typename T>void sendToAllClients(CPack<T> * info)
-	{
-		for(std::set<CConnection*>::iterator i=conns.begin(); i!=conns.end();i++)
-		{
-			(*i)->wmx->lock();
-			**i << info->getType() << *info->This();
-			(*i)->wmx->unlock();
-		}
-	}
-	template <typename T>void sendAndApply(CPack<T> * info)
-	{
-		gs->apply(info);
-		sendToAllClients(info);
-	}
-	void run();
-	void newTurn();
-
-	friend class CVCMIServer;
-	friend class CScriptCallback;
-};
-
-#endif // __CGAMEHANDLER_H__
+#ifndef __CGAMEHANDLER_H__
+#define __CGAMEHANDLER_H__
+
+#include "../global.h"
+#include <set>
+#include "../client/FunctionList.h"
+#include "../CGameState.h"
+#include "../lib/Connection.h"
+#include "../lib/IGameCallback.h"
+#include <boost/function.hpp>
+#include <boost/thread.hpp>
+class CVCMIServer;
+class CGameState;
+struct StartInfo;
+class CCPPObjectScript;
+class CScriptCallback;
+struct BattleResult;
+struct BattleAttack;
+struct BattleStackAttacked;
+template <typename T> struct CPack;
+template <typename T> struct Query;
+class CGHeroInstance;
+extern std::map<ui32, CFunctionList<void(ui32)> > callbacks; //question id => callback functions - for selection dialogs
+extern boost::mutex gsm;
+
+struct PlayerStatus
+{
+	bool makingTurn, engagedIntoBattle;
+	std::set<ui32> queries;
+
+	PlayerStatus():makingTurn(false),engagedIntoBattle(false){};
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & makingTurn & engagedIntoBattle & queries;
+	}
+};
+class PlayerStatuses
+{
+public:
+	std::map<ui8,PlayerStatus> players;
+	boost::mutex mx;
+	boost::condition_variable cv; //notifies when any changes are made
+
+	void addPlayer(ui8 player);
+	PlayerStatus operator[](ui8 player);
+	bool hasQueries(ui8 player);
+	bool checkFlag(ui8 player, bool PlayerStatus::*flag);
+	void setFlag(ui8 player, bool PlayerStatus::*flag, bool val);
+	void addQuery(ui8 player, ui32 id);
+	void removeQuery(ui8 player, ui32 id);
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & players;
+	}
+};
+
+class CGameHandler : public IGameCallback
+{
+	static ui32 QID;
+	//std::set<CCPPObjectScript *> cppscripts; //C++ scripts
+	//std::map<int, std::map<std::string, CObjectScript*> > objscr; //non-C++ scripts 
+
+	CVCMIServer *s;
+	std::map<int,CConnection*> connections; //player color -> connection to clinet with interface of that player
+	PlayerStatuses states; //player color -> player state
+	std::set<CConnection*> conns;
+
+	void changeSecSkill(int ID, ui16 which, int val, bool abs=false);
+	void giveSpells(const CGTownInstance *t, const CGHeroInstance *h);
+	void moveStack(int stack, int dest);
+	void startBattle(CCreatureSet army1, CCreatureSet army2, int3 tile, CGHeroInstance *hero1, CGHeroInstance *hero2, boost::function<void(BattleResult*)> cb); //use hero=NULL for no hero
+	void prepareAttack(BattleAttack &bat, CStack *att, CStack *def); //if last parameter is true, attack is by shooting, if false it's a melee attack
+	void prepareAttacked(BattleStackAttacked &bsa, CStack *def);
+	void checkForBattleEnd( std::vector<CStack*> &stacks );
+	void setupBattle( BattleInfo * curB, int3 tile, CCreatureSet &army1, CCreatureSet &army2, CGHeroInstance * hero1, CGHeroInstance * hero2 );
+
+public:
+	CGameHandler(void);
+	~CGameHandler(void);
+
+	//////////////////////////////////////////////////////////////////////////
+	//from IGameCallback
+	//get info
+	int getCurrentPlayer();
+	int getSelectedHero();
+
+
+	//do sth
+	void changeSpells(int hid, bool give, const std::set<ui32> &spells);
+	void removeObject(int objid);
+	void setBlockVis(int objid, bool bv);
+	void setOwner(int objid, ui8 owner);
+	void setHoverName(int objid, MetaString * name);
+	void setObjProperty(int objid, int prop, int val);
+	void changePrimSkill(int ID, int which, int val, bool abs=false);
+	void showInfoDialog(InfoWindow *iw);
+	void showYesNoDialog(YesNoDialog *iw, const CFunctionList<void(ui32)> &callback);
+	void showSelectionDialog(SelectionDialog *iw, const CFunctionList<void(ui32)> &callback); //returns question id
+	void giveResource(int player, int which, int val);
+	void showCompInfo(ShowInInfobox * comp);
+	void heroVisitCastle(int obj, int heroID);
+	void stopHeroVisitCastle(int obj, int heroID);
+	void giveHeroArtifact(int artid, int hid, int position); //pos==-1 - first free slot in backpack; pos==-2 - default if available or backpack
+	void startBattleI(const CCreatureSet * army1, const CCreatureSet * army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, boost::function<void(BattleResult*)> cb); //use hero=NULL for no hero
+	void startBattleI(int heroID, CCreatureSet army, int3 tile, boost::function<void(BattleResult*)> cb); //for hero<=>neutral army
+	void setAmount(int objid, ui32 val);
+	void moveHero(int hid, int3 pos, bool instant);
+	//////////////////////////////////////////////////////////////////////////
+
+	void init(StartInfo *si, int Seed);
+	void handleConnection(std::set<int> players, CConnection &c);
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & QID & gs & states;
+	}
+	template <typename T> void applyAndAsk(Query<T> * sel, ui8 player, boost::function<void(ui32)> &callback)
+	{
+		gsm.lock();
+		sel->id = QID;
+		callbacks[QID] = callback;
+		states.addQuery(player,QID);
+		QID++; 
+		sendAndApply(sel);
+		gsm.unlock();
+	}
+	template <typename T> void ask(Query<T> * sel, ui8 player, const CFunctionList<void(ui32)> &callback)
+	{
+		gsm.lock();
+		sel->id = QID;
+		callbacks[QID] = callback;
+		states.addQuery(player,QID);
+		sendToAllClients(sel);
+		QID++; 
+		gsm.unlock();
+	}
+
+	template <typename T>void sendDataToClients(const T & data)
+	{
+		for(std::set<CConnection*>::iterator i=conns.begin(); i!=conns.end();i++)
+		{
+			(*i)->wmx->lock();
+			**i << data;
+			(*i)->wmx->unlock();
+		}
+	}
+	template <typename T>void sendToAllClients(CPack<T> * info)
+	{
+		for(std::set<CConnection*>::iterator i=conns.begin(); i!=conns.end();i++)
+		{
+			(*i)->wmx->lock();
+			**i << info->getType() << *info->This();
+			(*i)->wmx->unlock();
+		}
+	}
+	template <typename T>void sendAndApply(CPack<T> * info)
+	{
+		gs->apply(info);
+		sendToAllClients(info);
+	}
+	void run();
+	void newTurn();
+
+	friend class CVCMIServer;
+	friend class CScriptCallback;
+};
+
+#endif // __CGAMEHANDLER_H__