bool CGameInfoCallback::getHeroInfo( const CGObjectInstance *hero, InfoAboutHero &dest ) const { const CGHeroInstance *h = dynamic_cast<const CGHeroInstance *>(hero); ERROR_RET_VAL_IF(!h, "That's not a hero!", false); ERROR_RET_VAL_IF(!isVisible(h->getPosition(false)), "That hero is not visible!", false); //TODO vision support dest.initFromHero(h, hasAccess(h->tempOwner)); return true; }
bool CGameInfoCallback::getHeroInfo(const CGObjectInstance * hero, InfoAboutHero & dest, const CGObjectInstance * selectedObject/* = nullptr*/) const { const CGHeroInstance *h = dynamic_cast<const CGHeroInstance *>(hero); ERROR_RET_VAL_IF(!h, "That's not a hero!", false); ERROR_RET_VAL_IF(!isVisible(h->getPosition(false)), "That hero is not visible!", false); InfoAboutHero::EInfoLevel infoLevel = InfoAboutHero::EInfoLevel::BASIC; if(hasAccess(h->tempOwner)) infoLevel = InfoAboutHero::EInfoLevel::DETAILED; if ( (infoLevel == InfoAboutHero::EInfoLevel::BASIC) && gs->curB) //if it's battle we can get enemy hero full data { if(gs->curB->playerHasAccessToHeroInfo(*player, h)) infoLevel = InfoAboutHero::EInfoLevel::INBATTLE; } if( (infoLevel == InfoAboutHero::EInfoLevel::BASIC) && nullptr != selectedObject) { const CGHeroInstance * selectedHero = dynamic_cast<const CGHeroInstance *>(selectedObject); if(nullptr != selectedHero) if(selectedHero->hasVisions(hero, 1)) infoLevel = InfoAboutHero::EInfoLevel::DETAILED; } dest.initFromHero(h, infoLevel); //DISGUISED bonus implementation bool disguiseFlag = (infoLevel == InfoAboutHero::EInfoLevel::DETAILED); if(getPlayerRelations(getLocalPlayer(), hero->tempOwner) == PlayerRelations::ENEMIES) { //todo: bonus cashing int disguiseLevel = h->valOfBonuses(Selector::typeSubtype(Bonus::DISGUISED, 0)); auto doBasicDisguise = [disguiseLevel](InfoAboutHero & info) { int maxAIValue = 0; const CCreature * mostStrong = nullptr; for(auto & elem : info.army) { if(elem.second.type->AIValue > maxAIValue) { maxAIValue = elem.second.type->AIValue; mostStrong = elem.second.type; } } if(nullptr == mostStrong)//just in case logGlobal->errorStream() << "CGameInfoCallback::getHeroInfo: Unable to select most strong stack" << disguiseLevel; else for(auto & elem : info.army) { elem.second.type = mostStrong; } }; auto doAdvancedDisguise = [disguiseFlag, &doBasicDisguise](InfoAboutHero & info) { doBasicDisguise(info); for(auto & elem : info.army) elem.second.count = 0; }; auto doExpertDisguise = [this,h](InfoAboutHero & info) { for(auto & elem : info.army) elem.second.count = 0; const auto factionIndex = getStartInfo(false)->playerInfos.at(h->tempOwner).castle; int maxAIValue = 0; const CCreature * mostStrong = nullptr; for(auto creature : VLC->creh->creatures) { if(creature->faction == factionIndex && creature->AIValue > maxAIValue) { maxAIValue = creature->AIValue; mostStrong = creature; } } if(nullptr != mostStrong) //possible, faction may have no creatures at all for(auto & elem : info.army) elem.second.type = mostStrong; }; switch (disguiseLevel) { case 0: //no bonus at all - do nothing break; case 1: doBasicDisguise(dest); break; case 2: doAdvancedDisguise(dest); break; case 3: doExpertDisguise(dest); break; default: //invalid value logGlobal->errorStream() << "CGameInfoCallback::getHeroInfo: Invalid DISGUISED bonus value " << disguiseLevel; break; } } return true; }