浏览代码

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 年之前
父节点
当前提交
58c12e8d73

+ 2 - 2
CCallback.cpp

@@ -691,10 +691,10 @@ int CCallback::canBuildStructure( const CGTownInstance *t, int ID )
 	return gs->canBuildStructure(t,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);
 	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 )
 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 std::vector<const CGHeroInstance *> getAvailableHeroes(const CGTownInstance * town) const =0; //heroes that can be recruited
 	virtual const TerrainTile * getTileInfo(int3 tile) const = 0;
 	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 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
 //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
 	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
 	std::vector<const CGHeroInstance *> getAvailableHeroes(const CGTownInstance * town) const; //heroes that can be recruited
 	const TerrainTile * getTileInfo(int3 tile) const;
 	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
 	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
 	//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
 	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)
 		if(currentPath)
 		{
 		{
 			tlog2<<"Warning: Lost path?" << std::endl;
 			tlog2<<"Warning: Lost path?" << std::endl;
-			delete currentPath;
+			//delete currentPath;
 			currentPath = NULL;
 			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
 		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);
 			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"
 	} //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->moveHero(static_cast<const CGHeroInstance*>(LOCPLINT->adventureInt->selection),*terrain.currentPath);
 	LOCPLINT->pim->lock();
 	LOCPLINT->pim->lock();
 }
 }
+
 void CAdvMapInt::fshowSpellbok()
 void CAdvMapInt::fshowSpellbok()
 {
 {
 	if (selection->ID!=HEROI_TYPE) //checking necessary values
 	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)));
 	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);
 	LOCPLINT->pushInt(spellWindow);
 }
 }
+
 void CAdvMapInt::fadventureOPtions()
 void CAdvMapInt::fadventureOPtions()
 {
 {
 }
 }
+
 void CAdvMapInt::fsystemOptions()
 void CAdvMapInt::fsystemOptions()
 {
 {
 	CSystemOptionsWindow * sysopWindow = new CSystemOptionsWindow(genRect(487, 481, 159, 57), LOCPLINT);
 	CSystemOptionsWindow * sysopWindow = new CSystemOptionsWindow(genRect(487, 481, 159, 57), LOCPLINT);
 	LOCPLINT->pushInt(sysopWindow);
 	LOCPLINT->pushInt(sysopWindow);
 }
 }
+
 void CAdvMapInt::fnextHero()
 void CAdvMapInt::fnextHero()
 {
 {
-	if(!heroList.items.size()) //no wandering heroes
+	if(!LOCPLINT->wanderingHeroes.size()) //no wandering heroes
 		return; 
 		return; 
 
 
 	int start = heroList.selected;
 	int start = heroList.selected;
 	int i = start;
 	int i = start;
+
 	do 
 	do 
 	{
 	{
 		i++;
 		i++;
-		if(i >= heroList.items.size())
+		if(i >= LOCPLINT->wanderingHeroes.size())
 			i = 0;
 			i = 0;
-	} while (!heroList.items[i].first->movement && i!=start);
+	} while (LOCPLINT->wanderingHeroes[i]->movement && i!=start);
 	heroList.select(i);
 	heroList.select(i);
 }
 }
+
 void CAdvMapInt::fendTurn()
 void CAdvMapInt::fendTurn()
 {
 {
 	LOCPLINT->makingTurn = false;
 	LOCPLINT->makingTurn = false;
@@ -1590,17 +1598,33 @@ void CAdvMapInt::select(const CArmedInstance *sel )
 	LOCPLINT->cb->setSelection(sel);
 	LOCPLINT->cb->setSelection(sel);
 	centerOn(sel->pos);
 	centerOn(sel->pos);
 	selection = sel;
 	selection = sel;
+
+	terrain.currentPath = NULL;
 	if(sel->ID==TOWNI_TYPE)
 	if(sel->ID==TOWNI_TYPE)
 	{
 	{
 		int pos = vstd::findPos(townList.items,sel);
 		int pos = vstd::findPos(townList.items,sel);
 		townList.selected = pos;
 		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);
 	townList.draw(screen);
 	heroList.draw(screen);
 	heroList.draw(screen);

+ 6 - 10
client/CAdvmapInterface.h

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

+ 3 - 3
client/CHeroWindow.cpp

@@ -583,9 +583,9 @@ void CHeroWindow::redrawCurBack()
 
 
 	//hero list blitting
 	//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)
 		if (cur->inTownGarrison)
 			// Only display heroes that are not in garrison
 			// Only display heroes that are not in garrison
 			continue;
 			continue;
@@ -875,7 +875,7 @@ void LClickableAreaHero::clickLeft(boost::logic::tribool down)
 	if(!down)
 	if(!down)
 	{
 	{
 		owner->deactivate();
 		owner->deactivate();
-		const CGHeroInstance * buf = LOCPLINT->cb->getHeroInfo(id, false);
+		const CGHeroInstance * buf = LOCPLINT->getWHero(id);
 		owner->setHero(buf);
 		owner->setHero(buf);
 		owner->redrawCurBack();
 		owner->redrawCurBack();
 		owner->activate();
 		owner->activate();

+ 32 - 11
client/CPlayerInterface.cpp

@@ -124,6 +124,7 @@ void CPlayerInterface::init(ICallback * CB)
 		SDL_Surface * pom = infoWin(tt[i]);
 		SDL_Surface * pom = infoWin(tt[i]);
 		graphics->townWins.insert(std::pair<int,SDL_Surface*>(tt[i]->id,pom));
 		graphics->townWins.insert(std::pair<int,SDL_Surface*>(tt[i]->id,pom));
 	}
 	}
+	recreateWanderingHeroes();
 }
 }
 void CPlayerInterface::yourTurn()
 void CPlayerInterface::yourTurn()
 {
 {
@@ -158,8 +159,8 @@ void CPlayerInterface::yourTurn()
 
 
 		//select first hero if available.
 		//select first hero if available.
 		//TODO: check if hero is slept
 		//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
 		else
 			adventureInt->select(adventureInt->townList.items[0]);
 			adventureInt->select(adventureInt->townList.items[0]);
 
 
@@ -320,9 +321,8 @@ void CPlayerInterface::heroMoved(const HeroMoveDetails & details)
 
 
 		if(ho->movement)
 		if(ho->movement)
 		{
 		{
-			delete adventureInt->terrain.currentPath;
+			adventureInt->paths.erase(ho);
 			adventureInt->terrain.currentPath = NULL;
 			adventureInt->terrain.currentPath = NULL;
-			adventureInt->heroList.items[adventureInt->heroList.getPosOfHero(ho)].second = NULL;
 		}
 		}
 		stillMoveHero.setn(STOP_MOVE);
 		stillMoveHero.setn(STOP_MOVE);
 		return;
 		return;
@@ -330,13 +330,12 @@ void CPlayerInterface::heroMoved(const HeroMoveDetails & details)
 
 
 	if (adventureInt->terrain.currentPath) //&& hero is moving
 	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);
 		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->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);
 	boost::unique_lock<boost::recursive_mutex> un(*pim);
 	graphics->heroWins.erase(hero->ID);
 	graphics->heroWins.erase(hero->ID);
+	wanderingHeroes -= hero;
 	adventureInt->heroList.updateHList(hero);
 	adventureInt->heroList.updateHList(hero);
 }
 }
 void CPlayerInterface::heroCreated(const CGHeroInstance * 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);
 	boost::unique_lock<boost::recursive_mutex> un(*pim);
 	if(graphics->heroWins.find(hero->subID)==graphics->heroWins.end())
 	if(graphics->heroWins.find(hero->subID)==graphics->heroWins.end())
 		graphics->heroWins.insert(std::pair<int,SDL_Surface*>(hero->subID,infoWin(hero)));
 		graphics->heroWins.insert(std::pair<int,SDL_Surface*>(hero->subID,infoWin(hero)));
+	wanderingHeroes.push_back(hero);
 	adventureInt->heroList.updateHList();
 	adventureInt->heroList.updateHList();
 }
 }
 void CPlayerInterface::openTownWindow(const CGTownInstance * town)
 void CPlayerInterface::openTownWindow(const CGTownInstance * town)
@@ -1076,15 +1077,21 @@ void CPlayerInterface::heroInGarrisonChange(const CGTownInstance *town)
 	//redraw infowindow
 	//redraw infowindow
 	SDL_FreeSurface(graphics->townWins[town->id]);
 	SDL_FreeSurface(graphics->townWins[town->id]);
 	graphics->townWins[town->id] = infoWin(town);
 	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);
 		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);
 		CGI->mh->printObject(town->visitingHero);
+		wanderingHeroes.push_back(town->visitingHero);
 	}
 	}
-	adventureInt->heroList.updateHList();
+
+	//adventureInt->heroList.updateHList();
 
 
 	CCastleInterface *c = castleInt;
 	CCastleInterface *c = castleInt;
 	if(c)
 	if(c)
@@ -1716,3 +1723,17 @@ void CPlayerInterface::requestRealized( PackageApplied *pa )
 		stillMoveHero.setn(CONTINUE_MOVE);
 		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
 	void setMapScrollingSpeed(int newSpeed) {mapScrollingSpeed = newSpeed;} //set the member above
 
 
 	SDL_Event * current; //current event
 	SDL_Event * current; //current event
-	//CMainInterface *curint;
 	CAdvMapInt * adventureInt;
 	CAdvMapInt * adventureInt;
 	CCastleInterface * castleInt; //NULL if castle window isn't opened
 	CCastleInterface * castleInt; //NULL if castle window isn't opened
 	CBattleInterface * battleInt; //NULL if no battle
 	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
 	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
 	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
 	//GUI elements
 	std::list<ClickableL*> lclickable;
 	std::list<ClickableL*> lclickable;
 	std::list<ClickableR*> rclickable;
 	std::list<ClickableR*> rclickable;

+ 38 - 64
client/GUIClasses.cpp

@@ -1033,7 +1033,7 @@ CList::CList(int Size)
 }
 }
 
 
 CHeroList::CHeroList(int Size)
 CHeroList::CHeroList(int Size)
-:CList(Size)
+:CList(Size), heroes(LOCPLINT->wanderingHeroes)
 {
 {
 	arrup = CDefHandler::giveDef(conf.go()->ac.hlistAU);
 	arrup = CDefHandler::giveDef(conf.go()->ac.hlistAU);
 	arrdo = CDefHandler::giveDef(conf.go()->ac.hlistAD);
 	arrdo = CDefHandler::giveDef(conf.go()->ac.hlistAD);
@@ -1069,13 +1069,13 @@ void CHeroList::init()
 
 
 void CHeroList::genList()
 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)
 void CHeroList::select(int which)
@@ -1088,23 +1088,11 @@ void CHeroList::select(int which)
 		draw(screen);
 		draw(screen);
 		LOCPLINT->adventureInt->infoBar.draw(screen);
 		LOCPLINT->adventureInt->infoBar.draw(screen);
 	}
 	}
-	if (which>=items.size())
+	if (which>=heroes.size())
 		return;
 		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)
 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))
 		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);
 				blitAt(arrdo->ourImages[1].bitmap,arrdop.x,arrdop.y);
 				pressed = false;
 				pressed = false;
@@ -1138,7 +1126,7 @@ void CHeroList::clickLeft(tribool down)
 		if (ny>=SIZE || ny<0)
 		if (ny>=SIZE || ny<0)
 			return;
 			return;
 		if ( (ny+from)==selected && (LOCPLINT->adventureInt->selection->ID == HEROI_TYPE))
 		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);
 		select(ny+from);
 	}
 	}
 	else
 	else
@@ -1188,7 +1176,7 @@ void CHeroList::mouseMoved (const SDL_MouseMotionEvent & sEvent)
 	}
 	}
 	else if(isItIn(&arrdop,LOCPLINT->current->motion.x,LOCPLINT->current->motion.y))
 	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);
 			LOCPLINT->adventureInt->statusbar.print(CGI->generaltexth->zelp[304].first);
 		else
 		else
 			LOCPLINT->adventureInt->statusbar.clear();
 			LOCPLINT->adventureInt->statusbar.clear();
@@ -1199,14 +1187,14 @@ void CHeroList::mouseMoved (const SDL_MouseMotionEvent & sEvent)
 	hx-=pos.x;
 	hx-=pos.x;
 	hy-=pos.y; hy-=arrup->ourImages[0].bitmap->h;
 	hy-=pos.y; hy-=arrup->ourImages[0].bitmap->h;
 	int ny = hy/32;
 	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();
 		LOCPLINT->adventureInt->statusbar.clear();
 		return;
 		return;
 	}
 	}
 	std::vector<std::string> temp;
 	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) );
 	LOCPLINT->adventureInt->statusbar.print( processStr(CGI->generaltexth->allTexts[15],temp) );
 	//select(ny+from);
 	//select(ny+from);
 }
 }
@@ -1220,7 +1208,7 @@ void CHeroList::clickRight(tribool down)
 		{
 		{
 			LOCPLINT->adventureInt->handleRightClick(CGI->generaltexth->zelp[303].second,down,this);
 			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);
 			LOCPLINT->adventureInt->handleRightClick(CGI->generaltexth->zelp[304].second,down,this);
 		}
 		}
@@ -1231,15 +1219,15 @@ void CHeroList::clickRight(tribool down)
 			hx-=pos.x;
 			hx-=pos.x;
 			hy-=pos.y; hy-=arrup->ourImages[0].bitmap->h;
 			hy-=pos.y; hy-=arrup->ourImages[0].bitmap->h;
 			int ny = hy/32;
 			int ny = hy/32;
-			if ((ny>SIZE || ny<0) || (from+ny>=items.size()))
+			if ((ny>SIZE || ny<0) || (from+ny>=heroes.size()))
 			{
 			{
 				return;
 				return;
 			}
 			}
 
 
 			//show popup
 			//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);
 				false);
 			LOCPLINT->pushInt(ip);
 			LOCPLINT->pushInt(ip);
 		}
 		}
@@ -1262,25 +1250,16 @@ void CHeroList::keyPressed (const SDL_KeyboardEvent & key)
 void CHeroList::updateHList(const CGHeroInstance *toRemove)
 void CHeroList::updateHList(const CGHeroInstance *toRemove)
 {
 {
 	if(toRemove) //remove specific hero
 	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
 	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);
 		LOCPLINT->adventureInt->townList.select(0);
 	else
 	else
 		select(selected);
 		select(selected);
@@ -1289,8 +1268,8 @@ void CHeroList::updateHList(const CGHeroInstance *toRemove)
 void CHeroList::updateMove(const CGHeroInstance* which) //draws move points bar
 void CHeroList::updateMove(const CGHeroInstance* which) //draws move points bar
 {
 {
 	int ser = -1;
 	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 = i;
 	ser -= from;
 	ser -= from;
 	if(ser<0 || ser > SIZE) return;
 	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++)
 	for (int iT=0+from;iT<SIZE+from;iT++)
 	{
 	{
 		int i = iT-from;
 		int i = iT-from;
-		if (iT>=items.size())
+		if (iT>=heroes.size())
 		{
 		{
 			blitAt(mobile->ourImages[0].bitmap,posmobx,posmoby+i*32,to);
 			blitAt(mobile->ourImages[0].bitmap,posmobx,posmoby+i*32,to);
 			blitAt(mana->ourImages[0].bitmap,posmanx,posmany+i*32,to);
 			blitAt(mana->ourImages[0].bitmap,posmanx,posmany+i*32,to);
 			blitAt(empty,posporx,pospory+i*32,to);
 			blitAt(empty,posporx,pospory+i*32,to);
 			continue;
 			continue;
 		}
 		}
-		const CGHeroInstance *cur = items[iT].first;
+		const CGHeroInstance *cur = heroes[iT];
 		int pom = cur->movement / 100;
 		int pom = cur->movement / 100;
 		if (pom>25) pom=25;
 		if (pom>25) pom=25;
 		if (pom<0) pom=0;
 		if (pom<0) pom=0;
@@ -1332,22 +1311,17 @@ void CHeroList::draw(SDL_Surface * to)
 	else
 	else
 		blitAt(arrup->ourImages[2].bitmap,arrupp.x,arrupp.y,to);
 		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);
 		blitAt(arrdo->ourImages[0].bitmap,arrdop.x,arrdop.y,to);
 	else
 	else
 		blitAt(arrdo->ourImages[2].bitmap,arrdop.x,arrdop.y,to);
 		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()
 CTownList::~CTownList()
 {
 {
 	delete arrup;
 	delete arrup;

+ 2 - 3
client/GUIClasses.h

@@ -268,11 +268,11 @@ class CHeroList
 {
 {
 public:
 public:
 	CDefHandler *mobile, *mana; //mana and movement indicators
 	CDefHandler *mobile, *mana; //mana and movement indicators
-	std::vector<std::pair<const CGHeroInstance*, CPath *> > items;
 	int posmobx, posporx, posmanx, posmoby, pospory, posmany;
 	int posmobx, posporx, posmanx, posmoby, pospory, posmany;
 
 
+	std::vector<const CGHeroInstance *> &heroes; //points to LOCPLINT->wandering heroes 
 	CHeroList(int Size); //c-tor
 	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 genList();
 	void select(int which); //call-in
 	void select(int which); //call-in
 	void mouseMoved (const SDL_MouseMotionEvent & sEvent); //call-in
 	void mouseMoved (const SDL_MouseMotionEvent & sEvent); //call-in
@@ -282,7 +282,6 @@ public:
 	void keyPressed (const SDL_KeyboardEvent & key); //call-in
 	void keyPressed (const SDL_KeyboardEvent & key); //call-in
 	void updateHList(const CGHeroInstance *toRemove=NULL); //removes specific hero from the list or recreates it
 	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 updateMove(const CGHeroInstance* which); //draws move points bar
-	void redrawAllOne(int which); //not imeplemented
 	void draw(SDL_Surface * to);
 	void draw(SDL_Surface * to);
 	void init();
 	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
 	if(!map->isInTheMap(src) || !map->isInTheMap(dest)) //check input
-		return NULL;
+		return false;
 
 
 	int3 hpos = hero->getPosition(false);
 	int3 hpos = hero->getPosition(false);
 	tribool blockLandSea; //true - blocks sea, false - blocks land, indeterminate - allows all
 	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];
 	CPathNode *curNode = &graph[dest.x][dest.y];
 	if(!curNode->theNodeBefore) //destination is not accessible
 	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)
 	while(curNode->coord != graph[src.x][src.y].coord)
 	{
 	{
-		ret->nodes.push_back(*curNode);
+		ret.nodes.push_back(*curNode);
 		curNode = curNode->theNodeBefore;
 		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
 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);
 	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
 	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
 	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(); //c-tor
 	~CGameState(); //d-tor
 	~CGameState(); //d-tor