Browse Source

ArtInfoWindow on client. Lib side

SoundSSGood 8 months ago
parent
commit
4609a83fc1

+ 1 - 1
client/Client.h

@@ -194,7 +194,7 @@ public:
 	void tryJoiningArmy(const CArmedInstance * src, const CArmedInstance * dst, bool removeObjWhenFinished, bool allowMerging) override {}
 	bool moveStack(const StackLocation & src, const StackLocation & dst, TQuantity count = -1) override {return false;}
 
-	void removeAfterVisit(const CGObjectInstance * object) override {};
+	void removeAfterVisit(const ObjectInstanceID & id) override {};
 	bool swapGarrisonOnSiege(ObjectInstanceID tid) override {return false;};
 	bool giveHeroNewArtifact(const CGHeroInstance * h, const ArtifactID & artId, const ArtifactPosition & pos) override {return false;};
 	bool giveHeroNewScroll(const CGHeroInstance * h, const SpellID & spellId, const ArtifactPosition & pos) override {return false;};

+ 2 - 2
client/NetPacksClient.cpp

@@ -851,8 +851,8 @@ void ApplyClientNetPackVisitor::visitStacksInjured(StacksInjured & pack)
 
 void ApplyClientNetPackVisitor::visitBattleResultsApplied(BattleResultsApplied & pack)
 {
-	callInterfaceIfPresent(cl, pack.player1, &IGameEventsReceiver::battleResultsApplied);
-	callInterfaceIfPresent(cl, pack.player2, &IGameEventsReceiver::battleResultsApplied);
+	callInterfaceIfPresent(cl, pack.victor, &IGameEventsReceiver::battleResultsApplied);
+	callInterfaceIfPresent(cl, pack.loser, &IGameEventsReceiver::battleResultsApplied);
 	callInterfaceIfPresent(cl, PlayerColor::SPECTATOR, &IGameEventsReceiver::battleResultsApplied);
 }
 

+ 1 - 1
lib/ArtifactUtils.cpp

@@ -67,7 +67,7 @@ DLL_LINKAGE ArtifactPosition ArtifactUtils::getArtBackpackPosition(const CArtifa
 	if(target->bearerType() == ArtBearer::HERO)
 		if(art->canBePutAt(target, ArtifactPosition::BACKPACK_START))
 		{
-			return ArtifactPosition::BACKPACK_START;
+			return ArtifactPosition::BACKPACK_START + target->artifactsInBackpack.size();
 		}
 	return ArtifactPosition::PRE_FIRST;
 }

+ 1 - 1
lib/IGameCallback.h

@@ -118,7 +118,7 @@ public:
 	virtual void tryJoiningArmy(const CArmedInstance *src, const CArmedInstance *dst, bool removeObjWhenFinished, bool allowMerging) =0; //merges army from src do dst or opens a garrison window
 	virtual bool moveStack(const StackLocation &src, const StackLocation &dst, TQuantity count) = 0;
 
-	virtual void removeAfterVisit(const CGObjectInstance *object) = 0; //object will be destroyed when interaction is over. Do not call when interaction is not ongoing!
+	virtual void removeAfterVisit(const ObjectInstanceID & id) = 0; //object will be destroyed when interaction is over. Do not call when interaction is not ongoing!
 
 	virtual bool giveHeroNewArtifact(const CGHeroInstance * h, const ArtifactID & artId, const ArtifactPosition & pos) = 0;
 	virtual bool giveHeroNewScroll(const CGHeroInstance * h, const SpellID & spellId, const ArtifactPosition & pos) = 0;

+ 16 - 16
lib/networkPacks/NetPacksLib.cpp

@@ -2105,26 +2105,24 @@ void BattleCancelled::applyGs(CGameState *gs)
 
 void BattleResultAccepted::applyGs(CGameState *gs)
 {
+	const auto attackerArmy = gs->getArmyInstance(heroResult[BattleSide::ATTACKER].army);
+	const auto defenderArmy = gs->getArmyInstance(heroResult[BattleSide::DEFENDER].army);
+
 	// Remove any "until next battle" bonuses
-	for(auto & res : heroResult)
-	{
-		if(res.hero)
-			res.hero->removeBonusesRecursive(Bonus::OneBattle);
-	}
+	attackerArmy->removeBonusesRecursive(Bonus::OneBattle);
+	defenderArmy->removeBonusesRecursive(Bonus::OneBattle);
 
 	if(winnerSide != BattleSide::NONE)
 	{
 		// Grow up growing artifacts
-		const auto hero = heroResult[winnerSide].hero;
-
-		if (hero)
+		if(const auto winnerHero = gs->getHero(heroResult[winnerSide].army))
 		{
-			if(hero->commander && hero->commander->alive)
+			if(winnerHero->commander && winnerHero->commander->alive)
 			{
-				for(auto & art : hero->commander->artifactsWorn)
+				for(auto & art : winnerHero->commander->artifactsWorn)
 					art.second.artifact->growingUp();
 			}
-			for(auto & art : hero->artifactsWorn)
+			for(auto & art : winnerHero->artifactsWorn)
 			{
 				art.second.artifact->growingUp();
 			}
@@ -2135,17 +2133,19 @@ void BattleResultAccepted::applyGs(CGameState *gs)
 	{
 		if(heroResult[BattleSide::ATTACKER].army)
 		{
-			heroResult[BattleSide::ATTACKER].army->giveStackExp(heroResult[BattleSide::ATTACKER].exp);
-			heroResult[BattleSide::ATTACKER].army->nodeHasChanged();
+			attackerArmy->giveStackExp(heroResult[BattleSide::ATTACKER].exp);
+			attackerArmy->nodeHasChanged();
 		}
 		if(heroResult[BattleSide::DEFENDER].army)
 		{
-			heroResult[BattleSide::DEFENDER].army->giveStackExp(heroResult[BattleSide::DEFENDER].exp);
-			heroResult[BattleSide::DEFENDER].army->nodeHasChanged();
+			defenderArmy->giveStackExp(heroResult[BattleSide::DEFENDER].exp);
+			defenderArmy->nodeHasChanged();
 		}
-
 	}
 
+	for(auto & artPack : artifacts)
+		artPack.applyGs(gs);
+
 	auto currentBattle = boost::range::find_if(gs->currentBattles, [&](const auto & battle)
 	{
 		return battle->battleID == battleID;

+ 11 - 9
lib/networkPacks/PacksForClientBattle.h

@@ -11,6 +11,7 @@
 
 #include "NetPacksBase.h"
 #include "BattleChanges.h"
+#include "PacksForClient.h"
 #include "../battle/BattleHexArray.h"
 #include "../battle/BattleAction.h"
 #include "../texts/MetaString.h"
@@ -95,15 +96,13 @@ struct DLL_LINKAGE BattleResultAccepted : public CPackForClient
 	struct HeroBattleResults
 	{
 		HeroBattleResults()
-			: hero(nullptr), army(nullptr), exp(0) {}
+			: army(ObjectInstanceID::NONE), exp(0) {}
 
-		CGHeroInstance * hero;
-		CArmedInstance * army;
+		ObjectInstanceID army;
 		TExpType exp;
 
 		template <typename Handler> void serialize(Handler & h)
 		{
-			h & hero;
 			h & army;
 			h & exp;
 		}
@@ -112,12 +111,14 @@ struct DLL_LINKAGE BattleResultAccepted : public CPackForClient
 	BattleID battleID = BattleID::NONE;
 	BattleSideArray<HeroBattleResults> heroResult;
 	BattleSide winnerSide;
+	std::vector<BulkMoveArtifacts> artifacts;
 
 	template <typename Handler> void serialize(Handler & h)
 	{
 		h & battleID;
 		h & heroResult;
 		h & winnerSide;
+		h & artifacts;
 		assert(battleID != BattleID::NONE);
 	}
 };
@@ -131,7 +132,6 @@ struct DLL_LINKAGE BattleResult : public Query
 	BattleSide winner = BattleSide::NONE; //0 - attacker, 1 - defender, [2 - draw (should be possible?)]
 	BattleSideArray<std::map<CreatureID, si32>> casualties; //first => casualties of attackers - map crid => number
 	BattleSideArray<TExpType> exp{0,0}; //exp for attacker and defender
-	std::set<ArtifactInstanceID> artifacts; //artifacts taken from loser to winner - currently unused
 
 	void visitTyped(ICPackVisitor & visitor) override;
 	void applyGs(CGameState *gs) override {}
@@ -144,7 +144,6 @@ struct DLL_LINKAGE BattleResult : public Query
 		h & winner;
 		h & casualties;
 		h & exp;
-		h & artifacts;
 		assert(battleID != BattleID::NONE);
 	}
 };
@@ -421,15 +420,18 @@ struct DLL_LINKAGE StacksInjured : public CPackForClient
 struct DLL_LINKAGE BattleResultsApplied : public CPackForClient
 {
 	BattleID battleID = BattleID::NONE;
-	PlayerColor player1, player2;
+	PlayerColor victor;
+	PlayerColor loser;
+	std::vector<BulkMoveArtifacts> artifacts;
 	void visitTyped(ICPackVisitor & visitor) override;
 	void applyGs(CGameState *gs) override {}
 
 	template <typename Handler> void serialize(Handler & h)
 	{
 		h & battleID;
-		h & player1;
-		h & player2;
+		h & victor;
+		h & loser;
+		h & artifacts;
 		assert(battleID != BattleID::NONE);
 	}
 };

+ 1 - 1
lib/rewardable/Interface.cpp

@@ -212,7 +212,7 @@ void Rewardable::Interface::grantRewardAfterLevelup(const Rewardable::VisitInfo
 
 	if(info.reward.removeObject)
 		if(auto * instance = dynamic_cast<const CGObjectInstance*>(this))
-			cb->removeAfterVisit(instance);
+			cb->removeAfterVisit(instance->id);
 }
 
 void Rewardable::Interface::serializeJson(JsonSerializeFormat & handler)

+ 8 - 3
server/CGameHandler.cpp

@@ -3842,7 +3842,7 @@ bool CGameHandler::addToSlot(const StackLocation &sl, const CCreature *c, TQuant
 void CGameHandler::tryJoiningArmy(const CArmedInstance *src, const CArmedInstance *dst, bool removeObjWhenFinished, bool allowMerging)
 {
 	if (removeObjWhenFinished)
-		removeAfterVisit(src);
+		removeAfterVisit(src->id);
 
 	if (!src->canBeMergedWith(*dst, allowMerging))
 	{
@@ -4090,18 +4090,23 @@ bool CGameHandler::isBlockedByQueries(const CPackForServer *pack, PlayerColor pl
 	return false;
 }
 
-void CGameHandler::removeAfterVisit(const CGObjectInstance *object)
+void CGameHandler::removeAfterVisit(const ObjectInstanceID & id)
 {
 	//If the object is being visited, there must be a matching query
 	for (const auto &query : queries->allQueries())
 	{
 		if (auto someVistQuery = std::dynamic_pointer_cast<MapObjectVisitQuery>(query))
 		{
-			if (someVistQuery->visitedObject == object)
+			if(someVistQuery->visitedObject->id == id)
 			{
 				someVistQuery->removeObjectAfterVisit = true;
 				return;
 			}
+			else if(someVistQuery->visitingHero->id == id)
+			{
+				someVistQuery->removeVisitorAfterVisit = true;
+				return;
+			}
 		}
 	}
 

+ 1 - 1
server/CGameHandler.h

@@ -132,7 +132,7 @@ public:
 	void tryJoiningArmy(const CArmedInstance *src, const CArmedInstance *dst, bool removeObjWhenFinished, bool allowMerging) override;
 	bool moveStack(const StackLocation &src, const StackLocation &dst, TQuantity count = -1) override;
 
-	void removeAfterVisit(const CGObjectInstance *object) override;
+	void removeAfterVisit(const ObjectInstanceID & id) override;
 
 	bool giveHeroNewArtifact(const CGHeroInstance * h, const CArtifact * artType, const SpellID & spellId, const ArtifactPosition & pos);
 	bool giveHeroNewArtifact(const CGHeroInstance * h, const ArtifactID & artId, const ArtifactPosition & pos) override;

+ 4 - 6
server/battles/BattleResultProcessor.cpp

@@ -520,10 +520,8 @@ void BattleResultProcessor::endBattleConfirm(const CBattleInfoCallback & battle)
 
 	BattleResultAccepted raccepted;
 	raccepted.battleID = battle.getBattle()->getBattleID();
-	raccepted.heroResult[BattleSide::ATTACKER].army = const_cast<CArmedInstance*>(battle.battleGetArmyObject(BattleSide::ATTACKER));
-	raccepted.heroResult[BattleSide::DEFENDER].army = const_cast<CArmedInstance*>(battle.battleGetArmyObject(BattleSide::DEFENDER));
-	raccepted.heroResult[BattleSide::ATTACKER].hero = const_cast<CGHeroInstance*>(battle.battleGetFightingHero(BattleSide::ATTACKER));
-	raccepted.heroResult[BattleSide::DEFENDER].hero = const_cast<CGHeroInstance*>(battle.battleGetFightingHero(BattleSide::DEFENDER));
+	raccepted.heroResult[BattleSide::ATTACKER].army = battle.battleGetArmyObject(BattleSide::ATTACKER)->id;
+	raccepted.heroResult[BattleSide::DEFENDER].army = battle.battleGetArmyObject(BattleSide::DEFENDER)->id;
 	raccepted.heroResult[BattleSide::ATTACKER].exp = battleResult->exp[BattleSide::ATTACKER];
 	raccepted.heroResult[BattleSide::DEFENDER].exp = battleResult->exp[BattleSide::DEFENDER];
 	raccepted.winnerSide = finishingBattle->winnerSide;
@@ -568,8 +566,8 @@ void BattleResultProcessor::battleAfterLevelUp(const BattleID & battleID, const
 
 	BattleResultsApplied resultsApplied;
 	resultsApplied.battleID = battleID;
-	resultsApplied.player1 = finishingBattle->victor;
-	resultsApplied.player2 = finishingBattle->loser;
+	resultsApplied.victor = finishingBattle->victor;
+	resultsApplied.loser = finishingBattle->loser;
 	gameHandler->sendAndApply(resultsApplied);
 
 	//handle victory/loss of engaged players

+ 3 - 0
server/queries/VisitQueries.cpp

@@ -43,6 +43,7 @@ void MapObjectVisitQuery::onExposure(QueryPtr topQuery)
 MapObjectVisitQuery::MapObjectVisitQuery(CGameHandler * owner, const CGObjectInstance * Obj, const CGHeroInstance * Hero)
 	: VisitQuery(owner, Obj, Hero)
 	, removeObjectAfterVisit(false)
+	, removeVisitorAfterVisit(false)
 {
 }
 
@@ -53,6 +54,8 @@ void MapObjectVisitQuery::onRemoval(PlayerColor color)
 	//Can object visit affect 2 players and what would be desired behavior?
 	if(removeObjectAfterVisit)
 		gh->removeObject(visitedObject, color);
+	if(removeVisitorAfterVisit)
+		gh->removeObject(visitingHero, color);
 }
 
 TownBuildingVisitQuery::TownBuildingVisitQuery(CGameHandler * owner, const CGTownInstance * Obj, std::vector<const CGHeroInstance *> heroes, std::vector<BuildingID> buildingToVisit)

+ 1 - 0
server/queries/VisitQueries.h

@@ -33,6 +33,7 @@ class MapObjectVisitQuery final : public VisitQuery
 {
 public:
 	bool removeObjectAfterVisit;
+	bool removeVisitorAfterVisit;
 
 	MapObjectVisitQuery(CGameHandler * owner, const CGObjectInstance * Obj, const CGHeroInstance * Hero);