1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-27 22:49:25 +02:00

GrowUpArtifact pack

This commit is contained in:
SoundSSGood
2025-05-09 22:56:22 +02:00
parent 630f911cc9
commit 9bbebd62e9
8 changed files with 59 additions and 22 deletions

View File

@@ -847,12 +847,12 @@ void ApplyClientNetPackVisitor::visitBattleResultsApplied(BattleResultsApplied &
UIHelper::getEagleEyeInfoWindowText(*hero, pack.learnedSpells.spells), UIHelper::getSpellsComponents(pack.learnedSpells.spells), soundBase::soundID(0)); UIHelper::getEagleEyeInfoWindowText(*hero, pack.learnedSpells.spells), UIHelper::getSpellsComponents(pack.learnedSpells.spells), soundBase::soundID(0));
} }
if(!pack.artifacts.empty()) if(!pack.movingArtifacts.empty())
{ {
const auto artSet = GAME->interface()->cb->getArtSet(ArtifactLocation(pack.artifacts.front().dstArtHolder)); const auto artSet = GAME->interface()->cb->getArtSet(ArtifactLocation(pack.movingArtifacts.front().dstArtHolder));
assert(artSet); assert(artSet);
std::vector<Component> artComponents; std::vector<Component> artComponents;
for(const auto & artPack : pack.artifacts) for(const auto & artPack : pack.movingArtifacts)
{ {
auto packComponents = UIHelper::getArtifactsComponents(*artSet, artPack.artsPack0); auto packComponents = UIHelper::getArtifactsComponents(*artSet, artPack.artsPack0);
artComponents.insert(artComponents.end(), std::make_move_iterator(packComponents.begin()), std::make_move_iterator(packComponents.end())); artComponents.insert(artComponents.end(), std::make_move_iterator(packComponents.begin()), std::make_move_iterator(packComponents.end()));
@@ -861,7 +861,7 @@ void ApplyClientNetPackVisitor::visitBattleResultsApplied(BattleResultsApplied &
artComponents, soundBase::soundID(0)); artComponents, soundBase::soundID(0));
} }
for(auto & artPack : pack.artifacts) for(auto & artPack : pack.movingArtifacts)
visitBulkMoveArtifacts(artPack); visitBulkMoveArtifacts(artPack);
if(pack.raisedStack.getCreature()) if(pack.raisedStack.getCreature())

View File

@@ -16,7 +16,7 @@ class JsonNode;
#define BONUS_LIST \ #define BONUS_LIST \
BONUS_NAME(NONE) \ BONUS_NAME(NONE) \
BONUS_NAME(LEVEL_COUNTER) /* for commander artifacts*/ \ BONUS_NAME(ARTIFACT_GROWING) \
BONUS_NAME(MOVEMENT) /*Subtype is 1 - land, 0 - sea*/ \ BONUS_NAME(MOVEMENT) /*Subtype is 1 - land, 0 - sea*/ \
BONUS_NAME(MORALE) \ BONUS_NAME(MORALE) \
BONUS_NAME(LUCK) \ BONUS_NAME(LUCK) \

View File

@@ -99,17 +99,16 @@ void CGrowingArtifactInstance::growingUp()
if(artInst->getType()->isGrowing()) if(artInst->getType()->isGrowing())
{ {
auto growingBonus = std::make_shared<Bonus>();
auto bonus = std::make_shared<Bonus>(); growingBonus->type = BonusType::ARTIFACT_GROWING;
bonus->type = BonusType::LEVEL_COUNTER; growingBonus->val = 1;
bonus->val = 1; growingBonus->duration = BonusDuration::PERMANENT;
bonus->duration = BonusDuration::COMMANDER_KILLED; artInst->accumulateBonus(growingBonus);
artInst->accumulateBonus(bonus);
for(const auto & bonus : artInst->getType()->getBonusesPerLevel()) for(const auto & bonus : artInst->getType()->getBonusesPerLevel())
{ {
// Every n levels // Every n levels
if(artInst->valOfBonuses(BonusType::LEVEL_COUNTER) % bonus.first == 0) if(artInst->valOfBonuses(BonusType::ARTIFACT_GROWING) % bonus.first == 0)
{ {
artInst->accumulateBonus(std::make_shared<Bonus>(bonus.second)); artInst->accumulateBonus(std::make_shared<Bonus>(bonus.second));
} }
@@ -117,7 +116,7 @@ void CGrowingArtifactInstance::growingUp()
for(const auto & bonus : artInst->getType()->getThresholdBonuses()) for(const auto & bonus : artInst->getType()->getThresholdBonuses())
{ {
// At n level // At n level
if(artInst->valOfBonuses(BonusType::LEVEL_COUNTER) == bonus.first) if(artInst->valOfBonuses(BonusType::ARTIFACT_GROWING) == bonus.first)
{ {
artInst->addNewBonus(std::make_shared<Bonus>(bonus.second)); artInst->addNewBonus(std::make_shared<Bonus>(bonus.second));
} }

View File

@@ -838,7 +838,7 @@ CArtifactInstance * CMap::createArtifact(const ArtifactID & artID, const SpellID
if(art->isGrowing()) if(art->isGrowing())
{ {
auto bonus = std::make_shared<Bonus>(); auto bonus = std::make_shared<Bonus>();
bonus->type = BonusType::LEVEL_COUNTER; bonus->type = BonusType::ARTIFACT_GROWING;
bonus->val = 0; bonus->val = 0;
artInst->addNewBonus(bonus); artInst->addNewBonus(bonus);
} }

View File

@@ -907,6 +907,23 @@ struct DLL_LINKAGE CArtifactOperationPack : CPackForClient
{ {
}; };
struct DLL_LINKAGE GrowUpArtifact : CArtifactOperationPack
{
ArtifactInstanceID id;
GrowUpArtifact() = default;
GrowUpArtifact(const ArtifactInstanceID & id)
: id(id)
{
}
void applyGs(CGameState * gs) override;
template <typename Handler> void serialize(Handler & h)
{
h & id;
}
};
struct DLL_LINKAGE PutArtifact : CArtifactOperationPack struct DLL_LINKAGE PutArtifact : CArtifactOperationPack
{ {
PutArtifact() = default; PutArtifact() = default;

View File

@@ -102,14 +102,12 @@ struct DLL_LINKAGE BattleResultAccepted : public CPackForClient
BattleID battleID = BattleID::NONE; BattleID battleID = BattleID::NONE;
BattleSideArray<HeroBattleResults> heroResult; BattleSideArray<HeroBattleResults> heroResult;
BattleSide winnerSide; BattleSide winnerSide;
std::vector<BulkMoveArtifacts> artifacts;
template <typename Handler> void serialize(Handler & h) template <typename Handler> void serialize(Handler & h)
{ {
h & battleID; h & battleID;
h & heroResult; h & heroResult;
h & winnerSide; h & winnerSide;
h & artifacts;
assert(battleID != BattleID::NONE); assert(battleID != BattleID::NONE);
} }
}; };
@@ -387,7 +385,8 @@ struct DLL_LINKAGE BattleResultsApplied : public CPackForClient
PlayerColor victor; PlayerColor victor;
PlayerColor loser; PlayerColor loser;
ChangeSpells learnedSpells; ChangeSpells learnedSpells;
std::vector<BulkMoveArtifacts> artifacts; std::vector<BulkMoveArtifacts> movingArtifacts;
std::vector<GrowUpArtifact> growingArtifacts;
CStackBasicDescriptor raisedStack; CStackBasicDescriptor raisedStack;
void visitTyped(ICPackVisitor & visitor) override; void visitTyped(ICPackVisitor & visitor) override;
@@ -397,7 +396,8 @@ struct DLL_LINKAGE BattleResultsApplied : public CPackForClient
h & victor; h & victor;
h & loser; h & loser;
h & learnedSpells; h & learnedSpells;
h & artifacts; h & movingArtifacts;
h & growingArtifacts;
h & raisedStack; h & raisedStack;
assert(battleID != BattleID::NONE); assert(battleID != BattleID::NONE);
} }

View File

@@ -219,6 +219,7 @@ void registerTypes(Serializer &s)
s.template registerType<SwapStacks>(165); s.template registerType<SwapStacks>(165);
s.template registerType<InsertNewStack>(166); s.template registerType<InsertNewStack>(166);
s.template registerType<RebalanceStacks>(167); s.template registerType<RebalanceStacks>(167);
s.template registerType<GrowUpArtifact>(168);
s.template registerType<PutArtifact>(169); s.template registerType<PutArtifact>(169);
s.template registerType<BulkEraseArtifacts>(170); s.template registerType<BulkEraseArtifacts>(170);
s.template registerType<AssembledArtifact>(171); s.template registerType<AssembledArtifact>(171);

View File

@@ -22,6 +22,7 @@
#include "../../lib/IGameSettings.h" #include "../../lib/IGameSettings.h"
#include "../../lib/battle/SideInBattle.h" #include "../../lib/battle/SideInBattle.h"
#include "../../lib/entities/artifact/ArtifactUtils.h" #include "../../lib/entities/artifact/ArtifactUtils.h"
#include "../../lib/entities/artifact/CArtifact.h"
#include "../../lib/entities/artifact/CArtifactFittingSet.h" #include "../../lib/entities/artifact/CArtifactFittingSet.h"
#include "../../lib/gameState/CGameState.h" #include "../../lib/gameState/CGameState.h"
#include "../../lib/mapObjects/CGTownInstance.h" #include "../../lib/mapObjects/CGTownInstance.h"
@@ -427,7 +428,7 @@ void BattleResultProcessor::battleFinalize(const BattleID & battleID, const Batt
} }
} }
// Artifacts handling // Moving artifacts handling
if(result.result == EBattleResult::NORMAL && !finishingBattle->isDraw() && winnerHero) if(result.result == EBattleResult::NORMAL && !finishingBattle->isDraw() && winnerHero)
{ {
CArtifactFittingSet artFittingSet(*winnerHero); CArtifactFittingSet artFittingSet(*winnerHero);
@@ -446,7 +447,7 @@ void BattleResultProcessor::battleFinalize(const BattleID & battleID, const Batt
if(loserHero) if(loserHero)
{ {
auto & packHero = resultsApplied.artifacts.emplace_back(finishingBattle->victor, finishingBattle->loserId, finishingBattle->winnerId, false); auto & packHero = resultsApplied.movingArtifacts.emplace_back(finishingBattle->victor, finishingBattle->loserId, finishingBattle->winnerId, false);
packHero.srcArtHolder = finishingBattle->loserId; packHero.srcArtHolder = finishingBattle->loserId;
for(const auto & slot : ArtifactUtils::commonWornSlots()) for(const auto & slot : ArtifactUtils::commonWornSlots())
{ {
@@ -463,7 +464,7 @@ void BattleResultProcessor::battleFinalize(const BattleID & battleID, const Batt
if(loserHero->getCommander()) if(loserHero->getCommander())
{ {
auto & packCommander = resultsApplied.artifacts.emplace_back(finishingBattle->victor, finishingBattle->loserId, finishingBattle->winnerId, false); auto & packCommander = resultsApplied.movingArtifacts.emplace_back(finishingBattle->victor, finishingBattle->loserId, finishingBattle->winnerId, false);
packCommander.srcCreature = loserHero->findStack(loserHero->getCommander()); packCommander.srcCreature = loserHero->findStack(loserHero->getCommander());
for(const auto & artSlot : loserHero->getCommander()->artifactsWorn) for(const auto & artSlot : loserHero->getCommander()->artifactsWorn)
addArtifactToTransfer(packCommander, artSlot.first, artSlot.second.getArt()); addArtifactToTransfer(packCommander, artSlot.first, artSlot.second.getArt());
@@ -471,7 +472,7 @@ void BattleResultProcessor::battleFinalize(const BattleID & battleID, const Batt
auto armyObj = dynamic_cast<const CArmedInstance*>(gameHandler->getObj(finishingBattle->loserId)); auto armyObj = dynamic_cast<const CArmedInstance*>(gameHandler->getObj(finishingBattle->loserId));
for(const auto & armySlot : armyObj->stacks) for(const auto & armySlot : armyObj->stacks)
{ {
auto & packsArmy = resultsApplied.artifacts.emplace_back(finishingBattle->victor, finishingBattle->loserId, finishingBattle->winnerId, false); auto & packsArmy = resultsApplied.movingArtifacts.emplace_back(finishingBattle->victor, finishingBattle->loserId, finishingBattle->winnerId, false);
packsArmy.srcArtHolder = armyObj->id; packsArmy.srcArtHolder = armyObj->id;
packsArmy.srcCreature = armySlot.first; packsArmy.srcCreature = armySlot.first;
for(const auto & artSlot : armySlot.second->artifactsWorn) for(const auto & artSlot : armySlot.second->artifactsWorn)
@@ -480,6 +481,25 @@ void BattleResultProcessor::battleFinalize(const BattleID & battleID, const Batt
} }
} }
// Growing artifacts handling
if(!finishingBattle->isDraw() && winnerHero)
{
const auto addArtifactToGrowing = [&resultsApplied](const std::map<ArtifactPosition, ArtSlotInfo> & artMap)
{
for(const auto & [slot, slotInfo] : artMap)
{
const auto artInst = slotInfo.getArt();
assert(artInst);
if(artInst->getType()->isGrowing())
resultsApplied.growingArtifacts.emplace_back(artInst->getId());
}
};
if(const auto commander = winnerHero->getCommander(); commander && commander->alive)
addArtifactToGrowing(commander->artifactsWorn);
addArtifactToGrowing(winnerHero->artifactsWorn);
}
// Necromancy handling // Necromancy handling
// Give raised units to winner, if any were raised, units will be given after casualties are taken // Give raised units to winner, if any were raised, units will be given after casualties are taken
if(winnerHero) if(winnerHero)