1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-24 08:32:34 +02:00

Adjust positions of heroes in towns earlier

fixes crash due to accessing tile that is outside of map bonds
This commit is contained in:
Ivan Savenko 2022-12-05 13:02:55 +02:00
parent 2cc4f59699
commit 46b8709712
2 changed files with 22 additions and 5 deletions

View File

@ -760,6 +760,7 @@ void CGameState::init(const IMapService * mapService, StartInfo * si, bool allow
initHeroes();
initStartingBonus();
initTowns();
placeHeroesInTowns();
initMapObjects();
buildBonusSystemTree();
initVisitingAndGarrisonedHeroes();
@ -1363,7 +1364,8 @@ void CGameState::placeStartingHeroes()
{
if(auto campaignBonus = scenarioOps->campState->getBonusForCurrentMap())
{
if(campaignBonus->type == CScenarioTravel::STravelBonus::HERO && playerColor == PlayerColor(campaignBonus->info1)) continue;
if(campaignBonus->type == CScenarioTravel::STravelBonus::HERO && playerColor == PlayerColor(campaignBonus->info1))
continue;
}
}
@ -1861,20 +1863,18 @@ void CGameState::initMapObjects()
map->calculateGuardingGreaturePositions(); //calculate once again when all the guards are placed and initialized
}
void CGameState::initVisitingAndGarrisonedHeroes()
void CGameState::placeHeroesInTowns()
{
for(auto k=players.begin(); k!=players.end(); ++k)
{
if(k->first==PlayerColor::NEUTRAL)
continue;
//init visiting and garrisoned heroes
for(CGHeroInstance *h : k->second.heroes)
{
for(CGTownInstance *t : k->second.towns)
{
bool heroOnTownBlockableTile = t->blockingAt(h->visitablePos().x, h->visitablePos().y);
bool heroOnTownVisitableTile = t->visitableAt(h->visitablePos().x, h->visitablePos().y);
// current hero position is at one of blocking tiles of current town
// assume that this hero should be visiting the town (H3M format quirk) and move hero to correct position
@ -1889,8 +1889,24 @@ void CGameState::initVisitingAndGarrisonedHeroes()
assert(t->visitableAt(h->visitablePos().x, h->visitablePos().y));
}
}
}
}
}
if (heroOnTownBlockableTile || heroOnTownVisitableTile)
void CGameState::initVisitingAndGarrisonedHeroes()
{
for(auto k=players.begin(); k!=players.end(); ++k)
{
if(k->first==PlayerColor::NEUTRAL)
continue;
//init visiting and garrisoned heroes
for(CGHeroInstance *h : k->second.heroes)
{
for(CGTownInstance *t : k->second.towns)
{
if (t->visitableAt(h->visitablePos().x, h->visitablePos().y))
{
assert(t->visitingHero == nullptr);
t->setVisitingHero(h);

View File

@ -269,6 +269,7 @@ private:
void placeStartingHero(PlayerColor playerColor, HeroTypeID heroTypeId, int3 townPos);
void initStartingResources();
void initHeroes();
void placeHeroesInTowns();
void giveCampaignBonusToHero(CGHeroInstance * hero);
void initFogOfWar();
void initStartingBonus();