1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-06-21 00:19:29 +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,24 +221,23 @@ DLL_LINKAGE std::vector<const CArtifact*> ArtifactUtils::assemblyPossibilities(
return arts; 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()); return ArtifactUtils::createArtifact(ArtifactID::SPELL_SCROLL, spellId);
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;
} }
DLL_LINKAGE CArtifactInstance * ArtifactUtils::createNewArtifactInstance(const CArtifact * art) DLL_LINKAGE CArtifactInstance * ArtifactUtils::createArtifact(const ArtifactID & artId, const SpellID & spellId)
{ {
const std::function<CArtifactInstance*(const CArtifact*)> createArtInst =
[&createArtInst, &spellId](const CArtifact * art) -> CArtifactInstance*
{
assert(art); assert(art);
auto * artInst = new CArtifactInstance(art); auto * artInst = new CArtifactInstance(art);
if(art->isCombined()) if(art->isCombined())
{ {
for(const auto & part : art->getConstituents()) for(const auto & part : art->getConstituents())
artInst->addPart(ArtifactUtils::createNewArtifactInstance(part), ArtifactPosition::PRE_FIRST); artInst->addPart(createArtInst(part), ArtifactPosition::PRE_FIRST);
} }
if(art->isGrowing()) if(art->isGrowing())
{ {
@ -247,26 +246,17 @@ DLL_LINKAGE CArtifactInstance * ArtifactUtils::createNewArtifactInstance(const C
bonus->val = 0; bonus->val = 0;
artInst->addNewBonus(bonus); 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; return artInst;
} };
DLL_LINKAGE CArtifactInstance * ArtifactUtils::createNewArtifactInstance(const ArtifactID & aid) if(artId.getNum() >= 0)
{
return ArtifactUtils::createNewArtifactInstance(aid.toArtifact());
}
DLL_LINKAGE CArtifactInstance * ArtifactUtils::createArtifact(const ArtifactID & aid, SpellID spellID)
{
if(aid.getNum() >= 0)
{ {
if(spellID == SpellID::NONE) return createArtInst(artId.toArtifact());
{
return ArtifactUtils::createNewArtifactInstance(aid);
}
else
{
return ArtifactUtils::createScroll(spellID);
}
} }
else else
{ {

View File

@ -39,10 +39,8 @@ namespace ArtifactUtils
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, const bool onlyEquiped = false); 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 * createScroll(const SpellID & spellId);
DLL_LINKAGE CArtifactInstance * createNewArtifactInstance(const CArtifact * art); DLL_LINKAGE CArtifactInstance * createArtifact(const ArtifactID & artId, const SpellID & spellId = SpellID::NONE);
DLL_LINKAGE CArtifactInstance * createNewArtifactInstance(const ArtifactID & aid);
DLL_LINKAGE CArtifactInstance * createArtifact(const ArtifactID & aid, SpellID spellID = SpellID::NONE);
DLL_LINKAGE void insertScrrollSpellName(std::string & description, const SpellID & sid); 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) bool CGameState::giveHeroArtifact(CGHeroInstance * h, const ArtifactID & aid)
{ {
CArtifactInstance * ai = ArtifactUtils::createNewArtifactInstance(aid); CArtifactInstance * ai = ArtifactUtils::createArtifact(aid);
map->addNewArtifactInstance(ai); map->addNewArtifactInstance(ai);
auto slot = ArtifactUtils::getArtAnyPosition(h, aid); auto slot = ArtifactUtils::getArtAnyPosition(h, aid);
if(ArtifactUtils::isSlotEquipment(slot) || ArtifactUtils::isSlotBackpack(slot)) 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 // hero starts with default spellbook presence status
if(!getArt(ArtifactPosition::SPELLBOOK) && type->haveSpellBook) if(!getArt(ArtifactPosition::SPELLBOOK) && type->haveSpellBook)
{ {
auto artifact = ArtifactUtils::createNewArtifactInstance(ArtifactID::SPELLBOOK); auto artifact = ArtifactUtils::createArtifact(ArtifactID::SPELLBOOK);
putArtifact(ArtifactPosition::SPELLBOOK, artifact); putArtifact(ArtifactPosition::SPELLBOOK, artifact);
} }
} }
@ -352,7 +352,7 @@ void CGHeroInstance::initHero(vstd::RNG & rand)
if(!getArt(ArtifactPosition::MACH4)) if(!getArt(ArtifactPosition::MACH4))
{ {
auto artifact = ArtifactUtils::createNewArtifactInstance(ArtifactID::CATAPULT); auto artifact = ArtifactUtils::createArtifact(ArtifactID::CATAPULT);
putArtifact(ArtifactPosition::MACH4, artifact); //everyone has a catapult putArtifact(ArtifactPosition::MACH4, artifact); //everyone has a catapult
} }
@ -468,7 +468,7 @@ void CGHeroInstance::initArmy(vstd::RNG & rand, IArmyDescriptor * dst)
if(!getArt(slot)) if(!getArt(slot))
{ {
auto artifact = ArtifactUtils::createNewArtifactInstance(aid); auto artifact = ArtifactUtils::createArtifact(aid);
putArtifact(slot, artifact); putArtifact(slot, artifact);
} }
else else

View File

@ -1472,17 +1472,11 @@ void NewObject::applyGs(CGameState *gs)
void NewArtifact::applyGs(CGameState *gs) void NewArtifact::applyGs(CGameState *gs)
{ {
assert(!vstd::contains(gs->map->artInstances, art)); auto art = ArtifactUtils::createArtifact(id);
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);
}
gs->map->addNewArtifactInstance(art); gs->map->addNewArtifactInstance(art);
PutArtifact pa(ArtifactLocation(artHolder, pos));
pa.art = art;
pa.applyGs(gs);
} }
const CStackInstance * StackLocation::getStack() const CStackInstance * StackLocation::getStack()
@ -1700,6 +1694,7 @@ void PutArtifact::applyGs(CGameState *gs)
auto hero = gs->getHero(al.artHolder); auto hero = gs->getHero(al.artHolder);
assert(hero); assert(hero);
assert(art && art->canBePutAt(hero, al.slot)); assert(art && art->canBePutAt(hero, al.slot));
assert(ArtifactUtils::checkIfSlotValid(*hero, al.slot));
art->putAt(*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 struct DLL_LINKAGE NewArtifact : public CArtifactOperationPack
{ {
ConstTransitivePtr<CArtifactInstance> art; ObjectInstanceID artHolder;
ArtifactID id;
ArtifactPosition pos;
void applyGs(CGameState * gs) override; void applyGs(CGameState * gs) override;
void visitTyped(ICPackVisitor & visitor) override; void visitTyped(ICPackVisitor & visitor) override;
template <typename Handler> void serialize(Handler & h) 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); nih->removeSpellFromSpellbook(SpellID::SPELLBOOK_PRESET);
if(!nih->getArt(ArtifactPosition::SPELLBOOK) && type->haveSpellBook) 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); assert(artType);
NewArtifact na;
na.artHolder = h->id;
na.id = artType->getId();
na.pos = pos;
if(pos == ArtifactPosition::FIRST_AVAILABLE) 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!"); COMPLAIN_RET("Cannot put artifact in that slot!");
} }
else if(ArtifactUtils::isSlotBackpack(pos)) 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!"); COMPLAIN_RET_FALSE_IF(!artType->canBePutAt(h, pos, false), "Cannot put artifact in that slot!");
} }
sendAndApply(&na);
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; return true;
else
return false;
} }
void CGameHandler::spawnWanderingMonsters(CreatureID creatureID) void CGameHandler::spawnWanderingMonsters(CreatureID creatureID)