1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-08-10 22:31:40 +02:00

Fix attaching of hero to bonus system (old bug?)

This commit is contained in:
Ivan Savenko
2025-04-24 20:41:49 +03:00
parent 4e8e85e3e4
commit a8a74888f7
2 changed files with 26 additions and 20 deletions

View File

@@ -543,14 +543,18 @@ void CGameState::placeStartingHero(const PlayerColor & playerColor, const HeroTy
} }
} }
auto hero = map->tryTakeFromHeroPool(heroTypeId);
if (!hero)
{
auto handler = LIBRARY->objtypeh->getHandlerFor(Obj::HERO, heroTypeId.toHeroType()->heroClass->getIndex()); auto handler = LIBRARY->objtypeh->getHandlerFor(Obj::HERO, heroTypeId.toHeroType()->heroClass->getIndex());
auto object = handler->create(cb, handler->getTemplates().front()); auto object = handler->create(cb, handler->getTemplates().front());
auto hero = std::dynamic_pointer_cast<CGHeroInstance>(object); hero = std::dynamic_pointer_cast<CGHeroInstance>(object);
hero->ID = Obj::HERO; hero->ID = Obj::HERO;
hero->setHeroType(heroTypeId); hero->setHeroType(heroTypeId);
hero->tempOwner = playerColor; }
hero->tempOwner = playerColor;
hero->setAnchorPos(townPos + hero->getVisitableOffset()); hero->setAnchorPos(townPos + hero->getVisitableOffset());
map->getEditManager()->insertObject(hero); map->getEditManager()->insertObject(hero);
} }

View File

@@ -1190,19 +1190,10 @@ void RemoveObject::applyGs(CGameState *gs)
if(obj->ID == Obj::HERO) //remove beaten hero if(obj->ID == Obj::HERO) //remove beaten hero
{ {
auto beatenObject = gs->getMap().eraseObject(obj->id); auto beatenHero = dynamic_cast<CGHeroInstance*>(obj);
auto beatenHero = std::dynamic_pointer_cast<CGHeroInstance>(beatenObject);
assert(beatenHero); assert(beatenHero);
auto * siegeNode = beatenHero->whereShouldBeAttachedOnSiege(gs); auto * siegeNode = beatenHero->whereShouldBeAttachedOnSiege(gs);
// FIXME: workaround:
// hero should be attached to siegeNode after battle
// however this code might also be called on dismissing hero while in town
if (siegeNode && vstd::contains(beatenHero->getParentNodes(), siegeNode))
beatenHero->detachFrom(*siegeNode);
beatenHero->tempOwner = PlayerColor::NEUTRAL; //no one owns beaten hero
vstd::erase_if(beatenHero->artifactsInBackpack, [](const ArtSlotInfo& asi) vstd::erase_if(beatenHero->artifactsInBackpack, [](const ArtSlotInfo& asi)
{ {
return asi.getArt()->getTypeId() == ArtifactID::GRAIL; return asi.getArt()->getTypeId() == ArtifactID::GRAIL;
@@ -1210,17 +1201,21 @@ void RemoveObject::applyGs(CGameState *gs)
if(beatenHero->getVisitedTown()) if(beatenHero->getVisitedTown())
{ {
if(beatenHero->getVisitedTown()->getGarrisonHero() == beatenHero.get()) if(beatenHero->getVisitedTown()->getGarrisonHero() == beatenHero)
beatenHero->getVisitedTown()->setGarrisonedHero(nullptr); beatenHero->getVisitedTown()->setGarrisonedHero(nullptr);
else else
beatenHero->getVisitedTown()->setVisitingHero(nullptr); beatenHero->getVisitedTown()->setVisitingHero(nullptr);
beatenHero->setVisitedTown(nullptr, false); beatenHero->setVisitedTown(nullptr, false);
} }
beatenHero->detachFromBonusSystem(*gs);
beatenHero->tempOwner = PlayerColor::NEUTRAL; //no one owns beaten hero
//return hero to the pool, so he may reappear in tavern // FIXME: workaround:
gs->heroesPool->addHeroToPool(beatenHero->getHeroTypeID()); // hero should be attached to siegeNode after battle
gs->getMap().addToHeroPool(beatenHero); // however this code might also be called on dismissing hero while in town
if (siegeNode && vstd::contains(beatenHero->getParentNodes(), siegeNode))
beatenHero->detachFrom(*siegeNode);
//If hero on Boat is removed, the Boat disappears //If hero on Boat is removed, the Boat disappears
if(beatenHero->inBoat()) if(beatenHero->inBoat())
@@ -1229,6 +1224,13 @@ void RemoveObject::applyGs(CGameState *gs)
beatenHero->setBoat(nullptr); beatenHero->setBoat(nullptr);
gs->getMap().eraseObject(boat->id); gs->getMap().eraseObject(boat->id);
} }
auto beatenObject = gs->getMap().eraseObject(obj->id);
//return hero to the pool, so he may reappear in tavern
gs->heroesPool->addHeroToPool(beatenHero->getHeroTypeID());
gs->getMap().addToHeroPool(std::dynamic_pointer_cast<CGHeroInstance>(beatenObject));
return; return;
} }