Bläddra i källkod

Reshaped some code responsible for hero list / paths.
* Garrisoning, then removing hero from garrison move him at the end of the list
* problems with the hero window hero list should be fixed

Michał W. Urbańczyk 16 år sedan
förälder
incheckning
58c12e8d73

+ 2 - 2
CCallback.cpp

@@ -691,10 +691,10 @@ int CCallback::canBuildStructure( const CGTownInstance *t, int ID )
 	return gs->canBuildStructure(t,ID);
 }
 
-CPath * CCallback::getPath( int3 src, int3 dest, const CGHeroInstance * hero )
+bool CCallback::getPath(int3 src, int3 dest, const CGHeroInstance * hero, CPath &ret)
 {
 	boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
-	return gs->getPath(src,dest,hero);
+	return gs->getPath(src,dest,hero, ret);
 }
 
 void CCallback::save( const std::string &fname )

+ 2 - 2
CCallback.h

@@ -87,7 +87,7 @@ public:
 	virtual std::vector<const CGHeroInstance *> getAvailableHeroes(const CGTownInstance * town) const =0; //heroes that can be recruited
 	virtual const TerrainTile * getTileInfo(int3 tile) const = 0;
 	virtual int canBuildStructure(const CGTownInstance *t, int ID) =0;//// 0 - no more than one capitol, 1 - lack of water, 2 - forbidden, 3 - Add another level to Mage Guild, 4 - already built, 5 - cannot build, 6 - cannot afford, 7 - build, 8 - lack of requirements
-	virtual CPath * getPath(int3 src, int3 dest, const CGHeroInstance * hero)=0;
+	virtual bool getPath(int3 src, int3 dest, const CGHeroInstance * hero, CPath &ret)=0;
 
 //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
@@ -181,7 +181,7 @@ public:
 	std::vector<const CGHeroInstance *> getAvailableHeroes(const CGTownInstance * town) const; //heroes that can be recruited
 	const TerrainTile * getTileInfo(int3 tile) const;
 	int canBuildStructure(const CGTownInstance *t, int ID);//// 0 - no more than one capitol, 1 - lack of water, 2 - forbidden, 3 - Add another level to Mage Guild, 4 - already built, 5 - cannot build, 6 - cannot afford, 7 - build, 8 - lack of requirements
-	CPath * getPath(int3 src, int3 dest, const CGHeroInstance * hero);
+	bool getPath(int3 src, int3 dest, const CGHeroInstance * hero, CPath &ret);
 
 	//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

+ 38 - 14
client/CAdvmapInterface.cpp

@@ -421,7 +421,7 @@ void CTerrainRect::clickLeft(tribool down)
 		if(currentPath)
 		{
 			tlog2<<"Warning: Lost path?" << std::endl;
-			delete currentPath;
+			//delete currentPath;
 			currentPath = NULL;
 		}
 
@@ -484,11 +484,13 @@ void CTerrainRect::clickLeft(tribool down)
 		else if(mp.z == currentHero->pos.z) //remove old path and find a new one if we clicked on the map level on which hero is present
 		{
 			int3 bufpos = currentHero->getPosition(false);
-			CPath *& pathForCurhero = LOCPLINT->adventureInt->heroList.items[LOCPLINT->adventureInt->heroList.selected].second;
-			if(pathForCurhero)
-				delete pathForCurhero;
-
-			currentPath = pathForCurhero = LOCPLINT->cb->getPath(bufpos, mp, currentHero);
+			CPath &path = LOCPLINT->adventureInt->paths[currentHero];
+			currentPath = &path;
+			if(!LOCPLINT->cb->getPath(bufpos, mp, currentHero, path))
+			{
+				LOCPLINT->adventureInt->paths.erase(currentHero);
+				currentPath = NULL;
+			}
 		}
 	} //end of hero is selected "case"
 }
@@ -1310,6 +1312,7 @@ void CAdvMapInt::fmoveHero()
 	LOCPLINT->moveHero(static_cast<const CGHeroInstance*>(LOCPLINT->adventureInt->selection),*terrain.currentPath);
 	LOCPLINT->pim->lock();
 }
+
 void CAdvMapInt::fshowSpellbok()
 {
 	if (selection->ID!=HEROI_TYPE) //checking necessary values
@@ -1319,29 +1322,34 @@ void CAdvMapInt::fshowSpellbok()
 	CSpellWindow * spellWindow = new CSpellWindow(genRect(595, 620, (conf.cc.resx - 620)/2, (conf.cc.resy - 595)/2), (static_cast<const CGHeroInstance*>(LOCPLINT->adventureInt->selection)));
 	LOCPLINT->pushInt(spellWindow);
 }
+
 void CAdvMapInt::fadventureOPtions()
 {
 }
+
 void CAdvMapInt::fsystemOptions()
 {
 	CSystemOptionsWindow * sysopWindow = new CSystemOptionsWindow(genRect(487, 481, 159, 57), LOCPLINT);
 	LOCPLINT->pushInt(sysopWindow);
 }
+
 void CAdvMapInt::fnextHero()
 {
-	if(!heroList.items.size()) //no wandering heroes
+	if(!LOCPLINT->wanderingHeroes.size()) //no wandering heroes
 		return; 
 
 	int start = heroList.selected;
 	int i = start;
+
 	do 
 	{
 		i++;
-		if(i >= heroList.items.size())
+		if(i >= LOCPLINT->wanderingHeroes.size())
 			i = 0;
-	} while (!heroList.items[i].first->movement && i!=start);
+	} while (LOCPLINT->wanderingHeroes[i]->movement && i!=start);
 	heroList.select(i);
 }
+
 void CAdvMapInt::fendTurn()
 {
 	LOCPLINT->makingTurn = false;
@@ -1590,17 +1598,33 @@ void CAdvMapInt::select(const CArmedInstance *sel )
 	LOCPLINT->cb->setSelection(sel);
 	centerOn(sel->pos);
 	selection = sel;
+
+	terrain.currentPath = NULL;
 	if(sel->ID==TOWNI_TYPE)
 	{
 		int pos = vstd::findPos(townList.items,sel);
 		townList.selected = pos;
-		terrain.currentPath = NULL;
 	}
-	else
+	else //hero selected
 	{
-		int pos = heroList.getPosOfHero(sel);
-		heroList.selected = pos;
-		terrain.currentPath = heroList.items[pos].second;
+		const CGHeroInstance *h = static_cast<const CGHeroInstance*>(sel);
+
+		if(LOCPLINT->getWHero(heroList.selected) != h)
+			heroList.selected = heroList.getPosOfHero(h);
+
+		if(vstd::contains(paths,h)) //hero has assigned path
+		{
+			CPath &path = paths[h];
+			//update the hero path in case of something has changed on map
+			if(LOCPLINT->cb->getPath(path.startPos(), path.endPos(), h, path))
+				terrain.currentPath = &path;
+			else
+				paths.erase(h);
+		}
+		else
+		{
+			terrain.currentPath;
+		}	
 	}
 	townList.draw(screen);
 	heroList.draw(screen);

+ 6 - 10
client/CAdvmapInterface.h

@@ -119,19 +119,17 @@ public:
 	int3 position; //top left corner of visible map part
 	int player, active;
 
-	std::vector<CDefHandler *> gems;
 
 	enum{LEFT=1, RIGHT=2, UP=4, DOWN=8};
 	ui8 scrollingDir; //uses enum: LEFT RIGHT, UP, DOWN
+
 	bool updateScreen, updateMinimap ;
 	unsigned char anim, animValHitCount; //animation frame
 	unsigned char heroAnim, heroAnimValHitCount; //animation frame
 
-	CMinimap minimap;
-
-
 	SDL_Surface * bg;
-
+	std::vector<CDefHandler *> gems;
+	CMinimap minimap;
 	CStatusBar statusbar;
 
 	AdventureMapButton kingOverview,//- kingdom overview
@@ -144,7 +142,6 @@ public:
 		sysOptions,//- system options
 		nextHero, //- next hero
 		endTurn;//- end turn
-	//CHeroList herolist;
 
 	CTerrainRect terrain; //visible terrain
 
@@ -156,9 +153,10 @@ public:
 
 	CHeroWindow * heroWindow;
 
-	const CArmedInstance *selection;
+	const CArmedInstance *selection; //currently selected town/hero
+	std::map<const CGHeroInstance *, CPath> paths; //maps hero => selected path in adventure map
 
-	//fuctions binded to buttons
+	//functions binded to buttons
 	void fshowOverview();
 	void fswitchLevel();
 	void fshowQuestlog();
@@ -182,7 +180,5 @@ public:
 	int3 verifyPos(int3 ver);
 	void handleRightClick(std::string text, boost::logic::tribool down, CIntObject * client);
 	void keyPressed(const SDL_KeyboardEvent & key);
-
-
 };
 #endif // __CADVMAPINTERFACE_H__

+ 3 - 3
client/CHeroWindow.cpp

@@ -583,9 +583,9 @@ void CHeroWindow::redrawCurBack()
 
 	//hero list blitting
 
-	for(int pos=0, g=0; g<LOCPLINT->cb->howManyHeroes(); ++g)
+	for(int pos=0, g=0; g<LOCPLINT->wanderingHeroes.size(); ++g)
 	{
-		const CGHeroInstance * cur = LOCPLINT->cb->getHeroInfo(g, false);
+		const CGHeroInstance * cur = LOCPLINT->wanderingHeroes[g];
 		if (cur->inTownGarrison)
 			// Only display heroes that are not in garrison
 			continue;
@@ -875,7 +875,7 @@ void LClickableAreaHero::clickLeft(boost::logic::tribool down)
 	if(!down)
 	{
 		owner->deactivate();
-		const CGHeroInstance * buf = LOCPLINT->cb->getHeroInfo(id, false);
+		const CGHeroInstance * buf = LOCPLINT->getWHero(id);
 		owner->setHero(buf);
 		owner->redrawCurBack();
 		owner->activate();

+ 32 - 11
client/CPlayerInterface.cpp

@@ -124,6 +124,7 @@ void CPlayerInterface::init(ICallback * CB)
 		SDL_Surface * pom = infoWin(tt[i]);
 		graphics->townWins.insert(std::pair<int,SDL_Surface*>(tt[i]->id,pom));
 	}
+	recreateWanderingHeroes();
 }
 void CPlayerInterface::yourTurn()
 {
@@ -158,8 +159,8 @@ void CPlayerInterface::yourTurn()
 
 		//select first hero if available.
 		//TODO: check if hero is slept
-		if(adventureInt->heroList.items.size())
-			adventureInt->select(adventureInt->heroList.items[0].first);
+		if(wanderingHeroes.size())
+			adventureInt->select(wanderingHeroes[0]);
 		else
 			adventureInt->select(adventureInt->townList.items[0]);
 
@@ -320,9 +321,8 @@ void CPlayerInterface::heroMoved(const HeroMoveDetails & details)
 
 		if(ho->movement)
 		{
-			delete adventureInt->terrain.currentPath;
+			adventureInt->paths.erase(ho);
 			adventureInt->terrain.currentPath = NULL;
-			adventureInt->heroList.items[adventureInt->heroList.getPosOfHero(ho)].second = NULL;
 		}
 		stillMoveHero.setn(STOP_MOVE);
 		return;
@@ -330,13 +330,12 @@ void CPlayerInterface::heroMoved(const HeroMoveDetails & details)
 
 	if (adventureInt->terrain.currentPath) //&& hero is moving
 	{
+		//remove one node from the path (the one we went)
 		adventureInt->terrain.currentPath->nodes.erase(adventureInt->terrain.currentPath->nodes.end()-1);
-		if(!adventureInt->terrain.currentPath->nodes.size())
+		if(!adventureInt->terrain.currentPath->nodes.size())  //if it was the last one, remove entire path
 		{
-
-			delete adventureInt->terrain.currentPath;
+			adventureInt->paths.erase(ho);
 			adventureInt->terrain.currentPath = NULL;
-			adventureInt->heroList.items[adventureInt->heroList.getPosOfHero(ho)].second = NULL;
 		}
 	}
 
@@ -808,6 +807,7 @@ void CPlayerInterface::heroKilled(const CGHeroInstance* hero)
 {
 	boost::unique_lock<boost::recursive_mutex> un(*pim);
 	graphics->heroWins.erase(hero->ID);
+	wanderingHeroes -= hero;
 	adventureInt->heroList.updateHList(hero);
 }
 void CPlayerInterface::heroCreated(const CGHeroInstance * hero)
@@ -815,6 +815,7 @@ void CPlayerInterface::heroCreated(const CGHeroInstance * hero)
 	boost::unique_lock<boost::recursive_mutex> un(*pim);
 	if(graphics->heroWins.find(hero->subID)==graphics->heroWins.end())
 		graphics->heroWins.insert(std::pair<int,SDL_Surface*>(hero->subID,infoWin(hero)));
+	wanderingHeroes.push_back(hero);
 	adventureInt->heroList.updateHList();
 }
 void CPlayerInterface::openTownWindow(const CGTownInstance * town)
@@ -1076,15 +1077,21 @@ void CPlayerInterface::heroInGarrisonChange(const CGTownInstance *town)
 	//redraw infowindow
 	SDL_FreeSurface(graphics->townWins[town->id]);
 	graphics->townWins[town->id] = infoWin(town);
-	if(town->garrisonHero)
+
+
+	if(town->garrisonHero && vstd::contains(wanderingHeroes,town->garrisonHero)) //wandering hero moved to the garrison
 	{
 		CGI->mh->hideObject(town->garrisonHero);
+		wanderingHeroes -= town->garrisonHero;
 	}
-	if(town->visitingHero)
+
+	if(town->visitingHero && !vstd::contains(wanderingHeroes,town->visitingHero)) //hero leaves garrison
 	{
 		CGI->mh->printObject(town->visitingHero);
+		wanderingHeroes.push_back(town->visitingHero);
 	}
-	adventureInt->heroList.updateHList();
+
+	//adventureInt->heroList.updateHList();
 
 	CCastleInterface *c = castleInt;
 	if(c)
@@ -1716,3 +1723,17 @@ void CPlayerInterface::requestRealized( PackageApplied *pa )
 		stillMoveHero.setn(CONTINUE_MOVE);
 }
 
+void CPlayerInterface::recreateWanderingHeroes()
+{
+	std::vector<const CGHeroInstance*> heroes = cb->getHeroesInfo();
+	for(size_t i = 0; i < heroes.size(); i++)
+		if(!heroes[i]->inTownGarrison)
+			wanderingHeroes.push_back(heroes[i]);
+}
+
+const CGHeroInstance * CPlayerInterface::getWHero( int pos )
+{
+	if(pos < 0 || pos >= wanderingHeroes.size())
+		return NULL;
+	return wanderingHeroes[pos];
+}

+ 4 - 1
client/CPlayerInterface.h

@@ -87,7 +87,6 @@ public:
 	void setMapScrollingSpeed(int newSpeed) {mapScrollingSpeed = newSpeed;} //set the member above
 
 	SDL_Event * current; //current event
-	//CMainInterface *curint;
 	CAdvMapInt * adventureInt;
 	CCastleInterface * castleInt; //NULL if castle window isn't opened
 	CBattleInterface * battleInt; //NULL if no battle
@@ -107,6 +106,10 @@ public:
 	void popInts(int howMany); //pops one or more interfaces - deactivates top, deletes and removes given number of interfaces, activates new front
 	IShowActivable *topInt(); //returns top interface
 
+	std::vector<const CGHeroInstance *> wanderingHeroes; //our heroes on the adventure map (not the garrisoned ones)
+	void recreateWanderingHeroes();
+	const CGHeroInstance *getWHero(int pos); //returns NULL if position is not valid
+
 	//GUI elements
 	std::list<ClickableL*> lclickable;
 	std::list<ClickableR*> rclickable;

+ 38 - 64
client/GUIClasses.cpp

@@ -1033,7 +1033,7 @@ CList::CList(int Size)
 }
 
 CHeroList::CHeroList(int Size)
-:CList(Size)
+:CList(Size), heroes(LOCPLINT->wanderingHeroes)
 {
 	arrup = CDefHandler::giveDef(conf.go()->ac.hlistAU);
 	arrdo = CDefHandler::giveDef(conf.go()->ac.hlistAD);
@@ -1069,13 +1069,13 @@ void CHeroList::init()
 
 void CHeroList::genList()
 {
-	int howMany = LOCPLINT->cb->howManyHeroes();
-	for (int i=0;i<howMany;i++)
-	{
-		const CGHeroInstance * h = LOCPLINT->cb->getHeroInfo(i,0);
-		if(!h->inTownGarrison)
-			items.push_back(std::pair<const CGHeroInstance *,CPath *>(h,NULL));
-	}
+	//int howMany = LOCPLINT->cb->howManyHeroes();
+	//for (int i=0;i<howMany;i++)
+	//{
+	//	const CGHeroInstance * h = LOCPLINT->cb->getHeroInfo(i,0);
+	//	if(!h->inTownGarrison)
+	//		items.push_back(std::pair<const CGHeroInstance *,CPath *>(h,NULL));
+	//}
 }
 
 void CHeroList::select(int which)
@@ -1088,23 +1088,11 @@ void CHeroList::select(int which)
 		draw(screen);
 		LOCPLINT->adventureInt->infoBar.draw(screen);
 	}
-	if (which>=items.size())
+	if (which>=heroes.size())
 		return;
-	selected = which;
 
-	//recalculationg path in case of something has changed on map
-	if(items[which].second)
-	{
-		CPath * newPath = LOCPLINT->cb->getPath(items[which].second->startPos(), items[which].second->endPos(), items[which].first);
-		delete items[which].second;
-		LOCPLINT->adventureInt->terrain.currentPath = items[which].second = newPath;
-	}
-	else
-	{
-		LOCPLINT->adventureInt->terrain.currentPath = NULL;
-	}
-	LOCPLINT->adventureInt->select(items[which].first);
-	//recalculated and assigned
+	selected = which;
+	LOCPLINT->adventureInt->select(heroes[which]);
 }
 
 void CHeroList::clickLeft(tribool down)
@@ -1123,7 +1111,7 @@ void CHeroList::clickLeft(tribool down)
 		}
 		else if(isItIn(&arrdop,LOCPLINT->current->motion.x,LOCPLINT->current->motion.y))
 		{
-			if(items.size()-from>SIZE)
+			if(heroes.size()-from>SIZE)
 			{
 				blitAt(arrdo->ourImages[1].bitmap,arrdop.x,arrdop.y);
 				pressed = false;
@@ -1138,7 +1126,7 @@ void CHeroList::clickLeft(tribool down)
 		if (ny>=SIZE || ny<0)
 			return;
 		if ( (ny+from)==selected && (LOCPLINT->adventureInt->selection->ID == HEROI_TYPE))
-			LOCPLINT->openHeroWindow(items[selected].first);//print hero screen
+			LOCPLINT->openHeroWindow(heroes[selected]);//print hero screen
 		select(ny+from);
 	}
 	else
@@ -1188,7 +1176,7 @@ void CHeroList::mouseMoved (const SDL_MouseMotionEvent & sEvent)
 	}
 	else if(isItIn(&arrdop,LOCPLINT->current->motion.x,LOCPLINT->current->motion.y))
 	{
-		if ((items.size()-from)  >  SIZE)
+		if ((heroes.size()-from)  >  SIZE)
 			LOCPLINT->adventureInt->statusbar.print(CGI->generaltexth->zelp[304].first);
 		else
 			LOCPLINT->adventureInt->statusbar.clear();
@@ -1199,14 +1187,14 @@ void CHeroList::mouseMoved (const SDL_MouseMotionEvent & sEvent)
 	hx-=pos.x;
 	hy-=pos.y; hy-=arrup->ourImages[0].bitmap->h;
 	int ny = hy/32;
-	if ((ny>SIZE || ny<0) || (from+ny>=items.size()))
+	if ((ny>SIZE || ny<0) || (from+ny>=heroes.size()))
 	{
 		LOCPLINT->adventureInt->statusbar.clear();
 		return;
 	}
 	std::vector<std::string> temp;
-	temp.push_back(items[from+ny].first->name);
-	temp.push_back(items[from+ny].first->type->heroClass->name);
+	temp.push_back(heroes[from+ny]->name);
+	temp.push_back(heroes[from+ny]->type->heroClass->name);
 	LOCPLINT->adventureInt->statusbar.print( processStr(CGI->generaltexth->allTexts[15],temp) );
 	//select(ny+from);
 }
@@ -1220,7 +1208,7 @@ void CHeroList::clickRight(tribool down)
 		{
 			LOCPLINT->adventureInt->handleRightClick(CGI->generaltexth->zelp[303].second,down,this);
 		}
-		else if(isItIn(&arrdop,LOCPLINT->current->motion.x,LOCPLINT->current->motion.y) && (items.size()-from>5))
+		else if(isItIn(&arrdop,LOCPLINT->current->motion.x,LOCPLINT->current->motion.y) && (heroes.size()-from>5))
 		{
 			LOCPLINT->adventureInt->handleRightClick(CGI->generaltexth->zelp[304].second,down,this);
 		}
@@ -1231,15 +1219,15 @@ void CHeroList::clickRight(tribool down)
 			hx-=pos.x;
 			hy-=pos.y; hy-=arrup->ourImages[0].bitmap->h;
 			int ny = hy/32;
-			if ((ny>SIZE || ny<0) || (from+ny>=items.size()))
+			if ((ny>SIZE || ny<0) || (from+ny>=heroes.size()))
 			{
 				return;
 			}
 
 			//show popup
-			CInfoPopup * ip = new CInfoPopup(graphics->heroWins[items[from+ny].first->subID],
-				LOCPLINT->current->motion.x-graphics->heroWins[items[from+ny].first->subID]->w,
-				LOCPLINT->current->motion.y-graphics->heroWins[items[from+ny].first->subID]->h,
+			CInfoPopup * ip = new CInfoPopup(graphics->heroWins[heroes[from+ny]->subID],
+				LOCPLINT->current->motion.x-graphics->heroWins[heroes[from+ny]->subID]->w,
+				LOCPLINT->current->motion.y-graphics->heroWins[heroes[from+ny]->subID]->h,
 				false);
 			LOCPLINT->pushInt(ip);
 		}
@@ -1262,25 +1250,16 @@ void CHeroList::keyPressed (const SDL_KeyboardEvent & key)
 void CHeroList::updateHList(const CGHeroInstance *toRemove)
 {
 	if(toRemove) //remove specific hero
-	{
-		for (std::vector<std::pair<const CGHeroInstance*, CPath *> >::iterator i=items.begin(); i != items.end(); i++)
-		{
-			if(i->first == toRemove)
-			{
-				delete i->second;
-				items.erase(i);
-				break;
-			}
-		}
-	}
+		heroes -= toRemove;
 	else
-	{
-		items.clear();
-		genList();
-	}
-	if(selected>=items.size())
-		select(items.size()-1);
-	if(items.size()==0)
+		LOCPLINT->recreateWanderingHeroes();
+
+
+	if(selected >= heroes.size())
+		select(heroes.size()-1);
+
+
+	if(heroes.size() == 0)
 		LOCPLINT->adventureInt->townList.select(0);
 	else
 		select(selected);
@@ -1289,8 +1268,8 @@ void CHeroList::updateHList(const CGHeroInstance *toRemove)
 void CHeroList::updateMove(const CGHeroInstance* which) //draws move points bar
 {
 	int ser = -1;
-	for(int i=0; i<items.size() && ser<0; i++)
-		if(items[i].first->subID == which->subID)
+	for(int i=0; i<heroes.size() && ser<0; i++)
+		if(heroes[i]->subID == which->subID)
 			ser = i;
 	ser -= from;
 	if(ser<0 || ser > SIZE) return;
@@ -1303,14 +1282,14 @@ void CHeroList::draw(SDL_Surface * to)
 	for (int iT=0+from;iT<SIZE+from;iT++)
 	{
 		int i = iT-from;
-		if (iT>=items.size())
+		if (iT>=heroes.size())
 		{
 			blitAt(mobile->ourImages[0].bitmap,posmobx,posmoby+i*32,to);
 			blitAt(mana->ourImages[0].bitmap,posmanx,posmany+i*32,to);
 			blitAt(empty,posporx,pospory+i*32,to);
 			continue;
 		}
-		const CGHeroInstance *cur = items[iT].first;
+		const CGHeroInstance *cur = heroes[iT];
 		int pom = cur->movement / 100;
 		if (pom>25) pom=25;
 		if (pom<0) pom=0;
@@ -1332,22 +1311,17 @@ void CHeroList::draw(SDL_Surface * to)
 	else
 		blitAt(arrup->ourImages[2].bitmap,arrupp.x,arrupp.y,to);
 
-	if (items.size()-from > SIZE)
+	if (heroes.size()-from > SIZE)
 		blitAt(arrdo->ourImages[0].bitmap,arrdop.x,arrdop.y,to);
 	else
 		blitAt(arrdo->ourImages[2].bitmap,arrdop.x,arrdop.y,to);
 }
 
-int CHeroList::getPosOfHero(const CArmedInstance* h)
+int CHeroList::getPosOfHero(const CGHeroInstance* h)
 {
-	return vstd::findPos(
-		items,h,
-		boost::bind(vstd::equal<std::pair<const CGHeroInstance*, CPath *>,
-		const CArmedInstance *,const CGHeroInstance*>,_1,
-		&std::pair<const CGHeroInstance*, CPath *>::first,_2));
+	return vstd::findPos(heroes, h, std::equal_to<const CGHeroInstance*>());
 }
 
-
 CTownList::~CTownList()
 {
 	delete arrup;

+ 2 - 3
client/GUIClasses.h

@@ -268,11 +268,11 @@ class CHeroList
 {
 public:
 	CDefHandler *mobile, *mana; //mana and movement indicators
-	std::vector<std::pair<const CGHeroInstance*, CPath *> > items;
 	int posmobx, posporx, posmanx, posmoby, pospory, posmany;
 
+	std::vector<const CGHeroInstance *> &heroes; //points to LOCPLINT->wandering heroes 
 	CHeroList(int Size); //c-tor
-	int getPosOfHero(const CArmedInstance* h); //hero's position on list
+	int getPosOfHero(const CGHeroInstance* h); //hero's position on list
 	void genList();
 	void select(int which); //call-in
 	void mouseMoved (const SDL_MouseMotionEvent & sEvent); //call-in
@@ -282,7 +282,6 @@ public:
 	void keyPressed (const SDL_KeyboardEvent & key); //call-in
 	void updateHList(const CGHeroInstance *toRemove=NULL); //removes specific hero from the list or recreates it
 	void updateMove(const CGHeroInstance* which); //draws move points bar
-	void redrawAllOne(int which); //not imeplemented
 	void draw(SDL_Surface * to);
 	void init();
 };

+ 8 - 8
lib/CGameState.cpp

@@ -1616,10 +1616,10 @@ PlayerState * CGameState::getPlayer( ui8 color )
 	}
 }
 
-CPath * CGameState::getPath(int3 src, int3 dest, const CGHeroInstance * hero)
+bool CGameState::getPath(int3 src, int3 dest, const CGHeroInstance * hero, CPath &ret)
 {
 	if(!map->isInTheMap(src) || !map->isInTheMap(dest)) //check input
-		return NULL;
+		return false;
 
 	int3 hpos = hero->getPosition(false);
 	tribool blockLandSea; //true - blocks sea, false - blocks land, indeterminate - allows all
@@ -1710,19 +1710,19 @@ CPath * CGameState::getPath(int3 src, int3 dest, const CGHeroInstance * hero)
 
 	CPathNode *curNode = &graph[dest.x][dest.y];
 	if(!curNode->theNodeBefore) //destination is not accessible
-		return NULL;
+		return false;
 
-	CPath * ret = new CPath;
 
+	//fill ret with found path
+	ret.nodes.clear();
 	while(curNode->coord != graph[src.x][src.y].coord)
 	{
-		ret->nodes.push_back(*curNode);
+		ret.nodes.push_back(*curNode);
 		curNode = curNode->theNodeBefore;
 	}
+	ret.nodes.push_back(graph[src.x][src.y]);
 
-	ret->nodes.push_back(graph[src.x][src.y]);
-
-	return ret;
+	return true;
 }
 
 bool CGameState::checkForVisitableDir(const int3 & src, const int3 & dst) const

+ 1 - 1
lib/CGameState.h

@@ -282,7 +282,7 @@ public:
 	float getMarketEfficiency(int player, int mode=0);
 	int canBuildStructure(const CGTownInstance *t, int ID);// 0 - no more than one capitol, 1 - lack of water, 2 - forbidden, 3 - Add another level to Mage Guild, 4 - already built, 5 - cannot build, 6 - cannot afford, 7 - build, 8 - lack of requirements
 	bool checkForVisitableDir(const int3 & src, const int3 & dst) const; //check if dst tile is visitable from dst tile
-	CPath * getPath(int3 src, int3 dest, const CGHeroInstance * hero); //calculates path between src and dest; returns pointer to newly allocated CPath or NULL if path does not exists
+	bool getPath(int3 src, int3 dest, const CGHeroInstance * hero, CPath &ret); //calculates path between src and dest; returns pointer to newly allocated CPath or NULL if path does not exists
 
 	CGameState(); //c-tor
 	~CGameState(); //d-tor