1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-28 23:06:24 +02:00

Artifact assembling changes

This commit is contained in:
SoundSSGood 2023-09-12 18:30:48 +03:00
parent 7f321b2fcb
commit 82eb2f8a2b
10 changed files with 74 additions and 65 deletions

View File

@ -264,7 +264,7 @@ bool ArtifactUtilsClient::askToAssemble(const CGHeroInstance * hero, const Artif
if(hero->tempOwner != LOCPLINT->playerID)
return false;
auto assemblyPossibilities = ArtifactUtils::assemblyPossibilities(hero, art->getTypeId(), ArtifactUtils::isSlotEquipment(slot));
auto assemblyPossibilities = ArtifactUtils::assemblyPossibilities(hero, art->getTypeId());
if(!assemblyPossibilities.empty())
{
auto askThread = new boost::thread([hero, art, slot, assemblyPossibilities]() -> void

View File

@ -261,8 +261,10 @@ void CArtifactsOfHeroBase::setSlotData(ArtPlacePtr artPlace, const ArtifactPosit
{
arts.insert(std::pair(combinedArt, 0));
for(const auto part : combinedArt->getConstituents())
if(artSet.hasArt(part->getId(), true))
{
if(artSet.hasArt(part->getId(), false))
arts.at(combinedArt)++;
}
}
artPlace->addCombinedArtInfo(arts);
}

View File

@ -244,7 +244,7 @@ void CWindowWithArtifacts::rightClickArtPlaceHero(CArtifactsOfHeroBase & artsIns
void CWindowWithArtifacts::artifactRemoved(const ArtifactLocation & artLoc)
{
updateSlots(artLoc.slot);
updateSlots();
}
void CWindowWithArtifacts::artifactMoved(const ArtifactLocation & srcLoc, const ArtifactLocation & destLoc, bool withRedraw)
@ -310,26 +310,23 @@ void CWindowWithArtifacts::artifactMoved(const ArtifactLocation & srcLoc, const
void CWindowWithArtifacts::artifactDisassembled(const ArtifactLocation & artLoc)
{
updateSlots(artLoc.slot);
updateSlots();
}
void CWindowWithArtifacts::artifactAssembled(const ArtifactLocation & artLoc)
{
markPossibleSlots();
updateSlots(artLoc.slot);
updateSlots();
}
void CWindowWithArtifacts::updateSlots(const ArtifactPosition & slot)
void CWindowWithArtifacts::updateSlots()
{
auto updateSlotBody = [slot](auto artSetWeak) -> void
auto updateSlotBody = [](auto artSetWeak) -> void
{
if(const auto artSetPtr = artSetWeak.lock())
{
if(ArtifactUtils::isSlotEquipment(slot))
artSetPtr->updateWornSlots();
else if(ArtifactUtils::isSlotBackpack(slot))
artSetPtr->updateBackpackSlots();
artSetPtr->updateWornSlots();
artSetPtr->updateBackpackSlots();
artSetPtr->redraw();
}
};

View File

@ -43,7 +43,7 @@ private:
std::vector<CArtifactsOfHeroPtr> artSets;
CloseCallback closeCallback;
void updateSlots(const ArtifactPosition & slot);
void updateSlots();
std::optional<std::tuple<const CGHeroInstance*, const CArtifactInstance*>> getState();
std::optional<CArtifactsOfHeroPtr> findAOHbyRef(CArtifactsOfHeroBase & artsInst);
void markPossibleSlots();

View File

@ -116,7 +116,7 @@ DLL_LINKAGE bool ArtifactUtils::isBackpackFreeSlots(const CArtifactSet * target,
}
DLL_LINKAGE std::vector<const CArtifact*> ArtifactUtils::assemblyPossibilities(
const CArtifactSet * artSet, const ArtifactID & aid, bool equipped)
const CArtifactSet * artSet, const ArtifactID & aid)
{
std::vector<const CArtifact*> arts;
const auto * art = aid.toArtifact();
@ -130,23 +130,10 @@ DLL_LINKAGE std::vector<const CArtifact*> ArtifactUtils::assemblyPossibilities(
for(const auto constituent : artifact->getConstituents()) //check if all constituents are available
{
if(equipped)
if(!artSet->hasArt(constituent->getId(), false, false, false))
{
// Search for equipped arts
if(!artSet->hasArt(constituent->getId(), true, false, false))
{
possible = false;
break;
}
}
else
{
// Search in backpack
if(!artSet->hasArtBackpack(constituent->getId()))
{
possible = false;
break;
}
possible = false;
break;
}
}
if(possible)

View File

@ -36,7 +36,7 @@ namespace ArtifactUtils
DLL_LINKAGE bool isSlotBackpack(const ArtifactPosition & slot);
DLL_LINKAGE bool isSlotEquipment(const ArtifactPosition & slot);
DLL_LINKAGE bool isBackpackFreeSlots(const CArtifactSet * target, const size_t reqSlots = 1);
DLL_LINKAGE std::vector<const CArtifact*> assemblyPossibilities(const CArtifactSet * artSet, const ArtifactID & aid, bool equipped);
DLL_LINKAGE std::vector<const CArtifact*> assemblyPossibilities(const CArtifactSet * artSet, const ArtifactID & aid);
DLL_LINKAGE CArtifactInstance * createScroll(const SpellID & sid);
DLL_LINKAGE CArtifactInstance * createNewArtifactInstance(CArtifact * art);
DLL_LINKAGE CArtifactInstance * createNewArtifactInstance(const ArtifactID & aid);

View File

@ -820,12 +820,6 @@ ArtifactPosition CArtifactSet::getArtPos(const ArtifactID & aid, bool onlyWorn,
return result.empty() ? ArtifactPosition{ArtifactPosition::PRE_FIRST} : result[0];
}
ArtifactPosition CArtifactSet::getArtBackpackPos(const ArtifactID & aid) const
{
const auto result = getBackpackArtPositions(aid);
return result.empty() ? ArtifactPosition{ArtifactPosition::PRE_FIRST} : result[0];
}
std::vector<ArtifactPosition> CArtifactSet::getAllArtPositions(const ArtifactID & aid, bool onlyWorn, bool allowLocked, bool getAll) const
{
std::vector<ArtifactPosition> result;

View File

@ -260,7 +260,6 @@ public:
/// (if more than one such artifact lower ID is returned)
ArtifactPosition getArtPos(const ArtifactID & aid, bool onlyWorn = true, bool allowLocked = true) const;
ArtifactPosition getArtPos(const CArtifactInstance *art) const;
ArtifactPosition getArtBackpackPos(const ArtifactID & aid) const;
std::vector<ArtifactPosition> getAllArtPositions(const ArtifactID & aid, bool onlyWorn, bool allowLocked, bool getAll) const;
std::vector<ArtifactPosition> getBackpackArtPositions(const ArtifactID & aid) const;
const CArtifactInstance * getArtByInstanceId(const ArtifactInstanceID & artInstId) const;

View File

@ -1907,43 +1907,69 @@ void BulkMoveArtifacts::applyGs(CGameState * gs)
void AssembledArtifact::applyGs(CGameState *gs)
{
CArtifactSet * artSet = al.getHolderArtSet();
[[maybe_unused]] const CArtifactInstance *transformedArt = al.getArt();
const CArtifactInstance * transformedArt = al.getArt();
assert(transformedArt);
bool combineEquipped = !ArtifactUtils::isSlotBackpack(al.slot);
assert(vstd::contains_if(ArtifactUtils::assemblyPossibilities(artSet, transformedArt->artType->getId(), combineEquipped), [=](const CArtifact * art)->bool
assert(vstd::contains_if(ArtifactUtils::assemblyPossibilities(artSet, transformedArt->getTypeId()), [=](const CArtifact * art)->bool
{
return art->getId() == builtArt->getId();
}));
const auto transformedArtSlot = artSet->getSlotByInstance(transformedArt);
auto * combinedArt = new CArtifactInstance(builtArt);
gs->map->addNewArtifactInstance(combinedArt);
// Retrieve all constituents
for(const CArtifact * constituent : builtArt->getConstituents())
{
ArtifactPosition pos = combineEquipped ? artSet->getArtPos(constituent->getId(), true, false) :
artSet->getArtBackpackPos(constituent->getId());
assert(pos != ArtifactPosition::PRE_FIRST);
CArtifactInstance * constituentInstance = artSet->getArt(pos);
//move constituent from hero to be part of new, combined artifact
constituentInstance->removeFrom(ArtifactLocation(al.artHolder, pos));
if(combineEquipped)
// Find slots for all involved artifacts
std::vector<ArtifactPosition> slotsInvolved;
for(const auto constituent : builtArt->getConstituents())
{
ArtifactPosition slot;
if(transformedArt->getTypeId() == constituent->getId())
slot = transformedArtSlot;
else
slot = artSet->getArtPos(constituent->getId(), false, false);
assert(slot != ArtifactPosition::PRE_FIRST);
slotsInvolved.emplace_back(slot);
}
std::sort(slotsInvolved.begin(), slotsInvolved.end(), std::greater<>());
// Find a slot for combined artifact
al.slot = transformedArtSlot;
for(const auto slot : slotsInvolved)
{
if(ArtifactUtils::isSlotEquipment(transformedArtSlot))
{
if(ArtifactUtils::isSlotBackpack(slot))
{
al.slot = ArtifactPosition::BACKPACK_START;
break;
}
if(!vstd::contains(combinedArt->artType->getPossibleSlots().at(artSet->bearerType()), al.slot)
&& vstd::contains(combinedArt->artType->getPossibleSlots().at(artSet->bearerType()), pos))
al.slot = pos;
if(al.slot == pos)
pos = ArtifactPosition::PRE_FIRST;
&& vstd::contains(combinedArt->artType->getPossibleSlots().at(artSet->bearerType()), slot))
al.slot = slot;
}
else
{
al.slot = std::min(al.slot, pos);
pos = ArtifactPosition::PRE_FIRST;
if(ArtifactUtils::isSlotBackpack(slot))
al.slot = std::min(al.slot, slot);
}
combinedArt->addPart(constituentInstance, pos);
}
//put new combined artifacts
// Delete parts from hero
for(const auto slot : slotsInvolved)
{
const auto constituentInstance = artSet->getArt(slot);
constituentInstance->removeFrom(ArtifactLocation(al.artHolder, slot));
if(ArtifactUtils::isSlotEquipment(al.slot) && slot != al.slot)
combinedArt->addPart(constituentInstance, slot);
else
combinedArt->addPart(constituentInstance, ArtifactPosition::PRE_FIRST);
}
// Put new combined artifacts
combinedArt->putAt(al);
}

View File

@ -2787,7 +2787,7 @@ bool CGameHandler::bulkMoveArtifacts(ObjectInstanceID srcHero, ObjectInstanceID
* @param assembleTo If assemble is true, this represents the artifact ID of the combination
* artifact to assemble to. Otherwise it's not used.
*/
bool CGameHandler::assembleArtifacts (ObjectInstanceID heroID, ArtifactPosition artifactSlot, bool assemble, ArtifactID assembleTo)
bool CGameHandler::assembleArtifacts(ObjectInstanceID heroID, ArtifactPosition artifactSlot, bool assemble, ArtifactID assembleTo)
{
const CGHeroInstance * hero = getHero(heroID);
const CArtifactInstance * destArtifact = hero->getArt(artifactSlot);
@ -2795,23 +2795,27 @@ bool CGameHandler::assembleArtifacts (ObjectInstanceID heroID, ArtifactPosition
if(!destArtifact)
COMPLAIN_RET("assembleArtifacts: there is no such artifact instance!");
const auto dstLoc = ArtifactLocation(hero, artifactSlot);
if(assemble)
{
CArtifact * combinedArt = VLC->arth->objects[assembleTo];
if(!combinedArt->isCombined())
COMPLAIN_RET("assembleArtifacts: Artifact being attempted to assemble is not a combined artifacts!");
if (!vstd::contains(ArtifactUtils::assemblyPossibilities(hero, destArtifact->getTypeId(),
ArtifactUtils::isSlotEquipment(artifactSlot)), combinedArt))
if(!vstd::contains(ArtifactUtils::assemblyPossibilities(hero, destArtifact->getTypeId()), combinedArt))
{
COMPLAIN_RET("assembleArtifacts: It's impossible to assemble requested artifact!");
}
if(!destArtifact->canBePutAt(dstLoc)
&& !destArtifact->canBePutAt(ArtifactLocation(hero, ArtifactPosition::BACKPACK_START)))
{
COMPLAIN_RET("assembleArtifacts: It's impossible to give the artholder requested artifact!");
}
if(ArtifactUtils::checkSpellbookIsNeeded(hero, assembleTo, artifactSlot))
giveHeroNewArtifact(hero, VLC->arth->objects[ArtifactID::SPELLBOOK], ArtifactPosition::SPELLBOOK);
AssembledArtifact aa;
aa.al = ArtifactLocation(hero, artifactSlot);
aa.al = dstLoc;
aa.builtArt = combinedArt;
sendAndApply(&aa);
}
@ -2825,7 +2829,7 @@ bool CGameHandler::assembleArtifacts (ObjectInstanceID heroID, ArtifactPosition
COMPLAIN_RET("assembleArtifacts: Artifact being attempted to disassemble but backpack is full!");
DisassembledArtifact da;
da.al = ArtifactLocation(hero, artifactSlot);
da.al = dstLoc;
sendAndApply(&da);
}