diff --git a/CCallback.cpp b/CCallback.cpp index 6773bf7c1..7053fa569 100644 --- a/CCallback.cpp +++ b/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 lock(*gs->mx); - return gs->getPath(src,dest,hero); + return gs->getPath(src,dest,hero, ret); } void CCallback::save( const std::string &fname ) diff --git a/CCallback.h b/CCallback.h index cb2b63745..f75c679ea 100644 --- a/CCallback.h +++ b/CCallback.h @@ -87,7 +87,7 @@ public: virtual std::vector 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 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 diff --git a/client/CAdvmapInterface.cpp b/client/CAdvmapInterface.cpp index 23ea2a373..608d0fc38 100644 --- a/client/CAdvmapInterface.cpp +++ b/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(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(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(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); diff --git a/client/CAdvmapInterface.h b/client/CAdvmapInterface.h index 3ca8718ec..7eaf95eca 100644 --- a/client/CAdvmapInterface.h +++ b/client/CAdvmapInterface.h @@ -119,19 +119,17 @@ public: int3 position; //top left corner of visible map part int player, active; - std::vector 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 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 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__ diff --git a/client/CHeroWindow.cpp b/client/CHeroWindow.cpp index 2d110a8da..44b63c430 100644 --- a/client/CHeroWindow.cpp +++ b/client/CHeroWindow.cpp @@ -583,9 +583,9 @@ void CHeroWindow::redrawCurBack() //hero list blitting - for(int pos=0, g=0; gcb->howManyHeroes(); ++g) + for(int pos=0, g=0; gwanderingHeroes.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(); diff --git a/client/CPlayerInterface.cpp b/client/CPlayerInterface.cpp index d97326506..5f75f531a 100644 --- a/client/CPlayerInterface.cpp +++ b/client/CPlayerInterface.cpp @@ -124,6 +124,7 @@ void CPlayerInterface::init(ICallback * CB) SDL_Surface * pom = infoWin(tt[i]); graphics->townWins.insert(std::pair(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 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 un(*pim); if(graphics->heroWins.find(hero->subID)==graphics->heroWins.end()) graphics->heroWins.insert(std::pair(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 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]; +} \ No newline at end of file diff --git a/client/CPlayerInterface.h b/client/CPlayerInterface.h index 5f1d8bc3c..3ac9b7745 100644 --- a/client/CPlayerInterface.h +++ b/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 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 lclickable; std::list rclickable; diff --git a/client/GUIClasses.cpp b/client/GUIClasses.cpp index 16e838efd..555e0f36b 100644 --- a/client/GUIClasses.cpp +++ b/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;icb->getHeroInfo(i,0); - if(!h->inTownGarrison) - items.push_back(std::pair(h,NULL)); - } + //int howMany = LOCPLINT->cb->howManyHeroes(); + //for (int i=0;icb->getHeroInfo(i,0); + // if(!h->inTownGarrison) + // items.push_back(std::pair(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 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 >::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; isubID == which->subID) + for(int i=0; isubID == 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=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, - const CArmedInstance *,const CGHeroInstance*>,_1, - &std::pair::first,_2)); + return vstd::findPos(heroes, h, std::equal_to()); } - CTownList::~CTownList() { delete arrup; diff --git a/client/GUIClasses.h b/client/GUIClasses.h index 80732a296..d6d459616 100644 --- a/client/GUIClasses.h +++ b/client/GUIClasses.h @@ -268,11 +268,11 @@ class CHeroList { public: CDefHandler *mobile, *mana; //mana and movement indicators - std::vector > items; int posmobx, posporx, posmanx, posmoby, pospory, posmany; + std::vector &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(); }; diff --git a/lib/CGameState.cpp b/lib/CGameState.cpp index af6633d4e..f5180b628 100644 --- a/lib/CGameState.cpp +++ b/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 diff --git a/lib/CGameState.h b/lib/CGameState.h index 65c7b3ca6..63b8f75cf 100644 --- a/lib/CGameState.h +++ b/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