1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-01-08 00:39:47 +02:00

Remove more subID access

This commit is contained in:
Ivan Savenko 2023-10-28 12:27:10 +03:00
parent 5cdbf408c7
commit 8346d71c98
33 changed files with 92 additions and 90 deletions

View File

@ -318,7 +318,7 @@ bool BuildAnalyzer::hasAnyBuilding(int32_t alignment, BuildingID bid) const
{
for(auto tdi : developmentInfos)
{
if(tdi.town->subID == alignment && tdi.town->hasBuilt(bid))
if(tdi.town->getFaction() == alignment && tdi.town->hasBuilt(bid))
return true;
}

View File

@ -71,7 +71,7 @@ bool needToRecruitHero(const CGTownInstance * startupTown)
for(auto obj : ai->nullkiller->objectClusterizer->getNearbyObjects())
{
if((obj->ID == Obj::RESOURCE && obj->subID == GameResID(EGameResID::GOLD))
if((obj->ID == Obj::RESOURCE && dynamic_cast<const CGResource *>(obj)->resourceID() == EGameResID::GOLD)
|| obj->ID == Obj::TREASURE_CHEST
|| obj->ID == Obj::CAMPFIRE
|| obj->ID == Obj::WATER_WHEEL)

View File

@ -24,7 +24,7 @@ ui64 FuzzyHelper::estimateBankDanger(const CBank * bank)
{
//this one is not fuzzy anymore, just calculate weighted average
auto objectInfo = VLC->objtypeh->getHandlerFor(bank->ID, bank->subID)->getObjectInfo(bank->appearance);
auto objectInfo = bank->getObjectHandler()->getObjectInfo(bank->appearance);
CBankInfo * bankInfo = dynamic_cast<CBankInfo *>(objectInfo.get());
@ -161,10 +161,7 @@ ui64 FuzzyHelper::evaluateDanger(const CGObjectInstance * obj)
}
case Obj::PYRAMID:
{
if(obj->subID == 0)
return estimateBankDanger(dynamic_cast<const CBank *>(obj));
else
return 0;
}
default:
return 0;

View File

@ -122,7 +122,7 @@ TResources getCreatureBankResources(const CGObjectInstance * target, const CGHer
{
//Fixme: unused variable hero
auto objectInfo = VLC->objtypeh->getHandlerFor(target->ID, target->subID)->getObjectInfo(target->appearance);
auto objectInfo = target->getObjectHandler()->getObjectInfo(target->appearance);
CBankInfo * bankInfo = dynamic_cast<CBankInfo *>(objectInfo.get());
auto resources = bankInfo->getPossibleResourcesReward();
TResources result = TResources();
@ -139,7 +139,7 @@ TResources getCreatureBankResources(const CGObjectInstance * target, const CGHer
uint64_t getCreatureBankArmyReward(const CGObjectInstance * target, const CGHeroInstance * hero)
{
auto objectInfo = VLC->objtypeh->getHandlerFor(target->ID, target->subID)->getObjectInfo(target->appearance);
auto objectInfo = target->getObjectHandler()->getObjectInfo(target->appearance);
CBankInfo * bankInfo = dynamic_cast<CBankInfo *>(objectInfo.get());
auto creatures = bankInfo->getPossibleCreaturesReward();
uint64_t result = 0;
@ -467,14 +467,20 @@ float RewardEvaluator::getStrategicalValue(const CGObjectInstance * target) cons
switch(target->ID)
{
case Obj::MINE:
return target->subID == GameResID(EGameResID::GOLD)
{
auto mine = dynamic_cast<const CGMine *>(target);
return mine->producedResource == EGameResID::GOLD
? 0.5f
: 0.4f * getTotalResourceRequirementStrength(target->subID) + 0.1f * getResourceRequirementStrength(target->subID);
: 0.4f * getTotalResourceRequirementStrength(mine->producedResource) + 0.1f * getResourceRequirementStrength(mine->producedResource);
}
case Obj::RESOURCE:
return target->subID == GameResID(EGameResID::GOLD)
{
auto resource = dynamic_cast<const CGResource *>(target);
return resource->resourceID() == EGameResID::GOLD
? 0
: 0.2f * getTotalResourceRequirementStrength(target->subID) + 0.4f * getResourceRequirementStrength(target->subID);
: 0.2f * getTotalResourceRequirementStrength(resource->resourceID()) + 0.4f * getResourceRequirementStrength(resource->resourceID());
}
case Obj::CREATURE_BANK:
{
@ -626,12 +632,14 @@ int32_t RewardEvaluator::getGoldReward(const CGObjectInstance * target, const CG
const int dailyIncomeMultiplier = 5;
const float enemyArmyEliminationGoldRewardRatio = 0.2f;
const int32_t heroEliminationBonus = GameConstants::HERO_GOLD_COST / 2;
auto isGold = target->subID == GameResID(EGameResID::GOLD); // TODO: other resorces could be sold but need to evaluate market power
switch(target->ID)
{
case Obj::RESOURCE:
return isGold ? 600 : 100;
{
auto * res = dynamic_cast<const CGResource*>(target);
return res->resourceID() == GameResID::GOLD ? 600 : 100;
}
case Obj::TREASURE_CHEST:
return 1500;
case Obj::WATER_WHEEL:
@ -640,7 +648,10 @@ int32_t RewardEvaluator::getGoldReward(const CGObjectInstance * target, const CG
return dailyIncomeMultiplier * estimateTownIncome(ai->cb.get(), target, hero);
case Obj::MINE:
case Obj::ABANDONED_MINE:
return dailyIncomeMultiplier * (isGold ? 1000 : 75);
{
auto * mine = dynamic_cast<const CGMine*>(target);
return dailyIncomeMultiplier * (mine->producedResource == GameResID::GOLD ? 1000 : 75);
}
case Obj::MYSTICAL_GARDEN:
case Obj::WINDMILL:
return 100;
@ -1005,7 +1016,7 @@ public:
uint64_t RewardEvaluator::getUpgradeArmyReward(const CGTownInstance * town, const BuildingInfo & bi) const
{
if(ai->buildAnalyzer->hasAnyBuilding(town->subID, bi.id))
if(ai->buildAnalyzer->hasAnyBuilding(town->getFaction(), bi.id))
return 0;
auto creaturesToUpgrade = ai->armyManager->getTotalCreaturesAvailable(bi.baseCreatureID);

View File

@ -26,7 +26,6 @@ using crint3 = const int3 &;
using crstring = const std::string &;
using dwellingContent = std::pair<ui32, std::vector<CreatureID>>;
const int GOLD_MINE_PRODUCTION = 1000, WOOD_ORE_MINE_PRODUCTION = 2, RESOURCE_MINE_PRODUCTION = 1;
const int ACTUAL_RESOURCE_COUNT = 7;
const int ALLOWED_ROAMING_HEROES = 8;

View File

@ -406,7 +406,7 @@ float VisitObjEngine::evaluate(Goals::VisitObj & goal)
else
{
MapObjectsEvaluator::getInstance().addObjectData(obj->ID, obj->subID, 0);
logGlobal->error("AI met object type it doesn't know - ID: " + std::to_string(obj->ID) + ", subID: " + std::to_string(obj->subID) + " - adding to database with value " + std::to_string(objValue));
logGlobal->error("AI met object type it doesn't know - ID: %d, subID: %d - adding to database with value %d ", obj->ID, obj->subID, objValue);
}
setSharedFuzzyVariables(goal);

View File

@ -66,7 +66,7 @@ ui64 FuzzyHelper::estimateBankDanger(const CBank * bank)
{
//this one is not fuzzy anymore, just calculate weighted average
auto objectInfo = VLC->objtypeh->getHandlerFor(bank->ID, bank->subID)->getObjectInfo(bank->appearance);
auto objectInfo = bank->getObjectHandler()->getObjectInfo(bank->appearance);
CBankInfo * bankInfo = dynamic_cast<CBankInfo *>(objectInfo.get());
@ -324,15 +324,8 @@ ui64 FuzzyHelper::evaluateDanger(const CGObjectInstance * obj, const VCAI * ai)
case Obj::DRAGON_UTOPIA:
case Obj::SHIPWRECK: //shipwreck
case Obj::DERELICT_SHIP: //derelict ship
// case Obj::PYRAMID:
return estimateBankDanger(dynamic_cast<const CBank *>(obj));
case Obj::PYRAMID:
{
if(obj->subID == 0)
return estimateBankDanger(dynamic_cast<const CBank *>(obj));
else
return 0;
}
default:
return 0;
}

View File

@ -43,10 +43,10 @@ TGoalVec CollectRes::getAllPossibleSubgoals()
return resID == GameResID(EGameResID::GOLD);
break;
case Obj::RESOURCE:
return obj->subID == resID;
return dynamic_cast<const CGResource*>(obj)->resourceID() == GameResID(resID);
break;
case Obj::MINE:
return (obj->subID == resID &&
return (dynamic_cast<const CGMine*>(obj)->producedResource == GameResID(resID) &&
(cb->getPlayerRelations(obj->tempOwner, ai->playerID) == PlayerRelations::ENEMIES)); //don't capture our mines
break;
case Obj::CAMPFIRE:

View File

@ -88,7 +88,7 @@ TGoalVec GatherTroops::getAllPossibleSubgoals()
}
auto creature = VLC->creatures()->getByIndex(objid);
if(t->subID == creature->getFaction()) //TODO: how to force AI to build unupgraded creatures? :O
if(t->getFaction() == creature->getFaction()) //TODO: how to force AI to build unupgraded creatures? :O
{
auto tryFindCreature = [&]() -> std::optional<std::vector<CreatureID>>
{

View File

@ -190,7 +190,7 @@ Goals::TSubgoal PathfindingManager::clearWayTo(HeroPtr hero, int3 firstTileToGet
if(isBlockedBorderGate(firstTileToGet))
{
//FIXME: this way we'll not visit gate and activate quest :?
return sptr(Goals::FindObj(Obj::KEYMASTER, cb->getTile(firstTileToGet)->visitableObjects.back()->subID));
return sptr(Goals::FindObj(Obj::KEYMASTER, cb->getTile(firstTileToGet)->visitableObjects.back()->getObjTypeIndex()));
}
auto topObj = cb->getTopObj(firstTileToGet);

View File

@ -59,19 +59,7 @@ TResources ResourceManager::estimateIncome() const
if (obj->ID == Obj::MINE)
{
auto mine = dynamic_cast<const CGMine*>(obj);
switch (mine->producedResource.toEnum())
{
case EGameResID::WOOD:
case EGameResID::ORE:
ret[obj->subID] += WOOD_ORE_MINE_PRODUCTION;
break;
case EGameResID::GOLD:
ret[EGameResID::GOLD] += GOLD_MINE_PRODUCTION;
break;
default:
ret[obj->subID] += RESOURCE_MINE_PRODUCTION;
break;
}
ret += mine->dailyIncome();
}
}

View File

@ -1760,11 +1760,11 @@ void VCAI::addVisitableObj(const CGObjectInstance * obj)
CGTeleport::addToChannel(knownTeleportChannels, teleportObj);
}
const CGObjectInstance * VCAI::lookForArt(int aid) const
const CGObjectInstance * VCAI::lookForArt(ArtifactID aid) const
{
for(const CGObjectInstance * obj : ai->visitableObjs)
{
if(obj->ID == Obj::ARTIFACT && obj->subID == aid)
if(obj->ID == Obj::ARTIFACT && dynamic_cast<const CGArtifact *>(obj)->getArtifact() == aid)
return obj;
}

View File

@ -251,7 +251,7 @@ public:
void retrieveVisitableObjs();
virtual std::vector<const CGObjectInstance *> getFlaggedObjects() const;
const CGObjectInstance * lookForArt(int aid) const;
const CGObjectInstance * lookForArt(ArtifactID aid) const;
bool isAccessible(const int3 & pos) const;
HeroPtr getHeroWithGrail() const;

View File

@ -265,7 +265,7 @@ void CCallback::recruitHero(const CGObjectInstance *townOrTavern, const CGHeroIn
assert(townOrTavern);
assert(hero);
HireHero pack(HeroTypeID(hero->subID), townOrTavern->id);
HireHero pack(hero->getHeroType(), townOrTavern->id);
pack.player = *player;
sendRequest(&pack);
}

View File

@ -604,7 +604,7 @@ void ApplyClientNetPackVisitor::visitSetHeroesInTown(SetHeroesInTown & pack)
void ApplyClientNetPackVisitor::visitHeroRecruited(HeroRecruited & pack)
{
CGHeroInstance *h = gs.map->heroesOnMap.back();
if(h->subID != pack.hid)
if(h->getHeroType() != pack.hid)
{
logNetwork->error("Something wrong with hero recruited!");
}

View File

@ -427,11 +427,7 @@ size_t MapRendererWorldViewContext::overlayImageIndex(const int3 & coordinates)
if(!object->visitableAt(coordinates.x, coordinates.y))
continue;
ObjectPosInfo info;
info.pos = coordinates;
info.id = object->ID;
info.subId = object->subID;
info.owner = object->tempOwner;
ObjectPosInfo info(object);
size_t iconIndex = selectOverlayImageForObject(info);

View File

@ -920,7 +920,7 @@ void CCastleBuildings::enterToTheQuickRecruitmentWindow()
void CCastleBuildings::enterFountain(const BuildingID & building, BuildingSubID::EBuildingSubID subID, BuildingID upgrades)
{
std::vector<std::shared_ptr<CComponent>> comps(1, std::make_shared<CComponent>(CComponent::building,town->subID,building));
std::vector<std::shared_ptr<CComponent>> comps(1, std::make_shared<CComponent>(CComponent::building,town->getFaction(),building));
std::string descr = town->town->buildings.find(building)->second->getDescriptionTranslated();
std::string hasNotProduced;
std::string hasProduced;
@ -971,7 +971,7 @@ void CCastleBuildings::enterMagesGuild()
// it would be nice to find a way to move this hack to config/mapOverrides.json
if(si && si->campState && // We're in campaign,
(si->campState->getFilename() == "DATA/YOG.H3C") && // which is "Birth of a Barbarian",
(hero->subID == 45)) // and the hero is Yog (based on Solmyr)
(hero->getHeroType() == 45)) // and the hero is Yog (based on Solmyr)
{
// "Yog has given up magic in all its forms..."
LOCPLINT->showInfoDialog(CGI->generaltexth->allTexts[736]);

View File

@ -667,10 +667,10 @@ CMarketplaceWindow::CMarketplaceWindow(const IMarket * Market, const CGHeroInsta
title = (*CGI->townh)[ETownType::STRONGHOLD]->town->buildings[BuildingID::FREELANCERS_GUILD]->getNameTranslated();
break;
case EMarketMode::RESOURCE_ARTIFACT:
title = (*CGI->townh)[o->subID]->town->buildings[BuildingID::ARTIFACT_MERCHANT]->getNameTranslated();
title = (*CGI->townh)[o->getFaction()]->town->buildings[BuildingID::ARTIFACT_MERCHANT]->getNameTranslated();
break;
case EMarketMode::ARTIFACT_RESOURCE:
title = (*CGI->townh)[o->subID]->town->buildings[BuildingID::ARTIFACT_MERCHANT]->getNameTranslated();
title = (*CGI->townh)[o->getFaction()]->town->buildings[BuildingID::ARTIFACT_MERCHANT]->getNameTranslated();
// create image that copies part of background containing slot MISC_1 into position of slot MISC_5
// this is workaround for bug in H3 files where this slot for ragdoll on this screen is missing

View File

@ -580,7 +580,7 @@ void CGameState::placeStartingHero(const PlayerColor & playerColor, const HeroTy
CGHeroInstance * hero = dynamic_cast<CGHeroInstance *>(obj);
hero->ID = Obj::HERO;
hero->subID = heroTypeId;
hero->setHeroType(heroTypeId);
hero->tempOwner = playerColor;
hero->pos = townPos;

View File

@ -256,7 +256,7 @@ void CGameStateCampaign::placeCampaignHeroes()
assert(0); // should not happen
}
hero->subID = heroTypeId;
hero->setHeroType(heroTypeId);
gameState->map->getEditManager()->insertObject(hero);
}
}

View File

@ -290,6 +290,12 @@ HeroTypeID CGHeroInstance::getHeroType() const
return HeroTypeID(getObjTypeIndex().getNum());
}
void CGHeroInstance::setHeroType(HeroTypeID heroType)
{
assert(type == nullptr);
subID = heroType;
}
void CGHeroInstance::initHero(CRandomGenerator & rand, const HeroTypeID & SUBID)
{
subID = SUBID.getNum();

View File

@ -232,6 +232,7 @@ public:
//////////////////////////////////////////////////////////////////////////
HeroTypeID getHeroType() const;
void setHeroType(HeroTypeID type);
void initHero(CRandomGenerator & rand);
void initHero(CRandomGenerator & rand, const HeroTypeID & SUBID);

View File

@ -129,6 +129,14 @@ bool CGMine::isAbandoned() const
return (getObjTypeIndex() >= 7);
}
ResourceSet CGMine::dailyIncome() const
{
ResourceSet result;
result[producedResource] += defaultResProduction();
return result;
}
std::string CGMine::getObjectName() const
{
return VLC->generaltexth->translate("core.minename", getObjTypeIndex());
@ -466,7 +474,7 @@ TeleportChannelID CGMonolith::findMeChannel(const std::vector<Obj> & IDs, int Su
if(!obj)
continue;
const auto * teleportObj = dynamic_cast<const CGTeleport *>(cb->getObj(obj->id));
const auto * teleportObj = dynamic_cast<const CGMonolith *>(cb->getObj(obj->id));
if(teleportObj && vstd::contains(IDs, teleportObj->ID) && teleportObj->subID == SubID)
return teleportObj->channel;
}

View File

@ -142,6 +142,7 @@ public:
std::set<GameResID> abandonedMineResources;
bool isAbandoned() const;
ResourceSet dailyIncome() const;
private:
void onHeroVisit(const CGHeroInstance * h) const override;

View File

@ -1263,7 +1263,7 @@ void CMapLoaderJson::readObjects()
std::sort(map->heroesOnMap.begin(), map->heroesOnMap.end(), [](const ConstTransitivePtr<CGHeroInstance> & a, const ConstTransitivePtr<CGHeroInstance> & b)
{
return a->subID < b->subID;
return a->getObjTypeIndex() < b->getObjTypeIndex();
});
}

View File

@ -1487,6 +1487,7 @@ void NewObject::applyGs(CGameState *gs)
CGObjectInstance * o = handler->create();
handler->configureObject(o, gs->getRandomGenerator());
assert(o->ID == this->ID);
if (ID == Obj::MONSTER) //probably more options will be needed
{
@ -1514,8 +1515,6 @@ void NewObject::applyGs(CGameState *gs)
o->appearance = handler->getTemplates().front();
o->id = ObjectInstanceID(static_cast<si32>(gs->map->objects.size()));
o->ID = ID;
o->subID = subID;
o->pos = targetPos + o->getVisitableOffset();
gs->map->objects.emplace_back(o);

View File

@ -260,9 +260,11 @@ std::vector<int3> CPathfinderHelper::getTeleportExits(const PathNodeInfo & sourc
teleportationExits.push_back(exit);
}
}
else if(options.useCastleGate
&& (source.nodeObject->ID == Obj::TOWN && source.nodeObject->subID == ETownType::INFERNO
&& source.objectRelations != PlayerRelations::ENEMIES))
else if(options.useCastleGate && source.nodeObject->ID == Obj::TOWN && source.objectRelations != PlayerRelations::ENEMIES)
{
auto * town = dynamic_cast<const CGTownInstance *>(source.nodeObject);
assert(town);
if (town && town->getFaction() == FactionID::INFERNO)
{
/// TODO: Find way to reuse CPlayerSpecificInfoCallback::getTownsInfo
/// This may be handy if we allow to use teleportation to friendly towns
@ -271,6 +273,7 @@ std::vector<int3> CPathfinderHelper::getTeleportExits(const PathNodeInfo & sourc
teleportationExits.push_back(exit);
}
}
}
return teleportationExits;
}

View File

@ -115,7 +115,7 @@ void Object::Instance::setAnyTemplate(CRandomGenerator & rng)
{
auto templates = dObject.getObjectHandler()->getTemplates();
if(templates.empty())
throw rmgException(boost::str(boost::format("Did not find any graphics for object (%d,%d)") % dObject.ID % dObject.subID));
throw rmgException(boost::str(boost::format("Did not find any graphics for object (%d,%d)") % dObject.ID % dObject.getObjTypeIndex()));
dObject.appearance = *RandomGeneratorUtil::nextItem(templates, rng);
dAccessibleAreaCache.clear();
@ -128,7 +128,7 @@ void Object::Instance::setTemplate(TerrainId terrain, CRandomGenerator & rng)
if (templates.empty())
{
auto terrainName = VLC->terrainTypeHandler->getById(terrain)->getNameTranslated();
throw rmgException(boost::str(boost::format("Did not find graphics for object (%d,%d) at %s") % dObject.ID % dObject.subID % terrainName));
throw rmgException(boost::str(boost::format("Did not find graphics for object (%d,%d) at %s") % dObject.ID % dObject.getObjTypeIndex() % terrainName));
}
dObject.appearance = *RandomGeneratorUtil::nextItem(templates, rng);
@ -338,7 +338,7 @@ void Object::Instance::finalize(RmgMap & map, CRandomGenerator & rng)
auto templates = dObject.getObjectHandler()->getTemplates(terrainType->getId());
if (templates.empty())
{
throw rmgException(boost::str(boost::format("Did not find graphics for object (%d,%d) at %s (terrain %d)") % dObject.ID % dObject.subID % getPosition(true).toString() % terrainType));
throw rmgException(boost::str(boost::format("Did not find graphics for object (%d,%d) at %s (terrain %d)") % dObject.ID % dObject.getObjTypeIndex() % getPosition(true).toString() % terrainType));
}
else
{

View File

@ -111,7 +111,7 @@ void TreasurePlacer::addAllPossibleObjects()
auto factory = VLC->objtypeh->getHandlerFor(Obj::PRISON, 0);
auto* obj = dynamic_cast<CGHeroInstance*>(factory->create());
obj->subID = hid; //will be initialized later
obj->setHeroType(hid); //will be initialized later
obj->exp = generator.getConfig().prisonExperience[i];
obj->setOwner(PlayerColor::NEUTRAL);
generator.banHero(hid);

View File

@ -16,7 +16,7 @@
VCMI_LIB_NAMESPACE_BEGIN
ObjectPosInfo::ObjectPosInfo(const CGObjectInstance * obj):
pos(obj->visitablePos()), id(obj->ID), subId(obj->subID), owner(obj->tempOwner)
pos(obj->visitablePos()), id(obj->ID), subId(obj->getObjTypeIndex()), owner(obj->tempOwner)
{
}

View File

@ -217,7 +217,7 @@ void MapController::repairMap(CMap * map) const
art->storedArtifact = a;
}
else
map->allowedArtifact.at(art->subID) = true;
map->allowedArtifact.at(art->getArtifact()) = true;
}
}
}
@ -623,7 +623,7 @@ ModCompatibilityInfo MapController::modAssessmentMap(const CMap & map)
if(obj->ID == Obj::HERO)
continue; //stub!
auto handler = VLC->objtypeh->getHandlerFor(obj->ID, obj->subID);
auto handler = obj->getObjectHandler();
auto modName = QString::fromStdString(handler->getJsonKey()).split(":").at(0).toStdString();
if(modName != "core")
result[modName] = VLC->modh->getModInfo(modName).getVerificationInfo();

View File

@ -2315,7 +2315,7 @@ bool CGameHandler::buildStructure(ObjectInstanceID tid, BuildingID requestedID,
auto isLibrary = isMageGuild ? false
: t->town->buildings.at(buildingID)->subId == BuildingSubID::EBuildingSubID::LIBRARY;
if(isMageGuild || isLibrary || (t->subID == ETownType::CONFLUX && buildingID == BuildingID::GRAIL))
if(isMageGuild || isLibrary || (t->getFaction() == ETownType::CONFLUX && buildingID == BuildingID::GRAIL))
{
if(t->visitingHero)
giveSpells(t,t->visitingHero);
@ -3284,7 +3284,7 @@ void CGameHandler::handleTownEvents(CGTownInstance * town, NewTurn &n)
if (!town->hasBuilt(i))
{
buildStructure(town->id, i, true);
iw.components.emplace_back(Component::EComponentType::BUILDING, town->subID, i, 0);
iw.components.emplace_back(Component::EComponentType::BUILDING, town->getFaction(), i, 0);
}
}
@ -3430,7 +3430,7 @@ void CGameHandler::objectVisited(const CGObjectInstance * obj, const CGHeroInsta
{
using events::ObjectVisitStarted;
logGlobal->debug("%s visits %s (%d:%d)", h->nodeName(), obj->getObjectName(), obj->ID, obj->subID);
logGlobal->debug("%s visits %s (%d)", h->nodeName(), obj->getObjectName(), obj->ID);
if (getVisitingHero(obj) != nullptr)
{

View File

@ -50,8 +50,8 @@ TavernHeroSlot HeroPoolProcessor::selectSlotForRole(const PlayerColor & player,
// try to find "better" slot to overwrite
// we want to avoid overwriting retreated heroes when tavern still has slot with random hero
// as well as avoid overwriting surrendered heroes if we can overwrite retreated hero
auto roleLeft = heroesPool->getSlotRole(HeroTypeID(heroes[0]->subID));
auto roleRight = heroesPool->getSlotRole(HeroTypeID(heroes[1]->subID));
auto roleLeft = heroesPool->getSlotRole(heroes[0]->getHeroType());
auto roleRight = heroesPool->getSlotRole(heroes[1]->getHeroType());
if (roleLeft > roleRight)
return TavernHeroSlot::RANDOM;
@ -73,7 +73,7 @@ void HeroPoolProcessor::onHeroSurrendered(const PlayerColor & color, const CGHer
sah.slotID = selectSlotForRole(color, sah.roleID);
sah.player = color;
sah.hid.setNum(hero->subID);
sah.hid = hero->getHeroType();
gameHandler->sendAndApply(&sah);
}
@ -84,7 +84,7 @@ void HeroPoolProcessor::onHeroEscaped(const PlayerColor & color, const CGHeroIns
sah.slotID = selectSlotForRole(color, sah.roleID);
sah.player = color;
sah.hid.setNum(hero->subID);
sah.hid = hero->getHeroType();
sah.army.clearSlots();
sah.army.setCreature(SlotID(0), hero->type->initialArmy.at(0).creature, 1);
@ -111,7 +111,7 @@ void HeroPoolProcessor::selectNewHeroForSlot(const PlayerColor & color, TavernHe
if (newHero)
{
sah.hid.setNum(newHero->subID);
sah.hid = newHero->getHeroType();
if (giveArmy)
{
@ -193,7 +193,7 @@ bool HeroPoolProcessor::hireHero(const ObjectInstanceID & objectID, const HeroTy
for(const auto & hero : recruitableHeroes)
{
if(hero->subID == heroToRecruit)
if(hero->getHeroType() == heroToRecruit)
recruitedHero = hero;
}
@ -206,7 +206,7 @@ bool HeroPoolProcessor::hireHero(const ObjectInstanceID & objectID, const HeroTy
HeroRecruited hr;
hr.tid = mapObject->id;
hr.hid.setNum(recruitedHero->subID);
hr.hid = recruitedHero->getHeroType();
hr.player = player;
hr.tile = recruitedHero->convertFromVisitablePos(targetPos );
if(gameHandler->getTile(targetPos)->isWater() && !recruitedHero->boat)