diff --git a/AI/Nullkiller/AIGateway.cpp b/AI/Nullkiller/AIGateway.cpp index 5566d3140..3caac7b35 100644 --- a/AI/Nullkiller/AIGateway.cpp +++ b/AI/Nullkiller/AIGateway.cpp @@ -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); diff --git a/AI/Nullkiller/AIGateway.h b/AI/Nullkiller/AIGateway.h index 66f9a323b..a29197b9e 100644 --- a/AI/Nullkiller/AIGateway.h +++ b/AI/Nullkiller/AIGateway.h @@ -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; diff --git a/AI/VCAI/VCAI.cpp b/AI/VCAI/VCAI.cpp index 0ec77b099..816d7acfe 100644 --- a/AI/VCAI/VCAI.cpp +++ b/AI/VCAI/VCAI.cpp @@ -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); diff --git a/AI/VCAI/VCAI.h b/AI/VCAI/VCAI.h index 90b6753f3..a932d8702 100644 --- a/AI/VCAI/VCAI.h +++ b/AI/VCAI/VCAI.h @@ -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; diff --git a/client/CPlayerInterface.cpp b/client/CPlayerInterface.cpp index b40d078b3..c4d180b7d 100644 --- a/client/CPlayerInterface.cpp +++ b/client/CPlayerInterface.cpp @@ -1317,11 +1317,8 @@ void CPlayerInterface::heroExchangeStarted(ObjectInstanceID hero1, ObjectInstanc GH.windows().createAndPushWindow(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(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(obj); + + if(obj->tempOwner == playerID) + { + localState->addOwnedTown(town); + adventureInt->onTownChanged(town); + } } + //redraw minimap if owner changed std::set pos = obj->getBlockedPos(); std::unordered_set upos(pos.begin(), pos.end()); adventureInt->onMapTilesChanged(upos); diff --git a/client/CPlayerInterface.h b/client/CPlayerInterface.h index c7273ed6e..877ff2146 100644 --- a/client/CPlayerInterface.h +++ b/client/CPlayerInterface.h @@ -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; diff --git a/client/ClientNetPackVisitors.h b/client/ClientNetPackVisitors.h index 20c51428c..f6cd06bc2 100644 --- a/client/ClientNetPackVisitors.h +++ b/client/ClientNetPackVisitors.h @@ -128,4 +128,5 @@ public: virtual void visitBattleStackMoved(BattleStackMoved & pack) override; virtual void visitBattleAttack(BattleAttack & pack) override; virtual void visitStartAction(StartAction & pack) override; -}; \ No newline at end of file + virtual void visitSetObjectProperty(SetObjectProperty & pack) override; +}; diff --git a/client/NetPacksClient.cpp b/client/NetPacksClient.cpp index 1be3c4c13..5c92bebe4 100644 --- a/client/NetPacksClient.cpp +++ b/client/NetPacksClient.cpp @@ -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) diff --git a/lib/IGameEventsReceiver.h b/lib/IGameEventsReceiver.h index 226b92198..af2132060 100644 --- a/lib/IGameEventsReceiver.h +++ b/lib/IGameEventsReceiver.h @@ -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