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

ArtifactUtils::createArtifact ArtifactUtils::createNewArtifactInstance unified

This commit is contained in:
SoundSSGood 2024-09-04 16:25:30 +03:00
parent b06426ac43
commit 30fa2846aa
8 changed files with 53 additions and 70 deletions

View File

@ -221,52 +221,42 @@ DLL_LINKAGE std::vector<const CArtifact*> ArtifactUtils::assemblyPossibilities(
return arts;
}
DLL_LINKAGE CArtifactInstance * ArtifactUtils::createScroll(const SpellID & sid)
DLL_LINKAGE CArtifactInstance * ArtifactUtils::createScroll(const SpellID & spellId)
{
auto ret = new CArtifactInstance(ArtifactID(ArtifactID::SPELL_SCROLL).toArtifact());
auto bonus = std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::SPELL,
BonusSource::ARTIFACT_INSTANCE, -1, BonusSourceID(ArtifactID(ArtifactID::SPELL_SCROLL)), BonusSubtypeID(sid));
ret->addNewBonus(bonus);
return ret;
return ArtifactUtils::createArtifact(ArtifactID::SPELL_SCROLL, spellId);
}
DLL_LINKAGE CArtifactInstance * ArtifactUtils::createNewArtifactInstance(const CArtifact * art)
DLL_LINKAGE CArtifactInstance * ArtifactUtils::createArtifact(const ArtifactID & artId, const SpellID & spellId)
{
assert(art);
auto * artInst = new CArtifactInstance(art);
if(art->isCombined())
const std::function<CArtifactInstance*(const CArtifact*)> createArtInst =
[&createArtInst, &spellId](const CArtifact * art) -> CArtifactInstance*
{
for(const auto & part : art->getConstituents())
artInst->addPart(ArtifactUtils::createNewArtifactInstance(part), ArtifactPosition::PRE_FIRST);
}
if(art->isGrowing())
{
auto bonus = std::make_shared<Bonus>();
bonus->type = BonusType::LEVEL_COUNTER;
bonus->val = 0;
artInst->addNewBonus(bonus);
}
return artInst;
}
assert(art);
DLL_LINKAGE CArtifactInstance * ArtifactUtils::createNewArtifactInstance(const ArtifactID & aid)
{
return ArtifactUtils::createNewArtifactInstance(aid.toArtifact());
}
DLL_LINKAGE CArtifactInstance * ArtifactUtils::createArtifact(const ArtifactID & aid, SpellID spellID)
{
if(aid.getNum() >= 0)
{
if(spellID == SpellID::NONE)
auto * artInst = new CArtifactInstance(art);
if(art->isCombined())
{
return ArtifactUtils::createNewArtifactInstance(aid);
for(const auto & part : art->getConstituents())
artInst->addPart(createArtInst(part), ArtifactPosition::PRE_FIRST);
}
else
if(art->isGrowing())
{
return ArtifactUtils::createScroll(spellID);
auto bonus = std::make_shared<Bonus>();
bonus->type = BonusType::LEVEL_COUNTER;
bonus->val = 0;
artInst->addNewBonus(bonus);
}
if(art->isScroll())
{
artInst->addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::SPELL,
BonusSource::ARTIFACT_INSTANCE, -1, BonusSourceID(ArtifactID(ArtifactID::SPELL_SCROLL)), BonusSubtypeID(spellId)));
}
return artInst;
};
if(artId.getNum() >= 0)
{
return createArtInst(artId.toArtifact());
}
else
{

View File

@ -39,10 +39,8 @@ namespace ArtifactUtils
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, const bool onlyEquiped = false);
DLL_LINKAGE CArtifactInstance * createScroll(const SpellID & sid);
DLL_LINKAGE CArtifactInstance * createNewArtifactInstance(const CArtifact * art);
DLL_LINKAGE CArtifactInstance * createNewArtifactInstance(const ArtifactID & aid);
DLL_LINKAGE CArtifactInstance * createArtifact(const ArtifactID & aid, SpellID spellID = SpellID::NONE);
DLL_LINKAGE CArtifactInstance * createScroll(const SpellID & spellId);
DLL_LINKAGE CArtifactInstance * createArtifact(const ArtifactID & artId, const SpellID & spellId = SpellID::NONE);
DLL_LINKAGE void insertScrrollSpellName(std::string & description, const SpellID & sid);
}

View File

@ -1628,7 +1628,7 @@ void CGameState::attachArmedObjects()
bool CGameState::giveHeroArtifact(CGHeroInstance * h, const ArtifactID & aid)
{
CArtifactInstance * ai = ArtifactUtils::createNewArtifactInstance(aid);
CArtifactInstance * ai = ArtifactUtils::createArtifact(aid);
map->addNewArtifactInstance(ai);
auto slot = ArtifactUtils::getArtAnyPosition(h, aid);
if(ArtifactUtils::isSlotEquipment(slot) || ArtifactUtils::isSlotBackpack(slot))

View File

@ -343,7 +343,7 @@ void CGHeroInstance::initHero(vstd::RNG & rand)
// hero starts with default spellbook presence status
if(!getArt(ArtifactPosition::SPELLBOOK) && type->haveSpellBook)
{
auto artifact = ArtifactUtils::createNewArtifactInstance(ArtifactID::SPELLBOOK);
auto artifact = ArtifactUtils::createArtifact(ArtifactID::SPELLBOOK);
putArtifact(ArtifactPosition::SPELLBOOK, artifact);
}
}
@ -352,7 +352,7 @@ void CGHeroInstance::initHero(vstd::RNG & rand)
if(!getArt(ArtifactPosition::MACH4))
{
auto artifact = ArtifactUtils::createNewArtifactInstance(ArtifactID::CATAPULT);
auto artifact = ArtifactUtils::createArtifact(ArtifactID::CATAPULT);
putArtifact(ArtifactPosition::MACH4, artifact); //everyone has a catapult
}
@ -468,7 +468,7 @@ void CGHeroInstance::initArmy(vstd::RNG & rand, IArmyDescriptor * dst)
if(!getArt(slot))
{
auto artifact = ArtifactUtils::createNewArtifactInstance(aid);
auto artifact = ArtifactUtils::createArtifact(aid);
putArtifact(slot, artifact);
}
else

View File

@ -1472,17 +1472,11 @@ void NewObject::applyGs(CGameState *gs)
void NewArtifact::applyGs(CGameState *gs)
{
assert(!vstd::contains(gs->map->artInstances, art));
assert(!art->getParentNodes().size());
assert(art->artType);
art->setType(art->artType);
if(art->isCombined())
{
for(const auto & part : art->artType->getConstituents())
art->addPart(ArtifactUtils::createNewArtifactInstance(part), ArtifactPosition::PRE_FIRST);
}
auto art = ArtifactUtils::createArtifact(id);
gs->map->addNewArtifactInstance(art);
PutArtifact pa(ArtifactLocation(artHolder, pos));
pa.art = art;
pa.applyGs(gs);
}
const CStackInstance * StackLocation::getStack()
@ -1700,6 +1694,7 @@ void PutArtifact::applyGs(CGameState *gs)
auto hero = gs->getHero(al.artHolder);
assert(hero);
assert(art && art->canBePutAt(hero, al.slot));
assert(ArtifactUtils::checkIfSlotValid(*hero, al.slot));
art->putAt(*hero, al.slot);
}

View File

@ -987,14 +987,18 @@ struct DLL_LINKAGE PutArtifact : CArtifactOperationPack
struct DLL_LINKAGE NewArtifact : public CArtifactOperationPack
{
ConstTransitivePtr<CArtifactInstance> art;
ObjectInstanceID artHolder;
ArtifactID id;
ArtifactPosition pos;
void applyGs(CGameState * gs) override;
void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler & h)
{
h & art;
h & artHolder;
h & id;
h & pos;
}
};

View File

@ -165,7 +165,7 @@ void MapController::repairMap(CMap * map) const
{
nih->removeSpellFromSpellbook(SpellID::SPELLBOOK_PRESET);
if(!nih->getArt(ArtifactPosition::SPELLBOOK) && type->haveSpellBook)
nih->putArtifact(ArtifactPosition::SPELLBOOK, ArtifactUtils::createNewArtifactInstance(ArtifactID::SPELLBOOK));
nih->putArtifact(ArtifactPosition::SPELLBOOK, ArtifactUtils::createArtifact(ArtifactID::SPELLBOOK));
}
}

View File

@ -3760,9 +3760,15 @@ bool CGameHandler::giveHeroNewArtifact(const CGHeroInstance * h, const CArtifact
{
assert(artType);
NewArtifact na;
na.artHolder = h->id;
na.id = artType->getId();
na.pos = pos;
if(pos == ArtifactPosition::FIRST_AVAILABLE)
{
if(!artType->canBePutAt(h, ArtifactUtils::getArtAnyPosition(h, artType->getId())))
na.pos = ArtifactUtils::getArtAnyPosition(h, artType->getId());
if(!artType->canBePutAt(h, na.pos))
COMPLAIN_RET("Cannot put artifact in that slot!");
}
else if(ArtifactUtils::isSlotBackpack(pos))
@ -3774,18 +3780,8 @@ bool CGameHandler::giveHeroNewArtifact(const CGHeroInstance * h, const CArtifact
{
COMPLAIN_RET_FALSE_IF(!artType->canBePutAt(h, pos, false), "Cannot put artifact in that slot!");
}
auto * newArtInst = new CArtifactInstance();
newArtInst->artType = artType; // *NOT* via settype -> all bonus-related stuff must be done by NewArtifact apply
NewArtifact na;
na.art = newArtInst;
sendAndApply(&na); // -> updates newArtInst!!!
if(putArtifact(ArtifactLocation(h->id, pos), newArtInst, false))
return true;
else
return false;
sendAndApply(&na);
return true;
}
void CGameHandler::spawnWanderingMonsters(CreatureID creatureID)