mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
- Fixed bug when the type id of the hero placeholder is the same as a already placed hero or prisoned hero
This commit is contained in:
parent
51e6961d08
commit
9d0387140f
@ -1127,13 +1127,55 @@ void CGameState::placeCampaignHeroes()
|
||||
const auto campaignHeroReplacements = generateCampaignHeroesToReplace(crossoverHeroes);
|
||||
|
||||
// remove same heroes on the map which will be added through crossover heroes
|
||||
/*for(auto & campaignHeroReplacement : campaignHeroReplacement)
|
||||
// INFO: we will remove heroes because later it may be possible that the API doesn't allow having heroes
|
||||
// with the same hero type id
|
||||
std::vector<CGHeroInstance *> removedHeroes;
|
||||
|
||||
for(auto & campaignHeroReplacement : campaignHeroReplacements)
|
||||
{
|
||||
campaignHeroReplacement.first->subID
|
||||
}*/
|
||||
auto hero = getUsedHero(HeroTypeID(campaignHeroReplacement.first->subID));
|
||||
if(hero)
|
||||
{
|
||||
removedHeroes.push_back(hero);
|
||||
map->heroesOnMap -= hero;
|
||||
map->objects[hero->id.getNum()] = nullptr;
|
||||
map->removeBlockVisTiles(hero, true);
|
||||
}
|
||||
}
|
||||
|
||||
logGlobal->debugStream() << "\tReplace placeholders with heroes";
|
||||
replaceHeroesPlaceholders(campaignHeroReplacements);
|
||||
|
||||
// now add removed heroes again with unused type ID
|
||||
for(auto hero : removedHeroes)
|
||||
{
|
||||
si32 heroTypeId = 0;
|
||||
if(hero->ID == Obj::HERO)
|
||||
{
|
||||
heroTypeId = pickUnusedHeroTypeRandomly(hero->tempOwner);
|
||||
}
|
||||
else if(hero->ID == Obj::PRISON)
|
||||
{
|
||||
auto unusedHeroTypeIds = getUnusedAllowedHeroes();
|
||||
if(!unusedHeroTypeIds.empty())
|
||||
{
|
||||
heroTypeId = std::next(unusedHeroTypeIds.begin(), ran() % unusedHeroTypeIds.size())->getNum();
|
||||
}
|
||||
else
|
||||
{
|
||||
logGlobal->errorStream() << "No free hero type ID found to replace prison.";
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(0); // should not happen
|
||||
}
|
||||
|
||||
hero->subID = heroTypeId;
|
||||
hero->portrait = hero->subID;
|
||||
map->getEditManager()->insertObject(hero, hero->pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1143,7 +1185,7 @@ void CGameState::placeStartingHero(PlayerColor playerColor, HeroTypeID heroTypeI
|
||||
townPos.x += 1;
|
||||
|
||||
CGHeroInstance * hero = static_cast<CGHeroInstance*>(createObject(Obj::HERO, heroTypeId.getNum(), townPos, playerColor));
|
||||
hero->initHero();
|
||||
hero->initHeroDefInfo();
|
||||
map->getEditManager()->insertObject(hero, townPos);
|
||||
}
|
||||
|
||||
@ -2721,7 +2763,8 @@ std::vector<std::pair<CGHeroInstance*, ObjectInstanceID> > CGameState::generateC
|
||||
if(!found)
|
||||
{
|
||||
auto nh = new CGHeroInstance();
|
||||
nh->initHero(HeroTypeID(hp->subID));
|
||||
nh->subID = hp->subID;
|
||||
nh->initHeroDefInfo();
|
||||
campaignHeroReplacements.push_back(std::make_pair(nh, gid));
|
||||
}
|
||||
|
||||
@ -2803,22 +2846,33 @@ void CGameState::replaceHeroesPlaceholders(const std::vector<std::pair<CGHeroIns
|
||||
map->heroesOnMap.push_back(heroToPlace);
|
||||
map->objects[heroToPlace->id.getNum()] = heroToPlace;
|
||||
map->addBlockVisTiles(heroToPlace);
|
||||
|
||||
//const auto & travelOptions = scenarioOps->campState->getCurrentScenario().travelOptions;
|
||||
}
|
||||
}
|
||||
|
||||
bool CGameState::isUsedHero(HeroTypeID hid) const
|
||||
{
|
||||
return getUsedHero(hid);
|
||||
}
|
||||
|
||||
CGHeroInstance * CGameState::getUsedHero(HeroTypeID hid) const
|
||||
{
|
||||
for(auto hero : map->heroesOnMap) //heroes instances initialization
|
||||
{
|
||||
if(hero->subID == hid.getNum())
|
||||
return true;
|
||||
{
|
||||
return hero;
|
||||
}
|
||||
}
|
||||
|
||||
for(auto obj : map->objects) //prisons
|
||||
if(obj && obj->ID == Obj::PRISON && obj->subID == hid.getNum())
|
||||
return true;
|
||||
{
|
||||
if(obj && obj->ID == Obj::PRISON && obj->subID == hid.getNum())
|
||||
{
|
||||
return dynamic_cast<CGHeroInstance *>(obj.get());
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CGPathNode::CGPathNode()
|
||||
|
@ -498,6 +498,7 @@ private:
|
||||
|
||||
// ---- misc helpers -----
|
||||
|
||||
CGHeroInstance * getUsedHero(HeroTypeID hid) const;
|
||||
bool isUsedHero(HeroTypeID hid) const; //looks in heroes and prisons
|
||||
std::set<HeroTypeID> getUnusedAllowedHeroes(bool alsoIncludeNotAllowed = false) const;
|
||||
std::pair<Obj,int> pickObject(CGObjectInstance *obj); //chooses type of object to be randomized, returns <type, subtype>
|
||||
|
Loading…
Reference in New Issue
Block a user