1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-08-13 19:54:17 +02:00

Fix positioning of heroes after release from prisons

This commit is contained in:
Ivan Savenko
2022-12-04 22:00:33 +02:00
parent fa3a05a074
commit b6b6063505
2 changed files with 20 additions and 4 deletions

View File

@@ -703,13 +703,18 @@ DLL_LINKAGE void GiveHero::applyGs(CGameState *gs)
//bonus system
h->detachFrom(gs->globalEffects);
h->attachTo(*gs->getPlayerState(player));
h->appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, h->type->heroClass->getIndex())->getTemplates().front();
auto oldOffset = h->getVisitableOffset();
gs->map->removeBlockVisTiles(h,true);
h->appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, h->type->heroClass->getIndex())->getTemplates().front();
auto newOffset = h->getVisitableOffset();
h->setOwner(player);
h->movement = h->maxMovePoints(true);
h->pos = h->pos - oldOffset + newOffset;
gs->map->heroesOnMap.push_back(h);
gs->getPlayerState(h->getOwner())->heroes.push_back(h);
gs->map->addBlockVisTiles(h);
h->inTownGarrison = false;
}

View File

@@ -195,7 +195,9 @@ std::set<int3> CGObjectInstance::getBlockedOffsets() const
void CGObjectInstance::setType(si32 ID, si32 subID)
{
const TerrainTile &tile = cb->gameState()->map->getTile(visitablePos());
auto position = visitablePos();
auto oldOffset = getVisitableOffset();
auto &tile = cb->gameState()->map->getTile(position);
//recalculate blockvis tiles - new appearance might have different blockmap than before
cb->gameState()->map->removeBlockVisTiles(this, true);
@@ -206,14 +208,23 @@ void CGObjectInstance::setType(si32 ID, si32 subID)
return;
}
if(!handler->getTemplates(tile.terType->id).empty())
{
appearance = handler->getTemplates(tile.terType->id)[0];
}
else
{
logGlobal->warn("Object %d:%d at %s has no templates suitable for terrain %s", ID, subID, visitablePos().toString(), tile.terType->name);
appearance = handler->getTemplates()[0]; // get at least some appearance since alternative is crash
}
if(this->ID == Obj::PRISON && ID == Obj::HERO)
{
//adjust for the prison offset
pos = visitablePos();
auto newOffset = getVisitableOffset();
// FIXME: potentially unused code - setType is NOT called when releasing hero from prison
// instead, appearance update & pos adjustment occurs in GiveHero::applyGs
// adjust position since hero and prison may have different visitable offset
pos = pos - oldOffset + newOffset;
}
this->ID = Obj(ID);