Pārlūkot izejas kodu

Merge pull request #4542 from MichalZr6/update_displayed_path

Update displayed hero path when hiring/dismissing creatures that give move penalty
Ivan Savenko 1 gadu atpakaļ
vecāks
revīzija
658c359bc7
3 mainītis faili ar 45 papildinājumiem un 22 dzēšanām
  1. 14 0
      client/Client.cpp
  2. 3 1
      client/Client.h
  3. 28 21
      client/NetPacksClient.cpp

+ 14 - 0
client/Client.cpp

@@ -13,6 +13,7 @@
 
 #include "CGameInfo.h"
 #include "CPlayerInterface.h"
+#include "PlayerLocalState.h"
 #include "CServerHandler.h"
 #include "ClientNetPackVisitors.h"
 #include "adventureMap/AdventureMapInterface.h"
@@ -495,6 +496,19 @@ void CClient::startPlayerBattleAction(const BattleID & battleID, PlayerColor col
 	}
 }
 
+void CClient::updatePath(const ObjectInstanceID & id)
+{
+	invalidatePaths();
+	auto hero = getHero(id);
+	updatePath(hero);
+}
+
+void CClient::updatePath(const CGHeroInstance * hero)
+{
+	if(LOCPLINT && hero)
+		LOCPLINT->localState->verifyPath(hero);
+}
+
 void CClient::invalidatePaths()
 {
 	boost::unique_lock<boost::mutex> pathLock(pathCacheMutex);

+ 3 - 1
client/Client.h

@@ -150,7 +150,9 @@ public:
 	void battleFinished(const BattleID & battleID);
 	void startPlayerBattleAction(const BattleID & battleID, PlayerColor color);
 
-	void invalidatePaths();
+	void invalidatePaths(); // clears this->pathCache()
+	void updatePath(const ObjectInstanceID & heroID); // invalidatePaths and update displayed hero path 
+	void updatePath(const CGHeroInstance * hero);
 	std::shared_ptr<const CPathsInfo> getPathsInfo(const CGHeroInstance * h);
 
 	friend class CCallback; //handling players actions

+ 28 - 21
client/NetPacksClient.cpp

@@ -101,7 +101,7 @@ void callBattleInterfaceIfPresentForBothSides(CClient & cl, const BattleID & bat
 {
 	assert(cl.gameState()->getBattle(battleID));
 
-	if (!cl.gameState()->getBattle(battleID))
+	if(!cl.gameState()->getBattle(battleID))
 	{
 		logGlobal->error("Attempt to call battle interface without ongoing battle!");
 		return;
@@ -161,14 +161,14 @@ void ApplyClientNetPackVisitor::visitSetMana(SetMana & pack)
 	if(settings["session"]["headless"].Bool())
 		return;
 
-	for (auto window : GH.windows().findWindows<BattleWindow>())
+	for(auto window : GH.windows().findWindows<BattleWindow>())
 		window->heroManaPointsChanged(h);
 }
 
 void ApplyClientNetPackVisitor::visitSetMovePoints(SetMovePoints & pack)
 {
 	const CGHeroInstance *h = cl.getHero(pack.hid);
-	cl.invalidatePaths();
+	cl.updatePath(h);
 	callInterfaceIfPresent(cl, h->tempOwner, &IGameEventsReceiver::heroMovePointsChanged, h);
 }
 
@@ -229,7 +229,7 @@ void ApplyClientNetPackVisitor::visitSetStackType(SetStackType & pack)
 void ApplyClientNetPackVisitor::visitEraseStack(EraseStack & pack)
 {
 	dispatchGarrisonChange(cl, pack.army, ObjectInstanceID());
-	cl.invalidatePaths(); //it is possible to remove last non-native unit for current terrain and lose movement penalty
+	cl.updatePath(pack.army); //it is possible to remove last non-native unit for current terrain and lose movement penalty
 }
 
 void ApplyClientNetPackVisitor::visitSwapStacks(SwapStacks & pack)
@@ -237,15 +237,14 @@ void ApplyClientNetPackVisitor::visitSwapStacks(SwapStacks & pack)
 	dispatchGarrisonChange(cl, pack.srcArmy, pack.dstArmy);
 
 	if(pack.srcArmy != pack.dstArmy)
-		cl.invalidatePaths(); // adding/removing units may change terrain type penalty based on creature native terrains
+		cl.updatePath(pack.dstArmy); // adding/removing units may change terrain type penalty based on creature native terrains
 }
 
 void ApplyClientNetPackVisitor::visitInsertNewStack(InsertNewStack & pack)
 {
 	dispatchGarrisonChange(cl, pack.army, ObjectInstanceID());
 
-	if(gs.getHero(pack.army))
-		cl.invalidatePaths(); // adding/removing units may change terrain type penalty based on creature native terrains
+	cl.updatePath(pack.army); // adding/removing units may change terrain type penalty based on creature native terrains
 }
 
 void ApplyClientNetPackVisitor::visitRebalanceStacks(RebalanceStacks & pack)
@@ -253,7 +252,10 @@ void ApplyClientNetPackVisitor::visitRebalanceStacks(RebalanceStacks & pack)
 	dispatchGarrisonChange(cl, pack.srcArmy, pack.dstArmy);
 
 	if(pack.srcArmy != pack.dstArmy)
-		cl.invalidatePaths(); // adding/removing units may change terrain type penalty based on creature native terrains
+	{
+		cl.updatePath(pack.srcArmy); // adding/removing units may change terrain type penalty based on creature native terrains
+		cl.updatePath(pack.dstArmy);
+	}
 }
 
 void ApplyClientNetPackVisitor::visitBulkRebalanceStacks(BulkRebalanceStacks & pack)
@@ -266,7 +268,10 @@ void ApplyClientNetPackVisitor::visitBulkRebalanceStacks(BulkRebalanceStacks & p
 		dispatchGarrisonChange(cl, pack.moves[0].srcArmy, destArmy);
 
 		if(pack.moves[0].srcArmy != destArmy)
-			cl.invalidatePaths(); // adding/removing units may change terrain type penalty based on creature native terrains
+		{
+			cl.updatePath(destArmy); // adding/removing units may change terrain type penalty based on creature native terrains
+			cl.updatePath(pack.moves[0].srcArmy);
+		}
 	}
 }
 
@@ -292,6 +297,7 @@ void ApplyClientNetPackVisitor::visitPutArtifact(PutArtifact & pack)
 
 void ApplyClientNetPackVisitor::visitEraseArtifact(BulkEraseArtifacts & pack)
 {
+	cl.updatePath(pack.artHolder);
 	for(const auto & slotErase : pack.posPack)
 		callInterfaceIfPresent(cl, cl.getOwner(pack.artHolder), &IGameEventsReceiver::artifactRemoved, ArtifactLocation(pack.artHolder, slotErase));
 }
@@ -312,7 +318,8 @@ void ApplyClientNetPackVisitor::visitBulkMoveArtifacts(BulkMoveArtifacts & pack)
 			if(pack.interfaceOwner != dstOwner)
 				callInterfaceIfPresent(cl, dstOwner, &IGameEventsReceiver::artifactMoved, srcLoc, dstLoc);
 
-			cl.invalidatePaths(); // hero might have equipped/unequipped Angel Wings
+			cl.updatePath(pack.srcArtHolder); // hero might have equipped/unequipped Angel Wings
+			cl.updatePath(pack.dstArtHolder);
 		}
 	};
 
@@ -342,14 +349,14 @@ void ApplyClientNetPackVisitor::visitAssembledArtifact(AssembledArtifact & pack)
 {
 	callInterfaceIfPresent(cl, cl.getOwner(pack.al.artHolder), &IGameEventsReceiver::artifactAssembled, pack.al);
 
-	cl.invalidatePaths(); // hero might have equipped/unequipped Angel Wings
+	cl.updatePath(pack.al.artHolder); // hero might have equipped/unequipped Angel Wings
 }
 
 void ApplyClientNetPackVisitor::visitDisassembledArtifact(DisassembledArtifact & pack)
 {
 	callInterfaceIfPresent(cl, cl.getOwner(pack.al.artHolder), &IGameEventsReceiver::artifactDisassembled, pack.al);
 
-	cl.invalidatePaths(); // hero might have equipped/unequipped Angel Wings
+	cl.updatePath(pack.al.artHolder); // hero might have equipped/unequipped Angel Wings
 }
 
 void ApplyClientNetPackVisitor::visitHeroVisit(HeroVisit & pack)
@@ -363,7 +370,7 @@ void ApplyClientNetPackVisitor::visitNewTurn(NewTurn & pack)
 {
 	cl.invalidatePaths();
 
-	if (pack.newWeekNotification)
+	if(pack.newWeekNotification)
 	{
 		const auto & newWeek = *pack.newWeekNotification;
 
@@ -380,7 +387,7 @@ void ApplyClientNetPackVisitor::visitGiveBonus(GiveBonus & pack)
 	case GiveBonus::ETarget::OBJECT:
 		{
 			const CGHeroInstance *h = gs.getHero(pack.id.as<ObjectInstanceID>());
-			if (h)
+			if(h)
 				callInterfaceIfPresent(cl, h->tempOwner, &IGameEventsReceiver::heroBonusChanged, h, pack.bonus, true);
 		}
 		break;
@@ -419,7 +426,7 @@ void ApplyClientNetPackVisitor::visitPlayerEndsGame(PlayerEndsGame & pack)
 
 	bool lastHumanEndsGame = CSH->howManyPlayerInterfaces() == 1 && vstd::contains(cl.playerint, pack.player) && cl.getPlayerState(pack.player)->human && !settings["session"]["spectate"].Bool();
 
-	if (lastHumanEndsGame)
+	if(lastHumanEndsGame)
 	{
 		assert(adventureInt);
 		if(adventureInt)
@@ -446,9 +453,9 @@ void ApplyClientNetPackVisitor::visitPlayerReinitInterface(PlayerReinitInterface
 	{
 		cl.initPlayerInterfaces();
 
-		for (PlayerColor player(0); player < PlayerColor::PLAYER_LIMIT; ++player)
+		for(PlayerColor player(0); player < PlayerColor::PLAYER_LIMIT; ++player)
 		{
-			if (cl.gameState()->isPlayerMakingTurn(player))
+			if(cl.gameState()->isPlayerMakingTurn(player))
 			{
 				callAllInterfaces(cl, &IGameEventsReceiver::playerStartsTurn, player);
 				callOnlyThatInterface(cl, player, &CGameInterface::yourTurn, QueryID::NONE);
@@ -482,7 +489,7 @@ void ApplyClientNetPackVisitor::visitRemoveBonus(RemoveBonus & pack)
 	case GiveBonus::ETarget::OBJECT:
 		{
 			const CGHeroInstance *h = gs.getHero(pack.whoID.as<ObjectInstanceID>());
-			if (h)
+			if(h)
 				callInterfaceIfPresent(cl, h->tempOwner, &IGameEventsReceiver::heroBonusChanged, h, pack.bonus, false);
 		}
 		break;
@@ -701,7 +708,7 @@ void ApplyFirstClientNetPackVisitor::visitSetObjectProperty(SetObjectProperty &
 	}
 
 	// invalidate section of map view with our object and force an update with new flag color
-	if (pack.what == ObjProperty::OWNER && CGI->mh)
+	if(pack.what == ObjProperty::OWNER && CGI->mh)
 	{
 		auto object = gs.getObjInstance(pack.id);
 		CGI->mh->onObjectInstantRemove(object, object->getOwner());
@@ -718,7 +725,7 @@ void ApplyClientNetPackVisitor::visitSetObjectProperty(SetObjectProperty & pack)
 	}
 
 	// invalidate section of map view with our object and force an update with new flag color
-	if (pack.what == ObjProperty::OWNER && CGI->mh)
+	if(pack.what == ObjProperty::OWNER && CGI->mh)
 	{
 		auto object = gs.getObjInstance(pack.id);
 		CGI->mh->onObjectInstantAdd(object, object->getOwner());
@@ -807,7 +814,7 @@ void ApplyClientNetPackVisitor::visitBattleSetActiveStack(BattleSetActiveStack &
 
 	const CStack *activated = gs.getBattle(pack.battleID)->battleGetStackByID(pack.stack);
 	PlayerColor playerToCall; //pack.player that will move activated stack
-	if (activated->hasBonusOfType(BonusType::HYPNOTIZED))
+	if(activated->hasBonusOfType(BonusType::HYPNOTIZED))
 	{
 		playerToCall = gs.getBattle(pack.battleID)->getSide(BattleSide::ATTACKER).color == activated->unitOwner()
 			? gs.getBattle(pack.battleID)->getSide(BattleSide::DEFENDER).color