mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Fix possible assertion failure on removing non-owned town
This commit is contained in:
		| @@ -448,6 +448,12 @@ void AIGateway::battleResultsApplied() | ||||
| 	status.setBattle(NO_BATTLE); | ||||
| } | ||||
|  | ||||
| void AIGateway::beforeObjectPropertyChanged(const SetObjectProperty * sop) | ||||
| { | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| void AIGateway::objectPropertyChanged(const SetObjectProperty * sop) | ||||
| { | ||||
| 	LOG_TRACE(logAi); | ||||
|   | ||||
| @@ -161,6 +161,7 @@ public: | ||||
| 	void heroManaPointsChanged(const CGHeroInstance * hero) override; | ||||
| 	void heroSecondarySkillChanged(const CGHeroInstance * hero, int which, int val) override; | ||||
| 	void battleResultsApplied() override; | ||||
| 	void beforeObjectPropertyChanged(const SetObjectProperty * sop) override; | ||||
| 	void objectPropertyChanged(const SetObjectProperty * sop) override; | ||||
| 	void buildChanged(const CGTownInstance * town, BuildingID buildingID, int what) override; | ||||
| 	void heroBonusChanged(const CGHeroInstance * hero, const Bonus & bonus, bool gain) override; | ||||
|   | ||||
| @@ -538,6 +538,11 @@ void VCAI::battleResultsApplied() | ||||
| 	status.setBattle(NO_BATTLE); | ||||
| } | ||||
|  | ||||
| void VCAI::beforeObjectPropertyChanged(const SetObjectProperty * sop) | ||||
| { | ||||
|  | ||||
| } | ||||
|  | ||||
| void VCAI::objectPropertyChanged(const SetObjectProperty * sop) | ||||
| { | ||||
| 	LOG_TRACE(logAi); | ||||
|   | ||||
| @@ -194,6 +194,7 @@ public: | ||||
| 	void heroManaPointsChanged(const CGHeroInstance * hero) override; | ||||
| 	void heroSecondarySkillChanged(const CGHeroInstance * hero, int which, int val) override; | ||||
| 	void battleResultsApplied() override; | ||||
| 	void beforeObjectPropertyChanged(const SetObjectProperty * sop) override; | ||||
| 	void objectPropertyChanged(const SetObjectProperty * sop) override; | ||||
| 	void buildChanged(const CGTownInstance * town, BuildingID buildingID, int what) override; | ||||
| 	void heroBonusChanged(const CGHeroInstance * hero, const Bonus & bonus, bool gain) override; | ||||
|   | ||||
| @@ -1317,11 +1317,8 @@ void CPlayerInterface::heroExchangeStarted(ObjectInstanceID hero1, ObjectInstanc | ||||
| 	GH.windows().createAndPushWindow<CExchangeWindow>(hero1, hero2, query); | ||||
| } | ||||
|  | ||||
| void CPlayerInterface::objectPropertyChanged(const SetObjectProperty * sop) | ||||
| void CPlayerInterface::beforeObjectPropertyChanged(const SetObjectProperty * sop) | ||||
| { | ||||
| 	EVENT_HANDLER_CALLED_BY_CLIENT; | ||||
|  | ||||
| 	//redraw minimap if owner changed | ||||
| 	if (sop->what == ObjProperty::OWNER) | ||||
| 	{ | ||||
| 		const CGObjectInstance * obj = cb->getObj(sop->id); | ||||
| @@ -1331,13 +1328,34 @@ void CPlayerInterface::objectPropertyChanged(const SetObjectProperty * sop) | ||||
| 			auto town = static_cast<const CGTownInstance *>(obj); | ||||
|  | ||||
| 			if(obj->tempOwner == playerID) | ||||
| 				localState->addOwnedTown(town); | ||||
| 			else | ||||
| 			{ | ||||
| 				localState->removeOwnedTown(town); | ||||
| 				adventureInt->onTownChanged(town); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| 			adventureInt->onTownChanged(town); | ||||
| void CPlayerInterface::objectPropertyChanged(const SetObjectProperty * sop) | ||||
| { | ||||
| 	EVENT_HANDLER_CALLED_BY_CLIENT; | ||||
|  | ||||
| 	if (sop->what == ObjProperty::OWNER) | ||||
| 	{ | ||||
| 		const CGObjectInstance * obj = cb->getObj(sop->id); | ||||
|  | ||||
| 		if(obj->ID == Obj::TOWN) | ||||
| 		{ | ||||
| 			auto town = static_cast<const CGTownInstance *>(obj); | ||||
|  | ||||
| 			if(obj->tempOwner == playerID) | ||||
| 			{ | ||||
| 				localState->addOwnedTown(town); | ||||
| 				adventureInt->onTownChanged(town); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		//redraw minimap if owner changed | ||||
| 		std::set<int3> pos = obj->getBlockedPos(); | ||||
| 		std::unordered_set<int3> upos(pos.begin(), pos.end()); | ||||
| 		adventureInt->onMapTilesChanged(upos); | ||||
|   | ||||
| @@ -144,6 +144,7 @@ protected: // Call-ins from server, should not be called directly, but only via | ||||
| 	void requestRealized(PackageApplied *pa) override; | ||||
| 	void heroExchangeStarted(ObjectInstanceID hero1, ObjectInstanceID hero2, QueryID query) override; | ||||
| 	void centerView (int3 pos, int focusTime) override; | ||||
| 	void beforeObjectPropertyChanged(const SetObjectProperty * sop) override; | ||||
| 	void objectPropertyChanged(const SetObjectProperty * sop) override; | ||||
| 	void objectRemoved(const CGObjectInstance *obj) override; | ||||
| 	void objectRemovedAfter() override; | ||||
|   | ||||
| @@ -128,4 +128,5 @@ public: | ||||
| 	virtual void visitBattleStackMoved(BattleStackMoved & pack) override; | ||||
| 	virtual void visitBattleAttack(BattleAttack & pack) override; | ||||
| 	virtual void visitStartAction(StartAction & pack) override; | ||||
| }; | ||||
| 	virtual void visitSetObjectProperty(SetObjectProperty & pack) override; | ||||
| }; | ||||
|   | ||||
| @@ -611,6 +611,20 @@ void ApplyClientNetPackVisitor::visitInfoWindow(InfoWindow & pack) | ||||
| 		logNetwork->warn("We received InfoWindow for not our player..."); | ||||
| } | ||||
|  | ||||
| void ApplyFirstClientNetPackVisitor::visitSetObjectProperty(SetObjectProperty & pack) | ||||
| { | ||||
| 	//inform all players that see this object | ||||
| 	for(auto it = cl.playerint.cbegin(); it != cl.playerint.cend(); ++it) | ||||
| 	{ | ||||
| 		if(gs.isVisible(gs.getObjInstance(pack.id), it->first)) | ||||
| 			callInterfaceIfPresent(cl, it->first, &IGameEventsReceiver::beforeObjectPropertyChanged, &pack); | ||||
| 	} | ||||
|  | ||||
| 	// invalidate section of map view with our object and force an update with new flag color | ||||
| 	if (pack.what == ObjProperty::OWNER) | ||||
| 		CGI->mh->onObjectInstantRemove(gs.getObjInstance(pack.id)); | ||||
| } | ||||
|  | ||||
| void ApplyClientNetPackVisitor::visitSetObjectProperty(SetObjectProperty & pack) | ||||
| { | ||||
| 	//inform all players that see this object | ||||
| @@ -620,12 +634,9 @@ void ApplyClientNetPackVisitor::visitSetObjectProperty(SetObjectProperty & pack) | ||||
| 			callInterfaceIfPresent(cl, it->first, &IGameEventsReceiver::objectPropertyChanged, &pack); | ||||
| 	} | ||||
|  | ||||
| 	// invalidate section of map view with our object and force an update with new flag color | ||||
| 	if (pack.what == ObjProperty::OWNER) | ||||
| 	{ | ||||
| 		// invalidate section of map view with our object and force an update with new flag color | ||||
| 		CGI->mh->onObjectInstantRemove(gs.getObjInstance(pack.id)); | ||||
| 		CGI->mh->onObjectInstantAdd(gs.getObjInstance(pack.id)); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void ApplyClientNetPackVisitor::visitHeroLevelUp(HeroLevelUp & pack) | ||||
|   | ||||
| @@ -127,6 +127,7 @@ public: | ||||
| 	virtual void playerBonusChanged(const Bonus &bonus, bool gain){};//if gain hero received bonus, else he lost it | ||||
| 	virtual void requestSent(const CPackForServer *pack, int requestID){}; | ||||
| 	virtual void requestRealized(PackageApplied *pa){}; | ||||
| 	virtual void beforeObjectPropertyChanged(const SetObjectProperty * sop){}; //eg. mine has been flagged | ||||
| 	virtual void objectPropertyChanged(const SetObjectProperty * sop){}; //eg. mine has been flagged | ||||
| 	virtual void objectRemoved(const CGObjectInstance *obj){}; //eg. collected resource, picked artifact, beaten hero | ||||
| 	virtual void objectRemovedAfter(){}; //eg. collected resource, picked artifact, beaten hero | ||||
|   | ||||
		Reference in New Issue
	
	Block a user