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:
parent
7f321b2fcb
commit
82eb2f8a2b
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
};
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user