mirror of
https://github.com/vcmi/vcmi.git
synced 2025-04-25 12:14:46 +02:00
Merge pull request #4766 from SoundSSGood/fused-artifacts
Fused artifacts
This commit is contained in:
commit
c25aef8f48
@ -358,6 +358,7 @@
|
|||||||
"vcmi.heroWindow.sortBackpackBySlot.help" : "Sort artifacts in backpack by equipped slot.",
|
"vcmi.heroWindow.sortBackpackBySlot.help" : "Sort artifacts in backpack by equipped slot.",
|
||||||
"vcmi.heroWindow.sortBackpackByClass.hover" : "Sort by class",
|
"vcmi.heroWindow.sortBackpackByClass.hover" : "Sort by class",
|
||||||
"vcmi.heroWindow.sortBackpackByClass.help" : "Sort artifacts in backpack by artifact class. Treasure, Minor, Major, Relic",
|
"vcmi.heroWindow.sortBackpackByClass.help" : "Sort artifacts in backpack by artifact class. Treasure, Minor, Major, Relic",
|
||||||
|
"vcmi.heroWindow.fusingArtifact.fusing" : "You possess all of the components needed for the fusion of the %s. Do you wish to perform the fusion? {All components will be consumed upon fusion.}",
|
||||||
|
|
||||||
"vcmi.tavernWindow.inviteHero" : "Invite hero",
|
"vcmi.tavernWindow.inviteHero" : "Invite hero",
|
||||||
|
|
||||||
|
@ -74,6 +74,9 @@ bool ArtifactsUIController::askToAssemble(const CGHeroInstance * hero, const Art
|
|||||||
MetaString message = MetaString::createFromTextID(art->artType->getDescriptionTextID());
|
MetaString message = MetaString::createFromTextID(art->artType->getDescriptionTextID());
|
||||||
message.appendEOL();
|
message.appendEOL();
|
||||||
message.appendEOL();
|
message.appendEOL();
|
||||||
|
if(combinedArt->isFused())
|
||||||
|
message.appendRawString(CGI->generaltexth->translate("vcmi.heroWindow.fusingArtifact.fusing"));
|
||||||
|
else
|
||||||
message.appendRawString(CGI->generaltexth->allTexts[732]); // You possess all of the components needed to assemble the
|
message.appendRawString(CGI->generaltexth->allTexts[732]); // You possess all of the components needed to assemble the
|
||||||
message.replaceName(ArtifactID(combinedArt->getId()));
|
message.replaceName(ArtifactID(combinedArt->getId()));
|
||||||
LOCPLINT->showYesNoDialog(message.toString(), [&assembleConfirmed, hero, slot, combinedArt]()
|
LOCPLINT->showYesNoDialog(message.toString(), [&assembleConfirmed, hero, slot, combinedArt]()
|
||||||
@ -102,7 +105,7 @@ bool ArtifactsUIController::askToDisassemble(const CGHeroInstance * hero, const
|
|||||||
if(hero->tempOwner != LOCPLINT->playerID)
|
if(hero->tempOwner != LOCPLINT->playerID)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(art->isCombined())
|
if(art->hasParts())
|
||||||
{
|
{
|
||||||
if(ArtifactUtils::isSlotBackpack(slot) && !ArtifactUtils::isBackpackFreeSlots(hero, art->artType->getConstituents().size() - 1))
|
if(ArtifactUtils::isSlotBackpack(slot) && !ArtifactUtils::isBackpackFreeSlots(hero, art->artType->getConstituents().size() - 1))
|
||||||
return false;
|
return false;
|
||||||
|
@ -217,9 +217,9 @@ void CArtPlace::setGestureCallback(const ClickFunctor & callback)
|
|||||||
|
|
||||||
void CArtPlace::addCombinedArtInfo(const std::map<const ArtifactID, std::vector<ArtifactID>> & arts)
|
void CArtPlace::addCombinedArtInfo(const std::map<const ArtifactID, std::vector<ArtifactID>> & arts)
|
||||||
{
|
{
|
||||||
for(const auto & availableArts : arts)
|
for(auto [combinedId, availableArts] : arts)
|
||||||
{
|
{
|
||||||
const auto combinedArt = availableArts.first.toArtifact();
|
const auto combinedArt = combinedId.toArtifact();
|
||||||
MetaString info;
|
MetaString info;
|
||||||
info.appendEOL();
|
info.appendEOL();
|
||||||
info.appendEOL();
|
info.appendEOL();
|
||||||
@ -227,14 +227,20 @@ void CArtPlace::addCombinedArtInfo(const std::map<const ArtifactID, std::vector<
|
|||||||
info.appendName(combinedArt->getId());
|
info.appendName(combinedArt->getId());
|
||||||
info.appendRawString("}");
|
info.appendRawString("}");
|
||||||
info.appendRawString(" (%d/%d)");
|
info.appendRawString(" (%d/%d)");
|
||||||
info.replaceNumber(availableArts.second.size());
|
info.replaceNumber(availableArts.size());
|
||||||
info.replaceNumber(combinedArt->getConstituents().size());
|
info.replaceNumber(combinedArt->getConstituents().size());
|
||||||
for(const auto part : combinedArt->getConstituents())
|
for(const auto part : combinedArt->getConstituents())
|
||||||
{
|
{
|
||||||
|
const auto found = std::find_if(availableArts.begin(), availableArts.end(), [part](const auto & availablePart) -> bool
|
||||||
|
{
|
||||||
|
return availablePart == part->getId() ? true : false;
|
||||||
|
});
|
||||||
|
|
||||||
info.appendEOL();
|
info.appendEOL();
|
||||||
if(vstd::contains(availableArts.second, part->getId()))
|
if(found < availableArts.end())
|
||||||
{
|
{
|
||||||
info.appendName(part->getId());
|
info.appendName(part->getId());
|
||||||
|
availableArts.erase(found);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -268,11 +268,17 @@ void CArtifactsOfHeroBase::setSlotData(ArtPlacePtr artPlace, const ArtifactPosit
|
|||||||
std::map<const ArtifactID, std::vector<ArtifactID>> arts;
|
std::map<const ArtifactID, std::vector<ArtifactID>> arts;
|
||||||
for(const auto combinedArt : slotInfo->artifact->artType->getPartOf())
|
for(const auto combinedArt : slotInfo->artifact->artType->getPartOf())
|
||||||
{
|
{
|
||||||
arts.try_emplace(combinedArt->getId(), std::vector<ArtifactID>{});
|
assert(combinedArt->isCombined());
|
||||||
|
arts.try_emplace(combinedArt->getId());
|
||||||
|
CArtifactFittingSet fittingSet(*curHero);
|
||||||
for(const auto part : combinedArt->getConstituents())
|
for(const auto part : combinedArt->getConstituents())
|
||||||
{
|
{
|
||||||
if(curHero->hasArt(part->getId(), false, false))
|
const auto partSlot = fittingSet.getArtPos(part->getId(), false, false);
|
||||||
|
if(partSlot != ArtifactPosition::PRE_FIRST)
|
||||||
|
{
|
||||||
arts.at(combinedArt->getId()).emplace_back(part->getId());
|
arts.at(combinedArt->getId()).emplace_back(part->getId());
|
||||||
|
fittingSet.lockSlot(partSlot);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
artPlace->addCombinedArtInfo(arts);
|
artPlace->addCombinedArtInfo(arts);
|
||||||
|
@ -61,6 +61,10 @@
|
|||||||
"description" : "Optional, list of components for combinational artifacts",
|
"description" : "Optional, list of components for combinational artifacts",
|
||||||
"items" : { "type" : "string" }
|
"items" : { "type" : "string" }
|
||||||
},
|
},
|
||||||
|
"fusedComponents" : {
|
||||||
|
"type" : "boolean",
|
||||||
|
"description" : "Used together with components fild. Marks the artifact as fused. Cannot be disassembled."
|
||||||
|
},
|
||||||
"bonuses" : {
|
"bonuses" : {
|
||||||
"type" : "array",
|
"type" : "array",
|
||||||
"description" : "Bonuses provided by this artifact using bonus system",
|
"description" : "Bonuses provided by this artifact using bonus system",
|
||||||
|
@ -68,6 +68,9 @@ In order to make functional artifact you also need:
|
|||||||
"artifact3"
|
"artifact3"
|
||||||
],
|
],
|
||||||
|
|
||||||
|
// Optional, by default is false. Set to true if components are supposed to be fused.
|
||||||
|
"fusedComponents" : true,
|
||||||
|
|
||||||
// Creature id to use on battle field. If set, this artifact is war machine
|
// Creature id to use on battle field. If set, this artifact is war machine
|
||||||
"warMachine" : "some.creature"
|
"warMachine" : "some.creature"
|
||||||
|
|
||||||
|
@ -202,21 +202,23 @@ DLL_LINKAGE std::vector<const CArtifact*> ArtifactUtils::assemblyPossibilities(
|
|||||||
if(art->isCombined())
|
if(art->isCombined())
|
||||||
return arts;
|
return arts;
|
||||||
|
|
||||||
for(const auto artifact : art->getPartOf())
|
for(const auto combinedArt : art->getPartOf())
|
||||||
{
|
{
|
||||||
assert(artifact->isCombined());
|
assert(combinedArt->isCombined());
|
||||||
bool possible = true;
|
bool possible = true;
|
||||||
|
CArtifactFittingSet fittingSet(*artSet);
|
||||||
for(const auto constituent : artifact->getConstituents()) //check if all constituents are available
|
for(const auto part : combinedArt->getConstituents()) // check if all constituents are available
|
||||||
{
|
{
|
||||||
if(!artSet->hasArt(constituent->getId(), onlyEquiped, false))
|
const auto slot = fittingSet.getArtPos(part->getId(), onlyEquiped, false);
|
||||||
|
if(slot == ArtifactPosition::PRE_FIRST)
|
||||||
{
|
{
|
||||||
possible = false;
|
possible = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
fittingSet.lockSlot(slot);
|
||||||
}
|
}
|
||||||
if(possible)
|
if(possible)
|
||||||
arts.push_back(artifact);
|
arts.push_back(combinedArt);
|
||||||
}
|
}
|
||||||
return arts;
|
return arts;
|
||||||
}
|
}
|
||||||
|
@ -56,11 +56,26 @@ const std::vector<const CArtifact*> & CCombinedArtifact::getConstituents() const
|
|||||||
return constituents;
|
return constituents;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<const CArtifact*> & CCombinedArtifact::getPartOf() const
|
const std::set<const CArtifact*> & CCombinedArtifact::getPartOf() const
|
||||||
{
|
{
|
||||||
return partOf;
|
return partOf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CCombinedArtifact::setFused(bool isFused)
|
||||||
|
{
|
||||||
|
fused = isFused;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CCombinedArtifact::isFused() const
|
||||||
|
{
|
||||||
|
return fused;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CCombinedArtifact::hasParts() const
|
||||||
|
{
|
||||||
|
return isCombined() && !isFused();
|
||||||
|
}
|
||||||
|
|
||||||
bool CScrollArtifact::isScroll() const
|
bool CScrollArtifact::isScroll() const
|
||||||
{
|
{
|
||||||
return static_cast<const CArtifact*>(this)->getId() == ArtifactID::SPELL_SCROLL;
|
return static_cast<const CArtifact*>(this)->getId() == ArtifactID::SPELL_SCROLL;
|
||||||
@ -203,7 +218,7 @@ bool CArtifact::canBePutAt(const CArtifactSet * artSet, ArtifactPosition slot, b
|
|||||||
|
|
||||||
auto artCanBePutAt = [this, simpleArtCanBePutAt](const CArtifactSet * artSet, ArtifactPosition slot, bool assumeDestRemoved) -> bool
|
auto artCanBePutAt = [this, simpleArtCanBePutAt](const CArtifactSet * artSet, ArtifactPosition slot, bool assumeDestRemoved) -> bool
|
||||||
{
|
{
|
||||||
if(isCombined())
|
if(hasParts())
|
||||||
{
|
{
|
||||||
if(!simpleArtCanBePutAt(artSet, slot, assumeDestRemoved))
|
if(!simpleArtCanBePutAt(artSet, slot, assumeDestRemoved))
|
||||||
return false;
|
return false;
|
||||||
@ -606,19 +621,21 @@ void CArtHandler::loadType(CArtifact * art, const JsonNode & node) const
|
|||||||
|
|
||||||
void CArtHandler::loadComponents(CArtifact * art, const JsonNode & node)
|
void CArtHandler::loadComponents(CArtifact * art, const JsonNode & node)
|
||||||
{
|
{
|
||||||
if (!node["components"].isNull())
|
if(!node["components"].isNull())
|
||||||
{
|
{
|
||||||
for(const auto & component : node["components"].Vector())
|
for(const auto & component : node["components"].Vector())
|
||||||
{
|
{
|
||||||
VLC->identifiers()->requestIdentifier("artifact", component, [=](si32 id)
|
VLC->identifiers()->requestIdentifier("artifact", component, [this, art](int32_t id)
|
||||||
{
|
{
|
||||||
// when this code is called both combinational art as well as component are loaded
|
// when this code is called both combinational art as well as component are loaded
|
||||||
// so it is safe to access any of them
|
// so it is safe to access any of them
|
||||||
art->constituents.push_back(ArtifactID(id).toArtifact());
|
art->constituents.push_back(ArtifactID(id).toArtifact());
|
||||||
objects[id]->partOf.push_back(art);
|
objects[id]->partOf.insert(art);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(!node["fusedComponents"].isNull())
|
||||||
|
art->setFused(node["fusedComponents"].Bool());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CArtHandler::makeItCreatureArt(CArtifact * a, bool onlyCreature)
|
void CArtHandler::makeItCreatureArt(CArtifact * a, bool onlyCreature)
|
||||||
@ -767,8 +784,27 @@ bool CArtifactSet::hasArt(const ArtifactID & aid, bool onlyWorn, bool searchComb
|
|||||||
CArtifactSet::ArtPlacementMap CArtifactSet::putArtifact(const ArtifactPosition & slot, CArtifactInstance * art)
|
CArtifactSet::ArtPlacementMap CArtifactSet::putArtifact(const ArtifactPosition & slot, CArtifactInstance * art)
|
||||||
{
|
{
|
||||||
ArtPlacementMap resArtPlacement;
|
ArtPlacementMap resArtPlacement;
|
||||||
|
const auto putToSlot = [this](const ArtifactPosition & targetSlot, CArtifactInstance * targetArt, bool locked)
|
||||||
|
{
|
||||||
|
ArtSlotInfo * slotInfo;
|
||||||
|
if(targetSlot == ArtifactPosition::TRANSITION_POS)
|
||||||
|
{
|
||||||
|
slotInfo = &artifactsTransitionPos;
|
||||||
|
}
|
||||||
|
else if(ArtifactUtils::isSlotEquipment(targetSlot))
|
||||||
|
{
|
||||||
|
slotInfo = &artifactsWorn[targetSlot];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto position = artifactsInBackpack.begin() + targetSlot - ArtifactPosition::BACKPACK_START;
|
||||||
|
slotInfo = &(*artifactsInBackpack.emplace(position));
|
||||||
|
}
|
||||||
|
slotInfo->artifact = targetArt;
|
||||||
|
slotInfo->locked = locked;
|
||||||
|
};
|
||||||
|
|
||||||
setNewArtSlot(slot, art, false);
|
putToSlot(slot, art, false);
|
||||||
if(art->artType->isCombined() && ArtifactUtils::isSlotEquipment(slot))
|
if(art->artType->isCombined() && ArtifactUtils::isSlotEquipment(slot))
|
||||||
{
|
{
|
||||||
const CArtifactInstance * mainPart = nullptr;
|
const CArtifactInstance * mainPart = nullptr;
|
||||||
@ -789,7 +825,7 @@ CArtifactSet::ArtPlacementMap CArtifactSet::putArtifact(const ArtifactPosition &
|
|||||||
partSlot = ArtifactUtils::getArtAnyPosition(this, part.art->getTypeId());
|
partSlot = ArtifactUtils::getArtAnyPosition(this, part.art->getTypeId());
|
||||||
|
|
||||||
assert(ArtifactUtils::isSlotEquipment(partSlot));
|
assert(ArtifactUtils::isSlotEquipment(partSlot));
|
||||||
setNewArtSlot(partSlot, part.art, true);
|
putToSlot(partSlot, part.art, true);
|
||||||
resArtPlacement.emplace(part.art, partSlot);
|
resArtPlacement.emplace(part.art, partSlot);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -877,7 +913,15 @@ const ArtSlotInfo * CArtifactSet::getSlot(const ArtifactPosition & pos) const
|
|||||||
|
|
||||||
void CArtifactSet::lockSlot(const ArtifactPosition & pos)
|
void CArtifactSet::lockSlot(const ArtifactPosition & pos)
|
||||||
{
|
{
|
||||||
setNewArtSlot(pos, nullptr, true);
|
if(pos == ArtifactPosition::TRANSITION_POS)
|
||||||
|
artifactsTransitionPos.locked = true;
|
||||||
|
else if(ArtifactUtils::isSlotEquipment(pos))
|
||||||
|
artifactsWorn[pos].locked = true;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert(artifactsInBackpack.size() > pos - ArtifactPosition::BACKPACK_START);
|
||||||
|
(artifactsInBackpack.begin() + pos - ArtifactPosition::BACKPACK_START)->locked = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CArtifactSet::isPositionFree(const ArtifactPosition & pos, bool onlyLockCheck) const
|
bool CArtifactSet::isPositionFree(const ArtifactPosition & pos, bool onlyLockCheck) const
|
||||||
@ -891,28 +935,6 @@ bool CArtifactSet::isPositionFree(const ArtifactPosition & pos, bool onlyLockChe
|
|||||||
return true; //no slot means not used
|
return true; //no slot means not used
|
||||||
}
|
}
|
||||||
|
|
||||||
void CArtifactSet::setNewArtSlot(const ArtifactPosition & slot, CArtifactInstance * art, bool locked)
|
|
||||||
{
|
|
||||||
assert(!vstd::contains(artifactsWorn, slot));
|
|
||||||
|
|
||||||
ArtSlotInfo * slotInfo;
|
|
||||||
if(slot == ArtifactPosition::TRANSITION_POS)
|
|
||||||
{
|
|
||||||
slotInfo = &artifactsTransitionPos;
|
|
||||||
}
|
|
||||||
else if(ArtifactUtils::isSlotEquipment(slot))
|
|
||||||
{
|
|
||||||
slotInfo = &artifactsWorn[slot];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto position = artifactsInBackpack.begin() + slot - ArtifactPosition::BACKPACK_START;
|
|
||||||
slotInfo = &(*artifactsInBackpack.emplace(position));
|
|
||||||
}
|
|
||||||
slotInfo->artifact = art;
|
|
||||||
slotInfo->locked = locked;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CArtifactSet::artDeserializationFix(CBonusSystemNode *node)
|
void CArtifactSet::artDeserializationFix(CBonusSystemNode *node)
|
||||||
{
|
{
|
||||||
for(auto & elem : artifactsWorn)
|
for(auto & elem : artifactsWorn)
|
||||||
|
@ -46,14 +46,19 @@ namespace ArtBearer
|
|||||||
class DLL_LINKAGE CCombinedArtifact
|
class DLL_LINKAGE CCombinedArtifact
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
CCombinedArtifact() = default;
|
CCombinedArtifact() : fused(false) {};
|
||||||
|
|
||||||
std::vector<const CArtifact*> constituents; // Artifacts IDs a combined artifact consists of, or nullptr.
|
std::vector<const CArtifact*> constituents; // Artifacts IDs a combined artifact consists of, or nullptr.
|
||||||
std::vector<const CArtifact*> partOf; // Reverse map of constituents - combined arts that include this art
|
std::set<const CArtifact*> partOf; // Reverse map of constituents - combined arts that include this art
|
||||||
|
bool fused;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool isCombined() const;
|
bool isCombined() const;
|
||||||
const std::vector<const CArtifact*> & getConstituents() const;
|
const std::vector<const CArtifact*> & getConstituents() const;
|
||||||
const std::vector<const CArtifact*> & getPartOf() const;
|
const std::set<const CArtifact*> & getPartOf() const;
|
||||||
|
void setFused(bool isFused);
|
||||||
|
bool isFused() const;
|
||||||
|
bool hasParts() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_LINKAGE CScrollArtifact
|
class DLL_LINKAGE CScrollArtifact
|
||||||
@ -224,8 +229,6 @@ public:
|
|||||||
const CArtifactInstance * getCombinedArtWithPart(const ArtifactID & partId) const;
|
const CArtifactInstance * getCombinedArtWithPart(const ArtifactID & partId) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setNewArtSlot(const ArtifactPosition & slot, CArtifactInstance * art, bool locked);
|
|
||||||
|
|
||||||
void serializeJsonHero(JsonSerializeFormat & handler);
|
void serializeJsonHero(JsonSerializeFormat & handler);
|
||||||
void serializeJsonCreature(JsonSerializeFormat & handler);
|
void serializeJsonCreature(JsonSerializeFormat & handler);
|
||||||
void serializeJsonCommander(JsonSerializeFormat & handler);
|
void serializeJsonCommander(JsonSerializeFormat & handler);
|
||||||
|
@ -44,6 +44,11 @@ bool CCombinedArtifactInstance::isPart(const CArtifactInstance * supposedPart) c
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CCombinedArtifactInstance::hasParts() const
|
||||||
|
{
|
||||||
|
return !partsInfo.empty();
|
||||||
|
}
|
||||||
|
|
||||||
const std::vector<CCombinedArtifactInstance::PartInfo> & CCombinedArtifactInstance::getPartsInfo() const
|
const std::vector<CCombinedArtifactInstance::PartInfo> & CCombinedArtifactInstance::getPartsInfo() const
|
||||||
{
|
{
|
||||||
return partsInfo;
|
return partsInfo;
|
||||||
|
@ -38,6 +38,7 @@ public:
|
|||||||
void addPart(CArtifactInstance * art, const ArtifactPosition & slot);
|
void addPart(CArtifactInstance * art, const ArtifactPosition & slot);
|
||||||
// Checks if supposed part inst is part of this combined art inst
|
// Checks if supposed part inst is part of this combined art inst
|
||||||
bool isPart(const CArtifactInstance * supposedPart) const;
|
bool isPart(const CArtifactInstance * supposedPart) const;
|
||||||
|
bool hasParts() const;
|
||||||
const std::vector<PartInfo> & getPartsInfo() const;
|
const std::vector<PartInfo> & getPartsInfo() const;
|
||||||
void addPlacementMap(const CArtifactSet::ArtPlacementMap & placementMap);
|
void addPlacementMap(const CArtifactSet::ArtPlacementMap & placementMap);
|
||||||
|
|
||||||
|
@ -1805,6 +1805,7 @@ void AssembledArtifact::applyGs(CGameState *gs)
|
|||||||
assert(hero);
|
assert(hero);
|
||||||
const auto transformedArt = hero->getArt(al.slot);
|
const auto transformedArt = hero->getArt(al.slot);
|
||||||
assert(transformedArt);
|
assert(transformedArt);
|
||||||
|
const auto builtArt = artId.toArtifact();
|
||||||
assert(vstd::contains_if(ArtifactUtils::assemblyPossibilities(hero, transformedArt->getTypeId()), [=](const CArtifact * art)->bool
|
assert(vstd::contains_if(ArtifactUtils::assemblyPossibilities(hero, transformedArt->getTypeId()), [=](const CArtifact * art)->bool
|
||||||
{
|
{
|
||||||
return art->getId() == builtArt->getId();
|
return art->getId() == builtArt->getId();
|
||||||
@ -1816,14 +1817,11 @@ void AssembledArtifact::applyGs(CGameState *gs)
|
|||||||
|
|
||||||
// Find slots for all involved artifacts
|
// Find slots for all involved artifacts
|
||||||
std::vector<ArtifactPosition> slotsInvolved;
|
std::vector<ArtifactPosition> slotsInvolved;
|
||||||
|
CArtifactFittingSet artSet(*hero);
|
||||||
for(const auto constituent : builtArt->getConstituents())
|
for(const auto constituent : builtArt->getConstituents())
|
||||||
{
|
{
|
||||||
ArtifactPosition slot;
|
const auto slot = artSet.getArtPos(constituent->getId(), false, false);
|
||||||
if(transformedArt->getTypeId() == constituent->getId())
|
artSet.lockSlot(slot);
|
||||||
slot = transformedArtSlot;
|
|
||||||
else
|
|
||||||
slot = hero->getArtPos(constituent->getId(), false, false);
|
|
||||||
|
|
||||||
assert(slot != ArtifactPosition::PRE_FIRST);
|
assert(slot != ArtifactPosition::PRE_FIRST);
|
||||||
slotsInvolved.emplace_back(slot);
|
slotsInvolved.emplace_back(slot);
|
||||||
}
|
}
|
||||||
@ -1831,7 +1829,7 @@ void AssembledArtifact::applyGs(CGameState *gs)
|
|||||||
|
|
||||||
// Find a slot for combined artifact
|
// Find a slot for combined artifact
|
||||||
al.slot = transformedArtSlot;
|
al.slot = transformedArtSlot;
|
||||||
for(const auto slot : slotsInvolved)
|
for(const auto & slot : slotsInvolved)
|
||||||
{
|
{
|
||||||
if(ArtifactUtils::isSlotEquipment(transformedArtSlot))
|
if(ArtifactUtils::isSlotEquipment(transformedArtSlot))
|
||||||
{
|
{
|
||||||
@ -1854,16 +1852,19 @@ void AssembledArtifact::applyGs(CGameState *gs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Delete parts from hero
|
// Delete parts from hero
|
||||||
for(const auto slot : slotsInvolved)
|
for(const auto & slot : slotsInvolved)
|
||||||
{
|
{
|
||||||
const auto constituentInstance = hero->getArt(slot);
|
const auto constituentInstance = hero->getArt(slot);
|
||||||
gs->map->removeArtifactInstance(*hero, slot);
|
gs->map->removeArtifactInstance(*hero, slot);
|
||||||
|
|
||||||
|
if(!combinedArt->artType->isFused())
|
||||||
|
{
|
||||||
if(ArtifactUtils::isSlotEquipment(al.slot) && slot != al.slot)
|
if(ArtifactUtils::isSlotEquipment(al.slot) && slot != al.slot)
|
||||||
combinedArt->addPart(constituentInstance, slot);
|
combinedArt->addPart(constituentInstance, slot);
|
||||||
else
|
else
|
||||||
combinedArt->addPart(constituentInstance, ArtifactPosition::PRE_FIRST);
|
combinedArt->addPart(constituentInstance, ArtifactPosition::PRE_FIRST);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Put new combined artifacts
|
// Put new combined artifacts
|
||||||
gs->map->putArtifactInstance(*hero, combinedArt, al.slot);
|
gs->map->putArtifactInstance(*hero, combinedArt, al.slot);
|
||||||
@ -2482,10 +2483,7 @@ void SetBankConfiguration::applyGs(CGameState *gs)
|
|||||||
const CArtifactInstance * ArtSlotInfo::getArt() const
|
const CArtifactInstance * ArtSlotInfo::getArt() const
|
||||||
{
|
{
|
||||||
if(locked)
|
if(locked)
|
||||||
{
|
|
||||||
logNetwork->warn("ArtifactLocation::getArt: This location is locked!");
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
|
||||||
return artifact;
|
return artifact;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1108,8 +1108,8 @@ struct DLL_LINKAGE BulkMoveArtifacts : CArtifactOperationPack
|
|||||||
|
|
||||||
struct DLL_LINKAGE AssembledArtifact : CArtifactOperationPack
|
struct DLL_LINKAGE AssembledArtifact : CArtifactOperationPack
|
||||||
{
|
{
|
||||||
ArtifactLocation al; //where assembly will be put
|
ArtifactLocation al;
|
||||||
const CArtifact * builtArt;
|
ArtifactID artId;
|
||||||
|
|
||||||
void applyGs(CGameState * gs) override;
|
void applyGs(CGameState * gs) override;
|
||||||
|
|
||||||
@ -1118,7 +1118,7 @@ struct DLL_LINKAGE AssembledArtifact : CArtifactOperationPack
|
|||||||
template <typename Handler> void serialize(Handler & h)
|
template <typename Handler> void serialize(Handler & h)
|
||||||
{
|
{
|
||||||
h & al;
|
h & al;
|
||||||
h & builtArt;
|
h & artId;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2913,7 +2913,7 @@ bool CGameHandler::assembleArtifacts(ObjectInstanceID heroID, ArtifactPosition a
|
|||||||
|
|
||||||
AssembledArtifact aa;
|
AssembledArtifact aa;
|
||||||
aa.al = dstLoc;
|
aa.al = dstLoc;
|
||||||
aa.builtArt = combinedArt;
|
aa.artId = assembleTo;
|
||||||
sendAndApply(aa);
|
sendAndApply(aa);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -2921,6 +2921,9 @@ bool CGameHandler::assembleArtifacts(ObjectInstanceID heroID, ArtifactPosition a
|
|||||||
if(!destArtifact->isCombined())
|
if(!destArtifact->isCombined())
|
||||||
COMPLAIN_RET("assembleArtifacts: Artifact being attempted to disassemble is not a combined artifact!");
|
COMPLAIN_RET("assembleArtifacts: Artifact being attempted to disassemble is not a combined artifact!");
|
||||||
|
|
||||||
|
if(!destArtifact->hasParts())
|
||||||
|
COMPLAIN_RET("assembleArtifacts: Artifact being attempted to disassemble is fused combined artifact!");
|
||||||
|
|
||||||
if(ArtifactUtils::isSlotBackpack(artifactSlot)
|
if(ArtifactUtils::isSlotBackpack(artifactSlot)
|
||||||
&& !ArtifactUtils::isBackpackFreeSlots(hero, destArtifact->artType->getConstituents().size() - 1))
|
&& !ArtifactUtils::isBackpackFreeSlots(hero, destArtifact->artType->getConstituents().size() - 1))
|
||||||
COMPLAIN_RET("assembleArtifacts: Artifact being attempted to disassemble but backpack is full!");
|
COMPLAIN_RET("assembleArtifacts: Artifact being attempted to disassemble but backpack is full!");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user