1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-28 08:48:48 +02:00
vcmi/client/widgets/CExchangeController.cpp
2023-09-19 16:04:37 +03:00

120 lines
3.2 KiB
C++

/*
* CExchangeController.cpp, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#include "StdInc.h"
#include "CExchangeController.h"
#include "../CPlayerInterface.h"
#include "../widgets/CGarrisonInt.h"
#include "../../CCallback.h"
#include "../lib/mapObjects/CGHeroInstance.h"
CExchangeController::CExchangeController(ObjectInstanceID hero1, ObjectInstanceID hero2)
: left(LOCPLINT->cb->getHero(hero1))
, right(LOCPLINT->cb->getHero(hero2))
{
}
void CExchangeController::swapArmy()
{
auto getStacks = [](const CArmedInstance * source) -> std::vector<std::pair<SlotID, CStackInstance*>>
{
auto slots = source->Slots();
return std::vector<std::pair<SlotID, CStackInstance*>>(slots.begin(), slots.end());
};
auto leftSlots = getStacks(left);
auto rightSlots = getStacks(right);
auto i = leftSlots.begin(), j = rightSlots.begin();
for(; i != leftSlots.end() && j != rightSlots.end(); i++, j++)
{
LOCPLINT->cb->swapCreatures(left, right, i->first, j->first);
}
if(i != leftSlots.end())
{
auto freeSlots = right->getFreeSlots();
auto slot = freeSlots.begin();
for(; i != leftSlots.end() && slot != freeSlots.end(); i++, slot++)
{
LOCPLINT->cb->swapCreatures(left, right, i->first, *slot);
}
}
else if(j != rightSlots.end())
{
auto freeSlots = left->getFreeSlots();
auto slot = freeSlots.begin();
for(; j != rightSlots.end() && slot != freeSlots.end(); j++, slot++)
{
LOCPLINT->cb->swapCreatures(left, right, *slot, j->first);
}
}
}
void CExchangeController::moveArmy(bool leftToRight, std::optional<SlotID> heldSlot)
{
const auto source = leftToRight ? left : right;
const auto target = leftToRight ? right : left;
if(!heldSlot.has_value())
{
auto weakestSlot = vstd::minElementByFun(source->Slots(),
[](const std::pair<SlotID, CStackInstance*> & s) -> int
{
return s.second->getCreatureID().toCreature()->getAIValue();
});
heldSlot = weakestSlot->first;
}
LOCPLINT->cb->bulkMoveArmy(source->id, target->id, heldSlot.value());
}
void CExchangeController::moveStack(bool leftToRight, SlotID sourceSlot)
{
const auto source = leftToRight ? left : right;
const auto target = leftToRight ? right : left;
auto creature = source->getCreature(sourceSlot);
if(creature == nullptr)
return;
SlotID targetSlot = target->getSlotFor(creature);
if(targetSlot.validSlot())
{
if(source->stacksCount() == 1 && source->needsLastStack())
{
LOCPLINT->cb->splitStack(source, target, sourceSlot, targetSlot,
target->getStackCount(targetSlot) + source->getStackCount(sourceSlot) - 1);
}
else
{
LOCPLINT->cb->mergeOrSwapStacks(source, target, sourceSlot, targetSlot);
}
}
}
void CExchangeController::swapArtifacts(bool equipped, bool baclpack)
{
LOCPLINT->cb->bulkMoveArtifacts(left->id, right->id, true, equipped, baclpack);
}
void CExchangeController::moveArtifacts(bool leftToRight, bool equipped, bool baclpack)
{
const auto source = leftToRight ? left : right;
const auto target = leftToRight ? right : left;
LOCPLINT->cb->bulkMoveArtifacts(source->id, target->id, false, equipped, baclpack);
}