Browse Source

* small refactoring

Please don't touch CGI->state directly in client code - use callbacks instead. I'd like to make some mechanics-critical handlers in CGI const - a lot of work, certain changes have been done here.
mateuszb 15 years ago
parent
commit
9445e5b184

+ 28 - 0
CCallback.cpp

@@ -987,6 +987,34 @@ std::string CCallback::getTavernGossip(const CGObjectInstance * townOrTavern) co
 	return "GOSSIP TEST";
 }
 
+std::vector < const CGObjectInstance * > CCallback::getMyObjects() const
+{
+	std::vector < const CGObjectInstance * > ret;
+	for (int g=0; g<gs->map->objects.size(); ++g)
+	{
+		if (gs->map->objects[g]->tempOwner == LOCPLINT->playerID)
+		{
+			ret.push_back(gs->map->objects[g]);
+		}
+	}
+	return ret;
+}
+
+std::vector < const CGDwelling * > CCallback::getMyDwellings() const
+{
+	std::vector < const CGDwelling * > ret;
+	BOOST_FOREACH(CGDwelling * dw, gs->getPlayer(player)->dwellings)
+	{
+		ret.push_back(dw);
+	}
+	return ret;
+}
+
+int CCallback::getPlayerRelations( ui8 color1, ui8 color2 ) const
+{
+	return gs->getPlayerRelations(color1, color2);
+}
+
 InfoAboutTown::InfoAboutTown()
 {
 	tType = NULL;

+ 6 - 0
CCallback.h

@@ -133,6 +133,8 @@ public:
 	virtual void castSpell(const CGHeroInstance *hero, int spellID, const int3 &pos = int3(-1, -1, -1))=0; //cast adventure map spell
 	
 	//map
+	virtual std::vector < const CGDwelling * > getMyDwellings() const =0; //returns all dwellings that belong to player
+	virtual std::vector < const CGObjectInstance * > getMyObjects() const =0; //returns all objects flagged by belonging player
 	virtual std::vector < const CGObjectInstance * > getBlockingObjs(int3 pos)const =0;
 	virtual std::vector < const CGObjectInstance * > getVisitableObjs(int3 pos)const =0;
 	virtual std::vector < const CGObjectInstance * > getFlaggableObjects(int3 pos) const =0;
@@ -153,6 +155,7 @@ public:
 
 	virtual int3 getMapSize() const =0; //returns size of map - z is 1 for one - level map and 2 for two level map
 	virtual const TerrainTile * getTileInfo(int3 tile) const = 0;
+	virtual int getPlayerRelations(ui8 color1, ui8 color2) const =0;// 0 = enemy, 1 = ally, 2 = same player 
 
 //battle
 	virtual int battleGetBattlefieldType()=0; //   1. sand/shore   2. sand/mesas   3. dirt/birches   4. dirt/hills   5. dirt/pines   6. grass/hills   7. grass/pines   8. lava   9. magic plains   10. snow/mountains   11. snow/trees   12. subterranean   13. swamp/trees   14. fiery fields   15. rock lands   16. magic clouds   17. lucid pools   18. holy ground   19. clover field   20. evil fog   21. "favourable winds" text on magic plains background   22. cursed ground   23. rough   24. ship to ship   25. ship
@@ -263,6 +266,8 @@ public:
 	void getThievesGuildInfo(SThievesGuildInfo & thi, const CGObjectInstance * obj); //get thieves' guild info obtainable while visiting given object
 	int3 getGrailPos(float &outKnownRatio); //returns pos and (via arg) percent of discovered obelisks; TODO: relies on fairness of GUI/AI... :/
 
+	std::vector < const CGDwelling * > getMyDwellings() const; //returns all dwellings that belong to player
+	std::vector < const CGObjectInstance * > getMyObjects() const; //returns all objects flagged by belonging player
 	std::vector < const CGObjectInstance * > getBlockingObjs(int3 pos) const;
 	std::vector < const CGObjectInstance * > getVisitableObjs(int3 pos) const;
 	std::vector < const CGObjectInstance * > getFlaggableObjects(int3 pos) const;
@@ -281,6 +286,7 @@ public:
 	bool getTownInfo(const CGObjectInstance *town, InfoAboutTown &dest) const;
 	int3 guardingCreaturePosition (int3 pos) const;
 	int getPlayerStatus(int player) const;
+	int getPlayerRelations(ui8 color1, ui8 color2) const;// 0 = enemy, 1 = ally, 2 = same player 
 
 	//battle
 	int battleGetBattlefieldType(); //   1. sand/shore   2. sand/mesas   3. dirt/birches   4. dirt/hills   5. dirt/pines   6. grass/hills   7. grass/pines   8. lava   9. magic plains   10. snow/mountains   11. snow/trees   12. subterranean   13. swamp/trees   14. fiery fields   15. rock lands   16. magic clouds   17. lucid pools   18. holy ground   19. clover field   20. evil fog   21. "favourable winds" text on magic plains background   22. cursed ground   23. rough   24. ship to ship   25. ship

+ 5 - 5
client/CAdvmapInterface.cpp

@@ -1773,7 +1773,7 @@ void CAdvMapInt::tileLClicked(const int3 &mp)
 	}
 	//check if we can select this object
 	bool canSelect = topBlocking && topBlocking->ID == HEROI_TYPE && topBlocking->tempOwner == LOCPLINT->playerID;
-	canSelect |= topBlocking && topBlocking->ID == TOWNI_TYPE && CGI->state->getPlayerRelations(topBlocking->tempOwner, LOCPLINT->playerID);
+	canSelect |= topBlocking && topBlocking->ID == TOWNI_TYPE && LOCPLINT->cb->getPlayerRelations(topBlocking->tempOwner, LOCPLINT->playerID);
 
 	if (selection->ID != HEROI_TYPE) //hero is not selected (presumably town)
 	{
@@ -1881,7 +1881,7 @@ void CAdvMapInt::tileHovered(const int3 &tile)
 	{
 		if(objAtTile)
 		{
-			if(objAtTile->ID == TOWNI_TYPE && CGI->state->getPlayerRelations(objAtTile->tempOwner, LOCPLINT->playerID))
+			if(objAtTile->ID == TOWNI_TYPE && LOCPLINT->cb->getPlayerRelations(objAtTile->tempOwner, LOCPLINT->playerID))
 				CGI->curh->changeGraphic(0, 3);
 			else if(objAtTile->ID == HEROI_TYPE && objAtTile->tempOwner == LOCPLINT->playerID)
 				CGI->curh->changeGraphic(0, 2);
@@ -1895,7 +1895,7 @@ void CAdvMapInt::tileHovered(const int3 &tile)
 		{
 			if(objAtTile->ID == HEROI_TYPE)
 			{
-				if(!CGI->state->getPlayerRelations( objAtTile->tempOwner, LOCPLINT->playerID)) //enemy hero
+				if(!LOCPLINT->cb->getPlayerRelations( objAtTile->tempOwner, LOCPLINT->playerID)) //enemy hero
 				{
 					if(accessible)
 						CGI->curh->changeGraphic(0, 5 + turns*6);
@@ -1914,7 +1914,7 @@ void CAdvMapInt::tileHovered(const int3 &tile)
 			}
 			else if(objAtTile->ID == TOWNI_TYPE)
 			{
-				if(!CGI->state->getPlayerRelations( objAtTile->tempOwner, LOCPLINT->playerID)) //enemy town
+				if(!LOCPLINT->cb->getPlayerRelations( objAtTile->tempOwner, LOCPLINT->playerID)) //enemy town
 				{
 					if(accessible) 
 					{
@@ -1955,7 +1955,7 @@ void CAdvMapInt::tileHovered(const int3 &tile)
 
 					// Show battle cursor for guarded enemy garrisons, otherwise movement cursor.
 					if (garrObj&&  garrObj->stacksCount() 
-						&& !CGI->state->getPlayerRelations( garrObj->tempOwner, LOCPLINT->playerID) )
+						&& !LOCPLINT->cb->getPlayerRelations( garrObj->tempOwner, LOCPLINT->playerID) )
 						CGI->curh->changeGraphic(0, 5 + turns*6);
 					else
 						CGI->curh->changeGraphic(0, 9 + turns*6);

+ 18 - 18
client/CBattleInterface.cpp

@@ -987,7 +987,7 @@ bool CShootingAnim::init()
 
 	spi.step = 0;
 	spi.frameNum = 0;
-	spi.spin = CGI->creh->idToProjectileSpin[spi.creID];
+	spi.spin = CGI->creh->idToProjectileSpin.find(spi.creID)->second;
 
 	Point xycoord = CBattleHex::getXYUnitAnim(shooter->position, true, shooter, owner);
 	Point destcoord;
@@ -1149,13 +1149,13 @@ CBattleInterface::CBattleInterface(const CCreatureSet * army1, const CCreatureSe
 			SDL_Surface * moat = BitmapHandler::loadBitmap( siegeH->getSiegeName(13) ),
 				* mlip = BitmapHandler::loadBitmap( siegeH->getSiegeName(14) );
 
-			std::pair<int, int> moatPos = CGI->heroh->wallPositions[siegeH->town->town->typeID][10],
-				mlipPos = CGI->heroh->wallPositions[siegeH->town->town->typeID][11];
+			Point moatPos = graphics->wallPositions[siegeH->town->town->typeID][10],
+				mlipPos = graphics->wallPositions[siegeH->town->town->typeID][11];
 
 			if(moat) //eg. tower has no moat
-				blitAt(moat, moatPos.first,moatPos.second, background);
+				blitAt(moat, moatPos.x,moatPos.y, background);
 			if(mlip) //eg. tower has no mlip
-				blitAt(mlip, mlipPos.first, mlipPos.second, background);
+				blitAt(mlip, mlipPos.x, mlipPos.y, background);
 
 			SDL_FreeSurface(moat);
 			SDL_FreeSurface(mlip);
@@ -1258,9 +1258,9 @@ CBattleInterface::CBattleInterface(const CCreatureSet * army1, const CCreatureSe
 	for(std::map<int, CStack>::iterator g = stacks.begin(); g != stacks.end(); ++g)
 	{
 		int creID = (g->second.type->idNumber == 149) ? CGI->creh->factionToTurretCreature[siegeH->town->town->typeID] : g->second.type->idNumber; //id of creature whose shots should be loaded
-		if(g->second.type->isShooting() && CGI->creh->idToProjectile[creID] != std::string())
+		if(g->second.type->isShooting() && CGI->creh->idToProjectile.find(creID) != CGI->creh->idToProjectile.end())
 		{	
-			idToProjectile[g->second.type->idNumber] = CDefHandler::giveDef(CGI->creh->idToProjectile[creID]);
+			idToProjectile[g->second.type->idNumber] = CDefHandler::giveDef(CGI->creh->idToProjectile.find(creID)->second);
 
 			if(idToProjectile[g->second.type->idNumber]->ourImages.size() > 2) //add symmetric images
 			{
@@ -1312,7 +1312,7 @@ CBattleInterface::CBattleInterface(const CCreatureSet * army1, const CCreatureSe
 	std::vector<CObstacleInstance> obst = curInt->cb->battleGetAllObstacles();
 	for(int t=0; t<obst.size(); ++t)
 	{
-		idToObstacle[obst[t].ID] = CDefHandler::giveDef(CGI->heroh->obstacles[obst[t].ID].defName);
+		idToObstacle[obst[t].ID] = CDefHandler::giveDef(CGI->heroh->obstacles.find(obst[t].ID)->second.defName);
 		for(int n=0; n<idToObstacle[obst[t].ID]->ourImages.size(); ++n)
 		{
 			SDL_SetColorKey(idToObstacle[obst[t].ID]->ourImages[n].bitmap, SDL_SRCCOLORKEY, SDL_MapRGB(idToObstacle[obst[t].ID]->ourImages[n].bitmap->format,0,255,255));
@@ -1535,7 +1535,7 @@ void CBattleInterface::show(SDL_Surface * to)
 	std::multimap<int, int> hexToObstacle;
 	for(int b=0; b<obstacles.size(); ++b)
 	{
-		int position = CGI->heroh->obstacles[obstacles[b].ID].getMaxBlocked(obstacles[b].pos);
+		int position = CGI->heroh->obstacles.find(obstacles[b].ID)->second.getMaxBlocked(obstacles[b].pos);
 		hexToObstacle.insert(std::make_pair(position, b));
 	}
 
@@ -1635,7 +1635,7 @@ void CBattleInterface::show(SDL_Surface * to)
 		for(std::multimap<int, int>::const_iterator it = obstRange.first; it != obstRange.second; ++it)
 		{
 			CObstacleInstance & curOb = obstacles[it->second];
-			std::pair<si16, si16> shift = CGI->heroh->obstacles[curOb.ID].posShift;
+			std::pair<si16, si16> shift = CGI->heroh->obstacles.find(curOb.ID)->second.posShift;
 			int x = ((curOb.pos/BFIELD_WIDTH)%2==0 ? 22 : 0) + 44*(curOb.pos%BFIELD_WIDTH) + pos.x + shift.first;
 			int y = 86 + 42 * (curOb.pos/BFIELD_WIDTH) + pos.y + shift.second;
 			std::vector<Cimage> &images = idToObstacle[curOb.ID]->ourImages; //reference to animation of obstacle
@@ -2338,7 +2338,7 @@ bool CBattleInterface::blockedByObstacle(int hex) const
 	std::set<int> coveredHexes;
 	for(int b = 0; b < obstacles.size(); ++b)
 	{
-		std::vector<int> blocked = CGI->heroh->obstacles[obstacles[b].ID].getBlocked(obstacles[b].pos);
+		std::vector<int> blocked = CGI->heroh->obstacles.find(obstacles[b].ID)->second.getBlocked(obstacles[b].pos);
 		for(int w = 0; w < blocked.size(); ++w)
 			coveredHexes.insert(blocked[w]);
 	}
@@ -2656,7 +2656,7 @@ void CBattleInterface::displayBattleFinished()
 
 void CBattleInterface::spellCast(BattleSpellCast * sc)
 {
-	CSpell &spell = CGI->spellh->spells[sc->id];
+	const CSpell &spell = CGI->spellh->spells[sc->id];
 
 	//spell opening battle is cast when no stack is active
 	if(sc->castedByHero && ( activeStack == -1 || sc->side == !curInt->cb->battleGetStackByID(activeStack)->attackerOwned) )
@@ -4096,19 +4096,19 @@ void CBattleInterface::SiegeHelper::printPartOfWall(SDL_Surface * to, int what)
 	case 10: //gate arch
 	case 11: //bottom static wall
 	case 12: //upper static wall
-		pos.x = CGI->heroh->wallPositions[town->town->typeID][what - 3].first + owner->pos.x;
-		pos.y = CGI->heroh->wallPositions[town->town->typeID][what - 3].second + owner->pos.y;
+		pos.x = graphics->wallPositions[town->town->typeID][what - 3].x + owner->pos.x;
+		pos.y = graphics->wallPositions[town->town->typeID][what - 3].y + owner->pos.y;
 		break;
 	case 15: //keep creature cover
 		pos = Point(owner->pos.w + owner->pos.x - walls[2]->w, 154 + owner->pos.y);
 		break;
 	case 16: //bottom turret creature cover
-		pos.x = CGI->heroh->wallPositions[town->town->typeID][0].first + owner->pos.x;
-		pos.y = CGI->heroh->wallPositions[town->town->typeID][0].second + owner->pos.y;
+		pos.x = graphics->wallPositions[town->town->typeID][0].x + owner->pos.x;
+		pos.y = graphics->wallPositions[town->town->typeID][0].y + owner->pos.y;
 		break;
 	case 17: //upper turret creature cover
-		pos.x = CGI->heroh->wallPositions[town->town->typeID][5].first + owner->pos.x;
-		pos.y = CGI->heroh->wallPositions[town->town->typeID][5].second + owner->pos.y;
+		pos.x = graphics->wallPositions[town->town->typeID][5].x + owner->pos.x;
+		pos.y = graphics->wallPositions[town->town->typeID][5].y + owner->pos.y;
 		break;
 	};
 

+ 12 - 12
client/CCastleInterface.cpp

@@ -170,7 +170,7 @@ void CBuildingRect::clickRight(tribool down, bool previousState)
 	{
 		int bid = hordeToDwellingID(str->ID);
 		
-		CBuilding *bld = CGI->buildh->buildings[str->townID][bid];
+		CBuilding *bld = CGI->buildh->buildings[str->townID].find(bid)->second;
 		assert(bld);
 
 		CInfoPopup *vinya = new CInfoPopup();
@@ -192,7 +192,7 @@ std::string getBuildingSubtitle(int tid, int bid)//hover text for building
 	bid = hordeToDwellingID(bid);
 	
 	if (bid<30)//non-dwellings - only buiding name
-		return CGI->buildh->buildings[tid][bid]->Name();
+		return CGI->buildh->buildings[tid].find(bid)->second->Name();
 	else//dwellings - recruit %creature%
 	{
 		int creaID = t->creatures[(bid-30)%CREATURES_PER_TOWN].second.back();//taking last of available creatures
@@ -576,7 +576,7 @@ void CCastleInterface::buildingClicked(int building)
 	tlog5<<"You've clicked on "<<building<<std::endl;
 	building = hordeToDwellingID(building);
 
-	const CBuilding *b = CGI->buildh->buildings[town->subID][building];
+	const CBuilding *b = CGI->buildh->buildings[town->subID].find(building)->second;
 
 	if(building >= 30)
 	{
@@ -799,7 +799,7 @@ void CCastleInterface::defaultBuildingClicked(int building)
 		new CCustomImgComponent(SComponent::building,town->subID,building,bicons->ourImages[building].bitmap,false));
 
 	LOCPLINT->showInfoDialog(
-		CGI->buildh->buildings[town->subID][building]->Description(),
+		CGI->buildh->buildings[town->subID].find(building)->second->Description(),
 		comps, soundBase::sound_todo);
 }
 
@@ -808,9 +808,9 @@ void CCastleInterface::enterFountain(int building)
 	std::vector<SComponent*> comps(1,
 		new CCustomImgComponent(SComponent::building,town->subID,building,bicons->ourImages[building].bitmap,false));
 
-	std::string descr = CGI->buildh->buildings[town->subID][building]->Description();
+	std::string descr = CGI->buildh->buildings[town->subID].find(building)->second->Description();
 	if ( building == 21)//we need description for mystic pond as well
-	descr += "\n\n"+CGI->buildh->buildings[town->subID][17]->Description();
+	descr += "\n\n"+CGI->buildh->buildings[town->subID].find(17)->second->Description();
 	if (town->bonusValue.first == 0)//fountain was builded this week
 		descr += "\n\n"+ CGI->generaltexth->allTexts[677];
 	else//fountain produced something;
@@ -830,7 +830,7 @@ void CCastleInterface::enterBlacksmith(int ArtifactID)
 	if(!hero)
 	{
 		std::string pom = CGI->generaltexth->allTexts[273];
-		boost::algorithm::replace_first(pom,"%s",CGI->buildh->buildings[town->subID][16]->Name());
+		boost::algorithm::replace_first(pom,"%s",CGI->buildh->buildings[town->subID].find(16)->second->Name());
 		LOCPLINT->showInfoDialog(pom,std::vector<SComponent*>(), soundBase::sound_todo);
 		return;
 	}
@@ -999,7 +999,7 @@ void CCastleInterface::recreateBuildings()
 
 	for (std::set<si32>::const_iterator i=town->builtBuildings.begin();i!=town->builtBuildings.end();i++)
 	{
-		if(CGI->townh->structures.find(town->subID) != CGI->townh->structures.end()) //we have info about structures in this town
+		if(town->subID >= 0 && town->subID < CGI->townh->structures.size()) //we have info about structures in this town
 		{
 			if(CGI->townh->structures[town->subID].find(*i)!=CGI->townh->structures[town->subID].end()) //we have info about that structure
 			{
@@ -1242,10 +1242,10 @@ void CCastleInterface::CCreaInfo::clickRight(tribool down, bool previousState)
 
 			cnt = 0;
 
-			for (std::vector<CGDwelling*>::const_iterator it = CGI->state->players[ci->town->tempOwner].dwellings.begin();
-				it !=CGI->state->players[ci->town->tempOwner].dwellings.end(); ++it)
-					if (CGI->creh->creatures[ci->town->town->basicCreatures[level]]->idNumber == (*it)->creatures[0].second[0])
-						cnt++;//external dwellings count to summ
+			std::vector< const CGDwelling * > myDwellings = LOCPLINT->cb->getMyDwellings();
+			for (std::vector<const CGDwelling*>::const_iterator it = myDwellings.begin(); it != myDwellings.end(); ++it)
+				if (CGI->creh->creatures[ci->town->town->basicCreatures[level]]->idNumber == (*it)->creatures[0].second[0])
+					cnt++;//external dwellings count to summ
 			summ+=AddToString(CGI->generaltexth->allTexts[591],descr,cnt);
 
 			const CGHeroInstance * ch = ci->town->garrisonHero;

+ 1 - 1
client/CGameInfo.cpp

@@ -12,7 +12,7 @@
  *
  */
 
-CGameInfo * CGI;
+CGameInfo * CGI; //game info for general use
 
 CGameInfo::CGameInfo()
 {

+ 22 - 14
client/CGameInfo.h

@@ -42,32 +42,40 @@ class CVideoPlayer;
 
 /*
 	CGameInfo class
-	for allowing different functions for modifying game informations
+	for allowing different functions for accessing game informations
 */
 class CGameInfo
 {
+	/*const*/ CGameState * state; //don't touch it in client's code
 public:
-	CGameState * state;
-	CArtHandler * arth;
-	CHeroHandler * heroh;
-	CCreatureHandler * creh;
-	CSpellHandler * spellh;
-	CMapHandler * mh;
-	CBuildingHandler * buildh;
-	CObjectHandler * objh;
+	/*const*/ CArtHandler * arth;
+	/*const*/ CHeroHandler * heroh;
+	/*const*/ CCreatureHandler * creh;
+	/*const*/ CSpellHandler * spellh;
+	/*const*/ CMapHandler * mh;
+	/*const*/ CBuildingHandler * buildh;
+	/*const*/ CObjectHandler * objh;
 	CSoundHandler * soundh;
 	CMusicHandler * musich;
-	CDefObjInfoHandler * dobjinfo;
-	CTownHandler * townh;
-	CGeneralTextHandler * generaltexth;
+	/*const*/ CDefObjInfoHandler * dobjinfo;
+	/*const*/ CTownHandler * townh;
+	/*const*/ CGeneralTextHandler * generaltexth;
 	CConsoleHandler * consoleh;
 	CCursorHandler * curh;
-	CScreenHandler * screenh;
+	/*const*/ CScreenHandler * screenh;
 	CVideoPlayer * videoh;
 
-	CGameInfo();
 	void setFromLib();
+
+	friend class CClient;
+	friend class CMapHandler; //TODO: remove it
+
+	CGameInfo();
 };
 
 
+
+
+
+
 #endif // __CGAMEINFO_H__

+ 14 - 16
client/CKingdomInterface.cpp

@@ -128,27 +128,25 @@ CKingdomInterface::CKingdomInterface()
 	INSERT_MAP (87,0) ,87));//Harbor
 	#undef INSERT_MAP
 
-	for(size_t i = 0; i<CGI->state->map->objects.size(); i++)//getting mines and dwelling (in one pass to make it faster)
+	std::vector<const CGObjectInstance * > myObjects = LOCPLINT->cb->getMyObjects();
+	for(size_t i = 0; i<myObjects.size(); i++)//getting mines and dwelling (in one pass to make it faster)
 	{
-		CGObjectInstance* obj = CGI->state->map->objects[i];//current object
+		const CGObjectInstance* obj = myObjects[i];//current object
 		if (obj)
 		{
-			if (obj->tempOwner == CGI->state->currentPlayer)//if object is our
+			std::pair<int,int > curElm = std::pair<int,int >(obj->ID, obj->subID);
+			if ( obj->ID == 17 )//dwelling, text is a plural name of a creature
 			{
-				std::pair<int,int > curElm = std::pair<int,int >(obj->ID, obj->subID);
-				if ( obj->ID == 17 )//dwelling, text is a plural name of a creature
-				{
-					objList[obj->subID].first += 1;
-					objList[obj->subID].second = & CGI->creh->creatures[CGI->objh->cregens[obj->subID]]->namePl;
-				}
-				else if (addObjects.find(curElm) != addObjects.end())
-				{//object from addObjects map, text is name of the object
-					objList[addObjects[curElm]].first += 1;
-					objList[addObjects[curElm]].second = & obj->hoverName;
-				}
-				else if ( obj->ID == 53 )//TODO: abandoned mines
-					incomesVal[obj->subID]+=1;
+				objList[obj->subID].first += 1;
+				objList[obj->subID].second = & CGI->creh->creatures[CGI->objh->cregens[obj->subID]]->namePl;
 			}
+			else if (addObjects.find(curElm) != addObjects.end())
+			{//object from addObjects map, text is name of the object
+				objList[addObjects[curElm]].first += 1;
+				objList[addObjects[curElm]].second = & obj->hoverName;
+			}
+			else if ( obj->ID == 53 )//TODO: abandoned mines
+				incomesVal[obj->subID]+=1;
 		}
 	}
 

+ 1 - 0
client/CMT.cpp

@@ -248,6 +248,7 @@ int main(int argc, char** argv)
 	srand ( time(NULL) );
 	//CPG=NULL;
 	CGI = new CGameInfo; //contains all global informations about game (texts, lodHandlers, map handler itp.)
+
 	if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_AUDIO))
 	{
 		tlog1<<"Something was wrong: "<< SDL_GetError() << std::endl;

+ 32 - 0
client/Graphics.cpp

@@ -279,6 +279,7 @@ Graphics::Graphics()
 	tasks += boost::bind(&Graphics::loadHeroFlags,this);
 	tasks += boost::bind(&Graphics::loadHeroPortraits,this);
 	tasks += boost::bind(&Graphics::initializeBattleGraphics,this);
+	tasks += boost::bind(&Graphics::loadWallPositions,this);
 	tasks += GET_SURFACE(hInfo,"HEROQVBK.bmp");
 	tasks += GET_SURFACE(tInfo,"TOWNQVBK.bmp");
 	tasks += GET_SURFACE(heroInGarrison,"TOWNQKGH.bmp");
@@ -364,6 +365,37 @@ void Graphics::loadHeroPortraits()
 	}
 	of.close();
 }
+
+void Graphics::loadWallPositions()
+{
+	std::ifstream inp;
+	inp.open(DATA_DIR "/config/wall_pos.txt", std::ios_base::in|std::ios_base::binary);
+	if(!inp.is_open())
+	{
+		tlog1<<"missing file: config/wall_pos.txt"<<std::endl;
+	}
+	else
+	{
+		const int MAX_BUF = 2000;
+		char buf[MAX_BUF+1];
+
+		inp.getline(buf, MAX_BUF);
+		std::string dump;
+		for(int g=0; g<ARRAY_COUNT(wallPositions); ++g)
+		{
+			inp >> dump;
+			for(int b=0; b<12; ++b)
+			{
+				Point pt;
+				inp >> pt.x;
+				inp >> pt.y;
+				wallPositions[g].push_back(pt);
+			}
+		}
+	}
+	inp.close();
+}
+
 void Graphics::loadHeroAnims()
 {
 	std::vector<std::pair<int,int> > rotations; //first - group number to be rotated1, second - group number after rotation1

+ 3 - 0
client/Graphics.h

@@ -4,6 +4,7 @@
 #include <SDL_ttf.h>
 #include "../global.h"
 #include "FontBase.h"
+#include "GUIBase.h"
 
 /*
  * Graphics.h, part of VCMI engine
@@ -69,6 +70,7 @@ public:
 	std::map< int, std::vector < std::string > > battleACToDef; //maps AC format to vector of appropriate def names
 	CDefEssential * spellEffectsPics; //bitmaps representing spells affecting a stack in battle
 	std::vector<std::string> guildBgs;// name of bitmaps with imgs for mage guild screen
+	std::vector< Point > wallPositions[F_NUMBER]; //positions of different pieces of wall <x, y>
 	//abilities
 	CDefEssential * abils32, * abils44, * abils82;
 	//spells
@@ -82,6 +84,7 @@ public:
 	void loadHeroAnims();
 	void loadHeroAnim(const std::string &name, const std::vector<std::pair<int,int> > &rotations, std::vector<CDefEssential *> Graphics::*dst);
 	void loadHeroPortraits();
+	void loadWallPositions();
 	SDL_Surface * drawHeroInfoWin(const InfoAboutHero &curh);
 	SDL_Surface * drawHeroInfoWin(const CGHeroInstance * curh);
 	SDL_Surface * drawTownInfoWin(const InfoAboutTown & curh);

+ 2 - 1
global.h

@@ -77,7 +77,8 @@ enum ElossCon {lossCastle, lossHero, timeExpires, lossStandard=255};
 enum ECombatInfo{ALIVE = 180, SUMMONED, CLONED, HAD_MORALE, WAITING, MOVED, DEFENDING};
 
 class CGameInfo;
-extern CGameInfo* CGI;
+extern CGameInfo* CGI; //game info for general use
+
 
 const int HEROI_TYPE = 34, 
 	TOWNI_TYPE = 98,

+ 3 - 2
hch/CBuildingHandler.cpp

@@ -54,6 +54,7 @@ void CBuildingHandler::loadBuildings()
 	temp = readTo(buf,it,'\n');temp = readTo(buf,it,'\n');//read 2 lines of file info
 
 	//read 9 special buildings for every faction
+	buildings.resize(F_NUMBER);
 	for(int i=0;i<F_NUMBER;i++)
 	{
 		temp = readTo(buf,it,'\n');//read blank line and faction name
@@ -166,8 +167,8 @@ void CBuildingHandler::loadBuildings()
 
 CBuildingHandler::~CBuildingHandler()
 {
-	for(std::map<int, std::map<int, CBuilding*> >::iterator i=buildings.begin(); i!=buildings.end(); i++)
-		for(std::map<int, CBuilding*>::iterator j=i->second.begin(); j!=i->second.end(); j++)
+	for(std::vector< std::map<int, CBuilding*> >::iterator i=buildings.begin(); i!=buildings.end(); i++)
+		for(std::map<int, CBuilding*>::iterator j=i->begin(); j!=i->end(); j++)
 			delete j->second;
 }
 

+ 1 - 1
hch/CBuildingHandler.h

@@ -37,7 +37,7 @@ public:
 class DLL_EXPORT CBuildingHandler
 {
 public:
-	std::map<int, std::map<int, CBuilding*> > buildings; ///< first int is the castle ID, second the building ID (in ERM-U format)
+	std::vector< std::map<int, CBuilding*> > buildings; ///< vector by castle ID, second the building ID (in ERM-U format)
 	std::map<int, std::pair<std::string,std::vector< std::vector< std::vector<int> > > > > hall; //map<castle ID, pair<hall bg name, std::vector< std::vector<building id> >[5]> - external vector is the vector of buildings in the row, internal is the list of buildings for the specific slot
 	std::map<int, std::string> ERMUtoPicture[F_NUMBER]; //maps building ID to it's picture's name for each town type
 

+ 9 - 38
hch/CHeroHandler.cpp

@@ -138,36 +138,6 @@ CHeroHandler::~CHeroHandler()
 CHeroHandler::CHeroHandler()
 {}
 
-void CHeroHandler::loadWallPositions()
-{
-	std::ifstream inp;
-	inp.open(DATA_DIR "/config/wall_pos.txt", std::ios_base::in|std::ios_base::binary);
-	if(!inp.is_open())
-	{
-		tlog1<<"missing file: config/wall_pos.txt"<<std::endl;
-	}
-	else
-	{
-		const int MAX_BUF = 2000;
-		char buf[MAX_BUF+1];
-
-		inp.getline(buf, MAX_BUF);
-		std::string dump;
-		for(int g=0; g<ARRAY_COUNT(wallPositions); ++g)
-		{
-			inp >> dump;
-			for(int b=0; b<12; ++b)
-			{
-				std::pair<int, int> pt;
-				inp >> pt.first;
-				inp >> pt.second;
-				wallPositions[g].push_back(pt);
-			}
-		}
-	}
-	inp.close();
-}
-
 void CHeroHandler::loadObstacles()
 {
 	std::ifstream inp;
@@ -376,6 +346,11 @@ void CHeroHandler::loadHeroes()
 	expPerLevel.push_back(24320);
 	expPerLevel.push_back(28784);
 	expPerLevel.push_back(34140);
+	while (expPerLevel[expPerLevel.size() - 1] > expPerLevel[expPerLevel.size() - 2])
+	{
+		int i = expPerLevel.size() - 1;
+		expPerLevel.push_back (expPerLevel[i] + (expPerLevel[i] - expPerLevel[i-1]) * 1.2);
+	}
 
 	//ballistics info
 	buf = bitmaph->getTextFile("BALLIST.TXT");
@@ -498,7 +473,7 @@ void CHeroHandler::initHeroClasses()
 	loadNativeTerrains();
 }
 
-unsigned int CHeroHandler::level (ui64 experience)
+unsigned int CHeroHandler::level (ui64 experience) const
 {
 	int i;
 	if (experience <= expPerLevel.back())
@@ -515,7 +490,7 @@ unsigned int CHeroHandler::level (ui64 experience)
 	}
 }
 
-ui64 CHeroHandler::reqExp (unsigned int level)
+ui64 CHeroHandler::reqExp (unsigned int level) const
 {
 	if(!level)
 		return 0;
@@ -526,12 +501,8 @@ ui64 CHeroHandler::reqExp (unsigned int level)
 	}
 	else
 	{
-		while (level > expPerLevel.size())
-		{
-			int i = expPerLevel.size() - 1;
-			expPerLevel.push_back (expPerLevel[i] + (expPerLevel[i] - expPerLevel[i-1]) * 1.2);
-		}
-		return expPerLevel[level-1];
+		tlog3 << "A hero has reached unsupported amount of experience\n";
+		return expPerLevel[expPerLevel.size()-1];
 	}
 }
 

+ 3 - 6
hch/CHeroHandler.h

@@ -132,9 +132,6 @@ public:
 	};
 	std::vector<SBallisticsLevelInfo> ballistics; //info about ballistics ability per level; [0] - none; [1] - basic; [2] - adv; [3] - expert
 
-	std::vector<std::pair<int, int> > wallPositions[F_NUMBER]; //positions of different pieces of wall <x, y>
-	void loadWallPositions();
-
 	std::map<int, CObstacleInfo> obstacles; //info about obstacles that may be placed on battlefield
 	std::vector<int> nativeTerrains; //info about native terrains of different factions
 
@@ -143,8 +140,8 @@ public:
 	std::vector<SPuzzleInfo> puzzleInfo[F_NUMBER]; //descriptions of puzzles
 	void loadPuzzleInfo();
 
-	unsigned int level(ui64 experience); //calculates level corresponding to given experience amount
-	ui64 reqExp(unsigned int level); //calculates experience required for given level
+	unsigned int level(ui64 experience) const; //calculates level corresponding to given experience amount
+	ui64 reqExp(unsigned int level) const; //calculates experience required for given level
 
 	void loadHeroes();
 	void loadHeroClasses();
@@ -156,7 +153,7 @@ public:
 
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
-		h & heroClasses & heroes & expPerLevel & ballistics & wallPositions & obstacles & nativeTerrains & puzzleInfo;
+		h & heroClasses & heroes & expPerLevel & ballistics & obstacles & nativeTerrains & puzzleInfo;
 		if(!h.saving)
 		{
 			//restore class pointers

+ 14 - 12
hch/CTownHandler.cpp

@@ -25,8 +25,8 @@ CTownHandler::CTownHandler()
 }
 CTownHandler::~CTownHandler()
 {
-	for( std::map<int,std::map<int, Structure*> >::iterator i= structures.begin(); i!=structures.end(); i++)
-		for( std::map<int, Structure*>::iterator j = i->second.begin(); j!=i->second.end(); j++)
+	for( std::vector<std::map<int, Structure*> >::iterator i= structures.begin(); i!=structures.end(); i++)
+		for( std::map<int, Structure*>::iterator j = i->begin(); j!=i->end(); j++)
 			delete j->second;
 }
 void CTownHandler::loadNames()
@@ -94,6 +94,7 @@ void CTownHandler::loadNames()
 	of.clear();
 
 	of.open(DATA_DIR "/config/requirements.txt");
+	requirements.resize(F_NUMBER);
 	while(!of.eof())
 	{
 		int ile, town, build, pom;
@@ -124,6 +125,7 @@ void CTownHandler::loadNames()
 
 void CTownHandler::loadStructures()
 {
+	structures.resize(F_NUMBER);
 	//read buildings coords
 	std::ifstream of(DATA_DIR "/config/buildings.txt");
 	while(!of.eof())
@@ -151,7 +153,7 @@ void CTownHandler::loadStructures()
 	of >> format >> idt;
 	while(!of.eof())
 	{
-		std::map<int,std::map<int, Structure*> >::iterator i;
+		std::vector<std::map<int, Structure*> >::iterator i;
 		std::map<int, Structure*>::iterator i2;
 		int itr=1, buildingID;
 		int castleID;
@@ -165,8 +167,8 @@ void CTownHandler::loadStructures()
 			if (s == "END")
 				break;
 			else
-				if((i=structures.find(castleID))!=structures.end())
-					if((i2=(i->second.find(buildingID=atoi(s.c_str()))))!=(i->second.end()))
+				if( (i=structures.begin() + castleID) != structures.end() )
+					if( (i2 = i->find( buildingID = atoi(s.c_str()) )) != (i->end()) )
 						i2->second->pos.z=itr++;
 					else
 						tlog3 << "Warning1: No building "<<buildingID<<" in the castle "<<castleID<<std::endl;
@@ -181,14 +183,14 @@ void CTownHandler::loadStructures()
 	of.open(DATA_DIR "/config/buildings3.txt");
 	while(!of.eof())
 	{
-		std::map<int,std::map<int, Structure*> >::iterator i;
+		std::vector<std::map<int, Structure*> >::iterator i;
 		std::map<int, Structure*>::iterator i2;
 		int town, id;
 		std::string border, area;
 		of >> town >> id >> border >> border >> area;
 
-		if((i=structures.find(town))!=structures.end())
-			if((i2=(i->second.find(id)))!=(i->second.end()))
+		if( (i = structures.begin() + town) != structures.end() )
+			if((i2=(i->find(id)))!=(i->end()))
 			{
 				i2->second->borderName = border;
 				i2->second->areaName = area;
@@ -216,7 +218,7 @@ void CTownHandler::loadStructures()
 		int itr=1;
 		while(!of.eof())
 		{
-			std::map<int,std::map<int, Structure*> >::iterator i;
+			std::vector<std::map<int, Structure*> >::iterator i;
 			std::map<int, Structure*>::iterator i2;
 			int buildingID;
 			int castleID;
@@ -246,8 +248,8 @@ void CTownHandler::loadStructures()
 						buildingID = atoi(s.c_str());
 						if(castleID>=0)
 						{
-							if((i=structures.find(castleID))!=structures.end())
-								if((i2=(i->second.find(buildingID)))!=(i->second.end()))
+							if((i = structures.begin() + castleID) != structures.end())
+								if((i2=(i->find(buildingID)))!=(i->end()))
 									i2->second->group = itr;
 								else
 									tlog3 << "Warning3: No building "<<buildingID<<" in the castle "<<castleID<<std::endl;
@@ -258,7 +260,7 @@ void CTownHandler::loadStructures()
 						{
 							for(i=structures.begin();i!=structures.end();i++)
 							{
-								for(i2=i->second.begin(); i2!=i->second.end(); i2++)
+								for(i2=i->begin(); i2!=i->end(); i2++)
 								{
 									if(i2->first == buildingID)
 									{

+ 2 - 2
hch/CTownHandler.h

@@ -64,8 +64,8 @@ class DLL_EXPORT CTownHandler
 {
 public:
 	std::vector<CTown> towns;
-	std::map<int,std::map<int, Structure*> > structures; // <town ID, <structure ID, structure>>
-	std::map<int, std::map<int,std::set<int> > > requirements; //requirements[town_id][structure_id] -> set of required buildings
+	std::vector<std::map<int, Structure*> > structures; // <town ID, <structure ID, structure>>
+	std::vector<std::map<int,std::set<int> > > requirements; //requirements[town_id][structure_id] -> set of required buildings
 
 	CTownHandler(); //c-tor
 	~CTownHandler(); //d-tor

+ 0 - 1
lib/VCMI_Lib.cpp

@@ -174,7 +174,6 @@ void LibClasses::init()
 	heroh = new CHeroHandler;
 	heroh->loadHeroes();
 	heroh->loadObstacles();
-	heroh->loadWallPositions();
 	heroh->loadPuzzleInfo();
 	tlog0 <<"\tHero handler: "<<pomtime.getDif()<<std::endl;