|
@@ -385,7 +385,6 @@ void GameStatePackVisitor::visitRemoveObject(RemoveObject & pack)
|
|
|
auto beatenHero = dynamic_cast<CGHeroInstance*>(obj);
|
|
|
assert(beatenHero);
|
|
|
|
|
|
- auto * siegeNode = beatenHero->whereShouldBeAttachedOnSiege(gs);
|
|
|
vstd::erase_if(beatenHero->artifactsInBackpack, [](const ArtSlotInfo& asi)
|
|
|
{
|
|
|
return asi.getArt()->getTypeId() == ArtifactID::GRAIL;
|
|
@@ -400,14 +399,6 @@ void GameStatePackVisitor::visitRemoveObject(RemoveObject & pack)
|
|
|
|
|
|
beatenHero->setVisitedTown(nullptr, false);
|
|
|
}
|
|
|
- beatenHero->detachFromBonusSystem(gs);
|
|
|
- beatenHero->tempOwner = PlayerColor::NEUTRAL; //no one owns beaten hero
|
|
|
-
|
|
|
- // 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);
|
|
|
|
|
|
//If hero on Boat is removed, the Boat disappears
|
|
|
if(beatenHero->inBoat())
|
|
@@ -417,12 +408,13 @@ void GameStatePackVisitor::visitRemoveObject(RemoveObject & pack)
|
|
|
gs.getMap().eraseObject(boat->id);
|
|
|
}
|
|
|
|
|
|
+ beatenHero->detachFromBonusSystem(gs);
|
|
|
+ beatenHero->tempOwner = PlayerColor::NEUTRAL; //no one owns beaten hero
|
|
|
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;
|
|
|
}
|
|
|
|
|
@@ -1173,6 +1165,18 @@ void GameStatePackVisitor::visitBattleStart(BattleStart & pack)
|
|
|
pack.info->battleID = gs.nextBattleID;
|
|
|
pack.info->localInit();
|
|
|
|
|
|
+ if (pack.info->getDefendedTown() && pack.info->getSideHero(BattleSide::DEFENDER))
|
|
|
+ {
|
|
|
+ CGTownInstance * town = gs.getTown(pack.info->townID);
|
|
|
+ CGHeroInstance * hero = gs.getHero(pack.info->getSideHero(BattleSide::DEFENDER)->id);
|
|
|
+
|
|
|
+ if (town->getVisitingHero() == hero)
|
|
|
+ {
|
|
|
+ hero->detachFrom(town->townAndVis);
|
|
|
+ hero->attachTo(*town);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
gs.currentBattles.push_back(std::move(pack.info));
|
|
|
gs.nextBattleID = BattleID(gs.nextBattleID.getNum() + 1);
|
|
|
}
|
|
@@ -1232,17 +1236,6 @@ void GameStatePackVisitor::visitBattleUpdateGateState(BattleUpdateGateState & pa
|
|
|
gs.getBattle(pack.battleID)->si.gateState = pack.state;
|
|
|
}
|
|
|
|
|
|
-void GameStatePackVisitor::visitBattleCancelled(BattleCancelled & pack)
|
|
|
-{
|
|
|
- auto currentBattle = boost::range::find_if(gs.currentBattles, [&](const auto & battle)
|
|
|
- {
|
|
|
- return battle->battleID == pack.battleID;
|
|
|
- });
|
|
|
-
|
|
|
- assert(currentBattle != gs.currentBattles.end());
|
|
|
- gs.currentBattles.erase(currentBattle);
|
|
|
-}
|
|
|
-
|
|
|
void GameStatePackVisitor::visitBattleResultAccepted(BattleResultAccepted & pack)
|
|
|
{
|
|
|
// Remove any "until next battle" bonuses
|
|
@@ -1348,8 +1341,44 @@ void GameStatePackVisitor::visitBattleUnitsChanged(BattleUnitsChanged & pack)
|
|
|
pack.visitTyped(battleVisitor);
|
|
|
}
|
|
|
|
|
|
+void GameStatePackVisitor::restorePreBattleState(BattleID battleID)
|
|
|
+{
|
|
|
+ auto battleIter = boost::range::find_if(gs.currentBattles, [&](const auto & battle)
|
|
|
+ {
|
|
|
+ return battle->battleID == battleID;
|
|
|
+ });
|
|
|
+
|
|
|
+ const auto & currentBattle = **battleIter;
|
|
|
+
|
|
|
+ if (currentBattle.getDefendedTown() && currentBattle.getSideHero(BattleSide::DEFENDER))
|
|
|
+ {
|
|
|
+ CGTownInstance * town = gs.getTown(currentBattle.townID);
|
|
|
+ CGHeroInstance * hero = gs.getHero(currentBattle.getSideHero(BattleSide::DEFENDER)->id);
|
|
|
+
|
|
|
+ if (town->getVisitingHero() == hero)
|
|
|
+ {
|
|
|
+ hero->detachFrom(*town);
|
|
|
+ hero->attachTo(town->townAndVis);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void GameStatePackVisitor::visitBattleCancelled(BattleCancelled & pack)
|
|
|
+{
|
|
|
+ restorePreBattleState(pack.battleID);
|
|
|
+
|
|
|
+ auto battleIter = boost::range::find_if(gs.currentBattles, [&](const auto & battle)
|
|
|
+ {
|
|
|
+ return battle->battleID == pack.battleID;
|
|
|
+ });
|
|
|
+
|
|
|
+ assert(battleIter != gs.currentBattles.end());
|
|
|
+ gs.currentBattles.erase(battleIter);
|
|
|
+}
|
|
|
+
|
|
|
void GameStatePackVisitor::visitBattleResultsApplied(BattleResultsApplied & pack)
|
|
|
{
|
|
|
+ restorePreBattleState(pack.battleID);
|
|
|
pack.learnedSpells.visit(*this);
|
|
|
|
|
|
for(auto & discharging : pack.dischargingArtifacts)
|