1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-08-10 22:31:40 +02:00

ArtInfoWindow on client. Lib side

This commit is contained in:
SoundSSGood
2025-04-05 17:45:24 +02:00
parent e1be9af5e6
commit 4609a83fc1
12 changed files with 50 additions and 41 deletions

View File

@@ -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;};

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);
}
};

View File

@@ -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)

View File

@@ -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;
}
}
}

View File

@@ -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;

View File

@@ -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

View File

@@ -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)

View File

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