mirror of
https://github.com/vcmi/vcmi.git
synced 2025-07-17 01:32:21 +02:00
arts refactoring part1
This commit is contained in:
@ -101,7 +101,7 @@ boost::optional<int> MapObjectsEvaluator::getObjectValue(const CGObjectInstance
|
|||||||
else if(obj->ID == Obj::SPELL_SCROLL)
|
else if(obj->ID == Obj::SPELL_SCROLL)
|
||||||
{
|
{
|
||||||
auto scrollObject = dynamic_cast<const CGArtifact *>(obj);
|
auto scrollObject = dynamic_cast<const CGArtifact *>(obj);
|
||||||
auto spell = scrollObject->storedArtifact->getGivenSpellID().toSpell();
|
auto spell = scrollObject->storedArtifact->getScrollSpellID().toSpell();
|
||||||
if(spell)
|
if(spell)
|
||||||
{
|
{
|
||||||
switch(spell->getLevel())
|
switch(spell->getLevel())
|
||||||
@ -116,7 +116,7 @@ boost::optional<int> MapObjectsEvaluator::getObjectValue(const CGObjectInstance
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
logAi->warn("AI found spell scroll with invalid spell ID: %s", scrollObject->storedArtifact->getGivenSpellID());
|
logAi->warn("AI found spell scroll with invalid spell ID: %s", scrollObject->storedArtifact->getScrollSpellID());
|
||||||
}
|
}
|
||||||
|
|
||||||
return getObjectValue(obj->ID, obj->subID);
|
return getObjectValue(obj->ID, obj->subID);
|
||||||
|
@ -200,7 +200,7 @@ bool CHeroArtPlace::askToAssemble(const CGHeroInstance * hero, ArtifactPosition
|
|||||||
assert(hero);
|
assert(hero);
|
||||||
const auto art = hero->getArt(slot);
|
const auto art = hero->getArt(slot);
|
||||||
assert(art);
|
assert(art);
|
||||||
auto assemblyPossibilities = art->assemblyPossibilities(hero, ArtifactUtils::isSlotEquipment(slot));
|
auto assemblyPossibilities = ArtifactUtils::assemblyPossibilities(hero, art->getTypeId(), ArtifactUtils::isSlotEquipment(slot));
|
||||||
|
|
||||||
// If the artifact can be assembled, display dialog.
|
// If the artifact can be assembled, display dialog.
|
||||||
for(const auto * combination : assemblyPossibilities)
|
for(const auto * combination : assemblyPossibilities)
|
||||||
@ -359,11 +359,32 @@ void CHeroArtPlace::setArtifact(const CArtifactInstance *art)
|
|||||||
image->enable();
|
image->enable();
|
||||||
image->setFrame(locked ? ArtifactID::ART_LOCK : art->artType->getIconIndex());
|
image->setFrame(locked ? ArtifactID::ART_LOCK : art->artType->getIconIndex());
|
||||||
|
|
||||||
text = art->getEffectiveDescription(ourOwner->curHero);
|
text = art->getDescription();
|
||||||
|
|
||||||
|
// Display info about set
|
||||||
|
if(ourOwner && ourOwner->curHero && !art->canBeDisassembled())
|
||||||
|
{
|
||||||
|
for(const auto combinedArt : art->artType->constituentOf)
|
||||||
|
{
|
||||||
|
std::string artList;
|
||||||
|
text += "\n\n";
|
||||||
|
text += "{" + combinedArt->getNameTranslated() + "}";
|
||||||
|
int wornArtifacts = 0;
|
||||||
|
for(const auto part : *combinedArt->constituents)
|
||||||
|
{
|
||||||
|
if(art->artType->constituentOf.size() <= 1)
|
||||||
|
artList += "\n" + part->getNameTranslated();
|
||||||
|
if(ourOwner->curHero->hasArt(part->getId(), true))
|
||||||
|
wornArtifacts++;
|
||||||
|
}
|
||||||
|
text += " (" + boost::str(boost::format("%d") % wornArtifacts) + " / " +
|
||||||
|
boost::str(boost::format("%d") % combinedArt->constituents->size()) + ")" + artList;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(art->artType->getId() == ArtifactID::SPELL_SCROLL)
|
if(art->artType->getId() == ArtifactID::SPELL_SCROLL)
|
||||||
{
|
{
|
||||||
int spellID = art->getGivenSpellID();
|
int spellID = art->getScrollSpellID();
|
||||||
if(spellID >= 0)
|
if(spellID >= 0)
|
||||||
{
|
{
|
||||||
//add spell component info (used to provide a pic in r-click popup)
|
//add spell component info (used to provide a pic in r-click popup)
|
||||||
@ -1039,11 +1060,11 @@ void CCommanderArtPlace::setArtifact(const CArtifactInstance * art)
|
|||||||
image->enable();
|
image->enable();
|
||||||
image->setFrame(art->artType->getIconIndex());
|
image->setFrame(art->artType->getIconIndex());
|
||||||
|
|
||||||
text = art->getEffectiveDescription();
|
text = art->getDescription();
|
||||||
|
|
||||||
if (art->artType->getId() == ArtifactID::SPELL_SCROLL)
|
if (art->artType->getId() == ArtifactID::SPELL_SCROLL)
|
||||||
{
|
{
|
||||||
int spellID = art->getGivenSpellID();
|
int spellID = art->getScrollSpellID();
|
||||||
if (spellID >= 0)
|
if (spellID >= 0)
|
||||||
{
|
{
|
||||||
//add spell component info (used to provide a pic in r-click popup)
|
//add spell component info (used to provide a pic in r-click popup)
|
||||||
|
@ -176,7 +176,7 @@ std::string CComponent::getDescription()
|
|||||||
{
|
{
|
||||||
art.reset(CArtifactInstance::createScroll(SpellID(val)));
|
art.reset(CArtifactInstance::createScroll(SpellID(val)));
|
||||||
}
|
}
|
||||||
return art->getEffectiveDescription();
|
return art->getDescription();
|
||||||
}
|
}
|
||||||
case experience: return CGI->generaltexth->allTexts[241];
|
case experience: return CGI->generaltexth->allTexts[241];
|
||||||
case spell: return (*CGI->spellh)[subtype]->getDescriptionTranslated(val);
|
case spell: return (*CGI->spellh)[subtype]->getDescriptionTranslated(val);
|
||||||
|
@ -837,7 +837,7 @@ void CArtifactInstance::init()
|
|||||||
setNodeType(ARTIFACT_INSTANCE);
|
setNodeType(ARTIFACT_INSTANCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CArtifactInstance::getEffectiveDescription(const CGHeroInstance * hero) const
|
std::string CArtifactInstance::getDescription() const
|
||||||
{
|
{
|
||||||
std::string text = artType->getDescriptionTranslated();
|
std::string text = artType->getDescriptionTranslated();
|
||||||
if (!vstd::contains(text, '{'))
|
if (!vstd::contains(text, '{'))
|
||||||
@ -848,7 +848,7 @@ std::string CArtifactInstance::getEffectiveDescription(const CGHeroInstance * he
|
|||||||
// we expect scroll description to be like this: This scroll contains the [spell name] spell which is added into your spell book for as long as you carry the scroll.
|
// we expect scroll description to be like this: This scroll contains the [spell name] spell which is added into your spell book for as long as you carry the scroll.
|
||||||
// so we want to replace text in [...] with a spell name
|
// so we want to replace text in [...] with a spell name
|
||||||
// however other language versions don't have name placeholder at all, so we have to be careful
|
// however other language versions don't have name placeholder at all, so we have to be careful
|
||||||
SpellID spellID = getGivenSpellID();
|
SpellID spellID = getScrollSpellID();
|
||||||
size_t nameStart = text.find_first_of('[');
|
size_t nameStart = text.find_first_of('[');
|
||||||
size_t nameEnd = text.find_first_of(']', nameStart);
|
size_t nameEnd = text.find_first_of(']', nameStart);
|
||||||
if(spellID.getNum() >= 0)
|
if(spellID.getNum() >= 0)
|
||||||
@ -857,24 +857,6 @@ std::string CArtifactInstance::getEffectiveDescription(const CGHeroInstance * he
|
|||||||
text = text.replace(nameStart, nameEnd - nameStart + 1, spellID.toSpell(VLC->spells())->getNameTranslated());
|
text = text.replace(nameStart, nameEnd - nameStart + 1, spellID.toSpell(VLC->spells())->getNameTranslated());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(hero && !artType->constituentOf.empty()) //display info about set
|
|
||||||
{
|
|
||||||
std::string artList;
|
|
||||||
auto * combinedArt = artType->constituentOf[0];
|
|
||||||
text += "\n\n";
|
|
||||||
text += "{" + combinedArt->getNameTranslated() + "}";
|
|
||||||
int wornArtifacts = 0;
|
|
||||||
for(auto * a : *combinedArt->constituents) //TODO: can the artifact be a part of more than one set?
|
|
||||||
{
|
|
||||||
artList += "\n" + a->getNameTranslated();
|
|
||||||
if (hero->hasArt(a->getId(), true))
|
|
||||||
wornArtifacts++;
|
|
||||||
}
|
|
||||||
text += " (" + boost::str(boost::format("%d") % wornArtifacts) + " / " +
|
|
||||||
boost::str(boost::format("%d") % combinedArt->constituents->size()) + ")" + artList;
|
|
||||||
//TODO: fancy colors and fonts for this text
|
|
||||||
}
|
|
||||||
|
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -910,46 +892,6 @@ bool CArtifactInstance::canBeDisassembled() const
|
|||||||
return artType->canBeDisassembled();
|
return artType->canBeDisassembled();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<const CArtifact *> CArtifactInstance::assemblyPossibilities(const CArtifactSet * h, bool equipped) const
|
|
||||||
{
|
|
||||||
std::vector<const CArtifact *> ret;
|
|
||||||
if(artType->constituents) //combined artifact already: no combining of combined artifacts... for now.
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
for(const auto * artifact : artType->constituentOf)
|
|
||||||
{
|
|
||||||
assert(artifact->constituents);
|
|
||||||
bool possible = true;
|
|
||||||
|
|
||||||
for(const auto * constituent : *artifact->constituents) //check if all constituents are available
|
|
||||||
{
|
|
||||||
if(equipped)
|
|
||||||
{
|
|
||||||
// Search for equipped arts
|
|
||||||
if (!h->hasArt(constituent->getId(), true, false, false))
|
|
||||||
{
|
|
||||||
possible = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Search in backpack
|
|
||||||
if(!h->hasArtBackpack(constituent->getId()))
|
|
||||||
{
|
|
||||||
possible = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(possible)
|
|
||||||
ret.push_back(artifact);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CArtifactInstance::move(const ArtifactLocation & src, const ArtifactLocation & dst)
|
void CArtifactInstance::move(const ArtifactLocation & src, const ArtifactLocation & dst)
|
||||||
{
|
{
|
||||||
removeFrom(src);
|
removeFrom(src);
|
||||||
@ -1022,7 +964,7 @@ void CArtifactInstance::deserializationFix()
|
|||||||
setType(artType);
|
setType(artType);
|
||||||
}
|
}
|
||||||
|
|
||||||
SpellID CArtifactInstance::getGivenSpellID() const
|
SpellID CArtifactInstance::getScrollSpellID() const
|
||||||
{
|
{
|
||||||
const auto b = getBonusLocalFirst(Selector::type()(Bonus::SPELL));
|
const auto b = getBonusLocalFirst(Selector::type()(Bonus::SPELL));
|
||||||
if(!b)
|
if(!b)
|
||||||
@ -1654,4 +1596,44 @@ DLL_LINKAGE bool ArtifactUtils::isBackpackFreeSlots(const CArtifactSet * target,
|
|||||||
return target->artifactsInBackpack.size() + reqSlots <= backpackCap;
|
return target->artifactsInBackpack.size() + reqSlots <= backpackCap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DLL_LINKAGE std::vector<const CArtifact*> ArtifactUtils::assemblyPossibilities(
|
||||||
|
const CArtifactSet * artSet, const ArtifactID & aid, bool equipped)
|
||||||
|
{
|
||||||
|
std::vector<const CArtifact*> arts;
|
||||||
|
const auto * art = aid.toArtifact();
|
||||||
|
if(art->canBeDisassembled())
|
||||||
|
return arts;
|
||||||
|
|
||||||
|
for(const auto artifact : art->constituentOf)
|
||||||
|
{
|
||||||
|
assert(artifact->constituents);
|
||||||
|
bool possible = true;
|
||||||
|
|
||||||
|
for(const auto constituent : *artifact->constituents) //check if all constituents are available
|
||||||
|
{
|
||||||
|
if(equipped)
|
||||||
|
{
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(possible)
|
||||||
|
arts.push_back(artifact);
|
||||||
|
}
|
||||||
|
return arts;
|
||||||
|
}
|
||||||
|
|
||||||
VCMI_LIB_NAMESPACE_END
|
VCMI_LIB_NAMESPACE_END
|
||||||
|
@ -153,8 +153,8 @@ public:
|
|||||||
void deserializationFix();
|
void deserializationFix();
|
||||||
void setType(CArtifact *Art);
|
void setType(CArtifact *Art);
|
||||||
|
|
||||||
std::string getEffectiveDescription(const CGHeroInstance *hero = nullptr) const;
|
std::string getDescription() const;
|
||||||
SpellID getGivenSpellID() const; //to be used with scrolls (and similar arts), -1 if none
|
SpellID getScrollSpellID() const; //to be used with scrolls (and similar arts), -1 if none
|
||||||
|
|
||||||
ArtifactID getTypeId() const;
|
ArtifactID getTypeId() const;
|
||||||
bool canBePutAt(const ArtifactLocation & al, bool assumeDestRemoved = false) const; //forwards to the above one
|
bool canBePutAt(const ArtifactLocation & al, bool assumeDestRemoved = false) const; //forwards to the above one
|
||||||
@ -165,7 +165,6 @@ public:
|
|||||||
/// of itself, additionally truth is returned for constituents of combined arts
|
/// of itself, additionally truth is returned for constituents of combined arts
|
||||||
virtual bool isPart(const CArtifactInstance *supposedPart) const;
|
virtual bool isPart(const CArtifactInstance *supposedPart) const;
|
||||||
|
|
||||||
std::vector<const CArtifact *> assemblyPossibilities(const CArtifactSet * h, bool equipped) const;
|
|
||||||
void move(const ArtifactLocation & src,const ArtifactLocation & dst);
|
void move(const ArtifactLocation & src,const ArtifactLocation & dst);
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
@ -390,6 +389,7 @@ namespace ArtifactUtils
|
|||||||
DLL_LINKAGE bool isSlotBackpack(const ArtifactPosition & slot);
|
DLL_LINKAGE bool isSlotBackpack(const ArtifactPosition & slot);
|
||||||
DLL_LINKAGE bool isSlotEquipment(const ArtifactPosition & slot);
|
DLL_LINKAGE bool isSlotEquipment(const ArtifactPosition & slot);
|
||||||
DLL_LINKAGE bool isBackpackFreeSlots(const CArtifactSet * target, const size_t reqSlots = 1);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
VCMI_LIB_NAMESPACE_END
|
VCMI_LIB_NAMESPACE_END
|
||||||
|
@ -1316,7 +1316,7 @@ void CGArtifact::onHeroVisit(const CGHeroInstance * h) const
|
|||||||
break;
|
break;
|
||||||
case Obj::SPELL_SCROLL:
|
case Obj::SPELL_SCROLL:
|
||||||
{
|
{
|
||||||
int spellID = storedArtifact->getGivenSpellID();
|
int spellID = storedArtifact->getScrollSpellID();
|
||||||
iw.components.emplace_back(Component::EComponentType::SPELL, spellID, 0, 0);
|
iw.components.emplace_back(Component::EComponentType::SPELL, spellID, 0, 0);
|
||||||
if(message.length())
|
if(message.length())
|
||||||
iw.text << message;
|
iw.text << message;
|
||||||
|
@ -280,7 +280,7 @@ void Inspector::updateProperties(CGArtifact * o)
|
|||||||
CArtifactInstance * instance = o->storedArtifact;
|
CArtifactInstance * instance = o->storedArtifact;
|
||||||
if(instance)
|
if(instance)
|
||||||
{
|
{
|
||||||
SpellID spellId = instance->getGivenSpellID();
|
SpellID spellId = instance->getScrollSpellID();
|
||||||
if(spellId != -1)
|
if(spellId != -1)
|
||||||
{
|
{
|
||||||
auto * delegate = new InspectorDelegate;
|
auto * delegate = new InspectorDelegate;
|
||||||
|
@ -730,7 +730,7 @@ void CGameHandler::endBattleConfirm(const BattleInfo * battleInfo)
|
|||||||
{
|
{
|
||||||
iw.components.emplace_back(
|
iw.components.emplace_back(
|
||||||
Component::EComponentType::ARTIFACT, art->artType->getId(),
|
Component::EComponentType::ARTIFACT, art->artType->getId(),
|
||||||
art->artType->getId() == ArtifactID::SPELL_SCROLL? art->getGivenSpellID() : 0, 0);
|
art->artType->getId() == ArtifactID::SPELL_SCROLL? art->getScrollSpellID() : 0, 0);
|
||||||
if (iw.components.size() >= 14)
|
if (iw.components.size() >= 14)
|
||||||
{
|
{
|
||||||
sendAndApply(&iw);
|
sendAndApply(&iw);
|
||||||
@ -4057,8 +4057,11 @@ bool CGameHandler::assembleArtifacts (ObjectInstanceID heroID, ArtifactPosition
|
|||||||
CArtifact * combinedArt = VLC->arth->objects[assembleTo];
|
CArtifact * combinedArt = VLC->arth->objects[assembleTo];
|
||||||
if(!combinedArt->constituents)
|
if(!combinedArt->constituents)
|
||||||
COMPLAIN_RET("assembleArtifacts: Artifact being attempted to assemble is not a combined artifacts!");
|
COMPLAIN_RET("assembleArtifacts: Artifact being attempted to assemble is not a combined artifacts!");
|
||||||
if(!vstd::contains(destArtifact->assemblyPossibilities(hero, ArtifactUtils::isSlotEquipment(artifactSlot)), combinedArt))
|
if (!vstd::contains(ArtifactUtils::assemblyPossibilities(hero, destArtifact->getTypeId(),
|
||||||
|
ArtifactUtils::isSlotEquipment(artifactSlot)), combinedArt))
|
||||||
|
{
|
||||||
COMPLAIN_RET("assembleArtifacts: It's impossible to assemble requested artifact!");
|
COMPLAIN_RET("assembleArtifacts: It's impossible to assemble requested artifact!");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if(ArtifactUtils::checkSpellbookIsNeeded(hero, assembleTo, artifactSlot))
|
if(ArtifactUtils::checkSpellbookIsNeeded(hero, assembleTo, artifactSlot))
|
||||||
|
Reference in New Issue
Block a user