Browse Source

Slowly recovering object scripts.

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

+ 5 - 263
CCallback.cpp

@@ -8,7 +8,6 @@
 #include "mapHandler.h"
 #include "CGameState.h"
 #include "CPlayerInterface.h"
-#include "CLua.h"
 #include "hch/CGeneralTextHandler.h"
 #include "CAdvmapInterface.h"
 #include "CPlayerInterface.h"
@@ -99,8 +98,8 @@ bool CCallback::moveHero(int ID, CPath * path, int idtype, int pathType)
 void CCallback::selectionMade(int selection, int asker)
 {
 	//todo - jak bedzie multiplayer po sieci, to moze wymagac przerobek zaleznych od obranego modelu
-	IChosen * ask = (IChosen *)asker;
-	ask->chosen(selection);
+	//IChosen * ask = (IChosen *)asker;
+	//ask->chosen(selection);
 }
 void CCallback::recruitCreatures(const CGObjectInstance *obj, int ID, int amount)
 {
@@ -295,19 +294,8 @@ int CCallback::getDate(int mode)
 std::vector < std::string > CCallback::getObjDescriptions(int3 pos)
 {
 	std::vector<std::string> ret;
-	//BOOST_FOREACH(const CGObjectInstance * obj, gs->map->terrain[i][j]
-	//{
-	//	if( (5-(objs[g].first->pos.y-pos.y)) >= 0 && (5-(objs[g].first->pos.y-pos.y)) < 6 && (objs[g].first->pos.x-pos.x) >= 0 && (objs[g].first->pos.x-pos.x)<7 && objs[g].first->defInfo &&
-	//		(((objs[g].first->defInfo->blockMap[5-(objs[g].first->pos.y-pos.y)])>>((objs[g].first->pos.x-pos.x)))&1)==0
-	//		) //checking position blocking
-	//	{
-	//		//unsigned char * blm = objs[g].first->defInfo->blockMap;
-	//		if (objs[g].first->state)
-	//			ret.push_back(objs[g].first->state->hoverText(objs[g].first));
-	//		else
-	//			ret.push_back(CGI->objh->objects[objs[g].first->ID].name);
-	//	}
-	//}
+	BOOST_FOREACH(const CGObjectInstance * obj, gs->map->terrain[pos.x][pos.y][pos.z].blockingObjects)
+		ret.push_back(obj->hoverName);
 	return ret;
 }
 bool CCallback::verifyPath(CPath * path, bool blockSea)
@@ -646,250 +634,4 @@ bool CCallback::battleIsStackMine(int ID)
 			return CGI->state->curB->stacks[h]->owner == player;
 	}
 	return false;
-}
-
-int3 CScriptCallback::getPos(CGObjectInstance * ob)
-{
-	return ob->pos;
-}
-void CScriptCallback::changePrimSkill(int ID, int which, int val)
-{	
-	CGHeroInstance * hero = gs->map->getHero(ID,0);
-	if (which<PRIMARY_SKILLS)
-	{
-		hero->primSkills[which]+=val;
-		cl->playerint[hero->getOwner()]->heroPrimarySkillChanged(hero, which, val);
-	}
-	else if (which==4)
-	{
-		hero->exp+=val;
-		if(hero->exp >= CGI->heroh->reqExp(hero->level+1)) //new level
-		{
-			hero->level++;
-			std::cout << hero->name <<" got level "<<hero->level<<std::endl;
-			int r = rand()%100, pom=0, x=0;
-			int std::pair<int,int>::*g  =  (hero->level>9) ? (&std::pair<int,int>::second) : (&std::pair<int,int>::first);
-			for(;x<PRIMARY_SKILLS;x++)
-			{
-				pom += hero->type->heroClass->primChance[x].*g;
-				if(r<pom)
-					break;
-			}
-			std::cout << "Bohater dostaje umiejetnosc pierwszorzedna " << x << " (wynik losowania "<<r<<")"<<std::endl; 
-			hero->primSkills[x]++;
-
-			//TODO: dac dwie umiejetnosci 2-rzedne to wyboru
-
-		}
-		//TODO - powiadomic interfejsy, sprawdzic czy nie ma awansu itp
-	}
-}
-
-int CScriptCallback::getHeroOwner(int heroID)
-{
-	CGHeroInstance * hero = CGI->state->map->getHero(heroID,0);
-	return hero->getOwner();
-}
-void CScriptCallback::showInfoDialog(int player, std::string text, std::vector<SComponent*> * components)
-{
-	//TODO: upewniac sie ze mozemy to zrzutowac (przy customowych interfejsach cos moze sie kopnac)
-	if (player>=0)
-	{
-		CGameInterface * temp = cl->playerint[player];
-		if (temp->human)
-			((CPlayerInterface*)(temp))->showInfoDialog(text,*components);
-		return;
-	}
-	else
-	{
-		typedef std::pair<const ui8, CGameInterface*> intf;
-		BOOST_FOREACH(intf & i, cl->playerint)
-		{
-			if (i.second->human)
-				((CPlayerInterface*)(i.second))->showInfoDialog(text,*components);
-		}
-	}
-}
-
-void CScriptCallback::showSelDialog(int player, std::string text, std::vector<CSelectableComponent*>*components, IChosen * asker)
-{
-	CGameInterface * temp = cl->playerint[player];
-	if (temp->human)
-		((CPlayerInterface*)(temp))->showSelDialog(text,*components,(int)asker);
-	return;
-}
-int CScriptCallback::getSelectedHero()
-{	
-	int ret;
-	if (LOCPLINT->adventureInt->selection.type == HEROI_TYPE)
-		ret = ((CGHeroInstance*)(LOCPLINT->adventureInt->selection.selected))->subID;
-	else 
-		ret = -1;;
-	return ret;
-}
-int CScriptCallback::getDate(int mode)
-{
-	int temp;
-	switch (mode)
-	{
-	case 0:
-		return gs->day;
-		break;
-	case 1:
-		temp = (gs->day)%7;
-		if (temp)
-			return temp;
-		else return 7;
-		break;
-	case 2:
-		temp = ((gs->day-1)/7)+1;
-		if (!(temp%4))
-			return 4;
-		else 
-			return (temp%4);
-		break;
-	case 3:
-		return ((gs->day-1)/28)+1;
-		break;
-	}
-	return 0;
-}
-void CScriptCallback::giveResource(int player, int which, int val)
-{
-	gs->players[player].resources[which]+=val;
-	cl->playerint[player]->receivedResource(which,val);
-}
-void CScriptCallback::showCompInfo(int player, SComponent * comp)
-{
-	CPlayerInterface * i = dynamic_cast<CPlayerInterface*>(cl->playerint[player]);
-	if(i)
-		i->showComp(*comp);
-}
-void CScriptCallback::heroVisitCastle(CGObjectInstance * ob, int heroID)
-{
-	CGTownInstance * n;
-	if(n = dynamic_cast<CGTownInstance*>(ob))
-	{
-		n->visitingHero = CGI->state->map->getHero(heroID,0);
-		gs->map->getHero(heroID,0)->visitedTown = n;
-		cl->playerint[getHeroOwner(heroID)]->heroVisitsTown(CGI->state->map->getHero(heroID,0),n);
-	}
-	else
-		return;
-}
-
-void CScriptCallback::stopHeroVisitCastle(CGObjectInstance * ob, int heroID)
-{
-	CGTownInstance * n;
-	if(n = dynamic_cast<CGTownInstance*>(ob))
-	{
-		CGI->state->map->getHero(heroID,0)->visitedTown = NULL;
-		if(n->visitingHero && n->visitingHero->type->ID == heroID)
-			n->visitingHero = NULL;
-		return;
-	}
-	else
-		return;
-}
-void CScriptCallback::giveHeroArtifact(int artid, int hid, int position) //pos==-1 - first free slot in backpack
-{
-	CGHeroInstance* h = gs->map->getHero(hid,0);
-	if(position<0)
-	{
-		for(int i=0;i<h->artifacts.size();i++)
-		{
-			if(!h->artifacts[i])
-			{
-				h->artifacts[i] = artid;
-				return;
-			}
-		}
-		h->artifacts.push_back(artid);
-		return;
-	}
-	else
-	{
-		if(h->artifWorn[position]) //slot is occupied
-		{
-			giveHeroArtifact(h->artifWorn[position],hid,-1);
-		}
-		h->artifWorn[position] = artid;
-	}
-}
-
-void CScriptCallback::startBattle(CCreatureSet * army1, CCreatureSet * army2, int3 tile, CGHeroInstance *hero1, CGHeroInstance *hero2) //use hero=NULL for no hero
-{
-	gs->battle(army1,army2,tile,hero1,hero2);
-}
-void CScriptCallback::startBattle(int heroID, CCreatureSet * army, int3 tile) //for hero<=>neutral army
-{
-	CGHeroInstance* h = gs->map->getHero(heroID,0);
-	gs->battle(&h->army,army,tile,h,NULL);
-}
-void CLuaCallback::registerFuncs(lua_State * L)
-{
-//	lua_newtable(L);
-//
-//#define REGISTER_C_FUNC(x) \
-//	lua_pushstring(L, #x);      \
-//	lua_pushcfunction(L, x);    \
-//	lua_rawset(L, -3)
-//
-//	REGISTER_C_FUNC(getPos);
-//	REGISTER_C_FUNC(changePrimSkill);
-//	REGISTER_C_FUNC(getGnrlText);
-//	REGISTER_C_FUNC(getSelectedHero);
-//
-//	lua_setglobal(L, "vcmi");
-//	#undef REGISTER_C_FUNC
-}
-int CLuaCallback::getPos(lua_State * L)//(CGObjectInstance * object);
-{	
-	//const int args = lua_gettop(L); // number of arguments
-	//if ((args < 1) || !lua_isnumber(L, 1) )
-	//	luaL_error(L,
-	//		"Incorrect arguments to getPos([Object address])");
-	//CGObjectInstance * object = (CGObjectInstance *)(lua_tointeger(L, 1));
-	//lua_pushinteger(L,object->pos.x);
-	//lua_pushinteger(L,object->pos.y);
-	//lua_pushinteger(L,object->pos.z);
-	return 3;
-}
-int CLuaCallback::changePrimSkill(lua_State * L)//(int ID, int which, int val);
-{	
-	//const int args = lua_gettop(L); // number of arguments
-	//if ((args < 1) || !lua_isnumber(L, 1) ||
-	//    ((args >= 2) && !lua_isnumber(L, 2)) ||
-	//    ((args >= 3) && !lua_isnumber(L, 3))		)
-	//{
-	//	luaL_error(L,
-	//		"Incorrect arguments to changePrimSkill([Hero ID], [Which Primary skill], [Change by])");
-	//}
-	//int ID = lua_tointeger(L, 1),
-	//	which = lua_tointeger(L, 2),
-	//	val = lua_tointeger(L, 3);
-
-	//CScriptCallback::changePrimSkill(ID,which,val);
-
-	return 0;
-}
-int CLuaCallback::getGnrlText(lua_State * L) //(int which),returns string
-{
-	//const int args = lua_gettop(L); // number of arguments
-	//if ((args < 1) || !lua_isnumber(L, 1) )
-	//	luaL_error(L,
-	//		"Incorrect arguments to getGnrlText([Text ID])");
-	//int which = lua_tointeger(L,1);
-	//lua_pushstring(L,CGI->generaltexth->allTexts[which].c_str());
-	return 1;
-}
-int CLuaCallback::getSelectedHero(lua_State * L) //(),returns int (ID of hero, -1 if no hero is seleceted)
-{
-	//int ret;
-	//if (LOCPLINT->adventureInt->selection.type == HEROI_TYPE)
-	//	ret = ((CGHeroInstance*)(LOCPLINT->adventureInt->selection.selected))->subID;
-	//else 
-	//	ret = -1;
-	//lua_pushinteger(L,ret);
-	return 1;
-}
+}

+ 0 - 42
CCallback.h

@@ -152,46 +152,4 @@ public:
 //friends
 	friend class CClient;
 };
-class CScriptCallback
-{
-	CScriptCallback(){};
-public:
-	CGameState * gs;
-	CClient *cl;
-
-	//get info
-	static int3 getPos(CGObjectInstance * ob);
-	int getHeroOwner(int heroID);
-	int getSelectedHero();
-	int getDate(int mode=0);
-
-	//do sth
-	void changePrimSkill(int ID, int which, int val);
-	void showInfoDialog(int player, std::string text, std::vector<SComponent*> * components); //TODO: obslugiwac nulle
-	void showSelDialog(int player, std::string text, std::vector<CSelectableComponent*>*components, IChosen * asker);
-	void giveResource(int player, int which, int val);
-	void showCompInfo(int player, SComponent * comp);
-	void heroVisitCastle(CGObjectInstance * ob, int heroID);
-	void stopHeroVisitCastle(CGObjectInstance * ob, int heroID);
-	void giveHeroArtifact(int artid, int hid, int position); //pos==-1 - first free slot in backpack
-	void startBattle(CCreatureSet * army1, CCreatureSet * army2, int3 tile, CGHeroInstance *hero1, CGHeroInstance *hero2); //use hero=NULL for no hero
-	void startBattle(int heroID, CCreatureSet * army, int3 tile); //for hero<=>neutral army
-
-	//friends
-	friend class CGameState;
-	friend class CClient;
-};
-class CLuaCallback : public CScriptCallback
-{
-private:
-
-	static void registerFuncs(lua_State * L);
-	static int getPos(lua_State * L);//(CGObjectInstance * object);
-	static int changePrimSkill(lua_State * L);//(int ID, int which, int val);
-	static int getGnrlText(lua_State * L);//(int ID, int which, int val);
-	static int getSelectedHero(lua_State * L);//()
-
-	friend class CGameState;
-	friend class CClient;
-};
 #endif //CCALLBACK_H

+ 23 - 81
CGameState.cpp

@@ -3,10 +3,6 @@
 #include <queue>
 #include <fstream>
 #include "CGameState.h"
-#include "CGameInterface.h"
-#include "CPlayerInterface.h"
-#include "SDL_Extensions.h"
-#include "CBattleInterface.h" //for CBattleHex
 #include <boost/random/linear_congruential.hpp>
 #include "hch/CDefObjInfoHandler.h"
 #include "hch/CArtHandler.h"
@@ -17,14 +13,10 @@
 #include "lib/VCMI_Lib.h"
 #include "map.h"
 #include "StartInfo.h"
-#include "CLua.h"
-#include "CCallback.h"
-#include "CLuaHandler.h"
 #include "lib/NetPacks.h"
 #include <boost/foreach.hpp>
 #include <boost/thread.hpp>
 #include <boost/thread/shared_mutex.hpp>
-
 boost::rand48 ran;
 class CMP_stack
 {
@@ -143,6 +135,28 @@ void CGameState::apply(IPack * pack)
 				players[h->getOwner()].fogOfWarMap[t.x][t.y][t.z] = 1;
 			break;
 		}
+	case 1001://set object property
+		{
+			SetObjectProperty *p = static_cast<SetObjectProperty*>(pack);
+			int CGObjectInstance::*point;
+			switch(p->what)
+			{
+			case 1:
+				point = &CGObjectInstance::tempOwner;
+				break;
+			case 2:
+				point = &CGObjectInstance::blockVisit;
+				break;
+			}
+			map->objects[p->id]->*point = p->val;
+			break;
+		}
+	//case 1002://set hover name
+	//	{
+	//		SetHoverName * shn = static_cast<SetHoverName*>(pack);
+	//		map->objects[shn->id]->hoverName = toString(shn->name);
+	//		break;
+	//	}
 	}
 	mx->unlock();
 }
@@ -395,18 +409,6 @@ CGameState::~CGameState()
 {
 	delete mx;
 }
-bool CGameState::checkFunc(int obid, std::string name)
-{
-	if (objscr.find(obid)!=objscr.end())
-	{
-		if(objscr[obid].find(name)!=objscr[obid].end())
-		{
-			return true;
-		}
-	}
-	return false;
-}
-
 void CGameState::init(StartInfo * si, Mapa * map, int Seed)
 {
 	day = 0;
@@ -441,6 +443,7 @@ void CGameState::init(StartInfo * si, Mapa * map, int Seed)
 		randomizeObject(map->objects[no]);
 		if(map->objects[no]->ID==26)
 			map->objects[no]->defInfo->handler=NULL;
+		map->objects[no]->hoverName = VLC->objh->names[map->objects[no]->ID];
 	}
 	//std::cout<<"\tRandomizing objects: "<<th.getDif()<<std::endl;
 
@@ -651,67 +654,6 @@ void CGameState::init(StartInfo * si, Mapa * map, int Seed)
 			}
 		}
 	}
-
-	///****************************SCRIPTS************************************************/
-	//std::map<int, std::map<std::string, CObjectScript*> > * skrypty = &objscr; //alias for easier access
-	///****************************C++ OBJECT SCRIPTS************************************************/
-	//std::map<int,CCPPObjectScript*> scripts;
-	//CScriptCallback * csc = new CScriptCallback();
-	//csc->gs = this;
-	//handleCPPObjS(&scripts,new CVisitableOPH(csc));
-	//handleCPPObjS(&scripts,new CVisitableOPW(csc));
-	//handleCPPObjS(&scripts,new CPickable(csc));
-	//handleCPPObjS(&scripts,new CMines(csc));
-	//handleCPPObjS(&scripts,new CTownScript(csc));
-	//handleCPPObjS(&scripts,new CHeroScript(csc));
-	//handleCPPObjS(&scripts,new CMonsterS(csc));
-	//handleCPPObjS(&scripts,new CCreatureGen(csc));
-	////created map
-
-	///****************************LUA OBJECT SCRIPTS************************************************/
-	//std::vector<std::string> * lf = CLuaHandler::searchForScripts("scripts/lua/objects"); //files
-	//for (int i=0; i<lf->size(); i++)
-	//{
-	//	try
-	//	{
-	//		std::vector<std::string> * temp =  CLuaHandler::functionList((*lf)[i]);
-	//		CLuaObjectScript * objs = new CLuaObjectScript((*lf)[i]);
-	//		CLuaCallback::registerFuncs(objs->is);
-	//		//objs
-	//		for (int j=0; j<temp->size(); j++)
-	//		{
-	//			int obid ; //obj ID
-	//			int dspos = (*temp)[j].find_first_of('_');
-	//			obid = atoi((*temp)[j].substr(dspos+1,(*temp)[j].size()-dspos-1).c_str());
-	//			std::string fname = (*temp)[j].substr(0,dspos);
-	//			if (skrypty->find(obid)==skrypty->end())
-	//				skrypty->insert(std::pair<int, std::map<std::string, CObjectScript*> >(obid,std::map<std::string,CObjectScript*>()));
-	//			(*skrypty)[obid].insert(std::pair<std::string, CObjectScript*>(fname,objs));
-	//		}
-	//		delete temp;
-	//	}HANDLE_EXCEPTION
-	//}
-	///****************************INITIALIZING OBJECT SCRIPTS************************************************/
-	//std::string temps("newObject");
-	//for (int i=0; i<map->objects.size(); i++)
-	//{
-	//	//c++ scripts
-	//	if (scripts.find(map->objects[i]->ID) != scripts.end())
-	//	{
-	//		map->objects[i]->state = scripts[map->objects[i]->ID];
-	//		map->objects[i]->state->newObject(map->objects[i]);
-	//	}
-	//	else 
-	//	{
-	//		map->objects[i]->state = NULL;
-	//	}
-
-	//	// lua scripts
-	//	if(checkFunc(map->objects[i]->ID,temps))
-	//		(*skrypty)[map->objects[i]->ID][temps]->newObject(map->objects[i]);
-	//}
-
-	//delete lf;
 }
 void CGameState::battle(CCreatureSet * army1, CCreatureSet * army2, int3 tile, CArmedInstance *hero1, CArmedInstance *hero2)
 {/*

+ 0 - 3
CGameState.h

@@ -78,8 +78,6 @@ private:
 	ui32 day; //total number of days in game
 	Mapa * map;
 	std::map<ui8,PlayerState> players; //ID <-> playerstate
-	std::set<CCPPObjectScript *> cppscripts; //C++ scripts
-	std::map<int, std::map<std::string, CObjectScript*> > objscr; //non-C++ scripts 
 	
 	std::map<int, CGDefInfo*> villages, forts, capitols; //def-info for town graphics
 
@@ -87,7 +85,6 @@ private:
 
 	CGameState();
 	~CGameState();
-	bool checkFunc(int obid, std::string name);
 	void init(StartInfo * si, Mapa * map, int Seed);
 	void apply(IPack * pack);
 	void randomizeObject(CGObjectInstance *cur);

+ 356 - 357
CLua.cpp

@@ -1,29 +1,26 @@
 #include "stdafx.h"
-#include "CLua.h"
-#include "CLuaHandler.h"
+#include <sstream>
+#include <boost/algorithm/string.hpp>
+#include <boost/algorithm/string/replace.hpp>
 #include "hch/CHeroHandler.h"
+#include "hch/CObjectHandler.h"
+#include "hch/CTownHandler.h"
+#include "hch/CArtHandler.h"
+#include "hch/CDefObjInfoHandler.h"
 //#include "lua.h"
 //#include "lualib.h"
 //#include "lauxlib.h"
 //#include "lobject.h"
 //#include "lgc.h"
 //#include "lapi.h"
-#include "CGameInfo.h"
+#include "CLua.h"
 #include "CGameState.h"
-#include <sstream>
-#include "hch/CObjectHandler.h"
-#include "hch/CTownHandler.h"
-#include "hch/CArtHandler.h"
-#include "CCallback.h"
-#include "hch/CGeneralTextHandler.h"
-#include <sstream>
-#include "CPlayerInterface.h"
-#include <boost/algorithm/string.hpp>
-#include <boost/algorithm/string/replace.hpp>
-#include "hch/CDefObjInfoHandler.h"
+#include "lib/VCMI_Lib.h"
 #include "map.h"
-#include "maphandler.h"
+#include "server/CScriptCallback.h"
+#include "lib/NetPacks.h"
 #pragma warning (disable : 4311)
+#define DEFOS const CGObjectInstance *os = cb->getObj(objid)
 bool getGlobalFunc(lua_State * L, std::string fname)
 {
 	//unsigned int hash = lua_calchash(fname.c_str(), fname.size());
@@ -138,7 +135,7 @@ std::string CLuaObjectScript::genFN(std::string base, int ID)
 	return sts.str();
 }
 
-void CLuaObjectScript::newObject(CGObjectInstance *os)
+void CLuaObjectScript::newObject(int objid)
 {
 	//findF(genFN("newObject",os->ID));
 	//lua_pushinteger(is, (int)os);
@@ -150,7 +147,7 @@ void CLuaObjectScript::newObject(CGObjectInstance *os)
 	//lua_settop(is, 0);
 	return;
 }
-void CLuaObjectScript::onHeroVisit(CGObjectInstance *os, int heroID)
+void CLuaObjectScript::onHeroVisit(int objid, int heroID)
 {
 	//findF(genFN("heroVisit",os->ID));
 	//lua_pushinteger(is, (int)os);
@@ -162,43 +159,75 @@ void CLuaObjectScript::onHeroVisit(CGObjectInstance *os, int heroID)
 	//}
 	//lua_settop(is, 0);
 }
-std::string CLuaObjectScript::hoverText(CGObjectInstance *os)
+//std::string CLuaObjectScript::hoverText(int objid)
+//{
+//	//findF(genFN("hoverText",os->ID));
+//	//lua_pushinteger(is, (int)os);
+//	//if (lua_pcall (is, 1, 1, 0))
+//	//{
+//	//	lua_settop(is, 0);
+//	//	throw new  std::exception(("Failed to call "+genFN("hoverText",os->ID)+" function in lua script.").c_str());
+//	//}
+//	//std::string ret = lua_tostring(is,1);
+//	//lua_settop(is, 0);
+//	return "";
+//}
+
+void CVisitableOPH::newObject(int objid)
 {
-	//findF(genFN("hoverText",os->ID));
-	//lua_pushinteger(is, (int)os);
-	//if (lua_pcall (is, 1, 1, 0))
-	//{
-	//	lua_settop(is, 0);
-	//	throw new  std::exception(("Failed to call "+genFN("hoverText",os->ID)+" function in lua script.").c_str());
-	//}
-	//std::string ret = lua_tostring(is,1);
-	//lua_settop(is, 0);
-	return "";
-}
+	visitors.insert
+		(std::pair<int,std::set<int> >(objid,std::set<int>()));
 
-std::string CCPPObjectScript::hoverText(CGObjectInstance *os)
-{
-	return CGI->objh->objects[os->defInfo->id].name;
-}
+	DEFOS;
+	MetaString hovername;
+	int pom;
+	switch(os->ID)
+	{
+	case 51:
+		pom = 8; 
+		break;
+	case 23:
+		pom = 7;
+		break;
+	case 61:
+		pom = 11; 
+		break;
+	case 32:
+		pom = 4; 
+		break;
+	case 100:
+		pom = 5; 
+		break;
+	default:
+		throw new std::exception("Unsupported ID in CVisitableOPH::hoverText");
+	}
 
-void CVisitableOPH::newObject(CGObjectInstance *os)
-{
-	visitors.insert
-		(std::pair<CGObjectInstance*,std::set<int> >(os,std::set<int>()));
+	hovername << std::pair<ui8,ui32>(3,os->ID) << " " << std::pair<ui8,ui32>(2,pom);
+	cb->setHoverName(objid,&hovername);
+
+	//int heroID = cb->getSelectedHero();
+	//if (heroID>=0)
+	//{
+		//add += ( (visitors[os].find(heroID) == visitors[os].end()) 
+		//		? 
+		//	(VLC->generaltexth->allTexts[353])  //not visited
+		//		: 
+		//	( VLC->generaltexth->allTexts[352]) ); //visited
+	//}
 };
 
-void CVisitableOPH::onHeroVisit(CGObjectInstance *os, int heroID)
+void CVisitableOPH::onHeroVisit(int objid, int heroID)
 {
-	if (visitors.find(os)!=visitors.end())
+	if (visitors.find(objid)!=visitors.end())
 	{
-		if(visitors[os].find(heroID)==visitors[os].end())
+		if(visitors[objid].find(heroID)==visitors[objid].end())
 		{
-			onNAHeroVisit(os,heroID, false);
-			visitors[os].insert(heroID);
+			onNAHeroVisit(objid,heroID, false);
+			visitors[objid].insert(heroID);
 		}
 		else
 		{
-			onNAHeroVisit(os,heroID, true);
+			onNAHeroVisit(objid,heroID, true);
 		}
 	}
 	else
@@ -206,8 +235,9 @@ void CVisitableOPH::onHeroVisit(CGObjectInstance *os, int heroID)
 		throw new std::exception("Skrypt nie zainicjalizowal instancji tego obiektu. :(");
 	}
 };
-void CVisitableOPH::onNAHeroVisit(CGObjectInstance *os, int heroID, bool alreadyVisited)
+void CVisitableOPH::onNAHeroVisit(int objid, int heroID, bool alreadyVisited)
 {
+	const CGObjectInstance *os = cb->getObj(objid);
 	int w=0, ot=0, vvv=1;
 	switch(os->ID)
 	{
@@ -242,30 +272,26 @@ void CVisitableOPH::onNAHeroVisit(CGObjectInstance *os, int heroID, bool already
 		case 61:
 		case 32:
 			{
-				cb->changePrimSkill(heroID,w,vvv);
-				std::vector<SComponent*> weko;
-				weko.push_back(new SComponent(SComponent::primskill,w,vvv)); 
-				cb->showInfoDialog(cb->getHeroOwner(heroID),CGI->objh->advobtxt[ot],&weko); 
-				//for (int ii=0; ii<weko.size();ii++)
-				//	delete weko[ii];
-				break;
+				//cb->changePrimSkill(heroID,w,vvv);
+				//std::vector<SComponent*> weko;
+				//weko.push_back(new SComponent(SComponent::primskill,w,vvv)); 
+				//cb->showInfoDialog(cb->getHeroOwner(heroID),VLC->objh->advobtxt[ot],&weko); 
+				//break;
 			}
 		case 100:
 			{
-				cb->changePrimSkill(heroID,w,vvv);
-				std::vector<SComponent*> weko;
-				weko.push_back(new SComponent(SComponent::experience,0,vvv)); 
-				cb->showInfoDialog(cb->getHeroOwner(heroID),CGI->objh->advobtxt[ot],&weko); 
-				//for (int ii=0; ii<weko.size();ii++)
-				//	delete weko[ii];
-				break;
+				//cb->changePrimSkill(heroID,w,vvv);
+				//std::vector<SComponent*> weko;
+				//weko.push_back(new SComponent(SComponent::experience,0,vvv)); 
+				//cb->showInfoDialog(cb->getHeroOwner(heroID),VLC->objh->advobtxt[ot],&weko); 
+				//break;
 			}
 		}
 	}
 	else
 	{
 		ot++;
-		cb->showInfoDialog(cb->getHeroOwner(heroID),CGI->objh->advobtxt[ot],&std::vector<SComponent*>());
+		cb->showInfoDialog(cb->getHeroOwner(heroID),VLC->objh->advobtxt[ot],&std::vector<SComponent*>());
 	}
 }
 
@@ -280,126 +306,93 @@ std::vector<int> CVisitableOPH::yourObjects()
 	return ret;
 }
 
-std::string CVisitableOPH::hoverText(CGObjectInstance *os)
-{
-	std::string add;
-	int pom;
-	switch(os->ID)
-	{
-	case 51:
-		pom = 8; 
-		break;
-	case 23:
-		pom = 7;
-		break;
-	case 61:
-		pom = 11; 
-		break;
-	case 32:
-		pom = 4; 
-		break;
-	case 100:
-		pom = 5; 
-		break;
-	default:
-		throw new std::exception("Unsupported ID in CVisitableOPH::hoverText");
-	}
-	add = " " + CGI->objh->xtrainfo[pom] + " ";
-	int heroID = cb->getSelectedHero();
-	if (heroID>=0)
-	{
-		add += ( (visitors[os].find(heroID) == visitors[os].end()) 
-				? 
-			(CGI->generaltexth->allTexts[353])  //not visited
-				: 
-			( CGI->generaltexth->allTexts[352]) ); //visited
-	}
-	return CGI->objh->objects[os->defInfo->id].name + add;
-}
-
-void CVisitableOPW::onNAHeroVisit(CGObjectInstance *os, int heroID, bool alreadyVisited)
+void CVisitableOPW::onNAHeroVisit(int objid, int heroID, bool alreadyVisited)
 {
-	int mid;
-	switch (os->ID)
-	{
-	case 55:
-		mid = 92;
-		break;
-	case 112:
-		mid = 170;
-		break;
-	case 109:
-		mid = 164;
-		break;
-	}
-	if (alreadyVisited)
-	{
-		if (os->ID!=112)
-			mid++;
-		else 
-			mid--;
-		cb->showInfoDialog(cb->getHeroOwner(heroID),CGI->objh->advobtxt[mid],&std::vector<SComponent*>()); //TODO: maybe we have memory leak with these windows
-	}
-	else
-	{
-		int type, sub, val;
-		type = SComponent::resource;
-		switch (os->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;
-		}
-		SComponent * com = new SComponent((SComponent::Etype)type,sub,val);
-		std::vector<SComponent*> weko;
-		weko.push_back(com);
-		cb->giveResource(cb->getHeroOwner(heroID),sub,val);
-		cb->showInfoDialog(cb->getHeroOwner(heroID),CGI->objh->advobtxt[mid],&weko);
-		visited[os] = true;
-	}
+	//int mid;
+	//switch (os->ID)
+	//{
+	//case 55:
+	//	mid = 92;
+	//	break;
+	//case 112:
+	//	mid = 170;
+	//	break;
+	//case 109:
+	//	mid = 164;
+	//	break;
+	//}
+	//if (alreadyVisited)
+	//{
+	//	if (os->ID!=112)
+	//		mid++;
+	//	else 
+	//		mid--;
+	//	cb->showInfoDialog(cb->getHeroOwner(heroID),VLC->objh->advobtxt[mid],&std::vector<SComponent*>()); //TODO: maybe we have memory leak with these windows
+	//}
+	//else
+	//{
+	//	int type, sub, val;
+	//	type = SComponent::resource;
+	//	switch (os->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;
+	//	}
+	//	SComponent * com = new SComponent((SComponent::Etype)type,sub,val);
+	//	std::vector<SComponent*> weko;
+	//	weko.push_back(com);
+	//	cb->giveResource(cb->getHeroOwner(heroID),sub,val);
+	//	cb->showInfoDialog(cb->getHeroOwner(heroID),VLC->objh->advobtxt[mid],&weko);
+	//	visited[os] = true;
+	//}
 }
 void CVisitableOPW::newTurn ()
 {
 	if (cb->getDate(1)==1)
 	{
-		for (std::map<CGObjectInstance*,bool>::iterator i = visited.begin(); i != visited.end(); i++)
+		for (std::map<int,bool>::iterator i = visited.begin(); i != visited.end(); i++)
 		{
 			(*i).second = false;
 		}
 	}
 } 
-void CVisitableOPW::newObject(CGObjectInstance *os)
+void CVisitableOPW::newObject(int objid)
 {
-	visited.insert(std::pair<CGObjectInstance*,bool>(os,false));
+	visited.insert(std::pair<int,bool>(objid,false));
+	DEFOS;
+	MetaString ms;
+	ms << std::pair<ui8,ui32>(3,os->ID) << " " << std::pair<ui8,ui32>(1,visited[objid] ? 352 : 353);
+	cb->setHoverName(objid,&ms);
 }
 
-void CVisitableOPW::onHeroVisit(CGObjectInstance *os, int heroID)
+void CVisitableOPW::onHeroVisit(int objid, int heroID)
 {
-	if(visited[os])
-		onNAHeroVisit(os,heroID,true);
+	if(visited[objid])
+		onNAHeroVisit(objid,heroID,true);
 	else 
-		onNAHeroVisit(os,heroID,false);
+		onNAHeroVisit(objid,heroID,false);
 }
 
 std::vector<int> CVisitableOPW::yourObjects() //returns IDs of objects which are handled by script
@@ -411,38 +404,43 @@ std::vector<int> CVisitableOPW::yourObjects() //returns IDs of objects which are
 	return ret;
 }
 
-std::string CVisitableOPW::hoverText(CGObjectInstance *os)
-{
-	return CGI->objh->objects[os->defInfo->id].name + " " + ( (visited[os]) ? (CGI->generaltexth->allTexts[352]) : (CGI->generaltexth->allTexts[353]))  ;
-}
-
-void CMines::newObject(CGObjectInstance *os)
-{
-	ourObjs.push_back(os);
-	os->tempOwner = NEUTRAL_PLAYER;
-}
-void CMines::onHeroVisit(CGObjectInstance *os, int heroID)
-{
-	int vv = 1;
-	if (os->subID==0 || os->subID==2)
-		vv++;
-	else if (os->subID==6)
-		vv = 1000;
-	if (os->tempOwner == cb->getHeroOwner(heroID))
-	{
-		//TODO: garrison
-	}
-	else
-	{
-		if (os->subID==7)
-			return; //TODO: support for abandoned mine
-		os->tempOwner = cb->getHeroOwner(heroID);
-		SComponent * com = new SComponent(SComponent::Etype::resource,os->subID,vv);
-		com->subtitle+=CGI->generaltexth->allTexts[3].substr(2,CGI->generaltexth->allTexts[3].length()-2);
-		std::vector<SComponent*> weko;
-		weko.push_back(com);
-		cb->showInfoDialog(cb->getHeroOwner(heroID),CGI->objh->mines[os->subID].second,&weko);
-	}
+void CMines::newObject(int objid)
+{
+	ourObjs.push_back(objid);
+	cb->setOwner(objid,NEUTRAL_PLAYER);
+	DEFOS;
+	MetaString ms;
+	ms << std::pair<ui8,ui32>(3,os->ID);
+	cb->setHoverName(objid,&ms);
+}
+void CMines::onHeroVisit(int objid, int heroID)
+{
+	DEFOS;
+	const CGHeroInstance *h = cb->getHero(heroID);
+	cb->setOwner(objid,h->tempOwner);
+	MetaString ms;
+	ms << std::pair<ui8,ui32>(9,os->subID) << " " << std::pair<ui8,ui32>(6,23+h->tempOwner);
+	cb->setHoverName(objid,&ms);
+	//int vv = 1;
+	//if (os->subID==0 || os->subID==2)
+	//	vv++;
+	//else if (os->subID==6)
+	//	vv = 1000;
+	//if (os->tempOwner == cb->getHeroOwner(heroID))
+	//{
+	//	//TODO: garrison
+	//}
+	//else
+	//{
+	//	if (os->subID==7)
+	//		return; //TODO: support for abandoned mine
+	//	os->tempOwner = cb->getHeroOwner(heroID);
+	//	SComponent * com = new SComponent(SComponent::Etype::resource,os->subID,vv);
+	//	com->subtitle+=VLC->generaltexth->allTexts[3].substr(2,VLC->generaltexth->allTexts[3].length()-2);
+	//	std::vector<SComponent*> weko;
+	//	weko.push_back(com);
+	//	cb->showInfoDialog(cb->getHeroOwner(heroID),VLC->objh->mines[os->subID].second,&weko);
+	//}
 }
 std::vector<int> CMines::yourObjects()
 {
@@ -450,36 +448,48 @@ std::vector<int> CMines::yourObjects()
 	ret.push_back(53);
 	return ret;
 }
-std::string CMines::hoverText(CGObjectInstance *os)
-{
-	if (os->tempOwner == NEUTRAL_PLAYER)
-		return CGI->objh->mines[os->subID].first;
-	else
-		return CGI->objh->mines[os->subID].first + " " + CGI->generaltexth->arraytxt[23+os->tempOwner];
-
-}
 void CMines::newTurn ()
 {
-	for (int i=0;i<ourObjs.size();i++)
+	const CGObjectInstance * obj;
+	for (unsigned i=0;i<ourObjs.size();i++)
 	{
-		if (ourObjs[i]->tempOwner == NEUTRAL_PLAYER)
+		obj = cb->getObj(ourObjs[i]);
+		if (obj->tempOwner == NEUTRAL_PLAYER)
 			continue;
 		int vv = 1;
-		if (ourObjs[i]->subID==0 || ourObjs[i]->subID==2)
+		if (obj->subID==0 || obj->subID==2)
 			vv++;
-		else if (ourObjs[i]->subID==6)
+		else if (obj->subID==6)
 			vv = 1000;
-		cb->giveResource(ourObjs[i]->tempOwner,ourObjs[i]->subID,vv);
+		cb->giveResource(obj->tempOwner,obj->subID,vv);
 	}
 }
 
 
-void CPickable::newObject(CGObjectInstance *os)
+void CPickable::newObject(int objid)
 {
-	os->blockVisit = true;
+	cb->setBlockVis(objid,true);
+
+	MetaString ms;
+	DEFOS;
+	switch (os->ID)
+	{
+	case 79:
+		ms << std::pair<ui8,ui32>(4,os->ID);
+		break;
+	case 5:
+		ms << std::pair<ui8,ui32>(5,os->ID);
+		break;
+	default:
+		ms << std::pair<ui8,ui32>(3,os->ID);
+		break;
+	}
+
+	cb->setHoverName(objid,&ms);
 }
-void CPickable::onHeroVisit(CGObjectInstance *os, int heroID)
+void CPickable::onHeroVisit(int objid, int heroID)
 {
+	DEFOS;
 	switch(os->ID)
 	{
 	case 5:
@@ -489,109 +499,93 @@ void CPickable::onHeroVisit(CGObjectInstance *os, int heroID)
 		}
 	case 79:
 		{
-			//TODO: handle guards (when battles are finished)
-			CResourceObjInfo * t2 = static_cast<CResourceObjInfo *>(os->info);
-			int val;
-			if(t2->amount)
-				val = t2->amount;
-			else
-			{
-				switch(os->subID)
-				{
-				case 6:
-					val = 500 + (rand()%6)*100;
-					break;
-				case 0: case 2:
-					val = 6 + (rand()%5);
-					break;
-				default:
-					val = 3 + (rand()%3);
-					break;
-				}
-			}
-			if(t2->message.length())
-				cb->showInfoDialog(cb->getHeroOwner(heroID),t2->message,&std::vector<SComponent*>());
-			SComponent ccc(SComponent::resource,os->subID,val);
-			ccc.description = CGI->objh->advobtxt[113];
-			boost::algorithm::replace_first(ccc.description,"%s",CGI->objh->restypes[os->subID]);
-			cb->giveResource(cb->getHeroOwner(heroID),os->subID,val);
-			cb->showCompInfo(cb->getHeroOwner(heroID),&ccc);
+			////TODO: handle guards (when battles are finished)
+			//CResourceObjInfo * t2 = static_cast<CResourceObjInfo *>(os->info);
+			//int val;
+			//if(t2->amount)
+			//	val = t2->amount;
+			//else
+			//{
+			//	switch(os->subID)
+			//	{
+			//	case 6:
+			//		val = 500 + (rand()%6)*100;
+			//		break;
+			//	case 0: case 2:
+			//		val = 6 + (rand()%5);
+			//		break;
+			//	default:
+			//		val = 3 + (rand()%3);
+			//		break;
+			//	}
+			//}
+			//if(t2->message.length())
+			//	cb->showInfoDialog(cb->getHeroOwner(heroID),t2->message,&std::vector<SComponent*>());
+			//SComponent ccc(SComponent::resource,os->subID,val);
+			//ccc.description = VLC->objh->advobtxt[113];
+			//boost::algorithm::replace_first(ccc.description,"%s",VLC->objh->restypes[os->subID]);
+			//cb->giveResource(cb->getHeroOwner(heroID),os->subID,val);
+			//cb->showCompInfo(cb->getHeroOwner(heroID),&ccc);
 			break;
 		}
 	case 101:
 		{
-			if (os->subID)
-				break; //not OH3 treasure chest
-			int wyn = rand()%100;
-			if (wyn<32)
-			{
-				tempStore.push_back(new CSelectableComponent(SComponent::resource,6,1000));
-				tempStore.push_back(new CSelectableComponent(SComponent::experience,0,500));
-			}//1k/0.5k
-			else if(wyn<64)
-			{
-				tempStore.push_back(new CSelectableComponent(SComponent::resource,6,1500));
-				tempStore.push_back(new CSelectableComponent(SComponent::experience,0,1000));
-			}//1.5k/1k
-			else if(wyn<95)
-			{
-				tempStore.push_back(new CSelectableComponent(SComponent::resource,6,2000));
-				tempStore.push_back(new CSelectableComponent(SComponent::experience,0,1500));
-			}//2k/1.5k
-			else
-			{
-				if (1/*TODO: backpack is full*/)
-				{
-					tempStore.push_back(new CSelectableComponent(SComponent::resource,6,1000));
-					tempStore.push_back(new CSelectableComponent(SComponent::experience,0,500));
-				}
-				else
-				{
-					//TODO: give treasure artifact
-					break;
-				}
-			}//random treasure artifact, or (if backapack is full) 1k/0.5k
-			tempStore[1]->ID = heroID;
-			player = cb->getHeroOwner(heroID);
-			cb->showSelDialog(player,CGI->objh->advobtxt[146],&tempStore,this);
+			//if (os->subID)
+			//	break; //not OH3 treasure chest
+			//int wyn = rand()%100;
+			//if (wyn<32)
+			//{
+			//	tempStore.push_back(new CSelectableComponent(SComponent::resource,6,1000));
+			//	tempStore.push_back(new CSelectableComponent(SComponent::experience,0,500));
+			//}//1k/0.5k
+			//else if(wyn<64)
+			//{
+			//	tempStore.push_back(new CSelectableComponent(SComponent::resource,6,1500));
+			//	tempStore.push_back(new CSelectableComponent(SComponent::experience,0,1000));
+			//}//1.5k/1k
+			//else if(wyn<95)
+			//{
+			//	tempStore.push_back(new CSelectableComponent(SComponent::resource,6,2000));
+			//	tempStore.push_back(new CSelectableComponent(SComponent::experience,0,1500));
+			//}//2k/1.5k
+			//else
+			//{
+			//	if (1/*TODO: backpack is full*/)
+			//	{
+			//		tempStore.push_back(new CSelectableComponent(SComponent::resource,6,1000));
+			//		tempStore.push_back(new CSelectableComponent(SComponent::experience,0,500));
+			//	}
+			//	else
+			//	{
+			//		//TODO: give treasure artifact
+			//		break;
+			//	}
+			//}//random treasure artifact, or (if backapack is full) 1k/0.5k
+			//tempStore[1]->ID = heroID;
+			//player = cb->getHeroOwner(heroID);
+			//cb->showSelDialog(player,VLC->objh->advobtxt[146],&tempStore,this);
 			break;
 		}
 	}
-	CGI->mh->removeObject(os);
+	//VLC->mh->removeObject(os);
 }
 void CPickable::chosen(int which)
 {
-	switch(tempStore[which]->type)
-	{
-	case SComponent::resource:
-		cb->giveResource(player,tempStore[which]->subtype,tempStore[which]->val);
-		break;
-	case SComponent::experience:
-		cb->changePrimSkill(tempStore[which]->ID,4,tempStore[which]->val);
-		break;
-	default:
-		throw new std::exception("Unhandled choice");
-		
-	}
-	for (int i=0;i<tempStore.size();i++)
-		delete tempStore[i];
-	tempStore.clear();
-}
-
-std::string CPickable::hoverText(CGObjectInstance *os)
-{
-	switch (os->ID)
-	{
-	case 79:
-		return CGI->objh->restypes[os->subID];
-		break;
-	case 5:
-		return CGI->arth->artifacts[os->subID].name;
-		break;
-	default:
-		return CGI->objh->objects[os->defInfo->id].name;
-		break;
-	}
+	//switch(tempStore[which]->type)
+	//{
+	//case SComponent::resource:
+	//	cb->giveResource(player,tempStore[which]->subtype,tempStore[which]->val);
+	//	break;
+	//case SComponent::experience:
+	//	cb->changePrimSkill(tempStore[which]->ID,4,tempStore[which]->val);
+	//	break;
+	//default:
+	//	throw new std::exception("Unhandled choice");
+	//	
+	//}
+	//for (int i=0;i<tempStore.size();i++)
+	//	delete tempStore[i];
+	//tempStore.clear();
 }
 
 std::vector<int> CPickable::yourObjects() //returns IDs of objects which are handled by script
@@ -603,20 +597,22 @@ std::vector<int> CPickable::yourObjects() //returns IDs of objects which are han
 	return ret;
 }
 
-void CTownScript::onHeroVisit(CGObjectInstance *os, int heroID)
+void CTownScript::onHeroVisit(int objid, int heroID)
 {
-	cb->heroVisitCastle(os,heroID);
+	cb->heroVisitCastle(objid,heroID);
 }
-void CTownScript::onHeroLeave(CGObjectInstance *os, int heroID)
+
+void CTownScript::newObject(int objid)
 {
-	cb->stopHeroVisitCastle(os,heroID);
+	MetaString ms;
+	const CGTownInstance * n = cb->getTown(objid);
+	ms << n->name << ", " << n->town->name;
+	cb->setHoverName(objid,&ms);
 }
-std::string CTownScript::hoverText(CGObjectInstance *os)
+
+void CTownScript::onHeroLeave(int objid, int heroID)
 {
-	CGTownInstance * n;
-	if(n = dynamic_cast<CGTownInstance*>(os))
-		return n->name + ", " + n->town->name;
-	else return "";
+	cb->stopHeroVisitCastle(objid,heroID);
 }
 
 std::vector<int> CTownScript::yourObjects() //returns IDs of objects which are handled by script
@@ -626,27 +622,28 @@ std::vector<int> CTownScript::yourObjects() //returns IDs of objects which are h
 	return ret;
 }
 
-void CHeroScript::newObject(CGObjectInstance *os)
+void CHeroScript::newObject(int objid)
 {
-	os->blockVisit = true;
-	heroes.insert(std::pair<int,CGObjectInstance*>(os->subID,os));
+	cb->setBlockVis(objid,true);
 }
 
-void CHeroScript::onHeroVisit(CGObjectInstance *os, int heroID)
+void CHeroScript::onHeroVisit(int objid, int heroID)
 {
 	//TODO: check for allies
-	if(static_cast<CGHeroInstance*>(heroes[heroID])->tempOwner == static_cast<CGHeroInstance*>(os)->tempOwner) //one of allied cases
+	const CGHeroInstance *my = cb->getHero(objid), 
+		*vis = cb->getHero(objid);
+	if(my->tempOwner == vis->tempOwner) //one of allied cases
 	{
 		//exchange
 	}
 	else
 	{
 		cb->startBattle(
-			&(static_cast<CGHeroInstance*>(heroes[heroID]))->army,
-			&(static_cast<CGHeroInstance*>(os))->army,
-			os->pos,
-			static_cast<CGHeroInstance*>(heroes[heroID]),
-			static_cast<CGHeroInstance*>(os));
+			&my->army,
+			&vis->army,
+			my->pos,
+			my,
+			vis);
 	}
 }
 std::vector<int> CHeroScript::yourObjects() //returns IDs of objects which are handled by script
@@ -655,64 +652,66 @@ std::vector<int> CHeroScript::yourObjects() //returns IDs of objects which are h
 	ret.push_back(34); //hero
 	return ret;
 }
-std::string CHeroScript::hoverText(CGObjectInstance *os)
-{
-	CGHeroInstance* h = static_cast<CGHeroInstance*>(os);
-	std::string ret = CGI->generaltexth->allTexts[15];
-	boost::algorithm::replace_first(ret,"%s",h->name);
-	boost::algorithm::replace_first(ret,"%s",h->type->heroClass->name);
-	return ret;
-}
-void CMonsterS::newObject(CGObjectInstance *os)
+//std::string CHeroScript::hoverText(int objid)
+//{
+//	//CGHeroInstance* h = static_cast<CGHeroInstance*>(os);
+//	//std::string ret = VLC->generaltexth->allTexts[15];
+//	//boost::algorithm::replace_first(ret,"%s",h->name);
+//	//boost::algorithm::replace_first(ret,"%s",h->type->heroClass->name);
+//	//return ret;
+//	return "";
+//}
+void CMonsterS::newObject(int objid)
 {
 	//os->blockVisit = true;
-	switch(CGI->creh->creatures[os->subID].level)
+	DEFOS;
+	switch(VLC->creh->creatures[os->subID].level)
 	{
 	case 1:
-		((CCreatureObjInfo*)os->info)->number = rand()%31+20;
+		amounts[objid] = rand()%31+20;
 		break;
 	case 2:
-		((CCreatureObjInfo*)os->info)->number = rand()%16+15;
+		amounts[objid] = rand()%16+15;
 		break;
 	case 3:
-		((CCreatureObjInfo*)os->info)->number = rand()%16+10;
+		amounts[objid] = rand()%16+10;
 		break;
 	case 4:
-		((CCreatureObjInfo*)os->info)->number = rand()%11+10;
+		amounts[objid] = rand()%11+10;
 		break;
 	case 5:
-		((CCreatureObjInfo*)os->info)->number = rand()%9+8;
+		amounts[objid] = rand()%9+8;
 		break;
 	case 6:
-		((CCreatureObjInfo*)os->info)->number = rand()%8+5;
+		amounts[objid] = rand()%8+5;
 		break;
 	case 7:
-		((CCreatureObjInfo*)os->info)->number = rand()%7+3;
+		amounts[objid] = rand()%7+3;
 		break;
 	case 8:
-		((CCreatureObjInfo*)os->info)->number = rand()%4+2;
+		amounts[objid] = rand()%4+2;
 		break;
 	case 9:
-		((CCreatureObjInfo*)os->info)->number = rand()%3+2;
+		amounts[objid] = rand()%3+2;
 		break;
 	case 10:
-		((CCreatureObjInfo*)os->info)->number = rand()%3+1;
+		amounts[objid] = rand()%3+1;
 		break;
 
 	}
 
-}
-std::string CMonsterS::hoverText(CGObjectInstance *os)
-{
-	int pom = CCreature::getQuantityID(((CCreatureObjInfo*)os->info)->number);
+	MetaString ms;
+	int pom = CCreature::getQuantityID(amounts[objid]);
 	pom = 174 + 3*pom + 1;
-	return CGI->generaltexth->arraytxt[pom] + " " + CGI->creh->creatures[os->subID].namePl;
+	ms << std::pair<ui8,ui32>(6,pom) << " " << std::pair<ui8,ui32>(7,os->subID);
+	cb->setHoverName(objid,&ms);
 }
-void CMonsterS::onHeroVisit(CGObjectInstance *os, int heroID)
+void CMonsterS::onHeroVisit(int objid, int heroID)
 {
+	DEFOS;
 	CCreatureSet set;
 	//TODO: zrobic secik w sposob wyrafinowany
-	set.slots[0] = std::pair<CCreature*,int>(&CGI->creh->creatures[os->subID],((CCreatureObjInfo*)os->info)->number);
+	set.slots[0] = std::pair<CCreature*,int>(&VLC->creh->creatures[os->subID],((CCreatureObjInfo*)os->info)->number);
 	cb->startBattle(heroID,&set,os->pos);
 }
 std::vector<int> CMonsterS::yourObjects() //returns IDs of objects which are handled by script
@@ -723,15 +722,15 @@ std::vector<int> CMonsterS::yourObjects() //returns IDs of objects which are han
 }
 
 
-void CCreatureGen::newObject(CGObjectInstance *os)
-{
-	amount[os] = CGI->creh->creatures[CGI->objh->cregens[os->subID]].growth;
-}
-std::string CCreatureGen::hoverText(CGObjectInstance *os)
+void CCreatureGen::newObject(int objid)
 {
-	return CGI->objh->creGens[os->subID];
+	DEFOS;
+	amount[objid] = VLC->creh->creatures[VLC->objh->cregens[os->subID]].growth;
+	MetaString ms;
+	ms << std::pair<ui8,ui32>(8,os->subID);
+	cb->setHoverName(objid,&ms);
 }
-void CCreatureGen::onHeroVisit(CGObjectInstance *os, int heroID)
+void CCreatureGen::onHeroVisit(int objid, int heroID)
 {
 }
 std::vector<int> CCreatureGen::yourObjects() //returns IDs of objects which are handled by script

+ 39 - 60
CLua.h

@@ -28,10 +28,10 @@ public:
 
 	//functions to be called in script
 	//virtual void init(){};
-	virtual void newObject(CGObjectInstance *os){};
-	virtual void onHeroVisit(CGObjectInstance *os, int heroID){};
-	virtual void onHeroLeave(CGObjectInstance *os, int heroID){};
-	virtual std::string hoverText(CGObjectInstance *os){return "";};
+	virtual void newObject(int objid){};
+	virtual void onHeroVisit(int objid, int heroID){};
+	virtual void onHeroLeave(int objid, int heroID){};
+	virtual std::string hoverText(int objid){return "";};
 	virtual void newTurn (){}; 
 
 
@@ -83,122 +83,101 @@ public:
 	static std::string genFN(std::string base, int ID);
 
 	void init();
-	void newObject(CGObjectInstance *os);
-	void onHeroVisit(CGObjectInstance *os, int heroID);
-	std::string hoverText(CGObjectInstance *os);
-
-	friend CGameState;
+	void newObject(int objid);
+	void onHeroVisit(int objid, int heroID);
 };
 class CCPPObjectScript: public CObjectScript
 {
-protected:
+public:
 	CScriptCallback * cb;
 	CCPPObjectScript(CScriptCallback * CB){cb=CB;};
-public:
 	virtual std::vector<int> yourObjects()=0; //returns IDs of objects which are handled by script
-	virtual std::string hoverText(CGObjectInstance *os);
 };
 class CVisitableOPH : public CCPPObjectScript  //once per hero
 {
+public:
 	CVisitableOPH(CScriptCallback * CB):CCPPObjectScript(CB){};
-	std::map<CGObjectInstance*,std::set<int> > visitors;
+	std::map<int,std::set<int> > visitors;
 	
-	void onNAHeroVisit(CGObjectInstance *os, int heroID, bool alreadyVisited);
-	void newObject(CGObjectInstance *os);
-	void onHeroVisit(CGObjectInstance *os, int heroID);
+	void onNAHeroVisit(int objid, int heroID, bool alreadyVisited);
+	void newObject(int objid);
+	void onHeroVisit(int objid, int heroID);
 	std::vector<int> yourObjects(); //returns IDs of objects which are handled by script
-	std::string hoverText(CGObjectInstance *os);
-
-	friend CGameState;
 };
 
 class CVisitableOPW : public CCPPObjectScript  //once per week
 {
+public:
 	CVisitableOPW(CScriptCallback * CB):CCPPObjectScript(CB){};
-	std::map<CGObjectInstance*,bool> visited;
-	void onNAHeroVisit(CGObjectInstance *os, int heroID, bool alreadyVisited);
-	void newObject(CGObjectInstance *os);
-	void onHeroVisit(CGObjectInstance *os, int heroID);
+	std::map<int,bool> visited;
+	void onNAHeroVisit(int objid, int heroID, bool alreadyVisited);
+	void newObject(int objid);
+	void onHeroVisit(int objid, int heroID);
 	std::vector<int> yourObjects(); //returns IDs of objects which are handled by script
-	std::string hoverText(CGObjectInstance *os);
 	void newTurn (); 
-
-	friend CGameState;
 };
 
 class CMines : public CCPPObjectScript  //flaggable, and giving resource at each day
 {
+public:
 	CMines(CScriptCallback * CB):CCPPObjectScript(CB){};
 
-	std::vector<CGObjectInstance*> ourObjs;
+	std::vector<int> ourObjs;
 
-	void newObject(CGObjectInstance *os);
-	void onHeroVisit(CGObjectInstance *os, int heroID);
+	void newObject(int objid);
+	void onHeroVisit(int objid, int heroID);
 	std::vector<int> yourObjects(); //returns IDs of objects which are handled by script
-	std::string hoverText(CGObjectInstance *os);
 	void newTurn (); 
-
-	friend CGameState;
 };
 
 class CPickable : public CCPPObjectScript, public IChosen  //pickable - resources, artifacts, etc
 {
+public:
 	std::vector<CSelectableComponent*> tempStore;
 	int player;
 
 	CPickable(CScriptCallback * CB):CCPPObjectScript(CB){};
 	void chosen(int which);
-	void newObject(CGObjectInstance *os);
-	void onHeroVisit(CGObjectInstance *os, int heroID);
-	std::string hoverText(CGObjectInstance *os);
+	void newObject(int objid);
+	void onHeroVisit(int objid, int heroID);
 	std::vector<int> yourObjects(); //returns IDs of objects which are handled by script
-
-	friend CGameState;
 };
 
 class CTownScript : public CCPPObjectScript  //pickable - resources, artifacts, etc
 {
+public:
 	CTownScript(CScriptCallback * CB):CCPPObjectScript(CB){};
-	void onHeroVisit(CGObjectInstance *os, int heroID);
-	void onHeroLeave(CGObjectInstance *os, int heroID);
-	std::string hoverText(CGObjectInstance *os);
+	void onHeroVisit(int objid, int heroID);
+	void onHeroLeave(int objid, int heroID);
+	void newObject(int objid);
 	std::vector<int> yourObjects(); //returns IDs of objects which are handled by script
-
-	friend CGameState;
 };
 
 class CHeroScript : public CCPPObjectScript
 {
-	std::map<int, CGObjectInstance*> heroes;
+public:
 	CHeroScript(CScriptCallback * CB):CCPPObjectScript(CB){};
-	void newObject(CGObjectInstance *os);
-	void onHeroVisit(CGObjectInstance *os, int heroID);
+	void newObject(int objid);
+	void onHeroVisit(int objid, int heroID);
 	std::vector<int> yourObjects(); //returns IDs of objects which are handled by script
-	std::string hoverText(CGObjectInstance *os);
-
-	friend CGameState;
 };
 
 class CMonsterS : public CCPPObjectScript
 {
-	std::map<int, CGObjectInstance*> heroes;
+public:
+	std::map<int, int> amounts; //monster id -> stack quantity
 	CMonsterS(CScriptCallback * CB):CCPPObjectScript(CB){};
-	void newObject(CGObjectInstance *os);
-	std::string hoverText(CGObjectInstance *os);
-	void onHeroVisit(CGObjectInstance *os, int heroID);
+	void newObject(int objid);
+	void onHeroVisit(int objid, int heroID);
 	std::vector<int> yourObjects(); //returns IDs of objects which are handled by script
-
-	friend CGameState;
 };
 
 class CCreatureGen : public CCPPObjectScript
 {
-	std::map<CGObjectInstance*, int> amount; //amount of creatures in each dwelling
+public:
+	std::map<int, int> amount; //amount of creatures in each dwelling
 	CCreatureGen(CScriptCallback * CB):CCPPObjectScript(CB){};
-	void newObject(CGObjectInstance *os);
-	std::string hoverText(CGObjectInstance *os);
-	void onHeroVisit(CGObjectInstance *os, int heroID);
+	void newObject(int objid);
+	void onHeroVisit(int objid, int heroID);
 	std::vector<int> yourObjects(); //returns IDs of objects which are handled by script
-
-	friend CGameState;
 };

+ 1 - 9
CMT.cpp

@@ -50,15 +50,7 @@ std::queue<SDL_Event> events;
 boost::mutex eventsM;
 
 TTF_Font * TNRB16, *TNR, *GEOR13, *GEORXX, *GEORM, *GEOR16;
-void handleCPPObjS(std::map<int,CCPPObjectScript*> * mapa, CCPPObjectScript * script)
-{
-	std::vector<int> tempv = script->yourObjects();
-	for (int i=0;i<tempv.size();i++)
-	{
-		(*mapa)[tempv[i]]=script;
-	}
-	CGI->state->cppscripts.insert(script);
-}
+
 int _tmain(int argc, _TCHAR* argv[])
 { 
 	std::cout.flags(ios::unitbuf);

+ 1 - 1
CPathfinder.cpp

@@ -213,7 +213,7 @@ void CPathfinder::CalcH(Coordinate* node)
 		y = CGI->mh->map->height-1;
 
 	//Get the movement cost.
-	ret = Hero->getTileCost(CGI->mh->ttiles[x][y][node->z].tileInfo->tertype, CGI->mh->map->terrain[x][y][0].malle,CGI->mh->map->terrain[x][y][0].nuine);
+	ret = Hero->getTileCost(CGI->mh->ttiles[x][y][node->z].tileInfo->tertype, CGI->mh->map->terrain[x][y][node->z].malle,CGI->mh->map->terrain[x][y][node->z].nuine);
 	
 	node->h = ret;
 }

+ 82 - 1
client/Client.cpp

@@ -12,8 +12,69 @@
 #include <boost/bind.hpp>
 #include <boost/thread.hpp>
 #include "../hch/CObjectHandler.h"
+#include "../hch/CGeneralTextHandler.h"
+#include "../hch/CArtHandler.h"
+#include <boost/thread/shared_mutex.hpp>
 CSharedCond<std::set<IPack*> > mess(new std::set<IPack*>);
 
+std::string toString(MetaString &ms)
+{
+	std::string ret;
+	for(int 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;
+			if(type == 5)
+			{
+				ret += CGI->arth->artifacts[ms.texts[-ms.message[i]-1].second].name;
+				continue;
+			}
+			else if(type == 7)
+			{
+				ret += CGI->creh->creatures[ms.texts[-ms.message[i]-1].second].namePl;
+				continue;
+			}
+			else if(type == 9)
+			{
+				ret += CGI->objh->mines[ms.texts[-ms.message[i]-1].second].first;
+				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;
+				}
+				ret += (*vec)[ms.texts[-ms.message[i]-1].second];
+			}
+		}
+	}
+	return ret;
+}
+
 CClient::CClient(void)
 {
 }
@@ -100,7 +161,7 @@ void CClient::process(int what)
 		}
 	case 501: //hero movement response - we have to notify interfaces and callback
 		{
-			TryMoveHero *th = new TryMoveHero;
+			TryMoveHero *th = new TryMoveHero; //will be deleted by callback after processing
 			*serv >> *th;
 			std::cout << "HeroMove: id="<<th->id<<"\tResult: "<<(unsigned)th->result<<"\tPosition "<<th->end<<std::endl;
 
@@ -134,6 +195,26 @@ void CClient::process(int what)
 			mess.cv->notify_all();
 			break;
 		}
+	case 1001:
+		{
+			SetObjectProperty sop;
+			*serv >> sop;
+			std::cout << "Setting " << (unsigned)sop.what << " property of " << sop.id <<" object to "<<sop.val<<std::endl;
+			gs->apply(&sop);
+			break;
+		}
+	case 1002:
+		{
+			SetHoverName shn;
+			*serv >> shn;
+			std::cout << "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();
+			break;
+		}
+	case 9999:
+		break;
 	default:
 		throw std::exception("Not supported server message!");
 		break;

+ 0 - 4
client/VCMI_client.vcproj

@@ -319,10 +319,6 @@
 				RelativePath=".\Client.cpp"
 				>
 			</File>
-			<File
-				RelativePath="..\CLua.cpp"
-				>
-			</File>
 			<File
 				RelativePath="..\CLuaHandler.cpp"
 				>

+ 5 - 5
hch/CObjectHandler.cpp

@@ -19,11 +19,11 @@ void CObjectHandler::loadObjects()
 	int it=0;
 	while (it<buf.length()-1)
 	{
-		CObject nobj;
-		loadToIt(nobj.name,buf,it,3);
-		if(nobj.name.size() && (nobj.name[nobj.name.size()-1]==(char)10 || nobj.name[nobj.name.size()-1]==(char)13 || nobj.name[nobj.name.size()-1]==(char)9))
-			nobj.name = nobj.name.substr(0, nobj.name.size()-1);
-		objects.push_back(nobj);
+		std::string nobj;
+		loadToIt(nobj,buf,it,3);
+		if(nobj.size() && (nobj[nobj.size()-1]==(char)10 || nobj[nobj.size()-1]==(char)13 || nobj[nobj.size()-1]==(char)9))
+			nobj = nobj.substr(0, nobj.size()-1);
+		names.push_back(nobj);
 	}
 
 	buf = bitmaph->getTextFile("ADVEVENT.TXT");

+ 3 - 8
hch/CObjectHandler.h

@@ -42,12 +42,6 @@ public:
 	}
 };
 
-class DLL_EXPORT CObject //typical object that can be encountered on a map
-{
-public:
-	std::string name; //object's name
-};
-
 class DLL_EXPORT CGObjectInstance
 {
 public:
@@ -58,9 +52,10 @@ public:
 	CCPPObjectScript * state;
 	CSpecObjInfo * info;
 	unsigned char animPhaseShift;
+	std::string hoverName;
 
 	int tempOwner; //uzywane dla szybkosci, skrypt ma obowiazek aktualizowac te zmienna
-	bool blockVisit;
+	int blockVisit; //if non-zero then blocks the tile but is visitable from neighbouring tile
 	
 	virtual bool isHero() const;
 	int getOwner() const; 
@@ -172,7 +167,7 @@ public:
 class DLL_EXPORT CObjectHandler
 {
 public:
-	std::vector<CObject> objects; //vector of objects; i-th object in vector has subnumber i
+	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();
 

+ 10 - 1
lib/Connection.h

@@ -252,7 +252,16 @@ public:
 			data.insert(ins);
 		}
 	}
-
+	template <typename T1, typename T2>
+	void saveSerializable(const std::pair<T1,T2> &data)
+	{
+		*this << data.first << data.second;
+	}
+	template <typename T1, typename T2>
+	void loadSerializable(std::pair<T1,T2> &data)
+	{
+		*this >> data.first >> data.second;
+	}
 	template <typename T>
 	void save(const T &data)
 	{

+ 54 - 1
lib/NetPacks.h

@@ -72,4 +72,57 @@ struct TryMoveHero : public CPack<TryMoveHero> //501
 	{
 		h & id & result & start & end & movePoints & fowRevealed;
 	}
-}; 
+}; 
+struct MetaString : public CPack<MetaString> //2001 helper for object scrips
+{
+	std::vector<std::string> strings;
+	std::vector<std::pair<ui8,ui32> > texts; //pairs<text handler type, text number>; types: 1 - generaltexthandler->all; 2 - objh->xtrainfo; 3 - objh->names; 4 - objh->restypes; 5 - arth->artifacts[id].name; 6 - generaltexth->arraytxt; 7 - creh->creatures[os->subID].namePl; 8 - objh->creGens; 9 - objh->mines[ID].first
+	std::vector<si32> message;
+
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & strings & texts & message;
+	}
+
+	MetaString& operator<<(const std::pair<ui8,ui32> &txt)
+	{
+		message.push_back(-((si32)texts.size())-1);
+		texts.push_back(txt);
+		return *this;
+	}
+	MetaString& operator<<(const std::string &txt)
+	{
+		message.push_back(strings.size()+1);
+		strings.push_back(txt);
+		return *this;
+	}
+
+	MetaString(){type = 2001;};
+};
+
+struct SetObjectProperty : public CPack<SetObjectProperty>//1001
+{
+	ui32 id;
+	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;};
+	
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & id & what & val;
+	}
+};
+
+struct SetHoverName : public CPack<SetHoverName>//1002
+{
+	ui32 id;
+	MetaString name;
+	SetHoverName(){type = 1002;};
+	SetHoverName(ui32 ID, MetaString& Name):id(ID),name(Name){type = 1002;};
+	
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & id & name;
+	}
+};

+ 97 - 24
server/CGameHandler.cpp

@@ -3,6 +3,7 @@
 #include <boost/thread/shared_mutex.hpp>
 #include <boost/bind.hpp>
 #include "CGameHandler.h"
+#include "CScriptCallback.h"
 #include "../CLua.h"
 #include "../CGameState.h"
 #include "../StartInfo.h"
@@ -24,6 +25,27 @@ double distance(int3 a, int3 b)
 {
 	return std::sqrt( (double)(a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y) );
 }
+//bool CGameState::checkFunc(int obid, std::string name)
+//{
+//	if (objscr.find(obid)!=objscr.end())
+//	{
+//		if(objscr[obid].find(name)!=objscr[obid].end())
+//		{
+//			return true;
+//		}
+//	}
+//	return false;
+//}
+
+void CGameHandler::handleCPPObjS(std::map<int,CCPPObjectScript*> * mapa, CCPPObjectScript * script)
+{
+	std::vector<int> tempv = script->yourObjects();
+	for (unsigned i=0;i<tempv.size();i++)
+	{
+		(*mapa)[tempv[i]]=script;
+	}
+	cppscripts.insert(script);
+}
 
 void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
 {
@@ -51,7 +73,7 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
 					int3 hmpos = end + int3(-1,0,0);
 					TerrainTile t = gs->map->terrain[hmpos.x][hmpos.y][hmpos.z];
 					CGHeroInstance *h = static_cast<CGHeroInstance *>(gs->map->objects[id]);
-					int cost = (double)h->getTileCost(t.tertype,t.malle,t.nuine) * distance(start,end);
+					int cost = (int)((double)h->getTileCost(t.tertype,t.malle,t.nuine) * distance(start,end));
 
 					TryMoveHero tmh;
 					tmh.id = id;
@@ -85,16 +107,15 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
 					//we start moving
 					if(blockvis)//interaction with blocking object (like resources)
 					{
-						gs->apply(&tmh);
-						sendToAllClients(&tmh); //failed to move to that tile but we visit object
+						sendAndApply(&tmh); //failed to move to that tile but we visit object
 						BOOST_FOREACH(CGObjectInstance *obj, t.visitableObjects)
 						{
 							if (obj->blockVisit)
 							{
-								if(gs->checkFunc(obj->ID,"heroVisit")) //script function
-									gs->objscr[obj->ID]["heroVisit"]->onHeroVisit(obj,h->subID);
+								//if(gs->checkFunc(obj->ID,"heroVisit")) //script function
+								//	gs->objscr[obj->ID]["heroVisit"]->onHeroVisit(obj,h->subID);
 								if(obj->state) //hard-coded function
-									obj->state->onHeroVisit(obj,h->subID);
+									obj->state->onHeroVisit(obj->id,h->subID);
 							}
 						}
 						break;
@@ -107,7 +128,7 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
 						{
 							//TODO: allow to handle this in script-languages
 							if(obj->state) //hard-coded function
-								obj->state->onHeroLeave(obj,h->subID);
+								obj->state->onHeroLeave(obj->id,h->subID);
 						}
 
 						//reveal fog of war
@@ -140,22 +161,19 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
 							}
 						}
 
-						gs->apply(&tmh);
-						sendToAllClients(&tmh);
+						sendAndApply(&tmh);
 
-						//call objects if they arevisited
-						BOOST_FOREACH(CGObjectInstance *obj, t.visitableObjects)
+						BOOST_FOREACH(CGObjectInstance *obj, t.visitableObjects)//call objects if they are visited
 						{
-							if(gs->checkFunc(obj->ID,"heroVisit")) //script function
-								gs->objscr[obj->ID]["heroVisit"]->onHeroVisit(obj,h->subID);
+							//if(gs->checkFunc(obj->ID,"heroVisit")) //script function
+							//	gs->objscr[obj->ID]["heroVisit"]->onHeroVisit(obj,h->subID);
 							if(obj->state) //hard-coded function
-								obj->state->onHeroVisit(obj,h->subID);
+								obj->state->onHeroVisit(obj->id,h->id);
 						}
 					}
 					break;
 				fail:
-					gs->apply(&tmh);
-					sendToAllClients(&tmh);
+					sendAndApply(&tmh);
 					break;
 				}
 			default:
@@ -180,11 +198,6 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
 		end = true;
 	}
 }
-template <typename T>void CGameHandler::sendToAllClients(CPack<T> * info)
-{
-	BOOST_FOREACH(CConnection* c, conns)
-		*c << info->getType() << *info->This();
-}
 CGameHandler::CGameHandler(void)
 {
 	gs = NULL;
@@ -198,7 +211,68 @@ void CGameHandler::init(StartInfo *si, int Seed)
 {
 	Mapa *map = new Mapa(si->mapname);
 	gs = new CGameState();
-	gs->init(si,map,Seed);
+	gs->init(si,map,Seed);	
+
+	/****************************SCRIPTS************************************************/
+	//std::map<int, std::map<std::string, CObjectScript*> > * skrypty = &objscr; //alias for easier access
+	/****************************C++ OBJECT SCRIPTS************************************************/
+	std::map<int,CCPPObjectScript*> scripts;
+	CScriptCallback * csc = new CScriptCallback();
+	csc->gh = this;
+	handleCPPObjS(&scripts,new CVisitableOPH(csc));
+	handleCPPObjS(&scripts,new CVisitableOPW(csc));
+	handleCPPObjS(&scripts,new CPickable(csc));
+	handleCPPObjS(&scripts,new CMines(csc));
+	handleCPPObjS(&scripts,new CTownScript(csc));
+	handleCPPObjS(&scripts,new CHeroScript(csc));
+	handleCPPObjS(&scripts,new CMonsterS(csc));
+	handleCPPObjS(&scripts,new CCreatureGen(csc));
+	//created map
+
+	/****************************LUA OBJECT SCRIPTS************************************************/
+	//std::vector<std::string> * lf = CLuaHandler::searchForScripts("scripts/lua/objects"); //files
+	//for (int i=0; i<lf->size(); i++)
+	//{
+	//	try
+	//	{
+	//		std::vector<std::string> * temp =  CLuaHandler::functionList((*lf)[i]);
+	//		CLuaObjectScript * objs = new CLuaObjectScript((*lf)[i]);
+	//		CLuaCallback::registerFuncs(objs->is);
+	//		//objs
+	//		for (int j=0; j<temp->size(); j++)
+	//		{
+	//			int obid ; //obj ID
+	//			int dspos = (*temp)[j].find_first_of('_');
+	//			obid = atoi((*temp)[j].substr(dspos+1,(*temp)[j].size()-dspos-1).c_str());
+	//			std::string fname = (*temp)[j].substr(0,dspos);
+	//			if (skrypty->find(obid)==skrypty->end())
+	//				skrypty->insert(std::pair<int, std::map<std::string, CObjectScript*> >(obid,std::map<std::string,CObjectScript*>()));
+	//			(*skrypty)[obid].insert(std::pair<std::string, CObjectScript*>(fname,objs));
+	//		}
+	//		delete temp;
+	//	}HANDLE_EXCEPTION
+	//}
+	/****************************INITIALIZING OBJECT SCRIPTS************************************************/
+	//std::string temps("newObject");
+	for (unsigned i=0; i<map->objects.size(); i++)
+	{
+		//c++ scripts
+		if (scripts.find(map->objects[i]->ID) != scripts.end())
+		{
+			map->objects[i]->state = scripts[map->objects[i]->ID];
+			map->objects[i]->state->newObject(map->objects[i]->id);
+		}
+		else 
+		{
+			map->objects[i]->state = NULL;
+		}
+
+		//// lua scripts
+		//if(checkFunc(map->objects[i]->ID,temps))
+		//	(*skrypty)[map->objects[i]->ID][temps]->newObject(map->objects[i]);
+	}
+
+	//delete lf;
 }
 int lowestSpeed(CGHeroInstance * chi)
 {
@@ -257,8 +331,7 @@ void CGameHandler::newTurn()
 		}
 		n.res.insert(r);
 	}	
-	gs->apply(&n);
-	sendToAllClients(&n);
+	sendAndApply(&n);
 	//for (std::set<CCPPObjectScript *>::iterator i=gs->cppscripts.begin();i!=gs->cppscripts.end();i++)
 	//{
 	//	(*i)->newTurn();

+ 24 - 1
server/CGameHandler.h

@@ -5,22 +5,45 @@ class CVCMIServer;
 class CGameState;
 class CConnection;
 struct StartInfo;
+class CCPPObjectScript;
+class CScriptCallback;
 template <typename T> struct CPack;
 
 class CGameHandler
 {
+
 	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;
 	std::set<CConnection*> conns;
+
+	void handleCPPObjS(std::map<int,CCPPObjectScript*> * mapa, CCPPObjectScript * script);
+
 public:
 	CGameHandler(void);
 	~CGameHandler(void);
 	void init(StartInfo *si, int Seed);
 	void handleConnection(std::set<int> players, CConnection &c);
-	template <typename T>void sendToAllClients(CPack<T> * info);
+	template <typename T>void sendToAllClients(CPack<T> * info)
+	{
+		for(std::set<CConnection*>::iterator i=conns.begin(); i!=conns.end();i++)
+		{
+			(*i)->rmx->lock();
+			**i << info->getType() << *info->This();
+			(*i)->rmx->unlock();
+		}
+	}
+	template <typename T>void sendAndApply(CPack<T> * info)
+	{
+		gs->apply(info);
+		sendToAllClients(info);
+	}
 	void run();
 	void newTurn();
 
 	friend class CVCMIServer;
+	friend class CScriptCallback;
 };

+ 292 - 0
server/CScriptCallback.cpp

@@ -0,0 +1,292 @@
+#include "CScriptCallback.h"
+#include "../lib/Connection.h"
+#include "CVCMIServer.h"
+#include "CGameHandler.h"
+#include "../CGameState.h"
+#include "../map.h"
+#include "../hch/CObjectHandler.h"
+#include "../hch/CTownHandler.h"
+#include "../hch/CHeroHandler.h"
+#include "../lib/NetPacks.h"
+#include <boost/foreach.hpp>
+#include <boost/thread.hpp>
+CScriptCallback::CScriptCallback(void)
+{
+}
+
+CScriptCallback::~CScriptCallback(void)
+{
+}
+void CScriptCallback::setBlockVis(int objid, bool bv)
+{
+	SetObjectProperty sop(objid,2,bv);
+	gh->sendAndApply(&sop);
+}
+void CScriptCallback::setOwner(int objid, ui8 owner)
+{
+	SetObjectProperty sop(objid,1,owner);
+	gh->sendAndApply(&sop);
+}
+const CGObjectInstance* CScriptCallback::getObj(int objid)
+{
+	return gh->gs->map->objects[objid];
+}
+const CGHeroInstance* CScriptCallback::getHero(int objid)
+{
+	return static_cast<const CGHeroInstance*>(gh->gs->map->objects[objid]);
+}
+const CGTownInstance* CScriptCallback::getTown(int objid)
+{
+	return static_cast<const CGTownInstance*>(gh->gs->map->objects[objid]);
+}
+void CScriptCallback::setHoverName(int objid, MetaString* name)
+{
+	SetHoverName shn(objid, *name);
+	gh->sendAndApply(&shn);
+}
+int3 CScriptCallback::getPos(CGObjectInstance * ob)
+{
+	return ob->pos;
+}
+void CScriptCallback::changePrimSkill(int ID, int which, int val)
+{	
+	//CGHeroInstance * hero = gh->gs->map->getHero(ID,0);
+	//if (which<PRIMARY_SKILLS)
+	//{
+	//	hero->primSkills[which]+=val;
+	//	sv->playerint[hero->getOwner()]->heroPrimarySkillChanged(hero, which, val);
+	//}
+	//else if (which==4)
+	//{
+	//	hero->exp+=val;
+	//	if(hero->exp >= CGI->heroh->reqExp(hero->level+1)) //new level
+	//	{
+	//		hero->level++;
+	//		std::cout << hero->name <<" got level "<<hero->level<<std::endl;
+	//		int r = rand()%100, pom=0, x=0;
+	//		int std::pair<int,int>::*g  =  (hero->level>9) ? (&std::pair<int,int>::second) : (&std::pair<int,int>::first);
+	//		for(;x<PRIMARY_SKILLS;x++)
+	//		{
+	//			pom += hero->type->heroClass->primChance[x].*g;
+	//			if(r<pom)
+	//				break;
+	//		}
+	//		std::cout << "Bohater dostaje umiejetnosc pierwszorzedna " << x << " (wynik losowania "<<r<<")"<<std::endl; 
+	//		hero->primSkills[x]++;
+
+	//		//TODO: dac dwie umiejetnosci 2-rzedne to wyboru
+
+	//	}
+	//	//TODO - powiadomic interfejsy, sprawdzic czy nie ma awansu itp
+	//}
+}
+
+int CScriptCallback::getHeroOwner(int heroID)
+{
+	//CGHeroInstance * hero = CGI->state->map->getHero(heroID,0);
+	//return hero->getOwner();
+	return -1;
+}
+void CScriptCallback::showInfoDialog(int player, std::string text, std::vector<SComponent*> * components)
+{
+	//TODO: upewniac sie ze mozemy to zrzutowac (przy customowych interfejsach cos moze sie kopnac)
+	//if (player>=0)
+	//{
+	//	CGameInterface * temp = sv->playerint[player];
+	//	if (temp->human)
+	//		((CPlayerInterface*)(temp))->showInfoDialog(text,*components);
+	//	return;
+	//}
+	//else
+	//{
+	//	typedef std::pair<const ui8, CGameInterface*> intf;
+	//	BOOST_FOREACH(intf & i, sv->playerint)
+	//	{
+	//		if (i.second->human)
+	//			((CPlayerInterface*)(i.second))->showInfoDialog(text,*components);
+	//	}
+	//}
+}
+
+void CScriptCallback::showSelDialog(int player, std::string text, std::vector<CSelectableComponent*>*components, IChosen * asker)
+{
+	//CGameInterface * temp = sv->playerint[player];
+	//if (temp->human)
+	//	((CPlayerInterface*)(temp))->showSelDialog(text,*components,(int)asker);
+	return;
+}
+int CScriptCallback::getSelectedHero()
+{	
+	int ret;
+	//if (LOCPLINT->adventureInt->selection.type == HEROI_TYPE)
+	//	ret = ((CGHeroInstance*)(LOCPLINT->adventureInt->selection.selected))->subID;
+	//else 
+	//	ret = -1;;
+	return ret;
+}
+int CScriptCallback::getDate(int mode)
+{
+	int temp;
+	switch (mode)
+	{
+	case 0:
+		return gh->gs->day;
+		break;
+	case 1:
+		temp = (gh->gs->day)%7;
+		if (temp)
+			return temp;
+		else return 7;
+		break;
+	case 2:
+		temp = ((gh->gs->day-1)/7)+1;
+		if (!(temp%4))
+			return 4;
+		else 
+			return (temp%4);
+		break;
+	case 3:
+		return ((gh->gs->day-1)/28)+1;
+		break;
+	}
+	return 0;
+}
+void CScriptCallback::giveResource(int player, int which, int val)
+{
+	//gh->gs->players[player].resources[which]+=val;
+	//sv->playerint[player]->receivedResource(which,val);
+}
+void CScriptCallback::showCompInfo(int player, SComponent * comp)
+{
+	//CPlayerInterface * i = dynamic_cast<CPlayerInterface*>(sv->playerint[player]);
+	//if(i)
+	//	i->showComp(*comp);
+}
+void CScriptCallback::heroVisitCastle(int obj, int heroID)
+{
+	//CGTownInstance * n;
+	//if(n = dynamic_cast<CGTownInstance*>(ob))
+	//{
+	//	n->visitingHero = CGI->state->map->getHero(heroID,0);
+	//	gh->gs->map->getHero(heroID,0)->visitedTown = n;
+	//	sv->playerint[getHeroOwner(heroID)]->heroVisitsTown(CGI->state->map->getHero(heroID,0),n);
+	//}
+	//else
+	//	return;
+}
+
+void CScriptCallback::stopHeroVisitCastle(int obj, int heroID)
+{
+	//CGTownInstance * n;
+	//if(n = dynamic_cast<CGTownInstance*>(ob))
+	//{
+	//	CGI->state->map->getHero(heroID,0)->visitedTown = NULL;
+	//	if(n->visitingHero && n->visitingHero->type->ID == heroID)
+	//		n->visitingHero = NULL;
+	//	return;
+	//}
+	//else
+	//	return;
+}
+void CScriptCallback::giveHeroArtifact(int artid, int hid, int position) //pos==-1 - first free slot in backpack
+{
+	CGHeroInstance* h = gh->gs->map->getHero(hid,0);
+	if(position<0)
+	{
+		for(unsigned i=0;i<h->artifacts.size();i++)
+		{
+			if(!h->artifacts[i])
+			{
+				h->artifacts[i] = artid;
+				return;
+			}
+		}
+		h->artifacts.push_back(artid);
+		return;
+	}
+	else
+	{
+		if(h->artifWorn[position]) //slot is occupied
+		{
+			giveHeroArtifact(h->artifWorn[position],hid,-1);
+		}
+		h->artifWorn[position] = artid;
+	}
+}
+
+void CScriptCallback::startBattle(const CCreatureSet * army1, const CCreatureSet * army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2) //use hero=NULL for no hero
+{
+	//gh->gs->battle(army1,army2,tile,hero1,hero2);
+}
+void CScriptCallback::startBattle(int heroID, CCreatureSet * army, int3 tile) //for hero<=>neutral army
+{
+	//CGHeroInstance* h = gh->gs->map->getHero(heroID,0);
+	//gh->gs->battle(&h->army,army,tile,h,NULL);
+}
+void CLuaCallback::registerFuncs(lua_State * L)
+{
+//	lua_newtable(L);
+//
+//#define REGISTER_C_FUNC(x) \
+//	lua_pushstring(L, #x);      \
+//	lua_pushcfunction(L, x);    \
+//	lua_rawset(L, -3)
+//
+//	REGISTER_C_FUNC(getPos);
+//	REGISTER_C_FUNC(changePrimSkill);
+//	REGISTER_C_FUNC(getGnrlText);
+//	REGISTER_C_FUNC(getSelectedHero);
+//
+//	lua_setglobal(L, "vcmi");
+//	#undef REGISTER_C_FUNC
+}
+int CLuaCallback::getPos(lua_State * L)//(CGObjectInstance * object);
+{	
+	//const int args = lua_gettop(L); // number of arguments
+	//if ((args < 1) || !lua_isnumber(L, 1) )
+	//	luaL_error(L,
+	//		"Incorrect arguments to getPos([Object address])");
+	//CGObjectInstance * object = (CGObjectInstance *)(lua_tointeger(L, 1));
+	//lua_pushinteger(L,object->pos.x);
+	//lua_pushinteger(L,object->pos.y);
+	//lua_pushinteger(L,object->pos.z);
+	return 3;
+}
+int CLuaCallback::changePrimSkill(lua_State * L)//(int ID, int which, int val);
+{	
+	//const int args = lua_gettop(L); // number of arguments
+	//if ((args < 1) || !lua_isnumber(L, 1) ||
+	//    ((args >= 2) && !lua_isnumber(L, 2)) ||
+	//    ((args >= 3) && !lua_isnumber(L, 3))		)
+	//{
+	//	luaL_error(L,
+	//		"Incorrect arguments to changePrimSkill([Hero ID], [Which Primary skill], [Change by])");
+	//}
+	//int ID = lua_tointeger(L, 1),
+	//	which = lua_tointeger(L, 2),
+	//	val = lua_tointeger(L, 3);
+
+	//CScriptCallback::changePrimSkill(ID,which,val);
+
+	return 0;
+}
+int CLuaCallback::getGnrlText(lua_State * L) //(int which),returns string
+{
+	//const int args = lua_gettop(L); // number of arguments
+	//if ((args < 1) || !lua_isnumber(L, 1) )
+	//	luaL_error(L,
+	//		"Incorrect arguments to getGnrlText([Text ID])");
+	//int which = lua_tointeger(L,1);
+	//lua_pushstring(L,CGI->generaltexth->allTexts[which].c_str());
+	return 1;
+}
+int CLuaCallback::getSelectedHero(lua_State * L) //(),returns int (ID of hero, -1 if no hero is seleceted)
+{
+	//int ret;
+	//if (LOCPLINT->adventureInt->selection.type == HEROI_TYPE)
+	//	ret = ((CGHeroInstance*)(LOCPLINT->adventureInt->selection.selected))->subID;
+	//else 
+	//	ret = -1;
+	//lua_pushinteger(L,ret);
+	return 1;
+}

+ 62 - 0
server/CScriptCallback.h

@@ -0,0 +1,62 @@
+#pragma once
+#include "../global.h"
+#include <vector>
+class CVCMIServer;
+class CGameHandler;
+class SComponent;
+class CSelectableComponent;
+class IChosen;
+class CCreatureSet;
+class CGHeroInstance;
+class CGObjectInstance;
+class CGHeroInstance;
+class CGTownInstance;
+class CGameState;
+struct lua_State;
+struct MetaString;
+class CScriptCallback
+{
+	CScriptCallback(void);
+public:
+	~CScriptCallback(void);
+	CGameHandler *gh;
+
+	//get info
+	static int3 getPos(CGObjectInstance * ob);
+	int getHeroOwner(int heroID);
+	int getSelectedHero();
+	int getDate(int mode=0);
+	const CGObjectInstance* getObj(int objid);
+	const CGHeroInstance* getHero(int objid);
+	const CGTownInstance* getTown(int objid);
+
+	//do sth
+	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);
+	void showInfoDialog(int player, std::string text, std::vector<SComponent*> * components); //TODO: obslugiwac nulle
+	void showSelDialog(int player, std::string text, std::vector<CSelectableComponent*>*components, IChosen * asker);
+	void giveResource(int player, int which, int val);
+	void showCompInfo(int player, SComponent * comp);
+	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
+	void startBattle(const CCreatureSet * army1, const CCreatureSet * army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2); //use hero=NULL for no hero
+	void startBattle(int heroID, CCreatureSet * army, int3 tile); //for hero<=>neutral army
+
+	//friends
+	friend class CGameHandler;
+};
+class CLuaCallback : public CScriptCallback
+{
+private:
+
+	static void registerFuncs(lua_State * L);
+	static int getPos(lua_State * L);//(CGObjectInstance * object);
+	static int changePrimSkill(lua_State * L);//(int ID, int which, int val);
+	static int getGnrlText(lua_State * L);//(int ID, int which, int val);
+	static int getSelectedHero(lua_State * L);//()
+
+	friend class CGameHandler;
+};

+ 1 - 0
server/CVCMIServer.h

@@ -1,6 +1,7 @@
 #pragma once
 #include "../global.h"
 #include <set>
+class CConnection;
 namespace boost
 {
 	namespace asio

+ 16 - 0
server/VCMI_server.vcproj

@@ -175,6 +175,14 @@
 				RelativePath=".\CGameHandler.cpp"
 				>
 			</File>
+			<File
+				RelativePath="..\CLua.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\CScriptCallback.cpp"
+				>
+			</File>
 			<File
 				RelativePath=".\CVCMIServer.cpp"
 				>
@@ -189,6 +197,14 @@
 				RelativePath=".\CGameHandler.h"
 				>
 			</File>
+			<File
+				RelativePath="..\CLua.h"
+				>
+			</File>
+			<File
+				RelativePath=".\CScriptCallback.h"
+				>
+			</File>
 			<File
 				RelativePath=".\CVCMIServer.h"
 				>