1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-07-17 01:32:21 +02:00

Merge pull request #4028 from SoundSSGood/artifacts-parts-calc

Parts calculation for combined artifacts
This commit is contained in:
Ivan Savenko
2024-05-28 16:48:01 +03:00
committed by GitHub
8 changed files with 60 additions and 43 deletions

View File

@ -140,11 +140,6 @@ void CCommanderArtPlace::showPopupWindow(const Point & cursorPosition)
CArtPlace::showPopupWindow(cursorPosition); CArtPlace::showPopupWindow(cursorPosition);
} }
CHeroArtPlace::CHeroArtPlace(Point position, const CArtifactInstance * art)
: CArtPlace(position, art)
{
}
void CArtPlace::lockSlot(bool on) void CArtPlace::lockSlot(bool on)
{ {
if(locked == on) if(locked == on)
@ -219,20 +214,35 @@ void CArtPlace::setGestureCallback(const ClickFunctor & callback)
gestureCallback = callback; gestureCallback = callback;
} }
void CHeroArtPlace::addCombinedArtInfo(const std::map<const CArtifact*, int> & arts) void CArtPlace::addCombinedArtInfo(const std::map<const ArtifactID, std::vector<ArtifactID>> & arts)
{ {
for(const auto & combinedArt : arts) for(const auto & availableArts : arts)
{ {
std::string artList; const auto combinedArt = availableArts.first.toArtifact();
text += "\n\n"; MetaString info;
text += "{" + combinedArt.first->getNameTranslated() + "}"; info.appendEOL();
if(arts.size() == 1) info.appendEOL();
info.appendRawString("{");
info.appendName(combinedArt->getId());
info.appendRawString("}");
info.appendRawString(" (%d/%d)");
info.replaceNumber(availableArts.second.size());
info.replaceNumber(combinedArt->getConstituents().size());
for(const auto part : combinedArt->getConstituents())
{ {
for(const auto part : combinedArt.first->getConstituents()) info.appendEOL();
artList += "\n" + part->getNameTranslated(); if(vstd::contains(availableArts.second, part->getId()))
{
info.appendName(part->getId());
}
else
{
info.appendRawString("{#A9A9A9|");
info.appendName(part->getId());
info.appendRawString("}");
}
} }
text += " (" + boost::str(boost::format("%d") % combinedArt.second) + " / " + text += info.toString();
boost::str(boost::format("%d") % combinedArt.first->getConstituents().size()) + ")" + artList;
} }
} }

View File

@ -31,6 +31,7 @@ public:
void clickPressed(const Point & cursorPosition) override; void clickPressed(const Point & cursorPosition) override;
void showPopupWindow(const Point & cursorPosition) override; void showPopupWindow(const Point & cursorPosition) override;
void gesture(bool on, const Point & initialPosition, const Point & finalPosition) override; void gesture(bool on, const Point & initialPosition, const Point & finalPosition) override;
void addCombinedArtInfo(const std::map<const ArtifactID, std::vector<ArtifactID>> & arts);
private: private:
const CArtifactInstance * ourArt; const CArtifactInstance * ourArt;
@ -59,13 +60,6 @@ public:
void showPopupWindow(const Point & cursorPosition) override; void showPopupWindow(const Point & cursorPosition) override;
}; };
class CHeroArtPlace: public CArtPlace
{
public:
CHeroArtPlace(Point position, const CArtifactInstance * art = nullptr);
void addCombinedArtInfo(const std::map<const CArtifact*, int> & arts);
};
namespace ArtifactUtilsClient namespace ArtifactUtilsClient
{ {
bool askToAssemble(const CGHeroInstance * hero, const ArtifactPosition & slot); bool askToAssemble(const CGHeroInstance * hero, const ArtifactPosition & slot);

View File

@ -82,7 +82,7 @@ void CArtifactsOfHeroBackpack::initAOHbackpack(size_t slots, bool slider)
const auto pos = Point(slotSizeWithMargin * (artPlaceIdx % slotsColumnsMax), const auto pos = Point(slotSizeWithMargin * (artPlaceIdx % slotsColumnsMax),
slotSizeWithMargin * (artPlaceIdx / slotsColumnsMax)); slotSizeWithMargin * (artPlaceIdx / slotsColumnsMax));
backpackSlotsBackgrounds.emplace_back(std::make_shared<CPicture>(ImagePath::builtin("heroWindow/artifactSlotEmpty"), pos)); backpackSlotsBackgrounds.emplace_back(std::make_shared<CPicture>(ImagePath::builtin("heroWindow/artifactSlotEmpty"), pos));
artPlace = std::make_shared<CHeroArtPlace>(pos); artPlace = std::make_shared<CArtPlace>(pos);
artPlace->setArtifact(nullptr); artPlace->setArtifact(nullptr);
artPlace->setClickPressedCallback(std::bind(&CArtifactsOfHeroBase::clickPrassedArtPlace, this, _1, _2)); artPlace->setClickPressedCallback(std::bind(&CArtifactsOfHeroBase::clickPrassedArtPlace, this, _1, _2));
artPlace->setShowPopupCallback(std::bind(&CArtifactsOfHeroBase::showPopupArtPlace, this, _1, _2)); artPlace->setShowPopupCallback(std::bind(&CArtifactsOfHeroBase::showPopupArtPlace, this, _1, _2));

View File

@ -57,12 +57,12 @@ void CArtifactsOfHeroBase::init(
pos += position; pos += position;
for(int g = 0; g < ArtifactPosition::BACKPACK_START; g++) for(int g = 0; g < ArtifactPosition::BACKPACK_START; g++)
{ {
artWorn[ArtifactPosition(g)] = std::make_shared<CHeroArtPlace>(slotPos[g]); artWorn[ArtifactPosition(g)] = std::make_shared<CArtPlace>(slotPos[g]);
} }
backpack.clear(); backpack.clear();
for(int s = 0; s < 5; s++) for(int s = 0; s < 5; s++)
{ {
auto artPlace = std::make_shared<CHeroArtPlace>(Point(403 + 46 * s, 365)); auto artPlace = std::make_shared<CArtPlace>(Point(403 + 46 * s, 365));
backpack.push_back(artPlace); backpack.push_back(artPlace);
} }
for(auto artPlace : artWorn) for(auto artPlace : artWorn)
@ -224,21 +224,21 @@ void CArtifactsOfHeroBase::setSlotData(ArtPlacePtr artPlace, const ArtifactPosit
{ {
artPlace->lockSlot(slotInfo->locked); artPlace->lockSlot(slotInfo->locked);
artPlace->setArtifact(slotInfo->artifact); artPlace->setArtifact(slotInfo->artifact);
if(!slotInfo->artifact->isCombined()) if(slotInfo->locked || slotInfo->artifact->isCombined())
return;
// If the artifact is part of at least one combined artifact, add additional information
std::map<const ArtifactID, std::vector<ArtifactID>> arts;
for(const auto combinedArt : slotInfo->artifact->artType->getPartOf())
{ {
// If the artifact is part of at least one combined artifact, add additional information arts.try_emplace(combinedArt->getId(), std::vector<ArtifactID>{});
std::map<const CArtifact*, int> arts; for(const auto part : combinedArt->getConstituents())
for(const auto combinedArt : slotInfo->artifact->artType->getPartOf())
{ {
arts.insert(std::pair(combinedArt, 0)); if(curHero->hasArt(part->getId(), false, false, false))
for(const auto part : combinedArt->getConstituents()) arts.at(combinedArt->getId()).emplace_back(part->getId());
{
if(curHero->hasArt(part->getId(), false))
arts.at(combinedArt)++;
}
} }
artPlace->addCombinedArtInfo(arts);
} }
artPlace->addCombinedArtInfo(arts);
} }
else else
{ {

View File

@ -16,7 +16,7 @@ class CButton;
class CArtifactsOfHeroBase : virtual public CIntObject class CArtifactsOfHeroBase : virtual public CIntObject
{ {
protected: protected:
using ArtPlacePtr = std::shared_ptr<CHeroArtPlace>; using ArtPlacePtr = std::shared_ptr<CArtPlace>;
using BpackScrollFunctor = std::function<void(int)>; using BpackScrollFunctor = std::function<void(int)>;
public: public:
@ -62,7 +62,7 @@ protected:
Point(381,295) //18 Point(381,295) //18
}; };
virtual void init(const CHeroArtPlace::ClickFunctor & lClickCallback, const CHeroArtPlace::ClickFunctor & showPopupCallback, virtual void init(const CArtPlace::ClickFunctor & lClickCallback, const CArtPlace::ClickFunctor & showPopupCallback,
const Point & position, const BpackScrollFunctor & scrollCallback); const Point & position, const BpackScrollFunctor & scrollCallback);
// Assigns an artifacts to an artifact place depending on it's new slot ID // Assigns an artifacts to an artifact place depending on it's new slot ID
virtual void setSlotData(ArtPlacePtr artPlace, const ArtifactPosition & slot); virtual void setSlotData(ArtPlacePtr artPlace, const ArtifactPosition & slot);

View File

@ -866,7 +866,7 @@ class ArtSlotsTab : public CIntObject
{ {
public: public:
std::shared_ptr<CAnimImage> background; std::shared_ptr<CAnimImage> background;
std::vector<std::shared_ptr<CHeroArtPlace>> arts; std::vector<std::shared_ptr<CArtPlace>> arts;
ArtSlotsTab() ArtSlotsTab()
{ {
@ -874,7 +874,7 @@ public:
background = std::make_shared<CAnimImage>(AnimationPath::builtin("OVSLOT"), 4); background = std::make_shared<CAnimImage>(AnimationPath::builtin("OVSLOT"), 4);
pos = background->pos; pos = background->pos;
for(int i=0; i<9; i++) for(int i=0; i<9; i++)
arts.push_back(std::make_shared<CHeroArtPlace>(Point(269+i*48, 66))); arts.push_back(std::make_shared<CArtPlace>(Point(269+i*48, 66)));
} }
}; };
@ -882,7 +882,7 @@ class BackpackTab : public CIntObject
{ {
public: public:
std::shared_ptr<CAnimImage> background; std::shared_ptr<CAnimImage> background;
std::vector<std::shared_ptr<CHeroArtPlace>> arts; std::vector<std::shared_ptr<CArtPlace>> arts;
std::shared_ptr<CButton> btnLeft; std::shared_ptr<CButton> btnLeft;
std::shared_ptr<CButton> btnRight; std::shared_ptr<CButton> btnRight;
@ -894,7 +894,7 @@ public:
btnLeft = std::make_shared<CButton>(Point(269, 66), AnimationPath::builtin("HSBTNS3"), CButton::tooltip(), 0); btnLeft = std::make_shared<CButton>(Point(269, 66), AnimationPath::builtin("HSBTNS3"), CButton::tooltip(), 0);
btnRight = std::make_shared<CButton>(Point(675, 66), AnimationPath::builtin("HSBTNS5"), CButton::tooltip(), 0); btnRight = std::make_shared<CButton>(Point(675, 66), AnimationPath::builtin("HSBTNS5"), CButton::tooltip(), 0);
for(int i=0; i<8; i++) for(int i=0; i<8; i++)
arts.push_back(std::make_shared<CHeroArtPlace>(Point(294+i*48, 66))); arts.push_back(std::make_shared<CArtPlace>(Point(294+i*48, 66)));
} }
}; };

View File

@ -64,6 +64,11 @@ void MetaString::appendNumber(int64_t value)
numbers.push_back(value); numbers.push_back(value);
} }
void MetaString::appendEOL()
{
message.push_back(EMessage::APPEND_EOL);
}
void MetaString::replaceLocalString(EMetaText type, ui32 serial) void MetaString::replaceLocalString(EMetaText type, ui32 serial)
{ {
message.push_back(EMessage::REPLACE_LOCAL_STRING); message.push_back(EMessage::REPLACE_LOCAL_STRING);
@ -155,6 +160,9 @@ DLL_LINKAGE std::string MetaString::toString() const
case EMessage::APPEND_NUMBER: case EMessage::APPEND_NUMBER:
dst += std::to_string(numbers.at(nums++)); dst += std::to_string(numbers.at(nums++));
break; break;
case EMessage::APPEND_EOL:
dst += '\n';
break;
case EMessage::REPLACE_RAW_STRING: case EMessage::REPLACE_RAW_STRING:
boost::replace_first(dst, "%s", exactStrings.at(exSt++)); boost::replace_first(dst, "%s", exactStrings.at(exSt++));
break; break;
@ -220,6 +228,9 @@ DLL_LINKAGE std::string MetaString::buildList() const
case EMessage::APPEND_NUMBER: case EMessage::APPEND_NUMBER:
lista += std::to_string(numbers.at(nums++)); lista += std::to_string(numbers.at(nums++));
break; break;
case EMessage::APPEND_EOL:
lista += '\n';
break;
case EMessage::REPLACE_RAW_STRING: case EMessage::REPLACE_RAW_STRING:
lista.replace(lista.find("%s"), 2, exactStrings.at(exSt++)); lista.replace(lista.find("%s"), 2, exactStrings.at(exSt++));
break; break;

View File

@ -48,7 +48,8 @@ private:
REPLACE_LOCAL_STRING, REPLACE_LOCAL_STRING,
REPLACE_TEXTID_STRING, REPLACE_TEXTID_STRING,
REPLACE_NUMBER, REPLACE_NUMBER,
REPLACE_POSITIVE_NUMBER REPLACE_POSITIVE_NUMBER,
APPEND_EOL
}; };
std::vector<EMessage> message; std::vector<EMessage> message;
@ -81,6 +82,7 @@ public:
void appendName(const CreatureID & id, TQuantity count); void appendName(const CreatureID & id, TQuantity count);
void appendNameSingular(const CreatureID & id); void appendNameSingular(const CreatureID & id);
void appendNamePlural(const CreatureID & id); void appendNamePlural(const CreatureID & id);
void appendEOL();
/// Replaces first '%s' placeholder in string with specified local string /// Replaces first '%s' placeholder in string with specified local string
void replaceLocalString(EMetaText type, ui32 serial); void replaceLocalString(EMetaText type, ui32 serial);