1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-06 09:09:40 +02:00

Merge pull request #5720 from SoundSSGood/artifact-charges

Charged artifacts
This commit is contained in:
Ivan Savenko
2025-05-21 13:49:14 +03:00
committed by GitHub
28 changed files with 480 additions and 57 deletions

View File

@@ -22,6 +22,7 @@
#include "../../lib/IGameSettings.h"
#include "../../lib/battle/SideInBattle.h"
#include "../../lib/entities/artifact/ArtifactUtils.h"
#include "../../lib/entities/artifact/CArtifact.h"
#include "../../lib/entities/artifact/CArtifactFittingSet.h"
#include "../../lib/gameState/CGameState.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)
{
CArtifactFittingSet artFittingSet(*winnerHero);
@@ -446,7 +447,7 @@ void BattleResultProcessor::battleFinalize(const BattleID & battleID, const Batt
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;
for(const auto & slot : ArtifactUtils::commonWornSlots())
{
@@ -463,7 +464,7 @@ void BattleResultProcessor::battleFinalize(const BattleID & battleID, const Batt
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());
for(const auto & artSlot : loserHero->getCommander()->artifactsWorn)
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));
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.srcCreature = armySlot.first;
for(const auto & artSlot : armySlot.second->artifactsWorn)
@@ -480,6 +481,53 @@ 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);
}
// Charged artifacts handling
const auto addArtifactToDischarging = [&resultsApplied](const std::map<ArtifactPosition, ArtSlotInfo> & artMap,
const ObjectInstanceID & id, const std::optional<SlotID> & creature = std::nullopt)
{
for(const auto & [slot, slotInfo] : artMap)
{
auto artInst = slotInfo.getArt();
assert(artInst);
if(const auto condition = artInst->getType()->getDischargeCondition(); condition == DischargeArtifactCondition::BATTLE)
{
auto & discharging = resultsApplied.dischargingArtifacts.emplace_back(artInst->getId(), 1);
discharging.artLoc.emplace(id, creature, slot);
}
}
};
if(winnerHero)
{
addArtifactToDischarging(winnerHero->artifactsWorn, winnerHero->id);
if(const auto commander = winnerHero->getCommander())
addArtifactToDischarging(commander->artifactsWorn, winnerHero->id, winnerHero->findStack(winnerHero->getCommander()));
}
if(loserHero)
{
addArtifactToDischarging(loserHero->artifactsWorn, loserHero->id);
if(const auto commander = loserHero->getCommander())
addArtifactToDischarging(commander->artifactsWorn, loserHero->id, loserHero->findStack(loserHero->getCommander()));
}
// Necromancy handling
// Give raised units to winner, if any were raised, units will be given after casualties are taken
if(winnerHero)