Browse Source

Allow dismissing hero from town

Ivan Savenko 2 năm trước cách đây
mục cha
commit
8129cbc514
3 tập tin đã thay đổi với 18 bổ sung5 xóa
  1. 8 1
      client/CPlayerInterface.cpp
  2. 0 3
      client/windows/CHeroWindow.cpp
  3. 10 1
      lib/NetPacksLib.cpp

+ 8 - 1
client/CPlayerInterface.cpp

@@ -398,7 +398,10 @@ void CPlayerInterface::heroKilled(const CGHeroInstance* hero)
 	EVENT_HANDLER_CALLED_BY_CLIENT;
 	LOG_TRACE_PARAMS(logGlobal, "Hero %s killed handler for player %s", hero->getNameTranslated() % playerID);
 
-	localState->removeWanderingHero(hero);
+	// if hero is not in town garrison
+	if (vstd::contains(localState->getWanderingHeroes(), hero))
+		localState->removeWanderingHero(hero);
+
 	adventureInt->onHeroChanged(hero);
 	localState->erasePath(hero);
 
@@ -1482,6 +1485,10 @@ void CPlayerInterface::objectRemovedAfter()
 {
 	EVENT_HANDLER_CALLED_BY_CLIENT;
 	adventureInt->onMapTilesChanged(boost::none);
+
+	// visiting or garrisoned hero removed - recreate castle window
+	if (castleInt)
+		openTownWindow(castleInt->town);
 }
 
 void CPlayerInterface::playerBlocked(int reason, bool start)

+ 0 - 3
client/windows/CHeroWindow.cpp

@@ -326,9 +326,6 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded)
 	if(curHero->isMissionCritical())
 		noDismiss = true;
 
-	if (curHero->visitedTown)
-		noDismiss = true;
-
 	dismissButton->block(noDismiss);
 
 	if(curHero->valOfBonuses(Selector::type()(BonusType::BEFORE_BATTLE_REPOSITION)) == 0)

+ 10 - 1
lib/NetPacksLib.cpp

@@ -1132,7 +1132,16 @@ void RemoveObject::applyGs(CGameState *gs)
 		PlayerState * p = gs->getPlayerState(beatenHero->tempOwner);
 		gs->map->heroesOnMap -= beatenHero;
 		p->heroes -= beatenHero;
-		beatenHero->detachFrom(*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)
 		{