diff --git a/CCallback.cpp b/CCallback.cpp index 0bcf961b7..5b1b7ec0b 100644 --- a/CCallback.cpp +++ b/CCallback.cpp @@ -173,6 +173,17 @@ const CGHeroInstance * CCallback::getHeroInfo(int val, int mode) const //mode = return NULL; } +bool CCallback::getHeroInfo( const CGObjectInstance *hero, InfoAboutHero &dest ) const +{ + const CGHeroInstance *h = dynamic_cast(hero); + if(!h || !isVisible(h->getPosition(false))) //it's not a hero or it's not visible for layer + return false; + + //TODO vision support, info about allies + dest.initFromHero(h, false); + return true; +} + int CCallback::getResourceAmount(int type) const { boost::shared_lock lock(*gs->mx); @@ -708,3 +719,47 @@ void CCallback::sendMessage(const std::string &mess) PlayerMessage pm(player, mess); *cl->serv << ± } + +InfoAboutHero::InfoAboutHero() +{ + details = NULL; + hclass = NULL; + portrait = -1; +} + +InfoAboutHero::~InfoAboutHero() +{ + delete details; +} + +void InfoAboutHero::initFromHero( const CGHeroInstance *h, bool detailed ) +{ + owner = h->tempOwner; + hclass = h->type->heroClass; + name = h->name; + portrait = h->portrait; + army = h->army; + + if(detailed) + { + //include details about hero + details = new Details; + details->luck = h->getCurrentLuck(); + details->morale = h->getCurrentMorale(); + details->mana = h->mana; + details->primskills.resize(PRIMARY_SKILLS); + + for (int i = 0; i < PRIMARY_SKILLS ; i++) + { + details->primskills[i] = h->getPrimSkillLevel(i); + } + } + else + { + //hide info about hero stacks counts using descriptives names ids + for(std::map >::iterator i = army.slots.begin(); i != army.slots.end(); ++i) + { + i->second.second = CCreature::getQuantityID(i->second.second); + } + } +} \ No newline at end of file diff --git a/CCallback.h b/CCallback.h index f75c679ea..621018c15 100644 --- a/CCallback.h +++ b/CCallback.h @@ -36,7 +36,26 @@ class CStack; struct lua_State; class CClient; struct TerrainTile; -//structure gathering info about upgrade possibilites +class CHeroClass; + +struct InfoAboutHero +{ + struct Details + { + std::vector primskills; + int mana, luck, morale; + } *details; + + char owner; + const CHeroClass *hclass; + std::string name; + int portrait; + CCreatureSet army; //numbers of creatures are exact numbers if detailed else they are quantity ids (0 - a few, 1 - several and so on) + + InfoAboutHero(); + ~InfoAboutHero(); + void initFromHero(const CGHeroInstance *h, bool detailed); +}; class ICallback { @@ -88,6 +107,7 @@ public: 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 bool getPath(int3 src, int3 dest, const CGHeroInstance * hero, CPath &ret)=0; + virtual bool getHeroInfo(const CGObjectInstance *hero, InfoAboutHero &dest) const = 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 @@ -182,6 +202,7 @@ public: 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 bool getPath(int3 src, int3 dest, const CGHeroInstance * hero, CPath &ret); + bool getHeroInfo(const CGObjectInstance *hero, InfoAboutHero &dest) const; //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 6346500d2..ca28db129 100644 --- a/client/CAdvmapInterface.cpp +++ b/client/CAdvmapInterface.cpp @@ -514,21 +514,34 @@ void CTerrainRect::clickRight(tribool down) if(!objs.size()) return; - const CGObjectInstance * obj = objs[objs.size()-1]; + const CGObjectInstance * obj = objs.front(); switch(obj->ID) { case HEROI_TYPE: { - if(!vstd::contains(graphics->heroWins,obj->subID)) + if(!vstd::contains(graphics->heroWins,obj->subID) || obj->tempOwner != LOCPLINT->playerID) { - tlog3 << "Warning - no infowin for hero " << obj->subID << std::endl; - break; + InfoAboutHero iah; + if(LOCPLINT->cb->getHeroInfo(obj, iah)) + { + SDL_Surface *iwin = graphics->drawHeroInfoWin(iah); + CInfoPopup * ip = new CInfoPopup(iwin, LOCPLINT->current->motion.x-iwin->w, + LOCPLINT->current->motion.y-iwin->h, true); + LOCPLINT->pushInt(ip); + } + else + { + tlog3 << "Warning - no infowin for hero " << obj->id << std::endl; + } + } + else + { + CInfoPopup * ip = new CInfoPopup(graphics->heroWins[obj->subID], + LOCPLINT->current->motion.x-graphics->heroWins[obj->subID]->w, + LOCPLINT->current->motion.y-graphics->heroWins[obj->subID]->h,false + ); + LOCPLINT->pushInt(ip); } - CInfoPopup * ip = new CInfoPopup(graphics->heroWins[obj->subID], - LOCPLINT->current->motion.x-graphics->heroWins[obj->subID]->w, - LOCPLINT->current->motion.y-graphics->heroWins[obj->subID]->h,false - ); - LOCPLINT->pushInt(ip); break; } case TOWNI_TYPE: diff --git a/client/Graphics.cpp b/client/Graphics.cpp index 3a76f4bdf..e323d53f6 100644 --- a/client/Graphics.cpp +++ b/client/Graphics.cpp @@ -14,6 +14,7 @@ #include "CGameInfo.h" #include "../hch/CLodHandler.h" #include "../lib/VCMI_Lib.h" +#include "../CCallback.h" using namespace boost::assign; using namespace CSDL_Ext; #ifdef min @@ -35,37 +36,56 @@ using namespace CSDL_Ext; Graphics * graphics = NULL; -SDL_Surface * Graphics::drawPrimarySkill(const CGHeroInstance *curh, SDL_Surface *ret, int from, int to) +SDL_Surface * Graphics::drawHeroInfoWin(const InfoAboutHero &curh) { char buf[10]; - for (int i=from;igetPrimSkillLevel(i),buf,10); - printAtMiddle(buf,84+28*i,68,GEOR13,zwykly,ret); - } - return ret; -} -SDL_Surface * Graphics::drawHeroInfoWin(const CGHeroInstance * curh) -{ - char buf[10]; - blueToPlayersAdv(hInfo,curh->tempOwner); + blueToPlayersAdv(hInfo,curh.owner); SDL_Surface * ret = SDL_DisplayFormat(hInfo); SDL_SetColorKey(ret,SDL_SRCCOLORKEY,SDL_MapRGB(ret->format,0,255,255)); - printAt(curh->name,75,15,GEOR13,zwykly,ret); - drawPrimarySkill(curh, ret); - for (std::map >::const_iterator i=curh->army.slots.begin(); i!=curh->army.slots.end();i++) + + printAt(curh.name,75,15,GEOR13,zwykly,ret); //name + blitAt(graphics->portraitLarge[curh.portrait],11,12,ret); //portrait + + //army + for (std::map >::const_iterator i=curh.army.slots.begin(); i!=curh.army.slots.end();i++) { blitAt(graphics->smallImgs[(*i).second.first],slotsPos[(*i).first].first+1,slotsPos[(*i).first].second+1,ret); - SDL_itoa((*i).second.second,buf,10); - printAtMiddle(buf,slotsPos[(*i).first].first+17,slotsPos[(*i).first].second+39,GEORM,zwykly,ret); + if(curh.details) + { + SDL_itoa((*i).second.second,buf,10); + printAtMiddle(buf,slotsPos[(*i).first].first+17,slotsPos[(*i).first].second+39,GEORM,zwykly,ret); + } + else + { + printAtMiddle(VLC->generaltexth->arraytxt[174 + 3*i->second.second],slotsPos[(*i).first].first+17,slotsPos[(*i).first].second+39,GEORM,zwykly,ret); + } + } + + if(curh.details) + { + for (int i = 0; i < PRIMARY_SKILLS; i++) + { + SDL_itoa(curh.details->primskills[i], buf, 10); + printAtMiddle(buf,84+28*i,68,GEOR13,zwykly,ret); + } + + //mana points + SDL_itoa(curh.details->mana,buf,10); + printAtMiddle(buf,166,109,GEORM,zwykly,ret); + + blitAt(morale22->ourImages[curh.details->morale+3].bitmap,14,84,ret); //luck + blitAt(luck22->ourImages[curh.details->morale+3].bitmap,14,101,ret); //morale } - blitAt(graphics->portraitLarge[curh->portrait],11,12,ret); - SDL_itoa(curh->mana,buf,10); - printAtMiddle(buf,166,109,GEORM,zwykly,ret); //mana points - blitAt(morale22->ourImages[curh->getCurrentMorale()+3].bitmap,14,84,ret); - blitAt(luck22->ourImages[curh->getCurrentLuck()+3].bitmap,14,101,ret); return ret; } + +SDL_Surface * Graphics::drawHeroInfoWin(const CGHeroInstance * curh) +{ + InfoAboutHero iah; + iah.initFromHero(curh, true); + return drawHeroInfoWin(iah); +} + SDL_Surface * Graphics::drawTownInfoWin(const CGTownInstance * curh) { char buf[10]; diff --git a/client/Graphics.h b/client/Graphics.h index a259feb92..2e50a694f 100644 --- a/client/Graphics.h +++ b/client/Graphics.h @@ -21,6 +21,8 @@ class CGTownInstance; class CDefHandler; class CHeroClass; struct SDL_Color; +struct InfoAboutHero; + class Graphics { public: @@ -73,8 +75,8 @@ public: void loadHeroAnims(); void loadHeroAnim(const std::string &name, const std::vector > &rotations, std::vector Graphics::*dst); void loadHeroPortraits(); + SDL_Surface * drawHeroInfoWin(const InfoAboutHero &curh); SDL_Surface * drawHeroInfoWin(const CGHeroInstance * curh); - SDL_Surface * drawPrimarySkill(const CGHeroInstance *curh, SDL_Surface *ret, int from=0, int to=PRIMARY_SKILLS); SDL_Surface * drawTownInfoWin(const CGTownInstance * curh); SDL_Surface * getPic(int ID, bool fort=true, bool builded=false); //returns small picture of town: ID=-1 - blank; -2 - border; -3 - random void blueToPlayersAdv(SDL_Surface * sur, int player); //replaces blue interface colour with a color of player