Michał W. Urbańczyk 14 年之前
父節點
當前提交
212bc13ad6
共有 5 個文件被更改,包括 21 次插入7 次删除
  1. 5 2
      CCallback.cpp
  2. 8 1
      client/Client.cpp
  3. 5 1
      client/Client.h
  4. 2 2
      client/NetPacksClient.cpp
  5. 1 1
      lib/NetPacksLib.cpp

+ 5 - 2
CCallback.cpp

@@ -236,7 +236,9 @@ void CCallback::setSelection(const CArmedInstance * obj)
 
 	if(obj->ID == HEROI_TYPE)
 	{
-		cl->gs->calculatePaths(static_cast<const CGHeroInstance *>(obj), *cl->pathInfo);
+		if(cl->pathInfo->hero != obj) //calculate new paths only if we selected a different hero
+			cl->calculatePaths(static_cast<const CGHeroInstance *>(obj));
+
 		//nasty workaround. TODO: nice workaround
 		cl->gs->getPlayer(player)->currentSelection = obj->id;
 	}
@@ -303,12 +305,13 @@ bool CCallback::getPath2( int3 dest, CGPath &ret )
 	{ 
 		recalculatePaths();
 	}
+	boost::unique_lock<boost::mutex> pathLock(cl->pathMx);
 	return cl->pathInfo->getPath(dest, ret);
 }
 
 void CCallback::recalculatePaths()
 {
-	gs->calculatePaths(cl->IGameCallback::getSelectedHero(player), *cl->pathInfo);
+	cl->calculatePaths(cl->IGameCallback::getSelectedHero(player));
 }
 
 void CCallback::calculatePaths( const CGHeroInstance *hero, CPathsInfo &out, int3 src /*= int3(-1,-1,-1)*/, int movement /*= -1*/ )

+ 8 - 1
client/Client.cpp

@@ -526,7 +526,7 @@ void CClient::updatePaths()
 {	
 	const CGHeroInstance *h = getSelectedHero();
 	if (h)//if we have selected hero...
-		gs->calculatePaths(h, *pathInfo);
+		calculatePaths(h);
 }
 
 void CClient::finishCampaign( CCampaignState * camp )
@@ -617,6 +617,13 @@ int CClient::getLocalPlayer() const
 	return getCurrentPlayer();
 }
 
+void CClient::calculatePaths(const CGHeroInstance *h)
+{
+	assert(h);
+	boost::unique_lock<boost::mutex> pathLock(pathMx);
+	gs->calculatePaths(h, *pathInfo);
+}
+
 template void CClient::serialize( CISer<CLoadFile> &h, const int version );
 template void CClient::serialize( COSer<CSaveFile> &h, const int version );
 

+ 5 - 1
client/Client.h

@@ -72,7 +72,10 @@ public:
 	bool hotSeat;
 	CConnection *serv;
 	BattleAction *curbaction;
+
 	CPathsInfo *pathInfo;
+	boost::mutex pathMx; //protects the variable above
+
 	CScriptingModule *erm;
 
 	CondSh<bool> waitingRequest;
@@ -97,6 +100,8 @@ public:
 	void run();
 	void finishCampaign( CCampaignState * camp );
 	void proposeNextMission( CCampaignState * camp );
+	void calculatePaths(const CGHeroInstance *h);
+	void updatePaths(); //calls calculatePaths for same hero for which we previously calculated paths
 
 	bool terminate;	// tell to terminate
 	boost::thread *connectionHandler; //thread running run() method
@@ -159,7 +164,6 @@ public:
 	friend void processCommand(const std::string &message, CClient *&client); //handling console
 	
 	void handlePack( CPack * pack ); //applies the given pack and deletes it
-	void updatePaths();
 	void battleStarted(const BattleInfo * info);
 
 	void commitPackage(CPackForClient *pack) OVERRIDE;

+ 2 - 2
client/NetPacksClient.cpp

@@ -154,7 +154,7 @@ void SetMovePoints::applyCl( CClient *cl )
 
 	if (cl->IGameCallback::getSelectedHero(LOCPLINT->playerID) == h)//if we have selected that hero
 	{
-		GS(cl)->calculatePaths(h, *cl->pathInfo);
+		cl->calculatePaths(h);
 	}
 
 	INTERFACE_CALL_IF_PRESENT(h->tempOwner, heroMovePointsChanged, h);
@@ -329,7 +329,7 @@ void RemoveObject::applyFirstCl( CClient *cl )
 void RemoveObject::applyCl( CClient *cl )
 {
 	if(cl->pathInfo->hero && cl->pathInfo->hero->id != id)
-		GS(cl)->calculatePaths(cl->pathInfo->hero, *cl->pathInfo);
+		cl->updatePaths();
 }
 
 void TryMoveHero::applyFirstCl( CClient *cl )

+ 1 - 1
lib/NetPacksLib.cpp

@@ -477,7 +477,7 @@ DLL_EXPORT void NewObject::applyGs( CGameState *gs )
 			cre->character = 2;
 			cre->gainedArtifact = -1;
 			cre->identifier = -1;
-			cre->addToSlot(0, new CStackInstance(-1, -1)); //add placeholder stack
+			cre->addToSlot(0, new CStackInstance(subID, -1)); //add placeholder stack
 		}
 		break;
 	default: