mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-27 22:49:25 +02:00
Sort backpack artifacts in both directions
This commit is contained in:
@@ -2729,29 +2729,59 @@ bool CGameHandler::manageBackpackArtifacts(const PlayerColor & player, const Obj
|
|||||||
const auto * artSet = gameState().getArtSet(heroID);
|
const auto * artSet = gameState().getArtSet(heroID);
|
||||||
COMPLAIN_RET_FALSE_IF(artSet == nullptr, "manageBackpackArtifacts: wrong hero's ID");
|
COMPLAIN_RET_FALSE_IF(artSet == nullptr, "manageBackpackArtifacts: wrong hero's ID");
|
||||||
|
|
||||||
|
auto isSortableCmd = [](const ManageBackpackArtifacts::ManageCmd & cmd)
|
||||||
|
{
|
||||||
|
using MC = ManageBackpackArtifacts::ManageCmd;
|
||||||
|
return cmd == MC::SORT_BY_SLOT || cmd == MC::SORT_BY_COST || cmd == MC::SORT_BY_CLASS;
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::map<ObjectInstanceID, std::pair<ManageBackpackArtifacts::ManageCmd, bool>> lastSort;
|
||||||
|
bool descending = false;
|
||||||
|
if(isSortableCmd(sortType))
|
||||||
|
{
|
||||||
|
auto it = lastSort.find(heroID);
|
||||||
|
if(it != lastSort.end() && it->second.first == sortType)
|
||||||
|
descending = !it->second.second;
|
||||||
|
else
|
||||||
|
descending = false;
|
||||||
|
|
||||||
|
lastSort[heroID] = { sortType, descending };
|
||||||
|
}
|
||||||
|
|
||||||
BulkMoveArtifacts bma(player, heroID, heroID, false);
|
BulkMoveArtifacts bma(player, heroID, heroID, false);
|
||||||
const auto makeSortBackpackRequest = [artSet, &bma](const std::function<int32_t(const ArtSlotInfo&)> & getSortId)
|
|
||||||
|
const auto makeSortBackpackRequest = [artSet, &bma, descending](const std::function<int32_t(const ArtSlotInfo&)> & getSortId)
|
||||||
{
|
{
|
||||||
std::map<int32_t, std::vector<MoveArtifactInfo>> packsSorted;
|
std::map<int32_t, std::vector<MoveArtifactInfo>> packsSorted;
|
||||||
ArtifactPosition backpackSlot = ArtifactPosition::BACKPACK_START;
|
ArtifactPosition backpackSlot = ArtifactPosition::BACKPACK_START;
|
||||||
|
|
||||||
for(const auto & backpackSlotInfo : artSet->artifactsInBackpack)
|
for(const auto & backpackSlotInfo : artSet->artifactsInBackpack)
|
||||||
packsSorted.try_emplace(getSortId(backpackSlotInfo)).first->second.emplace_back(backpackSlot++, ArtifactPosition::PRE_FIRST);
|
packsSorted.try_emplace(getSortId(backpackSlotInfo)).first->second.emplace_back(backpackSlot++, ArtifactPosition::PRE_FIRST);
|
||||||
|
|
||||||
|
auto sortPack = [artSet](std::vector<MoveArtifactInfo> & pack)
|
||||||
|
{
|
||||||
|
std::sort(pack.begin(), pack.end(), [artSet](const auto & a, const auto & b)
|
||||||
|
{
|
||||||
|
const auto art0 = artSet->getArt(a.srcPos);
|
||||||
|
const auto art1 = artSet->getArt(b.srcPos);
|
||||||
|
if (art0->isScroll() && art1->isScroll())
|
||||||
|
return art0->getScrollSpellID() > art1->getScrollSpellID();
|
||||||
|
return art0->getTypeId().num > art1->getTypeId().num;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
for(auto & [sortId, pack] : packsSorted)
|
for(auto & [sortId, pack] : packsSorted)
|
||||||
{
|
{
|
||||||
// Each pack of artifacts is also sorted by ArtifactID. Scrolls by SpellID
|
(void)sortId;
|
||||||
std::sort(pack.begin(), pack.end(), [artSet](const auto & slots0, const auto & slots1) -> bool
|
sortPack(pack);
|
||||||
{
|
|
||||||
const auto art0 = artSet->getArt(slots0.srcPos);
|
|
||||||
const auto art1 = artSet->getArt(slots1.srcPos);
|
|
||||||
if(art0->isScroll() && art1->isScroll())
|
|
||||||
return art0->getScrollSpellID() > art1->getScrollSpellID();
|
|
||||||
return art0->getTypeId().num > art1->getTypeId().num;
|
|
||||||
});
|
|
||||||
bma.artsPack0.insert(bma.artsPack0.end(), pack.begin(), pack.end());
|
bma.artsPack0.insert(bma.artsPack0.end(), pack.begin(), pack.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(descending)
|
||||||
|
std::reverse(bma.artsPack0.begin(), bma.artsPack0.end());
|
||||||
|
|
||||||
backpackSlot = ArtifactPosition::BACKPACK_START;
|
backpackSlot = ArtifactPosition::BACKPACK_START;
|
||||||
for(auto & slots : bma.artsPack0)
|
for (auto & slots : bma.artsPack0)
|
||||||
slots.dstPos = backpackSlot++;
|
slots.dstPos = backpackSlot++;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2760,15 +2790,15 @@ bool CGameHandler::manageBackpackArtifacts(const PlayerColor & player, const Obj
|
|||||||
makeSortBackpackRequest([](const ArtSlotInfo & inf) -> int32_t
|
makeSortBackpackRequest([](const ArtSlotInfo & inf) -> int32_t
|
||||||
{
|
{
|
||||||
auto possibleSlots = inf.getArt()->getType()->getPossibleSlots();
|
auto possibleSlots = inf.getArt()->getType()->getPossibleSlots();
|
||||||
if (possibleSlots.find(ArtBearer::CREATURE) != possibleSlots.end() && !possibleSlots.at(ArtBearer::CREATURE).empty())
|
if(possibleSlots.find(ArtBearer::CREATURE) != possibleSlots.end() && !possibleSlots.at(ArtBearer::CREATURE).empty())
|
||||||
{
|
{
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
else if (possibleSlots.find(ArtBearer::COMMANDER) != possibleSlots.end() && !possibleSlots.at(ArtBearer::COMMANDER).empty())
|
else if(possibleSlots.find(ArtBearer::COMMANDER) != possibleSlots.end() && !possibleSlots.at(ArtBearer::COMMANDER).empty())
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
else if (possibleSlots.find(ArtBearer::HERO) != possibleSlots.end() && !possibleSlots.at(ArtBearer::HERO).empty())
|
else if(possibleSlots.find(ArtBearer::HERO) != possibleSlots.end() && !possibleSlots.at(ArtBearer::HERO).empty())
|
||||||
{
|
{
|
||||||
return inf.getArt()->getType()->getPossibleSlots().at(ArtBearer::HERO).front().num;
|
return inf.getArt()->getType()->getPossibleSlots().at(ArtBearer::HERO).front().num;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user